xref: /OK3568_Linux_fs/external/rkwifibt/drivers/bcmdhd/bcmsrom.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Routines to access SPROM and to parse SROM/CIS variables.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Despite its file name, OTP contents is also parsed in this file.
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Copyright (C) 2020, Broadcom.
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  *      Unless you and Broadcom execute a separate written software license
9*4882a593Smuzhiyun  * agreement governing use of this software, this software is licensed to you
10*4882a593Smuzhiyun  * under the terms of the GNU General Public License version 2 (the "GPL"),
11*4882a593Smuzhiyun  * available at http://www.broadcom.com/licenses/GPLv2.php, with the
12*4882a593Smuzhiyun  * following added to such license:
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  *      As a special exception, the copyright holders of this software give you
15*4882a593Smuzhiyun  * permission to link this software with independent modules, and to copy and
16*4882a593Smuzhiyun  * distribute the resulting executable under terms of your choice, provided that
17*4882a593Smuzhiyun  * you also meet, for each linked independent module, the terms and conditions of
18*4882a593Smuzhiyun  * the license of that module.  An independent module is a module which is not
19*4882a593Smuzhiyun  * derived from this software.  The special exception does not apply to any
20*4882a593Smuzhiyun  * modifications of the software.
21*4882a593Smuzhiyun  *
22*4882a593Smuzhiyun  *
23*4882a593Smuzhiyun  * <<Broadcom-WL-IPTag/Dual:>>
24*4882a593Smuzhiyun  */
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun /*
27*4882a593Smuzhiyun  * List of non obvious preprocessor defines used in this file and their meaning:
28*4882a593Smuzhiyun  * DONGLEBUILD    : building firmware that runs on the dongle's CPU
29*4882a593Smuzhiyun  * BCM_DONGLEVARS : NVRAM variables can be read from OTP/S(P)ROM.
30*4882a593Smuzhiyun  * When host may supply nvram vars in addition to the ones in OTP/SROM:
31*4882a593Smuzhiyun  * 	BCMHOSTVARS    		: full nic / full dongle
32*4882a593Smuzhiyun  * BCMDONGLEHOST  : defined when building DHD, code executes on the host in a dongle environment.
33*4882a593Smuzhiyun  * DHD_SPROM      : defined when building a DHD that supports reading/writing to SPROM
34*4882a593Smuzhiyun  */
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun #include <typedefs.h>
37*4882a593Smuzhiyun #include <bcmdefs.h>
38*4882a593Smuzhiyun #include <osl.h>
39*4882a593Smuzhiyun #include <stdarg.h>
40*4882a593Smuzhiyun #include <bcmutils.h>
41*4882a593Smuzhiyun #include <hndsoc.h>
42*4882a593Smuzhiyun #include <sbchipc.h>
43*4882a593Smuzhiyun #include <bcmdevs.h>
44*4882a593Smuzhiyun #include <bcmendian.h>
45*4882a593Smuzhiyun #include <sbpcmcia.h>
46*4882a593Smuzhiyun #include <pcicfg.h>
47*4882a593Smuzhiyun #include <siutils.h>
48*4882a593Smuzhiyun #include <bcmsrom.h>
49*4882a593Smuzhiyun #include <bcmsrom_tbl.h>
50*4882a593Smuzhiyun #ifdef BCMSDIO
51*4882a593Smuzhiyun #include <bcmsdh.h>
52*4882a593Smuzhiyun #include <sdio.h>
53*4882a593Smuzhiyun #endif
54*4882a593Smuzhiyun #ifdef BCMSPI
55*4882a593Smuzhiyun #include <spid.h>
56*4882a593Smuzhiyun #endif
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun #include <bcmnvram.h>
59*4882a593Smuzhiyun #include <bcmotp.h>
60*4882a593Smuzhiyun #ifndef BCMUSBDEV_COMPOSITE
61*4882a593Smuzhiyun #define BCMUSBDEV_COMPOSITE
62*4882a593Smuzhiyun #endif
63*4882a593Smuzhiyun #if defined(BCMUSBDEV) || defined(BCMSDIO) || defined(BCMSDIODEV)
64*4882a593Smuzhiyun #include <sbsdio.h>
65*4882a593Smuzhiyun #include <sbhnddma.h>
66*4882a593Smuzhiyun #include <sbsdpcmdev.h>
67*4882a593Smuzhiyun #endif
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun #if defined(WLTEST) || defined (DHD_SPROM) || defined (BCMDBG)
70*4882a593Smuzhiyun #include <sbsprom.h>
71*4882a593Smuzhiyun #endif
72*4882a593Smuzhiyun #include <ethernet.h>	/* for sprom content groking */
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun #include <sbgci.h>
75*4882a593Smuzhiyun #ifdef EVENT_LOG_COMPILE
76*4882a593Smuzhiyun #include <event_log.h>
77*4882a593Smuzhiyun #endif
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun #if defined(EVENT_LOG_COMPILE) && defined(BCMDBG_ERR) && defined(ERR_USE_EVENT_LOG)
80*4882a593Smuzhiyun #if defined(ERR_USE_EVENT_LOG_RA)
81*4882a593Smuzhiyun #define	BS_ERROR(args)	EVENT_LOG_RA(EVENT_LOG_TAG_BSROM_ERROR, args)
82*4882a593Smuzhiyun #else
83*4882a593Smuzhiyun #define	BS_ERROR(args)	EVENT_LOG_COMPACT_CAST_PAREN_ARGS(EVENT_LOG_TAG_BSROM_ERROR, args)
84*4882a593Smuzhiyun #endif /* ERR_USE_EVENT_LOG_RA */
85*4882a593Smuzhiyun #elif defined(BCMDBG_ERR) || defined(WLTEST)
86*4882a593Smuzhiyun #define BS_ERROR(args)	printf args
87*4882a593Smuzhiyun #else
88*4882a593Smuzhiyun #define BS_ERROR(args)
89*4882a593Smuzhiyun #endif	/* defined(BCMDBG_ERR) && defined(ERR_USE_EVENT_LOG) */
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun #if defined(BCMPCIEDEV_SROM_FORMAT) && defined(WLC_TXCAL)
92*4882a593Smuzhiyun static bool BCMATTACHDATA(is_caldata_prsnt) = FALSE;
93*4882a593Smuzhiyun static uint16 BCMATTACHDATA(caldata_array)[SROM_MAX / 2];
94*4882a593Smuzhiyun static uint8 BCMATTACHDATA(srom_sromrev);
95*4882a593Smuzhiyun #endif
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun static const char BCMATTACHDATA(rstr_uuidstr)[] =
98*4882a593Smuzhiyun 	"%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X";
99*4882a593Smuzhiyun static const char BCMATTACHDATA(rstr_paddr)[] = "pa%d=0x%%x";
100*4882a593Smuzhiyun static const char BCMATTACHDATA(rstr_pdata)[] = "pd%d=0x%%x";
101*4882a593Smuzhiyun static const char BCMATTACHDATA(rstr_pdatah)[] = "pdh%d=0x%%x";
102*4882a593Smuzhiyun static const char BCMATTACHDATA(rstr_pdatal)[] = "pdl%d=0x%%x";
103*4882a593Smuzhiyun static const char BCMATTACHDATA(rstr_gci_ccreg_entry)[] = "gcr%d=0x%%x";
104*4882a593Smuzhiyun static const char BCMATTACHDATA(rstr_hex)[] = "0x%x";
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun /** curmap: contains host start address of PCI BAR0 window */
srom_offset(si_t * sih,volatile void * curmap)107*4882a593Smuzhiyun static volatile uint8* srom_offset(si_t *sih, volatile void *curmap)
108*4882a593Smuzhiyun {
109*4882a593Smuzhiyun 	if (sih->ccrev <= 31)
110*4882a593Smuzhiyun 		return (volatile uint8*)curmap + PCI_BAR0_SPROM_OFFSET;
111*4882a593Smuzhiyun 	if ((sih->cccaps & CC_CAP_SROM) == 0)
112*4882a593Smuzhiyun 		return NULL;
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun 	if (BUSTYPE(sih->bustype) == SI_BUS)
115*4882a593Smuzhiyun 		return (uint8 *)((uintptr)SI_ENUM_BASE(sih) + CC_SROM_OTP);
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun 	return (volatile uint8*)curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP;
118*4882a593Smuzhiyun }
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun #if defined(WLTEST) || defined (DHD_SPROM) || defined (BCMDBG)
121*4882a593Smuzhiyun #define WRITE_ENABLE_DELAY	500	/* 500 ms after write enable/disable toggle */
122*4882a593Smuzhiyun #define WRITE_WORD_DELAY	20	/* 20 ms between each word write */
123*4882a593Smuzhiyun #endif
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun srom_info_t *sromh = NULL;
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun extern char *_vars;
128*4882a593Smuzhiyun extern uint _varsz;
129*4882a593Smuzhiyun #ifdef DONGLEBUILD
130*4882a593Smuzhiyun char * BCMATTACHDATA(_vars_otp) = NULL;
131*4882a593Smuzhiyun #define DONGLE_STORE_VARS_OTP_PTR(v)	(_vars_otp = (v))
132*4882a593Smuzhiyun #else
133*4882a593Smuzhiyun #define DONGLE_STORE_VARS_OTP_PTR(v)
134*4882a593Smuzhiyun #endif
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun #define SROM_CIS_SINGLE	1
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun #if !defined(BCMDONGLEHOST)
139*4882a593Smuzhiyun static int initvars_srom_si(si_t *sih, osl_t *osh, volatile void *curmap, char **vars, uint *count);
140*4882a593Smuzhiyun static void _initvars_srom_pci(uint8 sromrev, uint16 *srom, uint off, varbuf_t *b);
141*4882a593Smuzhiyun static int initvars_srom_pci(si_t *sih, volatile void *curmap, char **vars, uint *count);
142*4882a593Smuzhiyun static int initvars_cis_pci(si_t *sih, osl_t *osh, volatile void *curmap, char **vars, uint *count);
143*4882a593Smuzhiyun #endif /* !defined(BCMDONGLEHOST) */
144*4882a593Smuzhiyun #if !defined(BCMUSBDEV_ENABLED) && !defined(BCMSDIODEV_ENABLED) &&\
145*4882a593Smuzhiyun 	!defined(BCMDONGLEHOST) && !defined(BCMPCIEDEV_ENABLED)
146*4882a593Smuzhiyun static int initvars_flash_si(si_t *sih, char **vars, uint *count);
147*4882a593Smuzhiyun #endif /* !defined(BCMUSBDEV) && !defined(BCMSDIODEV) && !defined(BCMDONGLEHOST) */
148*4882a593Smuzhiyun #ifdef BCMSDIO
149*4882a593Smuzhiyun #if !defined(BCMDONGLEHOST)
150*4882a593Smuzhiyun static int initvars_cis_sdio(si_t *sih, osl_t *osh, char **vars, uint *count);
151*4882a593Smuzhiyun #endif /* !defined(BCMDONGLEHOST) */
152*4882a593Smuzhiyun static int sprom_cmd_sdio(osl_t *osh, uint8 cmd);
153*4882a593Smuzhiyun static int sprom_read_sdio(osl_t *osh, uint16 addr, uint16 *data);
154*4882a593Smuzhiyun #if defined(WLTEST) || defined (DHD_SPROM) || defined (BCMDBG)
155*4882a593Smuzhiyun static int sprom_write_sdio(osl_t *osh, uint16 addr, uint16 data);
156*4882a593Smuzhiyun #endif /* defined(WLTEST) || defined (DHD_SPROM) || defined (BCMDBG) */
157*4882a593Smuzhiyun #endif /* BCMSDIO */
158*4882a593Smuzhiyun #if !defined(BCMDONGLEHOST)
159*4882a593Smuzhiyun #ifdef BCMSPI
160*4882a593Smuzhiyun static int initvars_cis_spi(si_t *sih, osl_t *osh, char **vars, uint *count);
161*4882a593Smuzhiyun #endif /* BCMSPI */
162*4882a593Smuzhiyun #endif /* !defined(BCMDONGLEHOST) */
163*4882a593Smuzhiyun static int sprom_read_pci(osl_t *osh, si_t *sih, volatile uint16 *sprom, uint wordoff, uint16 *buf,
164*4882a593Smuzhiyun                           uint nwords, bool check_crc);
165*4882a593Smuzhiyun #if !defined(BCMDONGLEHOST)
166*4882a593Smuzhiyun #if defined(BCMNVRAMW) || defined(BCMNVRAMR)
167*4882a593Smuzhiyun static int otp_read_pci(osl_t *osh, si_t *sih, uint16 *buf, uint bufsz);
168*4882a593Smuzhiyun #endif /* defined(BCMNVRAMW) || defined(BCMNVRAMR) */
169*4882a593Smuzhiyun #endif /* !defined(BCMDONGLEHOST) */
170*4882a593Smuzhiyun static uint16 srom_cc_cmd(si_t *sih, osl_t *osh, volatile void *ccregs, uint32 cmd, uint wordoff,
171*4882a593Smuzhiyun                           uint16 data);
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun #if !defined(BCMDONGLEHOST)
174*4882a593Smuzhiyun static int initvars_flash(si_t *sih, osl_t *osh, char **vp, uint len);
175*4882a593Smuzhiyun int dbushost_initvars_flash(si_t *sih, osl_t *osh, char **base, uint len);
176*4882a593Smuzhiyun static uint get_max_cis_size(si_t *sih);
177*4882a593Smuzhiyun #endif /* !defined(BCMDONGLEHOST) */
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun #if defined (BCMHOSTVARS)
180*4882a593Smuzhiyun /* Also used by wl_readconfigdata for vars download */
181*4882a593Smuzhiyun char BCMATTACHDATA(mfgsromvars)[VARS_MAX];
182*4882a593Smuzhiyun int BCMATTACHDATA(defvarslen) = 0;
183*4882a593Smuzhiyun #endif /* defined(BCMHOSTVARS) */
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun #if !defined(BCMDONGLEHOST)
186*4882a593Smuzhiyun #if defined (BCMHOSTVARS)
187*4882a593Smuzhiyun /* FIXME: Fake 4331 SROM to boot 4331 driver on QT w/o SPROM/OTP */
188*4882a593Smuzhiyun static char BCMATTACHDATA(defaultsromvars_4331)[] =
189*4882a593Smuzhiyun 	"sromrev=9\0"
190*4882a593Smuzhiyun 	"boardrev=0x1104\0"
191*4882a593Smuzhiyun 	"boardflags=0x200\0"
192*4882a593Smuzhiyun 	"boardflags2=0x0\0"
193*4882a593Smuzhiyun 	"boardtype=0x524\0"
194*4882a593Smuzhiyun 	"boardvendor=0x14e4\0"
195*4882a593Smuzhiyun 	"boardnum=0x2064\0"
196*4882a593Smuzhiyun 	"macaddr=00:90:4c:1a:20:64\0"
197*4882a593Smuzhiyun 	"ccode=0x0\0"
198*4882a593Smuzhiyun 	"regrev=0x0\0"
199*4882a593Smuzhiyun 	"opo=0x0\0"
200*4882a593Smuzhiyun 	"aa2g=0x7\0"
201*4882a593Smuzhiyun 	"aa5g=0x7\0"
202*4882a593Smuzhiyun 	"ag0=0x2\0"
203*4882a593Smuzhiyun 	"ag1=0x2\0"
204*4882a593Smuzhiyun 	"ag2=0x2\0"
205*4882a593Smuzhiyun 	"ag3=0xff\0"
206*4882a593Smuzhiyun 	"pa0b0=0xfe7f\0"
207*4882a593Smuzhiyun 	"pa0b1=0x15d9\0"
208*4882a593Smuzhiyun 	"pa0b2=0xfac6\0"
209*4882a593Smuzhiyun 	"pa0itssit=0x20\0"
210*4882a593Smuzhiyun 	"pa0maxpwr=0x48\0"
211*4882a593Smuzhiyun 	"pa1b0=0xfe89\0"
212*4882a593Smuzhiyun 	"pa1b1=0x14b1\0"
213*4882a593Smuzhiyun 	"pa1b2=0xfada\0"
214*4882a593Smuzhiyun 	"pa1lob0=0xffff\0"
215*4882a593Smuzhiyun 	"pa1lob1=0xffff\0"
216*4882a593Smuzhiyun 	"pa1lob2=0xffff\0"
217*4882a593Smuzhiyun 	"pa1hib0=0xfe8f\0"
218*4882a593Smuzhiyun 	"pa1hib1=0x13df\0"
219*4882a593Smuzhiyun 	"pa1hib2=0xfafa\0"
220*4882a593Smuzhiyun 	"pa1itssit=0x3e\0"
221*4882a593Smuzhiyun 	"pa1maxpwr=0x3c\0"
222*4882a593Smuzhiyun 	"pa1lomaxpwr=0x3c\0"
223*4882a593Smuzhiyun 	"pa1himaxpwr=0x3c\0"
224*4882a593Smuzhiyun 	"bxa2g=0x3\0"
225*4882a593Smuzhiyun 	"rssisav2g=0x7\0"
226*4882a593Smuzhiyun 	"rssismc2g=0xf\0"
227*4882a593Smuzhiyun 	"rssismf2g=0xf\0"
228*4882a593Smuzhiyun 	"bxa5g=0x3\0"
229*4882a593Smuzhiyun 	"rssisav5g=0x7\0"
230*4882a593Smuzhiyun 	"rssismc5g=0xf\0"
231*4882a593Smuzhiyun 	"rssismf5g=0xf\0"
232*4882a593Smuzhiyun 	"tri2g=0xff\0"
233*4882a593Smuzhiyun 	"tri5g=0xff\0"
234*4882a593Smuzhiyun 	"tri5gl=0xff\0"
235*4882a593Smuzhiyun 	"tri5gh=0xff\0"
236*4882a593Smuzhiyun 	"rxpo2g=0xff\0"
237*4882a593Smuzhiyun 	"rxpo5g=0xff\0"
238*4882a593Smuzhiyun 	"txchain=0x7\0"
239*4882a593Smuzhiyun 	"rxchain=0x7\0"
240*4882a593Smuzhiyun 	"antswitch=0x0\0"
241*4882a593Smuzhiyun 	"tssipos2g=0x1\0"
242*4882a593Smuzhiyun 	"extpagain2g=0x2\0"
243*4882a593Smuzhiyun 	"pdetrange2g=0x4\0"
244*4882a593Smuzhiyun 	"triso2g=0x3\0"
245*4882a593Smuzhiyun 	"antswctl2g=0x0\0"
246*4882a593Smuzhiyun 	"tssipos5g=0x1\0"
247*4882a593Smuzhiyun 	"elna2g=0xff\0"
248*4882a593Smuzhiyun 	"extpagain5g=0x2\0"
249*4882a593Smuzhiyun 	"pdetrange5g=0x4\0"
250*4882a593Smuzhiyun 	"triso5g=0x3\0"
251*4882a593Smuzhiyun 	"antswctl5g=0x0\0"
252*4882a593Smuzhiyun 	"elna5g=0xff\0"
253*4882a593Smuzhiyun 	"cckbw202gpo=0x0\0"
254*4882a593Smuzhiyun 	"cckbw20ul2gpo=0x0\0"
255*4882a593Smuzhiyun 	"legofdmbw202gpo=0x0\0"
256*4882a593Smuzhiyun 	"legofdmbw20ul2gpo=0x0\0"
257*4882a593Smuzhiyun 	"legofdmbw205glpo=0x0\0"
258*4882a593Smuzhiyun 	"legofdmbw20ul5glpo=0x0\0"
259*4882a593Smuzhiyun 	"legofdmbw205gmpo=0x0\0"
260*4882a593Smuzhiyun 	"legofdmbw20ul5gmpo=0x0\0"
261*4882a593Smuzhiyun 	"legofdmbw205ghpo=0x0\0"
262*4882a593Smuzhiyun 	"legofdmbw20ul5ghpo=0x0\0"
263*4882a593Smuzhiyun 	"mcsbw202gpo=0x0\0"
264*4882a593Smuzhiyun 	"mcsbw20ul2gpo=0x0\0"
265*4882a593Smuzhiyun 	"mcsbw402gpo=0x0\0"
266*4882a593Smuzhiyun 	"mcsbw205glpo=0x0\0"
267*4882a593Smuzhiyun 	"mcsbw20ul5glpo=0x0\0"
268*4882a593Smuzhiyun 	"mcsbw405glpo=0x0\0"
269*4882a593Smuzhiyun 	"mcsbw205gmpo=0x0\0"
270*4882a593Smuzhiyun 	"mcsbw20ul5gmpo=0x0\0"
271*4882a593Smuzhiyun 	"mcsbw405gmpo=0x0\0"
272*4882a593Smuzhiyun 	"mcsbw205ghpo=0x0\0"
273*4882a593Smuzhiyun 	"mcsbw20ul5ghpo=0x0\0"
274*4882a593Smuzhiyun 	"mcsbw405ghpo=0x0\0"
275*4882a593Smuzhiyun 	"mcs32po=0x0\0"
276*4882a593Smuzhiyun 	"legofdm40duppo=0x0\0"
277*4882a593Smuzhiyun 	"maxp2ga0=0x48\0"
278*4882a593Smuzhiyun 	"itt2ga0=0x20\0"
279*4882a593Smuzhiyun 	"itt5ga0=0x3e\0"
280*4882a593Smuzhiyun 	"pa2gw0a0=0xfe7f\0"
281*4882a593Smuzhiyun 	"pa2gw1a0=0x15d9\0"
282*4882a593Smuzhiyun 	"pa2gw2a0=0xfac6\0"
283*4882a593Smuzhiyun 	"maxp5ga0=0x3c\0"
284*4882a593Smuzhiyun 	"maxp5gha0=0x3c\0"
285*4882a593Smuzhiyun 	"maxp5gla0=0x3c\0"
286*4882a593Smuzhiyun 	"pa5gw0a0=0xfe89\0"
287*4882a593Smuzhiyun 	"pa5gw1a0=0x14b1\0"
288*4882a593Smuzhiyun 	"pa5gw2a0=0xfada\0"
289*4882a593Smuzhiyun 	"pa5glw0a0=0xffff\0"
290*4882a593Smuzhiyun 	"pa5glw1a0=0xffff\0"
291*4882a593Smuzhiyun 	"pa5glw2a0=0xffff\0"
292*4882a593Smuzhiyun 	"pa5ghw0a0=0xfe8f\0"
293*4882a593Smuzhiyun 	"pa5ghw1a0=0x13df\0"
294*4882a593Smuzhiyun 	"pa5ghw2a0=0xfafa\0"
295*4882a593Smuzhiyun 	"maxp2ga1=0x48\0"
296*4882a593Smuzhiyun 	"itt2ga1=0x20\0"
297*4882a593Smuzhiyun 	"itt5ga1=0x3e\0"
298*4882a593Smuzhiyun 	"pa2gw0a1=0xfe54\0"
299*4882a593Smuzhiyun 	"pa2gw1a1=0x1563\0"
300*4882a593Smuzhiyun 	"pa2gw2a1=0xfa7f\0"
301*4882a593Smuzhiyun 	"maxp5ga1=0x3c\0"
302*4882a593Smuzhiyun 	"maxp5gha1=0x3c\0"
303*4882a593Smuzhiyun 	"maxp5gla1=0x3c\0"
304*4882a593Smuzhiyun 	"pa5gw0a1=0xfe53\0"
305*4882a593Smuzhiyun 	"pa5gw1a1=0x14fe\0"
306*4882a593Smuzhiyun 	"pa5gw2a1=0xfa94\0"
307*4882a593Smuzhiyun 	"pa5glw0a1=0xffff\0"
308*4882a593Smuzhiyun 	"pa5glw1a1=0xffff\0"
309*4882a593Smuzhiyun 	"pa5glw2a1=0xffff\0"
310*4882a593Smuzhiyun 	"pa5ghw0a1=0xfe6e\0"
311*4882a593Smuzhiyun 	"pa5ghw1a1=0x1457\0"
312*4882a593Smuzhiyun 	"pa5ghw2a1=0xfab9\0"
313*4882a593Smuzhiyun 	"END\0";
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun static char BCMATTACHDATA(defaultsromvars_4360)[] =
316*4882a593Smuzhiyun 	"sromrev=11\0"
317*4882a593Smuzhiyun 	"boardrev=0x1421\0"
318*4882a593Smuzhiyun 	"boardflags=0x10401001\0"
319*4882a593Smuzhiyun 	"boardflags2=0x0\0"
320*4882a593Smuzhiyun 	"boardtype=0x61b\0"
321*4882a593Smuzhiyun 	"subvid=0x14e4\0"
322*4882a593Smuzhiyun 	"boardflags3=0x1\0"
323*4882a593Smuzhiyun 	"boardnum=62526\0"
324*4882a593Smuzhiyun 	"macaddr=00:90:4c:0d:f4:3e\0"
325*4882a593Smuzhiyun 	"ccode=X0\0"
326*4882a593Smuzhiyun 	"regrev=15\0"
327*4882a593Smuzhiyun 	"aa2g=7\0"
328*4882a593Smuzhiyun 	"aa5g=7\0"
329*4882a593Smuzhiyun 	"agbg0=71\0"
330*4882a593Smuzhiyun 	"agbg1=71\0"
331*4882a593Smuzhiyun 	"agbg2=133\0"
332*4882a593Smuzhiyun 	"aga0=71\0"
333*4882a593Smuzhiyun 	"aga1=133\0"
334*4882a593Smuzhiyun 	"aga2=133\0"
335*4882a593Smuzhiyun 	"antswitch=0\0"
336*4882a593Smuzhiyun 	"tssiposslope2g=1\0"
337*4882a593Smuzhiyun 	"epagain2g=0\0"
338*4882a593Smuzhiyun 	"pdgain2g=9\0"
339*4882a593Smuzhiyun 	"tworangetssi2g=0\0"
340*4882a593Smuzhiyun 	"papdcap2g=0\0"
341*4882a593Smuzhiyun 	"femctrl=2\0"
342*4882a593Smuzhiyun 	"tssiposslope5g=1\0"
343*4882a593Smuzhiyun 	"epagain5g=0\0"
344*4882a593Smuzhiyun 	"pdgain5g=9\0"
345*4882a593Smuzhiyun 	"tworangetssi5g=0\0"
346*4882a593Smuzhiyun 	"papdcap5g=0\0"
347*4882a593Smuzhiyun 	"gainctrlsph=0\0"
348*4882a593Smuzhiyun 	"tempthresh=255\0"
349*4882a593Smuzhiyun 	"tempoffset=255\0"
350*4882a593Smuzhiyun 	"rawtempsense=0x1ff\0"
351*4882a593Smuzhiyun 	"measpower=0x7f\0"
352*4882a593Smuzhiyun 	"tempsense_slope=0xff\0"
353*4882a593Smuzhiyun 	"tempcorrx=0x3f\0"
354*4882a593Smuzhiyun 	"tempsense_option=0x3\0"
355*4882a593Smuzhiyun 	"xtalfreq=65535\0"
356*4882a593Smuzhiyun 	"phycal_tempdelta=255\0"
357*4882a593Smuzhiyun 	"temps_period=15\0"
358*4882a593Smuzhiyun 	"temps_hysteresis=15\0"
359*4882a593Smuzhiyun 	"measpower1=0x7f\0"
360*4882a593Smuzhiyun 	"measpower2=0x7f\0"
361*4882a593Smuzhiyun 	"pdoffset2g40ma0=15\0"
362*4882a593Smuzhiyun 	"pdoffset2g40ma1=15\0"
363*4882a593Smuzhiyun 	"pdoffset2g40ma2=15\0"
364*4882a593Smuzhiyun 	"pdoffset2g40mvalid=1\0"
365*4882a593Smuzhiyun 	"pdoffset40ma0=9010\0"
366*4882a593Smuzhiyun 	"pdoffset40ma1=12834\0"
367*4882a593Smuzhiyun 	"pdoffset40ma2=8994\0"
368*4882a593Smuzhiyun 	"pdoffset80ma0=16\0"
369*4882a593Smuzhiyun 	"pdoffset80ma1=4096\0"
370*4882a593Smuzhiyun 	"pdoffset80ma2=0\0"
371*4882a593Smuzhiyun 	"subband5gver=0x4\0"
372*4882a593Smuzhiyun 	"cckbw202gpo=0\0"
373*4882a593Smuzhiyun 	"cckbw20ul2gpo=0\0"
374*4882a593Smuzhiyun 	"mcsbw202gpo=2571386880\0"
375*4882a593Smuzhiyun 	"mcsbw402gpo=2571386880\0"
376*4882a593Smuzhiyun 	"dot11agofdmhrbw202gpo=17408\0"
377*4882a593Smuzhiyun 	"ofdmlrbw202gpo=0\0"
378*4882a593Smuzhiyun 	"mcsbw205glpo=4001923072\0"
379*4882a593Smuzhiyun 	"mcsbw405glpo=4001923072\0"
380*4882a593Smuzhiyun 	"mcsbw805glpo=4001923072\0"
381*4882a593Smuzhiyun 	"mcsbw1605glpo=0\0"
382*4882a593Smuzhiyun 	"mcsbw205gmpo=3431497728\0"
383*4882a593Smuzhiyun 	"mcsbw405gmpo=3431497728\0"
384*4882a593Smuzhiyun 	"mcsbw805gmpo=3431497728\0"
385*4882a593Smuzhiyun 	"mcsbw1605gmpo=0\0"
386*4882a593Smuzhiyun 	"mcsbw205ghpo=3431497728\0"
387*4882a593Smuzhiyun 	"mcsbw405ghpo=3431497728\0"
388*4882a593Smuzhiyun 	"mcsbw805ghpo=3431497728\0"
389*4882a593Smuzhiyun 	"mcsbw1605ghpo=0\0"
390*4882a593Smuzhiyun 	"mcslr5glpo=0\0"
391*4882a593Smuzhiyun 	"mcslr5gmpo=0\0"
392*4882a593Smuzhiyun 	"mcslr5ghpo=0\0"
393*4882a593Smuzhiyun 	"sb20in40hrpo=0\0"
394*4882a593Smuzhiyun 	"sb20in80and160hr5glpo=0\0"
395*4882a593Smuzhiyun 	"sb40and80hr5glpo=0\0"
396*4882a593Smuzhiyun 	"sb20in80and160hr5gmpo=0\0"
397*4882a593Smuzhiyun 	"sb40and80hr5gmpo=0\0"
398*4882a593Smuzhiyun 	"sb20in80and160hr5ghpo=0\0"
399*4882a593Smuzhiyun 	"sb40and80hr5ghpo=0\0"
400*4882a593Smuzhiyun 	"sb20in40lrpo=0\0"
401*4882a593Smuzhiyun 	"sb20in80and160lr5glpo=0\0"
402*4882a593Smuzhiyun 	"sb40and80lr5glpo=0\0"
403*4882a593Smuzhiyun 	"sb20in80and160lr5gmpo=0\0"
404*4882a593Smuzhiyun 	"sb40and80lr5gmpo=0\0"
405*4882a593Smuzhiyun 	"sb20in80and160lr5ghpo=0\0"
406*4882a593Smuzhiyun 	"sb40and80lr5ghpo=0\0"
407*4882a593Smuzhiyun 	"dot11agduphrpo=0\0"
408*4882a593Smuzhiyun 	"dot11agduplrpo=0\0"
409*4882a593Smuzhiyun 	"pcieingress_war=15\0"
410*4882a593Smuzhiyun 	"sar2g=18\0"
411*4882a593Smuzhiyun 	"sar5g=15\0"
412*4882a593Smuzhiyun 	"noiselvl2ga0=31\0"
413*4882a593Smuzhiyun 	"noiselvl2ga1=31\0"
414*4882a593Smuzhiyun 	"noiselvl2ga2=31\0"
415*4882a593Smuzhiyun 	"noiselvl5ga0=31,31,31,31\0"
416*4882a593Smuzhiyun 	"noiselvl5ga1=31,31,31,31\0"
417*4882a593Smuzhiyun 	"noiselvl5ga2=31,31,31,31\0"
418*4882a593Smuzhiyun 	"rxgainerr2ga0=63\0"
419*4882a593Smuzhiyun 	"rxgainerr2ga1=31\0"
420*4882a593Smuzhiyun 	"rxgainerr2ga2=31\0"
421*4882a593Smuzhiyun 	"rxgainerr5ga0=63,63,63,63\0"
422*4882a593Smuzhiyun 	"rxgainerr5ga1=31,31,31,31\0"
423*4882a593Smuzhiyun 	"rxgainerr5ga2=31,31,31,31\0"
424*4882a593Smuzhiyun 	"maxp2ga0=76\0"
425*4882a593Smuzhiyun 	"pa2ga0=0xff3c,0x172c,0xfd20\0"
426*4882a593Smuzhiyun 	"rxgains5gmelnagaina0=7\0"
427*4882a593Smuzhiyun 	"rxgains5gmtrisoa0=15\0"
428*4882a593Smuzhiyun 	"rxgains5gmtrelnabypa0=1\0"
429*4882a593Smuzhiyun 	"rxgains5ghelnagaina0=7\0"
430*4882a593Smuzhiyun 	"rxgains5ghtrisoa0=15\0"
431*4882a593Smuzhiyun 	"rxgains5ghtrelnabypa0=1\0"
432*4882a593Smuzhiyun 	"rxgains2gelnagaina0=4\0"
433*4882a593Smuzhiyun 	"rxgains2gtrisoa0=7\0"
434*4882a593Smuzhiyun 	"rxgains2gtrelnabypa0=1\0"
435*4882a593Smuzhiyun 	"rxgains5gelnagaina0=3\0"
436*4882a593Smuzhiyun 	"rxgains5gtrisoa0=7\0"
437*4882a593Smuzhiyun 	"rxgains5gtrelnabypa0=1\0"
438*4882a593Smuzhiyun 	"maxp5ga0=76,76,76,76\0"
439*4882a593Smuzhiyun "pa5ga0=0xff3a,0x14d4,0xfd5f,0xff36,0x1626,0xfd2e,0xff42,0x15bd,0xfd47,0xff39,0x15a3,0xfd3d\0"
440*4882a593Smuzhiyun 	"maxp2ga1=76\0"
441*4882a593Smuzhiyun 	"pa2ga1=0xff2a,0x16b2,0xfd28\0"
442*4882a593Smuzhiyun 	"rxgains5gmelnagaina1=7\0"
443*4882a593Smuzhiyun 	"rxgains5gmtrisoa1=15\0"
444*4882a593Smuzhiyun 	"rxgains5gmtrelnabypa1=1\0"
445*4882a593Smuzhiyun 	"rxgains5ghelnagaina1=7\0"
446*4882a593Smuzhiyun 	"rxgains5ghtrisoa1=15\0"
447*4882a593Smuzhiyun 	"rxgains5ghtrelnabypa1=1\0"
448*4882a593Smuzhiyun 	"rxgains2gelnagaina1=3\0"
449*4882a593Smuzhiyun 	"rxgains2gtrisoa1=6\0"
450*4882a593Smuzhiyun 	"rxgains2gtrelnabypa1=1\0"
451*4882a593Smuzhiyun 	"rxgains5gelnagaina1=3\0"
452*4882a593Smuzhiyun 	"rxgains5gtrisoa1=6\0"
453*4882a593Smuzhiyun 	"rxgains5gtrelnabypa1=1\0"
454*4882a593Smuzhiyun 	"maxp5ga1=76,76,76,76\0"
455*4882a593Smuzhiyun "pa5ga1=0xff4e,0x1530,0xfd53,0xff58,0x15b4,0xfd4d,0xff58,0x1671,0xfd2f,0xff55,0x15e2,0xfd46\0"
456*4882a593Smuzhiyun 	"maxp2ga2=76\0"
457*4882a593Smuzhiyun 	"pa2ga2=0xff3c,0x1736,0xfd1f\0"
458*4882a593Smuzhiyun 	"rxgains5gmelnagaina2=7\0"
459*4882a593Smuzhiyun 	"rxgains5gmtrisoa2=15\0"
460*4882a593Smuzhiyun 	"rxgains5gmtrelnabypa2=1\0"
461*4882a593Smuzhiyun 	"rxgains5ghelnagaina2=7\0"
462*4882a593Smuzhiyun 	"rxgains5ghtrisoa2=15\0"
463*4882a593Smuzhiyun 	"rxgains5ghtrelnabypa2=1\0"
464*4882a593Smuzhiyun 	"rxgains2gelnagaina2=4\0"
465*4882a593Smuzhiyun 	"rxgains2gtrisoa2=7\0"
466*4882a593Smuzhiyun 	"rxgains2gtrelnabypa2=1\0"
467*4882a593Smuzhiyun 	"rxgains5gelnagaina2=3\0"
468*4882a593Smuzhiyun 	"rxgains5gtrisoa2=7\0"
469*4882a593Smuzhiyun 	"rxgains5gtrelnabypa2=1\0"
470*4882a593Smuzhiyun 	"maxp5ga2=76,76,76,76\0"
471*4882a593Smuzhiyun "pa5ga2=0xff2d,0x144a,0xfd63,0xff35,0x15d7,0xfd3b,0xff35,0x1668,0xfd2f,0xff31,0x1664,0xfd27\0"
472*4882a593Smuzhiyun 	"END\0";
473*4882a593Smuzhiyun 
474*4882a593Smuzhiyun #endif /* defined(BCMHOSTVARS) */
475*4882a593Smuzhiyun #endif /* !defined(BCMDONGLEHOST) */
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun #if !defined(BCMDONGLEHOST)
478*4882a593Smuzhiyun #if defined(BCMHOSTVARS)
479*4882a593Smuzhiyun static char BCMATTACHDATA(defaultsromvars_wltest)[] =
480*4882a593Smuzhiyun 	"macaddr=00:90:4c:f8:00:01\0"
481*4882a593Smuzhiyun 	"et0macaddr=00:11:22:33:44:52\0"
482*4882a593Smuzhiyun 	"et0phyaddr=30\0"
483*4882a593Smuzhiyun 	"et0mdcport=0\0"
484*4882a593Smuzhiyun 	"gpio2=robo_reset\0"
485*4882a593Smuzhiyun 	"boardvendor=0x14e4\0"
486*4882a593Smuzhiyun 	"boardflags=0x210\0"
487*4882a593Smuzhiyun 	"boardflags2=0\0"
488*4882a593Smuzhiyun 	"boardtype=0x04c3\0"
489*4882a593Smuzhiyun 	"boardrev=0x1100\0"
490*4882a593Smuzhiyun 	"sromrev=8\0"
491*4882a593Smuzhiyun 	"devid=0x432c\0"
492*4882a593Smuzhiyun 	"ccode=0\0"
493*4882a593Smuzhiyun 	"regrev=0\0"
494*4882a593Smuzhiyun 	"aa2g=3\0"
495*4882a593Smuzhiyun 	"ag0=2\0"
496*4882a593Smuzhiyun 	"ag1=2\0"
497*4882a593Smuzhiyun 	"aa5g=3\0"
498*4882a593Smuzhiyun 	"aa0=2\0"
499*4882a593Smuzhiyun 	"aa1=2\0"
500*4882a593Smuzhiyun 	"txchain=3\0"
501*4882a593Smuzhiyun 	"rxchain=3\0"
502*4882a593Smuzhiyun 	"antswitch=0\0"
503*4882a593Smuzhiyun 	"itt2ga0=0x20\0"
504*4882a593Smuzhiyun 	"maxp2ga0=0x48\0"
505*4882a593Smuzhiyun 	"pa2gw0a0=0xfe9e\0"
506*4882a593Smuzhiyun 	"pa2gw1a0=0x15d5\0"
507*4882a593Smuzhiyun 	"pa2gw2a0=0xfae9\0"
508*4882a593Smuzhiyun 	"itt2ga1=0x20\0"
509*4882a593Smuzhiyun 	"maxp2ga1=0x48\0"
510*4882a593Smuzhiyun 	"pa2gw0a1=0xfeb3\0"
511*4882a593Smuzhiyun 	"pa2gw1a1=0x15c9\0"
512*4882a593Smuzhiyun 	"pa2gw2a1=0xfaf7\0"
513*4882a593Smuzhiyun 	"tssipos2g=1\0"
514*4882a593Smuzhiyun 	"extpagain2g=0\0"
515*4882a593Smuzhiyun 	"pdetrange2g=0\0"
516*4882a593Smuzhiyun 	"triso2g=3\0"
517*4882a593Smuzhiyun 	"antswctl2g=0\0"
518*4882a593Smuzhiyun 	"tssipos5g=1\0"
519*4882a593Smuzhiyun 	"extpagain5g=0\0"
520*4882a593Smuzhiyun 	"pdetrange5g=0\0"
521*4882a593Smuzhiyun 	"triso5g=3\0"
522*4882a593Smuzhiyun 	"antswctl5g=0\0"
523*4882a593Smuzhiyun 	"cck2gpo=0\0"
524*4882a593Smuzhiyun 	"ofdm2gpo=0\0"
525*4882a593Smuzhiyun 	"mcs2gpo0=0\0"
526*4882a593Smuzhiyun 	"mcs2gpo1=0\0"
527*4882a593Smuzhiyun 	"mcs2gpo2=0\0"
528*4882a593Smuzhiyun 	"mcs2gpo3=0\0"
529*4882a593Smuzhiyun 	"mcs2gpo4=0\0"
530*4882a593Smuzhiyun 	"mcs2gpo5=0\0"
531*4882a593Smuzhiyun 	"mcs2gpo6=0\0"
532*4882a593Smuzhiyun 	"mcs2gpo7=0\0"
533*4882a593Smuzhiyun 	"cddpo=0\0"
534*4882a593Smuzhiyun 	"stbcpo=0\0"
535*4882a593Smuzhiyun 	"bw40po=4\0"
536*4882a593Smuzhiyun 	"bwduppo=0\0"
537*4882a593Smuzhiyun 	"END\0";
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun /**
540*4882a593Smuzhiyun  * The contents of this array is a first attempt, is likely incorrect for 43602, needs to be
541*4882a593Smuzhiyun  * edited in a later stage.
542*4882a593Smuzhiyun  */
543*4882a593Smuzhiyun static char BCMATTACHDATA(defaultsromvars_43602)[] =
544*4882a593Smuzhiyun 	"sromrev=11\0"
545*4882a593Smuzhiyun 	"boardrev=0x1421\0"
546*4882a593Smuzhiyun 	"boardflags=0x10401001\0"
547*4882a593Smuzhiyun 	"boardflags2=0x00000002\0"
548*4882a593Smuzhiyun 	"boardflags3=0x00000003\0"
549*4882a593Smuzhiyun 	"boardtype=0x61b\0"
550*4882a593Smuzhiyun 	"subvid=0x14e4\0"
551*4882a593Smuzhiyun 	"boardnum=62526\0"
552*4882a593Smuzhiyun 	"macaddr=00:90:4c:0d:f4:3e\0"
553*4882a593Smuzhiyun 	"ccode=X0\0"
554*4882a593Smuzhiyun 	"regrev=15\0"
555*4882a593Smuzhiyun 	"aa2g=7\0"
556*4882a593Smuzhiyun 	"aa5g=7\0"
557*4882a593Smuzhiyun 	"agbg0=71\0"
558*4882a593Smuzhiyun 	"agbg1=71\0"
559*4882a593Smuzhiyun 	"agbg2=133\0"
560*4882a593Smuzhiyun 	"aga0=71\0"
561*4882a593Smuzhiyun 	"aga1=133\0"
562*4882a593Smuzhiyun 	"aga2=133\0"
563*4882a593Smuzhiyun 	"antswitch=0\0"
564*4882a593Smuzhiyun 	"tssiposslope2g=1\0"
565*4882a593Smuzhiyun 	"epagain2g=0\0"
566*4882a593Smuzhiyun 	"pdgain2g=9\0"
567*4882a593Smuzhiyun 	"tworangetssi2g=0\0"
568*4882a593Smuzhiyun 	"papdcap2g=0\0"
569*4882a593Smuzhiyun 	"femctrl=2\0"
570*4882a593Smuzhiyun 	"tssiposslope5g=1\0"
571*4882a593Smuzhiyun 	"epagain5g=0\0"
572*4882a593Smuzhiyun 	"pdgain5g=9\0"
573*4882a593Smuzhiyun 	"tworangetssi5g=0\0"
574*4882a593Smuzhiyun 	"papdcap5g=0\0"
575*4882a593Smuzhiyun 	"gainctrlsph=0\0"
576*4882a593Smuzhiyun 	"tempthresh=255\0"
577*4882a593Smuzhiyun 	"tempoffset=255\0"
578*4882a593Smuzhiyun 	"rawtempsense=0x1ff\0"
579*4882a593Smuzhiyun 	"measpower=0x7f\0"
580*4882a593Smuzhiyun 	"tempsense_slope=0xff\0"
581*4882a593Smuzhiyun 	"tempcorrx=0x3f\0"
582*4882a593Smuzhiyun 	"tempsense_option=0x3\0"
583*4882a593Smuzhiyun 	"xtalfreq=40000\0"
584*4882a593Smuzhiyun 	"phycal_tempdelta=255\0"
585*4882a593Smuzhiyun 	"temps_period=15\0"
586*4882a593Smuzhiyun 	"temps_hysteresis=15\0"
587*4882a593Smuzhiyun 	"measpower1=0x7f\0"
588*4882a593Smuzhiyun 	"measpower2=0x7f\0"
589*4882a593Smuzhiyun 	"pdoffset2g40ma0=15\0"
590*4882a593Smuzhiyun 	"pdoffset2g40ma1=15\0"
591*4882a593Smuzhiyun 	"pdoffset2g40ma2=15\0"
592*4882a593Smuzhiyun 	"pdoffset2g40mvalid=1\0"
593*4882a593Smuzhiyun 	"pdoffset40ma0=9010\0"
594*4882a593Smuzhiyun 	"pdoffset40ma1=12834\0"
595*4882a593Smuzhiyun 	"pdoffset40ma2=8994\0"
596*4882a593Smuzhiyun 	"pdoffset80ma0=16\0"
597*4882a593Smuzhiyun 	"pdoffset80ma1=4096\0"
598*4882a593Smuzhiyun 	"pdoffset80ma2=0\0"
599*4882a593Smuzhiyun 	"subband5gver=0x4\0"
600*4882a593Smuzhiyun 	"cckbw202gpo=0\0"
601*4882a593Smuzhiyun 	"cckbw20ul2gpo=0\0"
602*4882a593Smuzhiyun 	"mcsbw202gpo=2571386880\0"
603*4882a593Smuzhiyun 	"mcsbw402gpo=2571386880\0"
604*4882a593Smuzhiyun 	"dot11agofdmhrbw202gpo=17408\0"
605*4882a593Smuzhiyun 	"ofdmlrbw202gpo=0\0"
606*4882a593Smuzhiyun 	"mcsbw205glpo=4001923072\0"
607*4882a593Smuzhiyun 	"mcsbw405glpo=4001923072\0"
608*4882a593Smuzhiyun 	"mcsbw805glpo=4001923072\0"
609*4882a593Smuzhiyun 	"mcsbw1605glpo=0\0"
610*4882a593Smuzhiyun 	"mcsbw205gmpo=3431497728\0"
611*4882a593Smuzhiyun 	"mcsbw405gmpo=3431497728\0"
612*4882a593Smuzhiyun 	"mcsbw805gmpo=3431497728\0"
613*4882a593Smuzhiyun 	"mcsbw1605gmpo=0\0"
614*4882a593Smuzhiyun 	"mcsbw205ghpo=3431497728\0"
615*4882a593Smuzhiyun 	"mcsbw405ghpo=3431497728\0"
616*4882a593Smuzhiyun 	"mcsbw805ghpo=3431497728\0"
617*4882a593Smuzhiyun 	"mcsbw1605ghpo=0\0"
618*4882a593Smuzhiyun 	"mcslr5glpo=0\0"
619*4882a593Smuzhiyun 	"mcslr5gmpo=0\0"
620*4882a593Smuzhiyun 	"mcslr5ghpo=0\0"
621*4882a593Smuzhiyun 	"sb20in40hrpo=0\0"
622*4882a593Smuzhiyun 	"sb20in80and160hr5glpo=0\0"
623*4882a593Smuzhiyun 	"sb40and80hr5glpo=0\0"
624*4882a593Smuzhiyun 	"sb20in80and160hr5gmpo=0\0"
625*4882a593Smuzhiyun 	"sb40and80hr5gmpo=0\0"
626*4882a593Smuzhiyun 	"sb20in80and160hr5ghpo=0\0"
627*4882a593Smuzhiyun 	"sb40and80hr5ghpo=0\0"
628*4882a593Smuzhiyun 	"sb20in40lrpo=0\0"
629*4882a593Smuzhiyun 	"sb20in80and160lr5glpo=0\0"
630*4882a593Smuzhiyun 	"sb40and80lr5glpo=0\0"
631*4882a593Smuzhiyun 	"sb20in80and160lr5gmpo=0\0"
632*4882a593Smuzhiyun 	"sb40and80lr5gmpo=0\0"
633*4882a593Smuzhiyun 	"sb20in80and160lr5ghpo=0\0"
634*4882a593Smuzhiyun 	"sb40and80lr5ghpo=0\0"
635*4882a593Smuzhiyun 	"dot11agduphrpo=0\0"
636*4882a593Smuzhiyun 	"dot11agduplrpo=0\0"
637*4882a593Smuzhiyun 	"pcieingress_war=15\0"
638*4882a593Smuzhiyun 	"sar2g=18\0"
639*4882a593Smuzhiyun 	"sar5g=15\0"
640*4882a593Smuzhiyun 	"noiselvl2ga0=31\0"
641*4882a593Smuzhiyun 	"noiselvl2ga1=31\0"
642*4882a593Smuzhiyun 	"noiselvl2ga2=31\0"
643*4882a593Smuzhiyun 	"noiselvl5ga0=31,31,31,31\0"
644*4882a593Smuzhiyun 	"noiselvl5ga1=31,31,31,31\0"
645*4882a593Smuzhiyun 	"noiselvl5ga2=31,31,31,31\0"
646*4882a593Smuzhiyun 	"rxgainerr2ga0=63\0"
647*4882a593Smuzhiyun 	"rxgainerr2ga1=31\0"
648*4882a593Smuzhiyun 	"rxgainerr2ga2=31\0"
649*4882a593Smuzhiyun 	"rxgainerr5ga0=63,63,63,63\0"
650*4882a593Smuzhiyun 	"rxgainerr5ga1=31,31,31,31\0"
651*4882a593Smuzhiyun 	"rxgainerr5ga2=31,31,31,31\0"
652*4882a593Smuzhiyun 	"maxp2ga0=76\0"
653*4882a593Smuzhiyun 	"pa2ga0=0xff3c,0x172c,0xfd20\0"
654*4882a593Smuzhiyun 	"rxgains5gmelnagaina0=7\0"
655*4882a593Smuzhiyun 	"rxgains5gmtrisoa0=15\0"
656*4882a593Smuzhiyun 	"rxgains5gmtrelnabypa0=1\0"
657*4882a593Smuzhiyun 	"rxgains5ghelnagaina0=7\0"
658*4882a593Smuzhiyun 	"rxgains5ghtrisoa0=15\0"
659*4882a593Smuzhiyun 	"rxgains5ghtrelnabypa0=1\0"
660*4882a593Smuzhiyun 	"rxgains2gelnagaina0=4\0"
661*4882a593Smuzhiyun 	"rxgains2gtrisoa0=7\0"
662*4882a593Smuzhiyun 	"rxgains2gtrelnabypa0=1\0"
663*4882a593Smuzhiyun 	"rxgains5gelnagaina0=3\0"
664*4882a593Smuzhiyun 	"rxgains5gtrisoa0=7\0"
665*4882a593Smuzhiyun 	"rxgains5gtrelnabypa0=1\0"
666*4882a593Smuzhiyun 	"maxp5ga0=76,76,76,76\0"
667*4882a593Smuzhiyun "pa5ga0=0xff3a,0x14d4,0xfd5f,0xff36,0x1626,0xfd2e,0xff42,0x15bd,0xfd47,0xff39,0x15a3,0xfd3d\0"
668*4882a593Smuzhiyun 	"maxp2ga1=76\0"
669*4882a593Smuzhiyun 	"pa2ga1=0xff2a,0x16b2,0xfd28\0"
670*4882a593Smuzhiyun 	"rxgains5gmelnagaina1=7\0"
671*4882a593Smuzhiyun 	"rxgains5gmtrisoa1=15\0"
672*4882a593Smuzhiyun 	"rxgains5gmtrelnabypa1=1\0"
673*4882a593Smuzhiyun 	"rxgains5ghelnagaina1=7\0"
674*4882a593Smuzhiyun 	"rxgains5ghtrisoa1=15\0"
675*4882a593Smuzhiyun 	"rxgains5ghtrelnabypa1=1\0"
676*4882a593Smuzhiyun 	"rxgains2gelnagaina1=3\0"
677*4882a593Smuzhiyun 	"rxgains2gtrisoa1=6\0"
678*4882a593Smuzhiyun 	"rxgains2gtrelnabypa1=1\0"
679*4882a593Smuzhiyun 	"rxgains5gelnagaina1=3\0"
680*4882a593Smuzhiyun 	"rxgains5gtrisoa1=6\0"
681*4882a593Smuzhiyun 	"rxgains5gtrelnabypa1=1\0"
682*4882a593Smuzhiyun 	"maxp5ga1=76,76,76,76\0"
683*4882a593Smuzhiyun "pa5ga1=0xff4e,0x1530,0xfd53,0xff58,0x15b4,0xfd4d,0xff58,0x1671,0xfd2f,0xff55,0x15e2,0xfd46\0"
684*4882a593Smuzhiyun 	"maxp2ga2=76\0"
685*4882a593Smuzhiyun 	"pa2ga2=0xff3c,0x1736,0xfd1f\0"
686*4882a593Smuzhiyun 	"rxgains5gmelnagaina2=7\0"
687*4882a593Smuzhiyun 	"rxgains5gmtrisoa2=15\0"
688*4882a593Smuzhiyun 	"rxgains5gmtrelnabypa2=1\0"
689*4882a593Smuzhiyun 	"rxgains5ghelnagaina2=7\0"
690*4882a593Smuzhiyun 	"rxgains5ghtrisoa2=15\0"
691*4882a593Smuzhiyun 	"rxgains5ghtrelnabypa2=1\0"
692*4882a593Smuzhiyun 	"rxgains2gelnagaina2=4\0"
693*4882a593Smuzhiyun 	"rxgains2gtrisoa2=7\0"
694*4882a593Smuzhiyun 	"rxgains2gtrelnabypa2=1\0"
695*4882a593Smuzhiyun 	"rxgains5gelnagaina2=3\0"
696*4882a593Smuzhiyun 	"rxgains5gtrisoa2=7\0"
697*4882a593Smuzhiyun 	"rxgains5gtrelnabypa2=1\0"
698*4882a593Smuzhiyun 	"maxp5ga2=76,76,76,76\0"
699*4882a593Smuzhiyun "pa5ga2=0xff2d,0x144a,0xfd63,0xff35,0x15d7,0xfd3b,0xff35,0x1668,0xfd2f,0xff31,0x1664,0xfd27\0"
700*4882a593Smuzhiyun 	"END\0";
701*4882a593Smuzhiyun 
702*4882a593Smuzhiyun /**
703*4882a593Smuzhiyun  * The contents of this array is a first attempt, was copied from 4378, needs to be edited in
704*4882a593Smuzhiyun  * a later stage.
705*4882a593Smuzhiyun  */
706*4882a593Smuzhiyun static char BCMATTACHDATA(defaultsromvars_4378)[] =
707*4882a593Smuzhiyun 	"cckdigfilttype=4\0"
708*4882a593Smuzhiyun 	"sromrev=11\0"
709*4882a593Smuzhiyun 	"boardrev=0x1102\0"
710*4882a593Smuzhiyun 	"boardtype=0x0771\0"
711*4882a593Smuzhiyun 	"boardflags=0x10481201\0"
712*4882a593Smuzhiyun 	"boardflags2=0x00000000\0"
713*4882a593Smuzhiyun 	"boardflags3=0x04000080\0"
714*4882a593Smuzhiyun 	"macaddr=00:90:4c:12:43:47\0"
715*4882a593Smuzhiyun 	"ccode=0\0"
716*4882a593Smuzhiyun 	"regrev=0\0"
717*4882a593Smuzhiyun 	"antswitch=0\0"
718*4882a593Smuzhiyun 	"pdgain5g=0\0"
719*4882a593Smuzhiyun 	"pdgain2g=0\0"
720*4882a593Smuzhiyun 	"tworangetssi2g=0\0"
721*4882a593Smuzhiyun 	"tworangetssi5g=0\0"
722*4882a593Smuzhiyun 	"femctrl=16\0"
723*4882a593Smuzhiyun 	"vendid=0x14e4\0"
724*4882a593Smuzhiyun 	"devid=0x4425\0"
725*4882a593Smuzhiyun 	"manfid=0x2d0\0"
726*4882a593Smuzhiyun 	"nocrc=1\0"
727*4882a593Smuzhiyun 	"btc_params82=0x1a0\0"
728*4882a593Smuzhiyun 	"otpimagesize=502\0"
729*4882a593Smuzhiyun 	"xtalfreq=37400\0"
730*4882a593Smuzhiyun 	"rxgains2gelnagaina0=3\0"
731*4882a593Smuzhiyun 	"rxgains2gtrisoa0=7\0"
732*4882a593Smuzhiyun 	"rxgains2gtrelnabypa0=1\0"
733*4882a593Smuzhiyun 	"rxgains5gelnagaina0=3\0"
734*4882a593Smuzhiyun 	"rxgains5gtrisoa0=6\0"
735*4882a593Smuzhiyun 	"rxgains5gtrelnabypa0=1\0"
736*4882a593Smuzhiyun 	"rxgains5gmelnagaina0=3\0"
737*4882a593Smuzhiyun 	"rxgains5gmtrisoa0=6\0"
738*4882a593Smuzhiyun 	"rxgains5gmtrelnabypa0=1\0"
739*4882a593Smuzhiyun 	"rxgains5ghelnagaina0=3\0"
740*4882a593Smuzhiyun 	"rxgains5ghtrisoa0=6\0"
741*4882a593Smuzhiyun 	"rxgains5ghtrelnabypa0=1\0"
742*4882a593Smuzhiyun 	"rxgains2gelnagaina1=3\0"
743*4882a593Smuzhiyun 	"rxgains2gtrisoa1=7\0"
744*4882a593Smuzhiyun 	"rxgains2gtrelnabypa1=1\0"
745*4882a593Smuzhiyun 	"rxgains5gelnagaina1=3\0"
746*4882a593Smuzhiyun 	"rxgains5gtrisoa1=6\0"
747*4882a593Smuzhiyun 	"rxgains5gtrelnabypa1=1\0"
748*4882a593Smuzhiyun 	"rxgains5gmelnagaina1=3\0"
749*4882a593Smuzhiyun 	"rxgains5gmtrisoa1=6\0"
750*4882a593Smuzhiyun 	"rxgains5gmtrelnabypa1=1\0"
751*4882a593Smuzhiyun 	"rxgains5ghelnagaina1=3\0"
752*4882a593Smuzhiyun 	"rxgains5ghtrisoa1=6\0"
753*4882a593Smuzhiyun 	"rxgains5ghtrelnabypa1=1\0"
754*4882a593Smuzhiyun 	"rxchain=3\0"
755*4882a593Smuzhiyun 	"txchain=3\0"
756*4882a593Smuzhiyun 	"aa2g=3\0"
757*4882a593Smuzhiyun 	"aa5g=3\0"
758*4882a593Smuzhiyun 	"agbg0=2\0"
759*4882a593Smuzhiyun 	"agbg1=2\0"
760*4882a593Smuzhiyun 	"aga0=2\0"
761*4882a593Smuzhiyun 	"aga1=2\0"
762*4882a593Smuzhiyun 	"tssipos2g=1\0"
763*4882a593Smuzhiyun 	"tssipos5g=1\0"
764*4882a593Smuzhiyun 	"tempthresh=255\0"
765*4882a593Smuzhiyun 	"tempoffset=255\0"
766*4882a593Smuzhiyun 	"rawtempsense=0x1ff\0"
767*4882a593Smuzhiyun 	"pa2gccka0=-200,7392,-897\0"
768*4882a593Smuzhiyun 	"pa2gccka1=-198,7522,-907\0"
769*4882a593Smuzhiyun 	"pa2ga0=-174,7035,-838\0"
770*4882a593Smuzhiyun 	"pa2ga1=-185,6772,-811\0"
771*4882a593Smuzhiyun 	"pa5ga0=-175,7296,-887,-164,7553,-910,-155,7801,-936,-149,7908,-951\0"
772*4882a593Smuzhiyun 	"pa5ga1=-155,7675,-925,-148,7851,-940,-152,7930,-954,-143,8121,-969\0"
773*4882a593Smuzhiyun 	"pa5gbw4080a0=-178,7872,-959,-173,8107,-986,-165,8398,-1019,-150,8809,-1063\0"
774*4882a593Smuzhiyun 	"pa5gbw4080a1=-166,8179,-993,-161,8378,-1015,-165,8402,-1019,-155,8757,-1057\0"
775*4882a593Smuzhiyun 	"maxp2ga0=66\0"
776*4882a593Smuzhiyun 	"maxp2ga1=66\0"
777*4882a593Smuzhiyun 	"maxp5ga0=66,66,66,66\0"
778*4882a593Smuzhiyun 	"maxp5ga1=66,66,66,66\0"
779*4882a593Smuzhiyun 	"subband5gver=0x4\0"
780*4882a593Smuzhiyun 	"paparambwver=3\0"
781*4882a593Smuzhiyun 	"cckpwroffset0=0\0"
782*4882a593Smuzhiyun 	"cckpwroffset1=0\0"
783*4882a593Smuzhiyun 	"pdoffset40ma0=0x0000\0"
784*4882a593Smuzhiyun 	"pdoffset80ma0=0xeeee\0"
785*4882a593Smuzhiyun 	"pdoffset40ma1=0x0000\0"
786*4882a593Smuzhiyun 	"pdoffset80ma1=0xeeee\0"
787*4882a593Smuzhiyun 	"cckbw202gpo=0\0"
788*4882a593Smuzhiyun 	"cckbw20ul2gpo=0\0"
789*4882a593Smuzhiyun 	"mcsbw202gpo=0xEC888222\0"
790*4882a593Smuzhiyun 	"mcsbw402gpo=0xEC888222\0"
791*4882a593Smuzhiyun 	"dot11agofdmhrbw202gpo=0x6622\0"
792*4882a593Smuzhiyun 	"ofdmlrbw202gpo=0x0000\0"
793*4882a593Smuzhiyun 	"mcsbw205glpo=0xCA666000\0"
794*4882a593Smuzhiyun 	"mcsbw405glpo=0xCA666000\0"
795*4882a593Smuzhiyun 	"mcsbw805glpo=0xEA666000\0"
796*4882a593Smuzhiyun 	"mcsbw1605glpo=0\0"
797*4882a593Smuzhiyun 	"mcsbw205gmpo=0xCA666000\0"
798*4882a593Smuzhiyun 	"mcsbw405gmpo=0xCA666000\0"
799*4882a593Smuzhiyun 	"mcsbw805gmpo=0xEA666000\0"
800*4882a593Smuzhiyun 	"mcsbw1605gmpo=0\0"
801*4882a593Smuzhiyun 	"mcsbw205ghpo=0xCA666000\0"
802*4882a593Smuzhiyun 	"mcsbw405ghpo=0xCA666000\0"
803*4882a593Smuzhiyun 	"mcsbw805ghpo=0xEA666000\0"
804*4882a593Smuzhiyun 	"mcsbw1605ghpo=0\0"
805*4882a593Smuzhiyun 	"mcslr5glpo=0x0000\0"
806*4882a593Smuzhiyun 	"mcslr5gmpo=0x0000\0"
807*4882a593Smuzhiyun 	"mcslr5ghpo=0x0000\0"
808*4882a593Smuzhiyun 	"sb20in40hrpo=0x0\0"
809*4882a593Smuzhiyun 	"sb20in80and160hr5glpo=0x0\0"
810*4882a593Smuzhiyun 	"sb40and80hr5glpo=0x0\0"
811*4882a593Smuzhiyun 	"sb20in80and160hr5gmpo=0x0\0"
812*4882a593Smuzhiyun 	"sb40and80hr5gmpo=0x0\0"
813*4882a593Smuzhiyun 	"sb20in80and160hr5ghpo=0x0\0"
814*4882a593Smuzhiyun 	"sb40and80hr5ghpo=0x0\0"
815*4882a593Smuzhiyun 	"sb20in40lrpo=0x0\0"
816*4882a593Smuzhiyun 	"sb20in80and160lr5glpo=0x0\0"
817*4882a593Smuzhiyun 	"sb40and80lr5glpo=0x0\0"
818*4882a593Smuzhiyun 	"sb20in80and160lr5gmpo=0x0\0"
819*4882a593Smuzhiyun 	"sb40and80lr5gmpo=0x0\0"
820*4882a593Smuzhiyun 	"sb20in80and160lr5ghpo=0x0\0"
821*4882a593Smuzhiyun 	"sb40and80lr5ghpo=0x0\0"
822*4882a593Smuzhiyun 	"dot11agduphrpo=0x0\0"
823*4882a593Smuzhiyun 	"dot11agduplrpo=0x0\0"
824*4882a593Smuzhiyun 	"phycal_tempdelta=15\0"
825*4882a593Smuzhiyun 	"temps_period=15\0"
826*4882a593Smuzhiyun 	"temps_hysteresis=15\0"
827*4882a593Smuzhiyun 	"swctrlmap_2g=0x00000404,0x0a0a0000,0x02020000,0x010a02,0x1fe\0"
828*4882a593Smuzhiyun 	"swctrlmapext_2g=0x00000000,0x00000000,0x00000000,0x000000,0x000\0"
829*4882a593Smuzhiyun 	"swctrlmap_5g=0x00001010,0x60600000,0x40400000,0x000000,0x0f0\0"
830*4882a593Smuzhiyun 	"swctrlmapext_5g=0x00000000,0x00000000,0x00000000,0x000000,0x000\0"
831*4882a593Smuzhiyun 	"powoffs2gtna0=1,3,3,1,0,0,1,2,2,2,1,1,0,0\0"
832*4882a593Smuzhiyun 	"powoffs2gtna1=-1,1,1,1,0,0,1,2,3,2,2,0,0,0\0"
833*4882a593Smuzhiyun 	"END\0";
834*4882a593Smuzhiyun 
835*4882a593Smuzhiyun /**
836*4882a593Smuzhiyun  * The contents of this array is a first attempt, was copied from 4387, needs to be edited in
837*4882a593Smuzhiyun  * a later stage.
838*4882a593Smuzhiyun  */
839*4882a593Smuzhiyun static char BCMATTACHDATA(defaultsromvars_4387)[] =
840*4882a593Smuzhiyun 	"cckdigfilttype=4\0"
841*4882a593Smuzhiyun 	"sromrev=11\0"
842*4882a593Smuzhiyun 	"boardrev=0x1102\0"
843*4882a593Smuzhiyun 	"boardtype=0x0771\0"
844*4882a593Smuzhiyun 	"boardflags=0x10481201\0"
845*4882a593Smuzhiyun 	"boardflags2=0x00000000\0"
846*4882a593Smuzhiyun 	"boardflags3=0x04000080\0"
847*4882a593Smuzhiyun 	"macaddr=00:90:4c:12:43:47\0"
848*4882a593Smuzhiyun 	"ccode=0\0"
849*4882a593Smuzhiyun 	"regrev=0\0"
850*4882a593Smuzhiyun 	"antswitch=0\0"
851*4882a593Smuzhiyun 	"pdgain5g=0\0"
852*4882a593Smuzhiyun 	"pdgain2g=0\0"
853*4882a593Smuzhiyun 	"tworangetssi2g=0\0"
854*4882a593Smuzhiyun 	"tworangetssi5g=0\0"
855*4882a593Smuzhiyun 	"femctrl=16\0"
856*4882a593Smuzhiyun 	"vendid=0x14e4\0"
857*4882a593Smuzhiyun 	"devid=0x4425\0"
858*4882a593Smuzhiyun 	"manfid=0x2d0\0"
859*4882a593Smuzhiyun 	"nocrc=1\0"
860*4882a593Smuzhiyun 	"btc_params82=0x1a0\0"
861*4882a593Smuzhiyun 	"otpimagesize=502\0"
862*4882a593Smuzhiyun 	"xtalfreq=37400\0"
863*4882a593Smuzhiyun 	"rxgains2gelnagaina0=3\0"
864*4882a593Smuzhiyun 	"rxgains2gtrisoa0=7\0"
865*4882a593Smuzhiyun 	"rxgains2gtrelnabypa0=1\0"
866*4882a593Smuzhiyun 	"rxgains5gelnagaina0=3\0"
867*4882a593Smuzhiyun 	"rxgains5gtrisoa0=6\0"
868*4882a593Smuzhiyun 	"rxgains5gtrelnabypa0=1\0"
869*4882a593Smuzhiyun 	"rxgains5gmelnagaina0=3\0"
870*4882a593Smuzhiyun 	"rxgains5gmtrisoa0=6\0"
871*4882a593Smuzhiyun 	"rxgains5gmtrelnabypa0=1\0"
872*4882a593Smuzhiyun 	"rxgains5ghelnagaina0=3\0"
873*4882a593Smuzhiyun 	"rxgains5ghtrisoa0=6\0"
874*4882a593Smuzhiyun 	"rxgains5ghtrelnabypa0=1\0"
875*4882a593Smuzhiyun 	"rxgains2gelnagaina1=3\0"
876*4882a593Smuzhiyun 	"rxgains2gtrisoa1=7\0"
877*4882a593Smuzhiyun 	"rxgains2gtrelnabypa1=1\0"
878*4882a593Smuzhiyun 	"rxgains5gelnagaina1=3\0"
879*4882a593Smuzhiyun 	"rxgains5gtrisoa1=6\0"
880*4882a593Smuzhiyun 	"rxgains5gtrelnabypa1=1\0"
881*4882a593Smuzhiyun 	"rxgains5gmelnagaina1=3\0"
882*4882a593Smuzhiyun 	"rxgains5gmtrisoa1=6\0"
883*4882a593Smuzhiyun 	"rxgains5gmtrelnabypa1=1\0"
884*4882a593Smuzhiyun 	"rxgains5ghelnagaina1=3\0"
885*4882a593Smuzhiyun 	"rxgains5ghtrisoa1=6\0"
886*4882a593Smuzhiyun 	"rxgains5ghtrelnabypa1=1\0"
887*4882a593Smuzhiyun 	"rxchain=3\0"
888*4882a593Smuzhiyun 	"txchain=3\0"
889*4882a593Smuzhiyun 	"aa2g=3\0"
890*4882a593Smuzhiyun 	"aa5g=3\0"
891*4882a593Smuzhiyun 	"agbg0=2\0"
892*4882a593Smuzhiyun 	"agbg1=2\0"
893*4882a593Smuzhiyun 	"aga0=2\0"
894*4882a593Smuzhiyun 	"aga1=2\0"
895*4882a593Smuzhiyun 	"tssipos2g=1\0"
896*4882a593Smuzhiyun 	"tssipos5g=1\0"
897*4882a593Smuzhiyun 	"tempthresh=255\0"
898*4882a593Smuzhiyun 	"tempoffset=255\0"
899*4882a593Smuzhiyun 	"rawtempsense=0x1ff\0"
900*4882a593Smuzhiyun 	"pa2gccka0=-200,7392,-897\0"
901*4882a593Smuzhiyun 	"pa2gccka1=-198,7522,-907\0"
902*4882a593Smuzhiyun 	"pa2ga0=-174,7035,-838\0"
903*4882a593Smuzhiyun 	"pa2ga1=-185,6772,-811\0"
904*4882a593Smuzhiyun 	"pa5ga0=-175,7296,-887,-164,7553,-910,-155,7801,-936,-149,7908,-951\0"
905*4882a593Smuzhiyun 	"pa5ga1=-155,7675,-925,-148,7851,-940,-152,7930,-954,-143,8121,-969\0"
906*4882a593Smuzhiyun 	"pa5gbw4080a0=-178,7872,-959,-173,8107,-986,-165,8398,-1019,-150,8809,-1063\0"
907*4882a593Smuzhiyun 	"pa5gbw4080a1=-166,8179,-993,-161,8378,-1015,-165,8402,-1019,-155,8757,-1057\0"
908*4882a593Smuzhiyun 	"maxp2ga0=66\0"
909*4882a593Smuzhiyun 	"maxp2ga1=66\0"
910*4882a593Smuzhiyun 	"maxp5ga0=66,66,66,66\0"
911*4882a593Smuzhiyun 	"maxp5ga1=66,66,66,66\0"
912*4882a593Smuzhiyun 	"subband5gver=0x4\0"
913*4882a593Smuzhiyun 	"paparambwver=3\0"
914*4882a593Smuzhiyun 	"cckpwroffset0=0\0"
915*4882a593Smuzhiyun 	"cckpwroffset1=0\0"
916*4882a593Smuzhiyun 	"pdoffset40ma0=0x0000\0"
917*4882a593Smuzhiyun 	"pdoffset80ma0=0xeeee\0"
918*4882a593Smuzhiyun 	"pdoffset40ma1=0x0000\0"
919*4882a593Smuzhiyun 	"pdoffset80ma1=0xeeee\0"
920*4882a593Smuzhiyun 	"cckbw202gpo=0\0"
921*4882a593Smuzhiyun 	"cckbw20ul2gpo=0\0"
922*4882a593Smuzhiyun 	"mcsbw202gpo=0xEC888222\0"
923*4882a593Smuzhiyun 	"mcsbw402gpo=0xEC888222\0"
924*4882a593Smuzhiyun 	"dot11agofdmhrbw202gpo=0x6622\0"
925*4882a593Smuzhiyun 	"ofdmlrbw202gpo=0x0000\0"
926*4882a593Smuzhiyun 	"mcsbw205glpo=0xCA666000\0"
927*4882a593Smuzhiyun 	"mcsbw405glpo=0xCA666000\0"
928*4882a593Smuzhiyun 	"mcsbw805glpo=0xEA666000\0"
929*4882a593Smuzhiyun 	"mcsbw1605glpo=0\0"
930*4882a593Smuzhiyun 	"mcsbw205gmpo=0xCA666000\0"
931*4882a593Smuzhiyun 	"mcsbw405gmpo=0xCA666000\0"
932*4882a593Smuzhiyun 	"mcsbw805gmpo=0xEA666000\0"
933*4882a593Smuzhiyun 	"mcsbw1605gmpo=0\0"
934*4882a593Smuzhiyun 	"mcsbw205ghpo=0xCA666000\0"
935*4882a593Smuzhiyun 	"mcsbw405ghpo=0xCA666000\0"
936*4882a593Smuzhiyun 	"mcsbw805ghpo=0xEA666000\0"
937*4882a593Smuzhiyun 	"mcsbw1605ghpo=0\0"
938*4882a593Smuzhiyun 	"mcslr5glpo=0x0000\0"
939*4882a593Smuzhiyun 	"mcslr5gmpo=0x0000\0"
940*4882a593Smuzhiyun 	"mcslr5ghpo=0x0000\0"
941*4882a593Smuzhiyun 	"sb20in40hrpo=0x0\0"
942*4882a593Smuzhiyun 	"sb20in80and160hr5glpo=0x0\0"
943*4882a593Smuzhiyun 	"sb40and80hr5glpo=0x0\0"
944*4882a593Smuzhiyun 	"sb20in80and160hr5gmpo=0x0\0"
945*4882a593Smuzhiyun 	"sb40and80hr5gmpo=0x0\0"
946*4882a593Smuzhiyun 	"sb20in80and160hr5ghpo=0x0\0"
947*4882a593Smuzhiyun 	"sb40and80hr5ghpo=0x0\0"
948*4882a593Smuzhiyun 	"sb20in40lrpo=0x0\0"
949*4882a593Smuzhiyun 	"sb20in80and160lr5glpo=0x0\0"
950*4882a593Smuzhiyun 	"sb40and80lr5glpo=0x0\0"
951*4882a593Smuzhiyun 	"sb20in80and160lr5gmpo=0x0\0"
952*4882a593Smuzhiyun 	"sb40and80lr5gmpo=0x0\0"
953*4882a593Smuzhiyun 	"sb20in80and160lr5ghpo=0x0\0"
954*4882a593Smuzhiyun 	"sb40and80lr5ghpo=0x0\0"
955*4882a593Smuzhiyun 	"dot11agduphrpo=0x0\0"
956*4882a593Smuzhiyun 	"dot11agduplrpo=0x0\0"
957*4882a593Smuzhiyun 	"phycal_tempdelta=15\0"
958*4882a593Smuzhiyun 	"temps_period=15\0"
959*4882a593Smuzhiyun 	"temps_hysteresis=15\0"
960*4882a593Smuzhiyun 	"swctrlmap_2g=0x00000404,0x0a0a0000,0x02020000,0x010a02,0x1fe\0"
961*4882a593Smuzhiyun 	"swctrlmapext_2g=0x00000000,0x00000000,0x00000000,0x000000,0x000\0"
962*4882a593Smuzhiyun 	"swctrlmap_5g=0x00001010,0x60600000,0x40400000,0x000000,0x0f0\0"
963*4882a593Smuzhiyun 	"swctrlmapext_5g=0x00000000,0x00000000,0x00000000,0x000000,0x000\0"
964*4882a593Smuzhiyun 	"powoffs2gtna0=1,3,3,1,0,0,1,2,2,2,1,1,0,0\0"
965*4882a593Smuzhiyun 	"powoffs2gtna1=-1,1,1,1,0,0,1,2,3,2,2,0,0,0\0"
966*4882a593Smuzhiyun 	"END\0";
967*4882a593Smuzhiyun 
968*4882a593Smuzhiyun #endif /* defined(BCMHOSTVARS) */
969*4882a593Smuzhiyun #endif /* !defined(BCMDONGLEHOST) */
970*4882a593Smuzhiyun 
971*4882a593Smuzhiyun static bool srvars_inited = FALSE; /* Use OTP/SROM as global variables */
972*4882a593Smuzhiyun 
973*4882a593Smuzhiyun #if (!defined(BCMDONGLEHOST) && defined(BCMHOSTVARS))
974*4882a593Smuzhiyun /* It must end with pattern of "END" */
975*4882a593Smuzhiyun static uint
BCMATTACHFN(srom_vars_len)976*4882a593Smuzhiyun BCMATTACHFN(srom_vars_len)(char *vars)
977*4882a593Smuzhiyun {
978*4882a593Smuzhiyun 	uint pos = 0;
979*4882a593Smuzhiyun 	uint len;
980*4882a593Smuzhiyun 	char *s;
981*4882a593Smuzhiyun 	char *emark = "END";
982*4882a593Smuzhiyun 	uint emark_len = strlen(emark) + 1;
983*4882a593Smuzhiyun 
984*4882a593Smuzhiyun 	for (s = vars; s && *s;) {
985*4882a593Smuzhiyun 
986*4882a593Smuzhiyun 		if (strcmp(s, emark) == 0)
987*4882a593Smuzhiyun 			break;
988*4882a593Smuzhiyun 
989*4882a593Smuzhiyun 		len = strlen(s);
990*4882a593Smuzhiyun 		s += strlen(s) + 1;
991*4882a593Smuzhiyun 		pos += len + 1;
992*4882a593Smuzhiyun 		/* BS_ERROR(("len %d vars[pos] %s\n", pos, s)); */
993*4882a593Smuzhiyun 		if (pos >= (VARS_MAX - emark_len)) {
994*4882a593Smuzhiyun 			return 0;
995*4882a593Smuzhiyun 		}
996*4882a593Smuzhiyun 	}
997*4882a593Smuzhiyun 
998*4882a593Smuzhiyun 	return pos + emark_len;	/* include the "END\0" */
999*4882a593Smuzhiyun }
1000*4882a593Smuzhiyun #endif /* BCMHOSTVARS */
1001*4882a593Smuzhiyun 
1002*4882a593Smuzhiyun #if !defined(BCMDONGLEHOST)
1003*4882a593Smuzhiyun #ifdef BCMNVRAMVARS
1004*4882a593Smuzhiyun static int
BCMATTACHFN(initvars_nvram_vars)1005*4882a593Smuzhiyun BCMATTACHFN(initvars_nvram_vars)(si_t *sih, osl_t *osh, char **vars, uint *vars_sz)
1006*4882a593Smuzhiyun {
1007*4882a593Smuzhiyun 	int ret;
1008*4882a593Smuzhiyun 
1009*4882a593Smuzhiyun 	ASSERT(vars != NULL && vars_sz != NULL);
1010*4882a593Smuzhiyun 
1011*4882a593Smuzhiyun 	/* allocate maximum buffer as we don't know big it should be */
1012*4882a593Smuzhiyun 	*vars = MALLOC(osh, MAXSZ_NVRAM_VARS);
1013*4882a593Smuzhiyun 	if (*vars == NULL) {
1014*4882a593Smuzhiyun 		ret = BCME_NOMEM;
1015*4882a593Smuzhiyun 		goto fail;
1016*4882a593Smuzhiyun 	}
1017*4882a593Smuzhiyun 	*vars_sz = MAXSZ_NVRAM_VARS;
1018*4882a593Smuzhiyun 
1019*4882a593Smuzhiyun 	/* query the name=value pairs */
1020*4882a593Smuzhiyun 	if ((ret = nvram_getall(*vars, *vars_sz)) != BCME_OK) {
1021*4882a593Smuzhiyun 		goto fail;
1022*4882a593Smuzhiyun 	}
1023*4882a593Smuzhiyun 
1024*4882a593Smuzhiyun 	/* treat empty name=value list as an error so that we can indicate
1025*4882a593Smuzhiyun 	 * the condition up throught error code return...
1026*4882a593Smuzhiyun 	 */
1027*4882a593Smuzhiyun 	if (*vars_sz == 0) {
1028*4882a593Smuzhiyun 		ret = BCME_ERROR;
1029*4882a593Smuzhiyun 		goto fail;
1030*4882a593Smuzhiyun 	}
1031*4882a593Smuzhiyun 
1032*4882a593Smuzhiyun 	return BCME_OK;
1033*4882a593Smuzhiyun 
1034*4882a593Smuzhiyun fail:
1035*4882a593Smuzhiyun 	if (*vars != NULL) {
1036*4882a593Smuzhiyun 		MFREE(osh, *vars, MAXSZ_NVRAM_VARS);
1037*4882a593Smuzhiyun 	}
1038*4882a593Smuzhiyun 	*vars = NULL;
1039*4882a593Smuzhiyun 	*vars_sz = 0;
1040*4882a593Smuzhiyun 	return ret;
1041*4882a593Smuzhiyun }
1042*4882a593Smuzhiyun #endif /* BCMNVRAMVARS */
1043*4882a593Smuzhiyun 
1044*4882a593Smuzhiyun /**
1045*4882a593Smuzhiyun  * Initialize local vars from the right source for this platform. Called from siutils.c.
1046*4882a593Smuzhiyun  *
1047*4882a593Smuzhiyun  * vars - pointer to a to-be created pointer area for "environment" variables. Some callers of this
1048*4882a593Smuzhiyun  *        function set 'vars' to NULL, in that case this function will prematurely return.
1049*4882a593Smuzhiyun  *
1050*4882a593Smuzhiyun  * Return 0 on success, nonzero on error.
1051*4882a593Smuzhiyun  */
1052*4882a593Smuzhiyun int
BCMATTACHFN(srom_var_init)1053*4882a593Smuzhiyun BCMATTACHFN(srom_var_init)(si_t *sih, uint bustype, volatile void *curmap, osl_t *osh,
1054*4882a593Smuzhiyun 	char **vars, uint *count)
1055*4882a593Smuzhiyun {
1056*4882a593Smuzhiyun 	ASSERT(bustype == BUSTYPE(bustype));
1057*4882a593Smuzhiyun 	if (vars == NULL || count == NULL)
1058*4882a593Smuzhiyun 		return (0);
1059*4882a593Smuzhiyun 
1060*4882a593Smuzhiyun 	*vars = NULL;
1061*4882a593Smuzhiyun 	*count = 0;
1062*4882a593Smuzhiyun 
1063*4882a593Smuzhiyun 	switch (BUSTYPE(bustype)) {
1064*4882a593Smuzhiyun 	case SI_BUS:
1065*4882a593Smuzhiyun #ifdef BCMPCIEDEV
1066*4882a593Smuzhiyun 		if (BCMPCIEDEV_ENAB()) {
1067*4882a593Smuzhiyun 			int ret;
1068*4882a593Smuzhiyun 
1069*4882a593Smuzhiyun 			ret = initvars_cis_pci(sih, osh, curmap, vars, count);
1070*4882a593Smuzhiyun 
1071*4882a593Smuzhiyun #ifdef BCMPCIEDEV_SROM_FORMAT
1072*4882a593Smuzhiyun 			if (ret)
1073*4882a593Smuzhiyun 				ret = initvars_srom_pci(sih, curmap, vars, count);
1074*4882a593Smuzhiyun #endif
1075*4882a593Smuzhiyun 			if (ret)
1076*4882a593Smuzhiyun 				ret =  initvars_srom_si(sih, osh, curmap, vars, count);
1077*4882a593Smuzhiyun 			return ret;
1078*4882a593Smuzhiyun 		} else
1079*4882a593Smuzhiyun #endif /* BCMPCIEDEV */
1080*4882a593Smuzhiyun 		{
1081*4882a593Smuzhiyun 			return initvars_srom_si(sih, osh, curmap, vars, count);
1082*4882a593Smuzhiyun 		}
1083*4882a593Smuzhiyun 	case PCI_BUS: {
1084*4882a593Smuzhiyun 		int ret;
1085*4882a593Smuzhiyun 
1086*4882a593Smuzhiyun #ifdef BCMNVRAMVARS
1087*4882a593Smuzhiyun 		if ((ret = initvars_nvram_vars(sih, osh, vars, count)) == BCME_OK) {
1088*4882a593Smuzhiyun 			return ret;
1089*4882a593Smuzhiyun 		} else
1090*4882a593Smuzhiyun #endif
1091*4882a593Smuzhiyun 		{
1092*4882a593Smuzhiyun 			ASSERT(curmap != NULL);
1093*4882a593Smuzhiyun 			if (curmap == NULL)
1094*4882a593Smuzhiyun 				return (-1);
1095*4882a593Smuzhiyun 
1096*4882a593Smuzhiyun 			/* First check for CIS format. if not CIS, try SROM format */
1097*4882a593Smuzhiyun 			if ((ret = initvars_cis_pci(sih, osh, curmap, vars, count)))
1098*4882a593Smuzhiyun 				return initvars_srom_pci(sih, curmap, vars, count);
1099*4882a593Smuzhiyun 			return ret;
1100*4882a593Smuzhiyun 		}
1101*4882a593Smuzhiyun 	}
1102*4882a593Smuzhiyun 
1103*4882a593Smuzhiyun #ifdef BCMSDIO
1104*4882a593Smuzhiyun 	case SDIO_BUS:
1105*4882a593Smuzhiyun 		return initvars_cis_sdio(sih, osh, vars, count);
1106*4882a593Smuzhiyun #endif /* BCMSDIO */
1107*4882a593Smuzhiyun 
1108*4882a593Smuzhiyun #ifdef BCMSPI
1109*4882a593Smuzhiyun 	case SPI_BUS:
1110*4882a593Smuzhiyun 		return initvars_cis_spi(sih, osh, vars, count);
1111*4882a593Smuzhiyun #endif /* BCMSPI */
1112*4882a593Smuzhiyun 
1113*4882a593Smuzhiyun 	default:
1114*4882a593Smuzhiyun 		ASSERT(0);
1115*4882a593Smuzhiyun 	}
1116*4882a593Smuzhiyun 	return (-1);
1117*4882a593Smuzhiyun }
1118*4882a593Smuzhiyun #endif /* !defined(BCMDONGLEHOST) */
1119*4882a593Smuzhiyun 
1120*4882a593Smuzhiyun /** support only 16-bit word read from srom */
1121*4882a593Smuzhiyun int
srom_read(si_t * sih,uint bustype,volatile void * curmap,osl_t * osh,uint byteoff,uint nbytes,uint16 * buf,bool check_crc)1122*4882a593Smuzhiyun srom_read(si_t *sih, uint bustype, volatile void *curmap, osl_t *osh,
1123*4882a593Smuzhiyun           uint byteoff, uint nbytes, uint16 *buf, bool check_crc)
1124*4882a593Smuzhiyun {
1125*4882a593Smuzhiyun 	uint i, off, nw;
1126*4882a593Smuzhiyun 
1127*4882a593Smuzhiyun 	BCM_REFERENCE(i);
1128*4882a593Smuzhiyun 
1129*4882a593Smuzhiyun 	ASSERT(bustype == BUSTYPE(bustype));
1130*4882a593Smuzhiyun 
1131*4882a593Smuzhiyun 	/* check input - 16-bit access only */
1132*4882a593Smuzhiyun 	if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > SROM_MAX)
1133*4882a593Smuzhiyun 		return 1;
1134*4882a593Smuzhiyun 
1135*4882a593Smuzhiyun 	off = byteoff / 2;
1136*4882a593Smuzhiyun 	nw = nbytes / 2;
1137*4882a593Smuzhiyun 
1138*4882a593Smuzhiyun #ifdef BCMPCIEDEV
1139*4882a593Smuzhiyun 	if ((BUSTYPE(bustype) == SI_BUS) &&
1140*4882a593Smuzhiyun 		(BCM43602_CHIP(sih->chip) ||
1141*4882a593Smuzhiyun 		(BCM4369_CHIP(sih->chip)) ||
1142*4882a593Smuzhiyun 		(BCM4378_CHIP(sih->chip)) ||
1143*4882a593Smuzhiyun 		(BCM4387_CHIP(sih->chip)) ||
1144*4882a593Smuzhiyun 		(BCM4388_CHIP(sih->chip)) ||
1145*4882a593Smuzhiyun 		(BCM4362_CHIP(sih->chip)) ||
1146*4882a593Smuzhiyun 		(BCM4385_CHIP(sih->chip)) ||
1147*4882a593Smuzhiyun 		(BCM4389_CHIP(sih->chip)) ||
1148*4882a593Smuzhiyun 		(BCM4397_CHIP(sih->chip)) ||
1149*4882a593Smuzhiyun 
1150*4882a593Smuzhiyun #ifdef UNRELEASEDCHIP
1151*4882a593Smuzhiyun #endif
1152*4882a593Smuzhiyun 
1153*4882a593Smuzhiyun 	     FALSE)) { /* building firmware for chips with a PCIe interface and internal SI bus */
1154*4882a593Smuzhiyun #else
1155*4882a593Smuzhiyun 	if (BUSTYPE(bustype) == PCI_BUS) {
1156*4882a593Smuzhiyun #endif /* BCMPCIEDEV */
1157*4882a593Smuzhiyun 		if (!curmap)
1158*4882a593Smuzhiyun 			return 1;
1159*4882a593Smuzhiyun 
1160*4882a593Smuzhiyun 		if (si_is_sprom_available(sih)) {
1161*4882a593Smuzhiyun 			volatile uint16 *srom;
1162*4882a593Smuzhiyun 
1163*4882a593Smuzhiyun 			srom = (volatile uint16 *)srom_offset(sih, curmap);
1164*4882a593Smuzhiyun 			if (srom == NULL)
1165*4882a593Smuzhiyun 				return 1;
1166*4882a593Smuzhiyun 
1167*4882a593Smuzhiyun 			if (sprom_read_pci(osh, sih, srom, off, buf, nw, check_crc))
1168*4882a593Smuzhiyun 				return 1;
1169*4882a593Smuzhiyun 		}
1170*4882a593Smuzhiyun #if !defined(BCMDONGLEHOST) && (defined(BCMNVRAMW) || defined(BCMNVRAMR))
1171*4882a593Smuzhiyun 		else if (!((BUSTYPE(bustype) == SI_BUS) &&
1172*4882a593Smuzhiyun 			(BCM43602_CHIP(sih->chip) ||
1173*4882a593Smuzhiyun 			(BCM4369_CHIP(sih->chip)) ||
1174*4882a593Smuzhiyun 			(BCM4362_CHIP(sih->chip)) ||
1175*4882a593Smuzhiyun 			(BCM4378_CHIP(sih->chip)) ||
1176*4882a593Smuzhiyun 			(BCM4385_CHIP(sih->chip)) ||
1177*4882a593Smuzhiyun 			(BCM4389_CHIP(sih->chip)) ||
1178*4882a593Smuzhiyun 			(BCM4387_CHIP(sih->chip)) ||
1179*4882a593Smuzhiyun 			(BCM4388_CHIP(sih->chip)) ||
1180*4882a593Smuzhiyun 			(BCM4397_CHIP(sih->chip)) ||
1181*4882a593Smuzhiyun 			0))) {
1182*4882a593Smuzhiyun 			if (otp_read_pci(osh, sih, buf, nbytes))
1183*4882a593Smuzhiyun 				return 1;
1184*4882a593Smuzhiyun 		}
1185*4882a593Smuzhiyun #endif /* !BCMDONGLEHOST && (BCMNVRAMW||BCMNVRAMR) */
1186*4882a593Smuzhiyun #ifdef BCMSDIO
1187*4882a593Smuzhiyun 	} else if (BUSTYPE(bustype) == SDIO_BUS) {
1188*4882a593Smuzhiyun 		off = byteoff / 2;
1189*4882a593Smuzhiyun 		nw = nbytes / 2;
1190*4882a593Smuzhiyun 		for (i = 0; i < nw; i++) {
1191*4882a593Smuzhiyun 			if (sprom_read_sdio(osh, (uint16)(off + i), (uint16 *)(buf + i)))
1192*4882a593Smuzhiyun 				return 1;
1193*4882a593Smuzhiyun 		}
1194*4882a593Smuzhiyun #endif /* BCMSDIO */
1195*4882a593Smuzhiyun #ifdef BCMSPI
1196*4882a593Smuzhiyun 	} else if (BUSTYPE(bustype) == SPI_BUS) {
1197*4882a593Smuzhiyun 		if (bcmsdh_cis_read(NULL, SDIO_FUNC_1, (uint8 *)buf, byteoff + nbytes) != 0)
1198*4882a593Smuzhiyun 			return 1;
1199*4882a593Smuzhiyun #endif /* BCMSPI */
1200*4882a593Smuzhiyun 	} else if (BUSTYPE(bustype) == SI_BUS) {
1201*4882a593Smuzhiyun 		return 1;
1202*4882a593Smuzhiyun 	} else {
1203*4882a593Smuzhiyun 		return 1;
1204*4882a593Smuzhiyun 	}
1205*4882a593Smuzhiyun 
1206*4882a593Smuzhiyun 	return 0;
1207*4882a593Smuzhiyun }
1208*4882a593Smuzhiyun 
1209*4882a593Smuzhiyun #if defined(WLTEST) || defined (DHD_SPROM) || defined (BCMDBG)
1210*4882a593Smuzhiyun /** support only 16-bit word write into srom */
1211*4882a593Smuzhiyun int
1212*4882a593Smuzhiyun srom_write(si_t *sih, uint bustype, volatile void *curmap, osl_t *osh,
1213*4882a593Smuzhiyun            uint byteoff, uint nbytes, uint16 *buf)
1214*4882a593Smuzhiyun {
1215*4882a593Smuzhiyun 	uint i, nw, crc_range;
1216*4882a593Smuzhiyun 	uint16 *old, *new;
1217*4882a593Smuzhiyun 	uint8 crc;
1218*4882a593Smuzhiyun 	volatile uint32 val32;
1219*4882a593Smuzhiyun 	int rc = 1;
1220*4882a593Smuzhiyun 
1221*4882a593Smuzhiyun 	ASSERT(bustype == BUSTYPE(bustype));
1222*4882a593Smuzhiyun 
1223*4882a593Smuzhiyun 	/* freed in same function */
1224*4882a593Smuzhiyun 	old = MALLOC_NOPERSIST(osh, SROM_MAXW * sizeof(uint16));
1225*4882a593Smuzhiyun 	new = MALLOC_NOPERSIST(osh, SROM_MAXW * sizeof(uint16));
1226*4882a593Smuzhiyun 
1227*4882a593Smuzhiyun 	if (old == NULL || new == NULL)
1228*4882a593Smuzhiyun 		goto done;
1229*4882a593Smuzhiyun 
1230*4882a593Smuzhiyun 	/* check input - 16-bit access only. use byteoff 0x55aa to indicate
1231*4882a593Smuzhiyun 	 * srclear
1232*4882a593Smuzhiyun 	 */
1233*4882a593Smuzhiyun 	if ((byteoff != 0x55aa) && ((byteoff & 1) || (nbytes & 1)))
1234*4882a593Smuzhiyun 		goto done;
1235*4882a593Smuzhiyun 
1236*4882a593Smuzhiyun 	if ((byteoff != 0x55aa) && ((byteoff + nbytes) > SROM_MAX))
1237*4882a593Smuzhiyun 		goto done;
1238*4882a593Smuzhiyun 
1239*4882a593Smuzhiyun 	if (FALSE) {
1240*4882a593Smuzhiyun 	}
1241*4882a593Smuzhiyun #ifdef BCMSDIO
1242*4882a593Smuzhiyun 	else if (BUSTYPE(bustype) == SDIO_BUS) {
1243*4882a593Smuzhiyun 		crc_range = SROM_MAX;
1244*4882a593Smuzhiyun 	}
1245*4882a593Smuzhiyun #endif
1246*4882a593Smuzhiyun 	else {
1247*4882a593Smuzhiyun 		crc_range = srom_size(sih, osh);
1248*4882a593Smuzhiyun 	}
1249*4882a593Smuzhiyun 
1250*4882a593Smuzhiyun 	nw = crc_range / 2;
1251*4882a593Smuzhiyun 	/* read first small number words from srom, then adjust the length, read all */
1252*4882a593Smuzhiyun 	if (srom_read(sih, bustype, curmap, osh, 0, crc_range, old, FALSE))
1253*4882a593Smuzhiyun 		goto done;
1254*4882a593Smuzhiyun 
1255*4882a593Smuzhiyun 	BS_ERROR(("srom_write: old[SROM4_SIGN] 0x%x, old[SROM8_SIGN] 0x%x\n",
1256*4882a593Smuzhiyun 	          old[SROM4_SIGN], old[SROM8_SIGN]));
1257*4882a593Smuzhiyun 	/* Deal with blank srom */
1258*4882a593Smuzhiyun 	if (old[0] == 0xffff) {
1259*4882a593Smuzhiyun 		/* Do nothing to blank srom when it's srclear */
1260*4882a593Smuzhiyun 		if (byteoff == 0x55aa) {
1261*4882a593Smuzhiyun 			rc = 0;
1262*4882a593Smuzhiyun 			goto done;
1263*4882a593Smuzhiyun 		}
1264*4882a593Smuzhiyun 
1265*4882a593Smuzhiyun 		/* see if the input buffer is valid SROM image or not */
1266*4882a593Smuzhiyun 		if (buf[SROM11_SIGN] == SROM11_SIGNATURE) {
1267*4882a593Smuzhiyun 			BS_ERROR(("srom_write: buf[SROM11_SIGN] 0x%x\n",
1268*4882a593Smuzhiyun 				buf[SROM11_SIGN]));
1269*4882a593Smuzhiyun 
1270*4882a593Smuzhiyun 			/* block invalid buffer size */
1271*4882a593Smuzhiyun 			if (nbytes < SROM11_WORDS * 2) {
1272*4882a593Smuzhiyun 				rc = BCME_BUFTOOSHORT;
1273*4882a593Smuzhiyun 				goto done;
1274*4882a593Smuzhiyun 			} else if (nbytes > SROM11_WORDS * 2) {
1275*4882a593Smuzhiyun 				rc = BCME_BUFTOOLONG;
1276*4882a593Smuzhiyun 				goto done;
1277*4882a593Smuzhiyun 			}
1278*4882a593Smuzhiyun 
1279*4882a593Smuzhiyun 			nw = SROM11_WORDS;
1280*4882a593Smuzhiyun 
1281*4882a593Smuzhiyun 		} else if (buf[SROM12_SIGN] == SROM12_SIGNATURE) {
1282*4882a593Smuzhiyun 			BS_ERROR(("srom_write: buf[SROM12_SIGN] 0x%x\n",
1283*4882a593Smuzhiyun 				buf[SROM12_SIGN]));
1284*4882a593Smuzhiyun 
1285*4882a593Smuzhiyun 			/* block invalid buffer size */
1286*4882a593Smuzhiyun 			if (nbytes < SROM12_WORDS * 2) {
1287*4882a593Smuzhiyun 				rc = BCME_BUFTOOSHORT;
1288*4882a593Smuzhiyun 				goto done;
1289*4882a593Smuzhiyun 			} else if (nbytes > SROM12_WORDS * 2) {
1290*4882a593Smuzhiyun 				rc = BCME_BUFTOOLONG;
1291*4882a593Smuzhiyun 				goto done;
1292*4882a593Smuzhiyun 			}
1293*4882a593Smuzhiyun 
1294*4882a593Smuzhiyun 			nw = SROM12_WORDS;
1295*4882a593Smuzhiyun 
1296*4882a593Smuzhiyun 		} else if (buf[SROM13_SIGN] == SROM13_SIGNATURE) {
1297*4882a593Smuzhiyun 			BS_ERROR(("srom_write: buf[SROM13_SIGN] 0x%x\n",
1298*4882a593Smuzhiyun 				buf[SROM13_SIGN]));
1299*4882a593Smuzhiyun 
1300*4882a593Smuzhiyun 			/* block invalid buffer size */
1301*4882a593Smuzhiyun 			if (nbytes < SROM13_WORDS * 2) {
1302*4882a593Smuzhiyun 				rc = BCME_BUFTOOSHORT;
1303*4882a593Smuzhiyun 				goto done;
1304*4882a593Smuzhiyun 			} else if (nbytes > SROM13_WORDS * 2) {
1305*4882a593Smuzhiyun 				rc = BCME_BUFTOOLONG;
1306*4882a593Smuzhiyun 				goto done;
1307*4882a593Smuzhiyun 			}
1308*4882a593Smuzhiyun 
1309*4882a593Smuzhiyun 			nw = SROM13_WORDS;
1310*4882a593Smuzhiyun 
1311*4882a593Smuzhiyun 		} else if (buf[SROM16_SIGN] == SROM16_SIGNATURE) {
1312*4882a593Smuzhiyun 			BS_ERROR(("srom_write: buf[SROM16_SIGN] 0x%x\n",
1313*4882a593Smuzhiyun 				buf[SROM16_SIGN]));
1314*4882a593Smuzhiyun 
1315*4882a593Smuzhiyun 			/* block invalid buffer size */
1316*4882a593Smuzhiyun 			if (nbytes < SROM16_WORDS * 2) {
1317*4882a593Smuzhiyun 				rc = BCME_BUFTOOSHORT;
1318*4882a593Smuzhiyun 				goto done;
1319*4882a593Smuzhiyun 			} else if (nbytes > SROM16_WORDS * 2) {
1320*4882a593Smuzhiyun 				rc = BCME_BUFTOOLONG;
1321*4882a593Smuzhiyun 				goto done;
1322*4882a593Smuzhiyun 			}
1323*4882a593Smuzhiyun 
1324*4882a593Smuzhiyun 			nw = SROM16_WORDS;
1325*4882a593Smuzhiyun 
1326*4882a593Smuzhiyun 		} else if (buf[SROM17_SIGN] == SROM17_SIGNATURE) {
1327*4882a593Smuzhiyun 			BS_ERROR(("srom_write: buf[SROM17_SIGN] 0x%x\n",
1328*4882a593Smuzhiyun 				buf[SROM17_SIGN]));
1329*4882a593Smuzhiyun 
1330*4882a593Smuzhiyun 			/* block invalid buffer size */
1331*4882a593Smuzhiyun 			if (nbytes < SROM17_WORDS * 2) {
1332*4882a593Smuzhiyun 				rc = BCME_BUFTOOSHORT;
1333*4882a593Smuzhiyun 				goto done;
1334*4882a593Smuzhiyun 			} else if (nbytes > SROM17_WORDS * 2) {
1335*4882a593Smuzhiyun 				rc = BCME_BUFTOOLONG;
1336*4882a593Smuzhiyun 				goto done;
1337*4882a593Smuzhiyun 			}
1338*4882a593Smuzhiyun 
1339*4882a593Smuzhiyun 			nw = SROM17_WORDS;
1340*4882a593Smuzhiyun 		} else if (buf[SROM18_SIGN] == SROM18_SIGNATURE) {
1341*4882a593Smuzhiyun 			BS_ERROR(("srom_write: buf[SROM18_SIGN] 0x%x\n",
1342*4882a593Smuzhiyun 				buf[SROM18_SIGN]));
1343*4882a593Smuzhiyun 
1344*4882a593Smuzhiyun 			/* block invalid buffer size */
1345*4882a593Smuzhiyun 			/* nbytes can be < SROM18 bytes since host limits transfer chunk size
1346*4882a593Smuzhiyun 			 * to 1500 Bytes
1347*4882a593Smuzhiyun 			 */
1348*4882a593Smuzhiyun 			if (nbytes > SROM18_WORDS * 2) {
1349*4882a593Smuzhiyun 				rc = BCME_BUFTOOLONG;
1350*4882a593Smuzhiyun 				goto done;
1351*4882a593Smuzhiyun 			}
1352*4882a593Smuzhiyun 
1353*4882a593Smuzhiyun 			nw = SROM18_WORDS;
1354*4882a593Smuzhiyun 
1355*4882a593Smuzhiyun 		} else if (buf[SROM11_SIGN] == SROM15_SIGNATURE) {
1356*4882a593Smuzhiyun 			BS_ERROR(("srom_write: buf[SROM15_SIGN] 0x%x\n",
1357*4882a593Smuzhiyun 				buf[SROM11_SIGN]));
1358*4882a593Smuzhiyun 			 /* nbytes can be < SROM15 bytes since host limits trasnfer chunk size
1359*4882a593Smuzhiyun 			 * to 1518 Bytes
1360*4882a593Smuzhiyun 			 */
1361*4882a593Smuzhiyun 			 if (nbytes > SROM15_WORDS * 2) {
1362*4882a593Smuzhiyun 				rc = BCME_BUFTOOLONG;
1363*4882a593Smuzhiyun 				goto done;
1364*4882a593Smuzhiyun 			}
1365*4882a593Smuzhiyun 			nw = SROM15_WORDS;
1366*4882a593Smuzhiyun 		} else if ((buf[SROM4_SIGN] == SROM4_SIGNATURE) ||
1367*4882a593Smuzhiyun 			(buf[SROM8_SIGN] == SROM4_SIGNATURE)) {
1368*4882a593Smuzhiyun 			BS_ERROR(("srom_write: buf[SROM4_SIGN] 0x%x, buf[SROM8_SIGN] 0x%x\n",
1369*4882a593Smuzhiyun 				buf[SROM4_SIGN], buf[SROM8_SIGN]));
1370*4882a593Smuzhiyun 
1371*4882a593Smuzhiyun 			/* block invalid buffer size */
1372*4882a593Smuzhiyun 			if (nbytes < SROM4_WORDS * 2) {
1373*4882a593Smuzhiyun 				rc = BCME_BUFTOOSHORT;
1374*4882a593Smuzhiyun 				goto done;
1375*4882a593Smuzhiyun 			} else if (nbytes > SROM4_WORDS * 2) {
1376*4882a593Smuzhiyun 				rc = BCME_BUFTOOLONG;
1377*4882a593Smuzhiyun 				goto done;
1378*4882a593Smuzhiyun 			}
1379*4882a593Smuzhiyun 
1380*4882a593Smuzhiyun 			nw = SROM4_WORDS;
1381*4882a593Smuzhiyun 		} else if (nbytes == SROM_WORDS * 2){ /* the other possible SROM format */
1382*4882a593Smuzhiyun 			BS_ERROR(("srom_write: Not SROM4 or SROM8.\n"));
1383*4882a593Smuzhiyun 
1384*4882a593Smuzhiyun 			nw = SROM_WORDS;
1385*4882a593Smuzhiyun 		} else {
1386*4882a593Smuzhiyun 			BS_ERROR(("srom_write: Invalid input file signature\n"));
1387*4882a593Smuzhiyun 			rc = BCME_BADARG;
1388*4882a593Smuzhiyun 			goto done;
1389*4882a593Smuzhiyun 		}
1390*4882a593Smuzhiyun 		crc_range = nw * 2;
1391*4882a593Smuzhiyun 		if (srom_read(sih, bustype, curmap, osh, 0, crc_range, old, FALSE)) {
1392*4882a593Smuzhiyun 			goto done;
1393*4882a593Smuzhiyun 		}
1394*4882a593Smuzhiyun 	} else if (old[SROM18_SIGN] == SROM18_SIGNATURE) {
1395*4882a593Smuzhiyun 		nw = SROM18_WORDS;
1396*4882a593Smuzhiyun 		crc_range = nw * 2;
1397*4882a593Smuzhiyun 		if (srom_read(sih, bustype, curmap, osh, 0, crc_range, old, FALSE)) {
1398*4882a593Smuzhiyun 			goto done;
1399*4882a593Smuzhiyun 		}
1400*4882a593Smuzhiyun 	} else if (old[SROM17_SIGN] == SROM17_SIGNATURE) {
1401*4882a593Smuzhiyun 		nw = SROM17_WORDS;
1402*4882a593Smuzhiyun 		crc_range = nw * 2;
1403*4882a593Smuzhiyun 		if (srom_read(sih, bustype, curmap, osh, 0, crc_range, old, FALSE)) {
1404*4882a593Smuzhiyun 			goto done;
1405*4882a593Smuzhiyun 		}
1406*4882a593Smuzhiyun 	} else if (old[SROM16_SIGN] == SROM16_SIGNATURE) {
1407*4882a593Smuzhiyun 		nw = SROM16_WORDS;
1408*4882a593Smuzhiyun 		crc_range = nw * 2;
1409*4882a593Smuzhiyun 		if (srom_read(sih, bustype, curmap, osh, 0, crc_range, old, FALSE)) {
1410*4882a593Smuzhiyun 			goto done;
1411*4882a593Smuzhiyun 		}
1412*4882a593Smuzhiyun 	} else if (old[SROM15_SIGN] == SROM15_SIGNATURE) {
1413*4882a593Smuzhiyun 		nw = SROM15_WORDS;
1414*4882a593Smuzhiyun 		crc_range = nw * 2;
1415*4882a593Smuzhiyun 		if (srom_read(sih, bustype, curmap, osh, 0, crc_range, old, FALSE)) {
1416*4882a593Smuzhiyun 			goto done;
1417*4882a593Smuzhiyun 		}
1418*4882a593Smuzhiyun 	} else if (old[SROM13_SIGN] == SROM13_SIGNATURE) {
1419*4882a593Smuzhiyun 		nw = SROM13_WORDS;
1420*4882a593Smuzhiyun 		crc_range = nw * 2;
1421*4882a593Smuzhiyun 		if (srom_read(sih, bustype, curmap, osh, 0, crc_range, old, FALSE)) {
1422*4882a593Smuzhiyun 			goto done;
1423*4882a593Smuzhiyun 		}
1424*4882a593Smuzhiyun 	} else if (old[SROM12_SIGN] == SROM12_SIGNATURE) {
1425*4882a593Smuzhiyun 		nw = SROM12_WORDS;
1426*4882a593Smuzhiyun 		crc_range = nw * 2;
1427*4882a593Smuzhiyun 		if (srom_read(sih, bustype, curmap, osh, 0, crc_range, old, FALSE)) {
1428*4882a593Smuzhiyun 			goto done;
1429*4882a593Smuzhiyun 		}
1430*4882a593Smuzhiyun 	} else if (old[SROM11_SIGN] == SROM11_SIGNATURE) {
1431*4882a593Smuzhiyun 		nw = SROM11_WORDS;
1432*4882a593Smuzhiyun 		crc_range = nw * 2;
1433*4882a593Smuzhiyun 		if (srom_read(sih, bustype, curmap, osh, 0, crc_range, old, FALSE)) {
1434*4882a593Smuzhiyun 			goto done;
1435*4882a593Smuzhiyun 		}
1436*4882a593Smuzhiyun 	} else if ((old[SROM4_SIGN] == SROM4_SIGNATURE) ||
1437*4882a593Smuzhiyun 	           (old[SROM8_SIGN] == SROM4_SIGNATURE)) {
1438*4882a593Smuzhiyun 		nw = SROM4_WORDS;
1439*4882a593Smuzhiyun 		crc_range = nw * 2;
1440*4882a593Smuzhiyun 		if (srom_read(sih, bustype, curmap, osh, 0, crc_range, old, FALSE)) {
1441*4882a593Smuzhiyun 			goto done;
1442*4882a593Smuzhiyun 		}
1443*4882a593Smuzhiyun 	} else {
1444*4882a593Smuzhiyun 		/* Assert that we have already read enough for sromrev 2 */
1445*4882a593Smuzhiyun 		ASSERT(crc_range >= SROM_WORDS * 2);
1446*4882a593Smuzhiyun 		nw = SROM_WORDS;
1447*4882a593Smuzhiyun 		crc_range = nw * 2;
1448*4882a593Smuzhiyun 	}
1449*4882a593Smuzhiyun 
1450*4882a593Smuzhiyun 	if (byteoff == 0x55aa) {
1451*4882a593Smuzhiyun 		/* Erase request */
1452*4882a593Smuzhiyun 		crc_range = 0;
1453*4882a593Smuzhiyun 		memset((void *)new, 0xff, nw * 2);
1454*4882a593Smuzhiyun 	} else {
1455*4882a593Smuzhiyun 		/* Copy old contents */
1456*4882a593Smuzhiyun 		bcopy((void *)old, (void *)new, nw * 2);
1457*4882a593Smuzhiyun 		/* make changes */
1458*4882a593Smuzhiyun 		bcopy((void *)buf, (void *)&new[byteoff / 2], nbytes);
1459*4882a593Smuzhiyun 	}
1460*4882a593Smuzhiyun 
1461*4882a593Smuzhiyun 	if (crc_range) {
1462*4882a593Smuzhiyun 		/* calculate crc */
1463*4882a593Smuzhiyun 		htol16_buf(new, crc_range);
1464*4882a593Smuzhiyun 		crc = ~hndcrc8((uint8 *)new, crc_range - 1, CRC8_INIT_VALUE);
1465*4882a593Smuzhiyun 		ltoh16_buf(new, crc_range);
1466*4882a593Smuzhiyun 		new[nw - 1] = (crc << 8) | (new[nw - 1] & 0xff);
1467*4882a593Smuzhiyun 	}
1468*4882a593Smuzhiyun 
1469*4882a593Smuzhiyun #ifdef BCMPCIEDEV
1470*4882a593Smuzhiyun 	if ((BUSTYPE(bustype) == SI_BUS) &&
1471*4882a593Smuzhiyun 		(BCM43602_CHIP(sih->chip) ||
1472*4882a593Smuzhiyun 		(BCM4369_CHIP(sih->chip)) ||
1473*4882a593Smuzhiyun 		(BCM4362_CHIP(sih->chip)) ||
1474*4882a593Smuzhiyun 		(BCM4378_CHIP(sih->chip)) ||
1475*4882a593Smuzhiyun 		(BCM4387_CHIP(sih->chip)) ||
1476*4882a593Smuzhiyun 		(BCM4388_CHIP(sih->chip)) ||
1477*4882a593Smuzhiyun 		(BCM4385_CHIP(sih->chip)) ||
1478*4882a593Smuzhiyun 		(BCM4389_CHIP(sih->chip)) ||
1479*4882a593Smuzhiyun 		(BCM4397_CHIP(sih->chip)) ||
1480*4882a593Smuzhiyun 
1481*4882a593Smuzhiyun #ifdef UNRELEASEDCHIP
1482*4882a593Smuzhiyun #endif /* UNRELEASEDCHIP */
1483*4882a593Smuzhiyun 
1484*4882a593Smuzhiyun 	     FALSE)) {
1485*4882a593Smuzhiyun #else
1486*4882a593Smuzhiyun 	if (BUSTYPE(bustype) == PCI_BUS) {
1487*4882a593Smuzhiyun #endif /* BCMPCIEDEV */
1488*4882a593Smuzhiyun 		volatile uint16 *srom = NULL;
1489*4882a593Smuzhiyun 		volatile void *ccregs = NULL;
1490*4882a593Smuzhiyun 		uint32 ccval = 0;
1491*4882a593Smuzhiyun 
1492*4882a593Smuzhiyun 		if ((CHIPID(sih->chip) == BCM4360_CHIP_ID) ||
1493*4882a593Smuzhiyun 		    (CHIPID(sih->chip) == BCM43460_CHIP_ID) ||
1494*4882a593Smuzhiyun 		    (CHIPID(sih->chip) == BCM43526_CHIP_ID) ||
1495*4882a593Smuzhiyun 		    (CHIPID(sih->chip) == BCM4352_CHIP_ID) ||
1496*4882a593Smuzhiyun 		    BCM43602_CHIP(sih->chip)) {
1497*4882a593Smuzhiyun 			/* save current control setting */
1498*4882a593Smuzhiyun 			ccval = si_chipcontrl_read(sih);
1499*4882a593Smuzhiyun 		}
1500*4882a593Smuzhiyun 
1501*4882a593Smuzhiyun 		if (BCM43602_CHIP(sih->chip) ||
1502*4882a593Smuzhiyun 			(((CHIPID(sih->chip) == BCM4360_CHIP_ID) ||
1503*4882a593Smuzhiyun 			(CHIPID(sih->chip) == BCM43460_CHIP_ID) ||
1504*4882a593Smuzhiyun 			(CHIPID(sih->chip) == BCM4352_CHIP_ID)) &&
1505*4882a593Smuzhiyun 			(CHIPREV(sih->chiprev) <= 2))) {
1506*4882a593Smuzhiyun 			si_chipcontrl_srom4360(sih, TRUE);
1507*4882a593Smuzhiyun 		}
1508*4882a593Smuzhiyun 
1509*4882a593Smuzhiyun 		if (FALSE) {
1510*4882a593Smuzhiyun 			si_srom_clk_set(sih); /* corrects srom clock frequency */
1511*4882a593Smuzhiyun 		}
1512*4882a593Smuzhiyun 
1513*4882a593Smuzhiyun 		/* enable writes to the SPROM */
1514*4882a593Smuzhiyun 		if (sih->ccrev > 31) {
1515*4882a593Smuzhiyun 			if (BUSTYPE(sih->bustype) == SI_BUS)
1516*4882a593Smuzhiyun 				ccregs = (void *)(uintptr)SI_ENUM_BASE(sih);
1517*4882a593Smuzhiyun 			else
1518*4882a593Smuzhiyun 				ccregs = ((volatile uint8 *)curmap + PCI_16KB0_CCREGS_OFFSET);
1519*4882a593Smuzhiyun 			srom = (volatile uint16 *)((volatile uint8 *)ccregs + CC_SROM_OTP);
1520*4882a593Smuzhiyun 			(void)srom_cc_cmd(sih, osh, ccregs, SRC_OP_WREN, 0, 0);
1521*4882a593Smuzhiyun 		} else {
1522*4882a593Smuzhiyun 			srom = (volatile uint16 *)
1523*4882a593Smuzhiyun 					((volatile uint8 *)curmap + PCI_BAR0_SPROM_OFFSET);
1524*4882a593Smuzhiyun 			val32 = OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32));
1525*4882a593Smuzhiyun 			val32 |= SPROM_WRITEEN;
1526*4882a593Smuzhiyun 			OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32);
1527*4882a593Smuzhiyun 		}
1528*4882a593Smuzhiyun 		bcm_mdelay(WRITE_ENABLE_DELAY);
1529*4882a593Smuzhiyun 		/* write srom */
1530*4882a593Smuzhiyun 		for (i = 0; i < nw; i++) {
1531*4882a593Smuzhiyun 			if (old[i] != new[i]) {
1532*4882a593Smuzhiyun 				if (sih->ccrev > 31) {
1533*4882a593Smuzhiyun 					if ((sih->cccaps & CC_CAP_SROM) == 0) {
1534*4882a593Smuzhiyun 						/* No srom support in this chip */
1535*4882a593Smuzhiyun 						BS_ERROR(("srom_write, invalid srom, skip\n"));
1536*4882a593Smuzhiyun 					} else
1537*4882a593Smuzhiyun 						(void)srom_cc_cmd(sih, osh, ccregs, SRC_OP_WRITE,
1538*4882a593Smuzhiyun 							i, new[i]);
1539*4882a593Smuzhiyun 				} else {
1540*4882a593Smuzhiyun 					W_REG(osh, &srom[i], new[i]);
1541*4882a593Smuzhiyun 				}
1542*4882a593Smuzhiyun 				bcm_mdelay(WRITE_WORD_DELAY);
1543*4882a593Smuzhiyun 			}
1544*4882a593Smuzhiyun 		}
1545*4882a593Smuzhiyun 		/* disable writes to the SPROM */
1546*4882a593Smuzhiyun 		if (sih->ccrev > 31) {
1547*4882a593Smuzhiyun 			(void)srom_cc_cmd(sih, osh, ccregs, SRC_OP_WRDIS, 0, 0);
1548*4882a593Smuzhiyun 		} else {
1549*4882a593Smuzhiyun 			OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32 &
1550*4882a593Smuzhiyun 			                     ~SPROM_WRITEEN);
1551*4882a593Smuzhiyun 		}
1552*4882a593Smuzhiyun 
1553*4882a593Smuzhiyun 		if (BCM43602_CHIP(sih->chip) ||
1554*4882a593Smuzhiyun 		    (CHIPID(sih->chip) == BCM4360_CHIP_ID) ||
1555*4882a593Smuzhiyun 		    (CHIPID(sih->chip) == BCM43460_CHIP_ID) ||
1556*4882a593Smuzhiyun 		    (CHIPID(sih->chip) == BCM4352_CHIP_ID)) {
1557*4882a593Smuzhiyun 			/* Restore config after reading SROM */
1558*4882a593Smuzhiyun 			si_chipcontrl_restore(sih, ccval);
1559*4882a593Smuzhiyun 		}
1560*4882a593Smuzhiyun #ifdef BCMSDIO
1561*4882a593Smuzhiyun 	} else if (BUSTYPE(bustype) == SDIO_BUS) {
1562*4882a593Smuzhiyun 		/* enable writes to the SPROM */
1563*4882a593Smuzhiyun 		if (sprom_cmd_sdio(osh, SBSDIO_SPROM_WEN))
1564*4882a593Smuzhiyun 			goto done;
1565*4882a593Smuzhiyun 		bcm_mdelay(WRITE_ENABLE_DELAY);
1566*4882a593Smuzhiyun 		/* write srom */
1567*4882a593Smuzhiyun 		for (i = 0; i < nw; i++) {
1568*4882a593Smuzhiyun 			if (old[i] != new[i]) {
1569*4882a593Smuzhiyun 				sprom_write_sdio(osh, (uint16)(i), new[i]);
1570*4882a593Smuzhiyun 				bcm_mdelay(WRITE_WORD_DELAY);
1571*4882a593Smuzhiyun 			}
1572*4882a593Smuzhiyun 		}
1573*4882a593Smuzhiyun 		/* disable writes to the SPROM */
1574*4882a593Smuzhiyun 		if (sprom_cmd_sdio(osh, SBSDIO_SPROM_WDS))
1575*4882a593Smuzhiyun 			goto done;
1576*4882a593Smuzhiyun #endif /* BCMSDIO */
1577*4882a593Smuzhiyun 	} else if (BUSTYPE(bustype) == SI_BUS) {
1578*4882a593Smuzhiyun 		goto done;
1579*4882a593Smuzhiyun 	} else {
1580*4882a593Smuzhiyun 		goto done;
1581*4882a593Smuzhiyun 	}
1582*4882a593Smuzhiyun 
1583*4882a593Smuzhiyun 	bcm_mdelay(WRITE_ENABLE_DELAY);
1584*4882a593Smuzhiyun 	rc = 0;
1585*4882a593Smuzhiyun 
1586*4882a593Smuzhiyun done:
1587*4882a593Smuzhiyun 	if (old != NULL)
1588*4882a593Smuzhiyun 		MFREE(osh, old, SROM_MAXW * sizeof(uint16));
1589*4882a593Smuzhiyun 	if (new != NULL)
1590*4882a593Smuzhiyun 		MFREE(osh, new, SROM_MAXW * sizeof(uint16));
1591*4882a593Smuzhiyun 
1592*4882a593Smuzhiyun 	return rc;
1593*4882a593Smuzhiyun }
1594*4882a593Smuzhiyun 
1595*4882a593Smuzhiyun /** support only 16-bit word write into srom */
1596*4882a593Smuzhiyun int
1597*4882a593Smuzhiyun srom_write_short(si_t *sih, uint bustype, volatile void *curmap, osl_t *osh,
1598*4882a593Smuzhiyun                  uint byteoff, uint16 value)
1599*4882a593Smuzhiyun {
1600*4882a593Smuzhiyun 	volatile uint32 val32;
1601*4882a593Smuzhiyun 	int rc = 1;
1602*4882a593Smuzhiyun 
1603*4882a593Smuzhiyun 	ASSERT(bustype == BUSTYPE(bustype));
1604*4882a593Smuzhiyun 
1605*4882a593Smuzhiyun 	if (byteoff & 1)
1606*4882a593Smuzhiyun 		goto done;
1607*4882a593Smuzhiyun 
1608*4882a593Smuzhiyun #ifdef BCMPCIEDEV
1609*4882a593Smuzhiyun 	if ((BUSTYPE(bustype) == SI_BUS) &&
1610*4882a593Smuzhiyun 	    (BCM43602_CHIP(sih->chip) ||
1611*4882a593Smuzhiyun 	     FALSE)) {
1612*4882a593Smuzhiyun #else
1613*4882a593Smuzhiyun 	if (BUSTYPE(bustype) == PCI_BUS) {
1614*4882a593Smuzhiyun #endif /* BCMPCIEDEV */
1615*4882a593Smuzhiyun 		volatile uint16 *srom = NULL;
1616*4882a593Smuzhiyun 		volatile void *ccregs = NULL;
1617*4882a593Smuzhiyun 		uint32 ccval = 0;
1618*4882a593Smuzhiyun 
1619*4882a593Smuzhiyun 		if (BCM43602_CHIP(sih->chip) ||
1620*4882a593Smuzhiyun 		    (CHIPID(sih->chip) == BCM4360_CHIP_ID) ||
1621*4882a593Smuzhiyun 		    (CHIPID(sih->chip) == BCM43460_CHIP_ID) ||
1622*4882a593Smuzhiyun 		    (CHIPID(sih->chip) == BCM43526_CHIP_ID) ||
1623*4882a593Smuzhiyun 		    (CHIPID(sih->chip) == BCM4352_CHIP_ID)) {
1624*4882a593Smuzhiyun 			/* save current control setting */
1625*4882a593Smuzhiyun 			ccval = si_chipcontrl_read(sih);
1626*4882a593Smuzhiyun 		}
1627*4882a593Smuzhiyun 
1628*4882a593Smuzhiyun 		if (BCM43602_CHIP(sih->chip) ||
1629*4882a593Smuzhiyun 			(((CHIPID(sih->chip) == BCM4360_CHIP_ID) ||
1630*4882a593Smuzhiyun 			(CHIPID(sih->chip) == BCM43460_CHIP_ID) ||
1631*4882a593Smuzhiyun 			(CHIPID(sih->chip) == BCM4352_CHIP_ID)) &&
1632*4882a593Smuzhiyun 			(CHIPREV(sih->chiprev) <= 2))) {
1633*4882a593Smuzhiyun 			si_chipcontrl_srom4360(sih, TRUE);
1634*4882a593Smuzhiyun 		}
1635*4882a593Smuzhiyun 
1636*4882a593Smuzhiyun 		if (FALSE) {
1637*4882a593Smuzhiyun 			si_srom_clk_set(sih); /* corrects srom clock frequency */
1638*4882a593Smuzhiyun 		}
1639*4882a593Smuzhiyun 
1640*4882a593Smuzhiyun 		/* enable writes to the SPROM */
1641*4882a593Smuzhiyun 		if (sih->ccrev > 31) {
1642*4882a593Smuzhiyun 			if (BUSTYPE(sih->bustype) == SI_BUS)
1643*4882a593Smuzhiyun 				ccregs = (void *)(uintptr)SI_ENUM_BASE(sih);
1644*4882a593Smuzhiyun 			else
1645*4882a593Smuzhiyun 				ccregs = ((volatile uint8 *)curmap + PCI_16KB0_CCREGS_OFFSET);
1646*4882a593Smuzhiyun 			srom = (volatile uint16 *)((volatile uint8 *)ccregs + CC_SROM_OTP);
1647*4882a593Smuzhiyun 			(void)srom_cc_cmd(sih, osh, ccregs, SRC_OP_WREN, 0, 0);
1648*4882a593Smuzhiyun 		} else {
1649*4882a593Smuzhiyun 			srom = (volatile uint16 *)
1650*4882a593Smuzhiyun 					((volatile uint8 *)curmap + PCI_BAR0_SPROM_OFFSET);
1651*4882a593Smuzhiyun 			val32 = OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32));
1652*4882a593Smuzhiyun 			val32 |= SPROM_WRITEEN;
1653*4882a593Smuzhiyun 			OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32);
1654*4882a593Smuzhiyun 		}
1655*4882a593Smuzhiyun 		bcm_mdelay(WRITE_ENABLE_DELAY);
1656*4882a593Smuzhiyun 		/* write srom */
1657*4882a593Smuzhiyun 		if (sih->ccrev > 31) {
1658*4882a593Smuzhiyun 			if ((sih->cccaps & CC_CAP_SROM) == 0) {
1659*4882a593Smuzhiyun 				/* No srom support in this chip */
1660*4882a593Smuzhiyun 				BS_ERROR(("srom_write, invalid srom, skip\n"));
1661*4882a593Smuzhiyun 			} else
1662*4882a593Smuzhiyun 				(void)srom_cc_cmd(sih, osh, ccregs, SRC_OP_WRITE,
1663*4882a593Smuzhiyun 				                   byteoff/2, value);
1664*4882a593Smuzhiyun 		} else {
1665*4882a593Smuzhiyun 			W_REG(osh, &srom[byteoff/2], value);
1666*4882a593Smuzhiyun 		}
1667*4882a593Smuzhiyun 		bcm_mdelay(WRITE_WORD_DELAY);
1668*4882a593Smuzhiyun 
1669*4882a593Smuzhiyun 		/* disable writes to the SPROM */
1670*4882a593Smuzhiyun 		if (sih->ccrev > 31) {
1671*4882a593Smuzhiyun 			(void)srom_cc_cmd(sih, osh, ccregs, SRC_OP_WRDIS, 0, 0);
1672*4882a593Smuzhiyun 		} else {
1673*4882a593Smuzhiyun 			OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32 &
1674*4882a593Smuzhiyun 			                     ~SPROM_WRITEEN);
1675*4882a593Smuzhiyun 		}
1676*4882a593Smuzhiyun 
1677*4882a593Smuzhiyun 		if (BCM43602_CHIP(sih->chip) ||
1678*4882a593Smuzhiyun 		    (CHIPID(sih->chip) == BCM4360_CHIP_ID) ||
1679*4882a593Smuzhiyun 		    (CHIPID(sih->chip) == BCM43460_CHIP_ID) ||
1680*4882a593Smuzhiyun 		    (CHIPID(sih->chip) == BCM43526_CHIP_ID) ||
1681*4882a593Smuzhiyun 		    (CHIPID(sih->chip) == BCM4352_CHIP_ID)) {
1682*4882a593Smuzhiyun 			/* Restore config after reading SROM */
1683*4882a593Smuzhiyun 			si_chipcontrl_restore(sih, ccval);
1684*4882a593Smuzhiyun 		}
1685*4882a593Smuzhiyun #ifdef BCMSDIO
1686*4882a593Smuzhiyun 	} else if (BUSTYPE(bustype) == SDIO_BUS) {
1687*4882a593Smuzhiyun 		/* enable writes to the SPROM */
1688*4882a593Smuzhiyun 		if (sprom_cmd_sdio(osh, SBSDIO_SPROM_WEN))
1689*4882a593Smuzhiyun 			goto done;
1690*4882a593Smuzhiyun 		bcm_mdelay(WRITE_ENABLE_DELAY);
1691*4882a593Smuzhiyun 		/* write srom */
1692*4882a593Smuzhiyun 		sprom_write_sdio(osh, (uint16)(byteoff/2), value);
1693*4882a593Smuzhiyun 		bcm_mdelay(WRITE_WORD_DELAY);
1694*4882a593Smuzhiyun 
1695*4882a593Smuzhiyun 		/* disable writes to the SPROM */
1696*4882a593Smuzhiyun 		if (sprom_cmd_sdio(osh, SBSDIO_SPROM_WDS))
1697*4882a593Smuzhiyun 			goto done;
1698*4882a593Smuzhiyun #endif /* BCMSDIO */
1699*4882a593Smuzhiyun 	} else if (BUSTYPE(bustype) == SI_BUS) {
1700*4882a593Smuzhiyun 		goto done;
1701*4882a593Smuzhiyun 	} else {
1702*4882a593Smuzhiyun 		goto done;
1703*4882a593Smuzhiyun 	}
1704*4882a593Smuzhiyun 
1705*4882a593Smuzhiyun 	bcm_mdelay(WRITE_ENABLE_DELAY);
1706*4882a593Smuzhiyun 	rc = 0;
1707*4882a593Smuzhiyun 
1708*4882a593Smuzhiyun done:
1709*4882a593Smuzhiyun 	return rc;
1710*4882a593Smuzhiyun }
1711*4882a593Smuzhiyun #endif /* defined(WLTEST) || defined (DHD_SPROM) || defined (BCMDBG) */
1712*4882a593Smuzhiyun 
1713*4882a593Smuzhiyun /**
1714*4882a593Smuzhiyun  * These 'vstr_*' definitions are used to convert from CIS format to a 'NVRAM var=val' format, the
1715*4882a593Smuzhiyun  * NVRAM format is used throughout the rest of the firmware.
1716*4882a593Smuzhiyun  */
1717*4882a593Smuzhiyun #if !defined(BCMDONGLEHOST)
1718*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_manf)[] = "manf=%s";
1719*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_productname)[] = "productname=%s";
1720*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_manfid)[] = "manfid=0x%x";
1721*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_prodid)[] = "prodid=0x%x";
1722*4882a593Smuzhiyun #ifdef BCMSDIO
1723*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_sdmaxspeed)[] = "sdmaxspeed=%d";
1724*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_sdmaxblk)[][13] =
1725*4882a593Smuzhiyun 	{ "sdmaxblk0=%d", "sdmaxblk1=%d", "sdmaxblk2=%d" };
1726*4882a593Smuzhiyun #endif
1727*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_regwindowsz)[] = "regwindowsz=%d";
1728*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_sromrev)[] = "sromrev=%d";
1729*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_chiprev)[] = "chiprev=%d";
1730*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_subvendid)[] = "subvendid=0x%x";
1731*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_subdevid)[] = "subdevid=0x%x";
1732*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_boardrev)[] = "boardrev=0x%x";
1733*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_aa2g)[] = "aa2g=0x%x";
1734*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_aa5g)[] = "aa5g=0x%x";
1735*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_ag)[] = "ag%d=0x%x";
1736*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_cc)[] = "cc=%d";
1737*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_opo)[] = "opo=%d";
1738*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pa0b)[][9] = { "pa0b0=%d", "pa0b1=%d", "pa0b2=%d" };
1739*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pa0b_lo)[][12] =
1740*4882a593Smuzhiyun 	{ "pa0b0_lo=%d", "pa0b1_lo=%d", "pa0b2_lo=%d" };
1741*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pa0itssit)[] = "pa0itssit=%d";
1742*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pa0maxpwr)[] = "pa0maxpwr=%d";
1743*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pa1b)[][9] = { "pa1b0=%d", "pa1b1=%d", "pa1b2=%d" };
1744*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pa1lob)[][11] =
1745*4882a593Smuzhiyun 	{ "pa1lob0=%d", "pa1lob1=%d", "pa1lob2=%d" };
1746*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pa1hib)[][11] =
1747*4882a593Smuzhiyun 	{ "pa1hib0=%d", "pa1hib1=%d", "pa1hib2=%d" };
1748*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pa1itssit)[] = "pa1itssit=%d";
1749*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pa1maxpwr)[] = "pa1maxpwr=%d";
1750*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pa1lomaxpwr)[] = "pa1lomaxpwr=%d";
1751*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pa1himaxpwr)[] = "pa1himaxpwr=%d";
1752*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_oem)[] = "oem=%02x%02x%02x%02x%02x%02x%02x%02x";
1753*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_boardflags)[] = "boardflags=0x%x";
1754*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_boardflags2)[] = "boardflags2=0x%x";
1755*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_boardflags3)[] = "boardflags3=0x%x";
1756*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_boardflags4)[] = "boardflags4=0x%x";
1757*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_boardflags5)[] = "boardflags5=0x%x";
1758*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_noccode)[] = "ccode=0x0";
1759*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_ccode)[] = "ccode=%c%c";
1760*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_cctl)[] = "cctl=0x%x";
1761*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_cckpo)[] = "cckpo=0x%x";
1762*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_ofdmpo)[] = "ofdmpo=0x%x";
1763*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_rdlid)[] = "rdlid=0x%x";
1764*4882a593Smuzhiyun #ifdef BCM_BOOTLOADER
1765*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_rdlrndis)[] = "rdlrndis=%d";
1766*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_rdlrwu)[] = "rdlrwu=%d";
1767*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_rdlsn)[] = "rdlsn=%d";
1768*4882a593Smuzhiyun #endif /* BCM_BOOTLOADER */
1769*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_usbfs)[] = "usbfs=%d";
1770*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_wpsgpio)[] = "wpsgpio=%d";
1771*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_wpsled)[] = "wpsled=%d";
1772*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_rssismf2g)[] = "rssismf2g=%d";
1773*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_rssismc2g)[] = "rssismc2g=%d";
1774*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_rssisav2g)[] = "rssisav2g=%d";
1775*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_bxa2g)[] = "bxa2g=%d";
1776*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_rssismf5g)[] = "rssismf5g=%d";
1777*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_rssismc5g)[] = "rssismc5g=%d";
1778*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_rssisav5g)[] = "rssisav5g=%d";
1779*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_bxa5g)[] = "bxa5g=%d";
1780*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_tri2g)[] = "tri2g=%d";
1781*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_tri5gl)[] = "tri5gl=%d";
1782*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_tri5g)[] = "tri5g=%d";
1783*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_tri5gh)[] = "tri5gh=%d";
1784*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_rxpo2g)[] = "rxpo2g=%d";
1785*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_rxpo5g)[] = "rxpo5g=%d";
1786*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_boardtype)[] = "boardtype=0x%x";
1787*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_vendid)[] = "vendid=0x%x";
1788*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_devid)[] = "devid=0x%x";
1789*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_xtalfreq)[] = "xtalfreq=%d";
1790*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_txchain)[] = "txchain=0x%x";
1791*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_rxchain)[] = "rxchain=0x%x";
1792*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_elna2g)[] = "elna2g=0x%x";
1793*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_elna5g)[] = "elna5g=0x%x";
1794*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_antswitch)[] = "antswitch=0x%x";
1795*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_regrev)[] = "regrev=0x%x";
1796*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_antswctl2g)[] = "antswctl2g=0x%x";
1797*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_triso2g)[] = "triso2g=0x%x";
1798*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pdetrange2g)[] = "pdetrange2g=0x%x";
1799*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_extpagain2g)[] = "extpagain2g=0x%x";
1800*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_tssipos2g)[] = "tssipos2g=0x%x";
1801*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_antswctl5g)[] = "antswctl5g=0x%x";
1802*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_triso5g)[] = "triso5g=0x%x";
1803*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pdetrange5g)[] = "pdetrange5g=0x%x";
1804*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_extpagain5g)[] = "extpagain5g=0x%x";
1805*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_tssipos5g)[] = "tssipos5g=0x%x";
1806*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_maxp2ga)[] = "maxp2ga%d=0x%x";
1807*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_itt2ga0)[] = "itt2ga0=0x%x";
1808*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pa)[] = "pa%dgw%da%d=0x%x";
1809*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pahl)[] = "pa%dg%cw%da%d=0x%x";
1810*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_maxp5ga0)[] = "maxp5ga0=0x%x";
1811*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_itt5ga0)[] = "itt5ga0=0x%x";
1812*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_maxp5gha0)[] = "maxp5gha0=0x%x";
1813*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_maxp5gla0)[] = "maxp5gla0=0x%x";
1814*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_itt2ga1)[] = "itt2ga1=0x%x";
1815*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_maxp5ga1)[] = "maxp5ga1=0x%x";
1816*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_itt5ga1)[] = "itt5ga1=0x%x";
1817*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_maxp5gha1)[] = "maxp5gha1=0x%x";
1818*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_maxp5gla1)[] = "maxp5gla1=0x%x";
1819*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_cck2gpo)[] = "cck2gpo=0x%x";
1820*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_ofdm2gpo)[] = "ofdm2gpo=0x%x";
1821*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_ofdm5gpo)[] = "ofdm5gpo=0x%x";
1822*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_ofdm5glpo)[] = "ofdm5glpo=0x%x";
1823*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_ofdm5ghpo)[] = "ofdm5ghpo=0x%x";
1824*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_cddpo)[] = "cddpo=0x%x";
1825*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_stbcpo)[] = "stbcpo=0x%x";
1826*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_bw40po)[] = "bw40po=0x%x";
1827*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_bwduppo)[] = "bwduppo=0x%x";
1828*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_mcspo)[] = "mcs%dgpo%d=0x%x";
1829*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_mcspohl)[] = "mcs%dg%cpo%d=0x%x";
1830*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_custom)[] = "customvar%d=0x%x";
1831*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_cckdigfilttype)[] = "cckdigfilttype=%d";
1832*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_usbflags)[] = "usbflags=0x%x";
1833*4882a593Smuzhiyun #ifdef BCM_BOOTLOADER
1834*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_mdio)[] = "mdio%d=0x%%x";
1835*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_mdioex)[] = "mdioex%d=0x%%x";
1836*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_brmin)[] = "brmin=0x%x";
1837*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_brmax)[] = "brmax=0x%x";
1838*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pllreg)[] = "pll%d=0x%x";
1839*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_ccreg)[] = "chipc%d=0x%x";
1840*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_regctrl)[] = "reg%d=0x%x";
1841*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_time)[] = "r%dt=0x%x";
1842*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_depreg)[] = "r%dd=0x%x";
1843*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_usbpredly)[] = "usbpredly=0x%x";
1844*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_usbpostdly)[] = "usbpostdly=0x%x";
1845*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_usbrdy)[] = "usbrdy=0x%x";
1846*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_hsicphyctrl1)[] = "hsicphyctrl1=0x%x";
1847*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_hsicphyctrl2)[] = "hsicphyctrl2=0x%x";
1848*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_usbdevctrl)[] = "usbdevctrl=0x%x";
1849*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_bldr_reset_timeout)[] = "bldr_to=0x%x";
1850*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_muxenab)[] = "muxenab=0x%x";
1851*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pubkey)[] = "pubkey=%s";
1852*4882a593Smuzhiyun #endif /* BCM_BOOTLOADER */
1853*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_boardnum)[] = "boardnum=%d";
1854*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_macaddr)[] = "macaddr=%s";
1855*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_macaddr2)[] = "macaddr2=%s";
1856*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_usbepnum)[] = "usbepnum=0x%x";
1857*4882a593Smuzhiyun #ifdef BCMUSBDEV_COMPOSITE
1858*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_usbdesc_composite)[] = "usbdesc_composite=0x%x";
1859*4882a593Smuzhiyun #endif /* BCMUSBDEV_COMPOSITE */
1860*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_usbutmi_ctl)[] = "usbutmi_ctl=0x%x";
1861*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_usbssphy_utmi_ctl0)[] = "usbssphy_utmi_ctl0=0x%x";
1862*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_usbssphy_utmi_ctl1)[] = "usbssphy_utmi_ctl1=0x%x";
1863*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_usbssphy_utmi_ctl2)[] = "usbssphy_utmi_ctl2=0x%x";
1864*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_usbssphy_sleep0)[] = "usbssphy_sleep0=0x%x";
1865*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_usbssphy_sleep1)[] = "usbssphy_sleep1=0x%x";
1866*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_usbssphy_sleep2)[] = "usbssphy_sleep2=0x%x";
1867*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_usbssphy_sleep3)[] = "usbssphy_sleep3=0x%x";
1868*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_usbssphy_mdio)[] = "usbssmdio%d=0x%x,0x%x,0x%x,0x%x";
1869*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_usb30phy_noss)[] = "usbnoss=0x%x";
1870*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_usb30phy_u1u2)[] = "usb30u1u2=0x%x";
1871*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_usb30phy_regs)[] = "usb30regs%d=0x%x,0x%x,0x%x,0x%x";
1872*4882a593Smuzhiyun 
1873*4882a593Smuzhiyun /* Power per rate for SROM V9 */
1874*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_cckbw202gpo)[][21] =
1875*4882a593Smuzhiyun 	{ "cckbw202gpo=0x%x", "cckbw20ul2gpo=0x%x", "cckbw20in802gpo=0x%x" };
1876*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_legofdmbw202gpo)[][23] =
1877*4882a593Smuzhiyun 	{ "legofdmbw202gpo=0x%x", "legofdmbw20ul2gpo=0x%x" };
1878*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_legofdmbw205gpo)[][24] =
1879*4882a593Smuzhiyun 	{ "legofdmbw205glpo=0x%x", "legofdmbw20ul5glpo=0x%x",
1880*4882a593Smuzhiyun 	"legofdmbw205gmpo=0x%x", "legofdmbw20ul5gmpo=0x%x",
1881*4882a593Smuzhiyun 	"legofdmbw205ghpo=0x%x", "legofdmbw20ul5ghpo=0x%x" };
1882*4882a593Smuzhiyun 
1883*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_mcs2gpo)[][19] =
1884*4882a593Smuzhiyun { "mcsbw202gpo=0x%x", "mcsbw20ul2gpo=0x%x", "mcsbw402gpo=0x%x", "mcsbw802gpo=0x%x" };
1885*4882a593Smuzhiyun 
1886*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_mcs5glpo)[][20] =
1887*4882a593Smuzhiyun 	{ "mcsbw205glpo=0x%x", "mcsbw20ul5glpo=0x%x", "mcsbw405glpo=0x%x" };
1888*4882a593Smuzhiyun 
1889*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_mcs5gmpo)[][20] =
1890*4882a593Smuzhiyun 	{ "mcsbw205gmpo=0x%x", "mcsbw20ul5gmpo=0x%x", "mcsbw405gmpo=0x%x" };
1891*4882a593Smuzhiyun 
1892*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_mcs5ghpo)[][20] =
1893*4882a593Smuzhiyun 	{ "mcsbw205ghpo=0x%x", "mcsbw20ul5ghpo=0x%x", "mcsbw405ghpo=0x%x" };
1894*4882a593Smuzhiyun 
1895*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_mcs32po)[] = "mcs32po=0x%x";
1896*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_legofdm40duppo)[] = "legofdm40duppo=0x%x";
1897*4882a593Smuzhiyun 
1898*4882a593Smuzhiyun /* SROM V11 */
1899*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_tempthresh)[] = "tempthresh=%d";	/* HNBU_TEMPTHRESH */
1900*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_temps_period)[] = "temps_period=%d";
1901*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_temps_hysteresis)[] = "temps_hysteresis=%d";
1902*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_tempoffset)[] = "tempoffset=%d";
1903*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_tempsense_slope)[] = "tempsense_slope=%d";
1904*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_temp_corrx)[] = "tempcorrx=%d";
1905*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_tempsense_option)[] = "tempsense_option=%d";
1906*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_phycal_tempdelta)[] = "phycal_tempdelta=%d";
1907*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_tssiposslopeg)[] = "tssiposslope%dg=%d";	/* HNBU_FEM_CFG */
1908*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_epagaing)[] = "epagain%dg=%d";
1909*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pdgaing)[] = "pdgain%dg=%d";
1910*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_tworangetssi)[] = "tworangetssi%dg=%d";
1911*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_papdcap)[] = "papdcap%dg=%d";
1912*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_femctrl)[] = "femctrl=%d";
1913*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_gainctrlsph)[] = "gainctrlsph=%d";
1914*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_subband5gver)[] = "subband5gver=%d";	/* HNBU_ACPA_CX */
1915*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pa2ga)[] = "pa2ga%d=0x%x,0x%x,0x%x";
1916*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_maxp5ga)[] = "maxp5ga%d=0x%x,0x%x,0x%x,0x%x";
1917*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pa5ga)[] = "pa5ga%d=0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,"
1918*4882a593Smuzhiyun 	"0x%x,0x%x,0x%x,0x%x,0x%x,0x%x";
1919*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_subband6gver)[] = "subband6gver=%d";	/* HNBU_ACPA_CX */
1920*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_maxp6ga)[] = "maxp6ga%d=0x%x,0x%x,0x%x,0x%x,0x%x,0x%x";
1921*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pa6ga)[] = "pa6ga%d=0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,"
1922*4882a593Smuzhiyun 	"0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x";
1923*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pa2gccka)[] = "pa2gccka%d=0x%x,0x%x,0x%x";
1924*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pa5gbw40a)[] = "pa5gbw40a%d=0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,"
1925*4882a593Smuzhiyun 	"0x%x,0x%x,0x%x,0x%x,0x%x,0x%x";
1926*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pa5gbw80a)[] = "pa5gbw80a%d=0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,"
1927*4882a593Smuzhiyun 	"0x%x,0x%x,0x%x,0x%x,0x%x,0x%x";
1928*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pa5gbw4080a)[] = "pa5gbw4080a%d=0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,"
1929*4882a593Smuzhiyun 	"0x%x,0x%x,0x%x,0x%x,0x%x,0x%x";
1930*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_rxgainsgelnagaina)[] = "rxgains%dgelnagaina%d=%d";
1931*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_rxgainsgtrisoa)[] = "rxgains%dgtrisoa%d=%d";
1932*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_rxgainsgtrelnabypa)[] = "rxgains%dgtrelnabypa%d=%d";
1933*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_rxgainsgxelnagaina)[] = "rxgains%dg%celnagaina%d=%d";
1934*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_rxgainsgxtrisoa)[] = "rxgains%dg%ctrisoa%d=%d";
1935*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_rxgainsgxtrelnabypa)[] = "rxgains%dg%ctrelnabypa%d=%d";
1936*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_measpower)[] = "measpower=0x%x";	/* HNBU_MEAS_PWR */
1937*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_measpowerX)[] = "measpower%d=0x%x";
1938*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pdoffsetma)[] = "pdoffset%dma%d=0x%x";	/* HNBU_PDOFF */
1939*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pdoffset2gma)[] = "pdoffset2g%dma%d=0x%x";	/* HNBU_PDOFF_2G */
1940*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pdoffset2gmvalid)[] = "pdoffset2g%dmvalid=0x%x";
1941*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_rawtempsense)[] = "rawtempsense=0x%x";
1942*4882a593Smuzhiyun /* HNBU_ACPPR_2GPO */
1943*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_dot11agofdmhrbw202gpo)[] = "dot11agofdmhrbw202gpo=0x%x";
1944*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_ofdmlrbw202gpo)[] = "ofdmlrbw202gpo=0x%x";
1945*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_mcsbw805gpo)[] = "mcsbw805g%cpo=0x%x"; /* HNBU_ACPPR_5GPO */
1946*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_mcsbw1605gpo)[] = "mcsbw1605g%cpo=0x%x";
1947*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_mcsbw80p805gpo)[] = "mcsbw80p805g%cpo=0x%x";
1948*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_mcsbw80p805g1po)[] = "mcsbw80p805g%c1po=0x%x";
1949*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_mcsbw1605g1po)[] = "mcsbw1605g%c1po=0x%x";
1950*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_mcsbw805g1po)[] = "mcsbw805g%c1po=0x%x";
1951*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_mcsbw405g1po)[] = "mcsbw405g%c1po=0x%x";
1952*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_mcsbw205g1po)[] = "mcsbw205g%c1po=0x%x";
1953*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_mcslr5gpo)[] = "mcslr5g%cpo=0x%x";
1954*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_mcslr5g1po)[] = "mcslr5g%c1po=0x%x";
1955*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_mcslr5g80p80po)[] = "mcslr5g80p80po=0x%x";
1956*4882a593Smuzhiyun /* HNBU_ACPPR_SBPO */
1957*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_sb20in40rpo)[] = "sb20in40%crpo=0x%x";
1958*4882a593Smuzhiyun /* HNBU_ACPPR_SBPO */
1959*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_sb20in40and80rpo)[] = "sb20in40and80%crpo=0x%x";
1960*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_sb20in80and160r5gpo)[] = "sb20in80and160%cr5g%cpo=0x%x";
1961*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_sb20in80and160r5g1po)[] = "sb20in80and160%cr5g%c1po=0x%x";
1962*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_sb2040and80in80p80r5gpo)[] =
1963*4882a593Smuzhiyun 	"sb2040and80in80p80%cr5g%cpo=0x%x";
1964*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_sb2040and80in80p80r5g1po)[] =
1965*4882a593Smuzhiyun 	"sb2040and80in80p80%cr5g%c1po=0x%x";
1966*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_sb20in40dot11agofdm2gpo)[] = "sb20in40dot11agofdm2gpo=0x%x";
1967*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_sb20in80dot11agofdm2gpo)[] = "sb20in80dot11agofdm2gpo=0x%x";
1968*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_sb20in40ofdmlrbw202gpo)[] = "sb20in40ofdmlrbw202gpo=0x%x";
1969*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_sb20in80ofdmlrbw202gpo)[] = "sb20in80ofdmlrbw202gpo=0x%x";
1970*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_sb20in80p80r5gpo)[] = "sb20in80p80%cr5gpo=0x%x";
1971*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_sb40and80r5gpo)[] = "sb40and80%cr5g%cpo=0x%x";
1972*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_sb40and80r5g1po)[] = "sb40and80%cr5g%c1po=0x%x";
1973*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_dot11agduprpo)[] = "dot11agdup%crpo=0x%x";
1974*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_dot11agduppo)[] = "dot11agduppo=0x%x";
1975*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_noiselvl2ga)[] = "noiselvl2ga%d=%d";	/* HNBU_NOISELVL */
1976*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_noiselvl5ga)[] = "noiselvl5ga%d=%d,%d,%d,%d";
1977*4882a593Smuzhiyun /* HNBU_RXGAIN_ERR */
1978*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_rxgainerr2ga)[] = "rxgainerr2ga%d=0x%x";
1979*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_rxgainerr5ga)[] = "rxgainerr5ga%d=0x%x,0x%x,0x%x,0x%x";
1980*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_agbg)[] = "agbg%d=0x%x";	/* HNBU_AGBGA */
1981*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_aga)[] = "aga%d=0x%x";
1982*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_txduty_ofdm)[] = "tx_duty_cycle_ofdm_%d_5g=%d";
1983*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_txduty_thresh)[] = "tx_duty_cycle_thresh_%d_5g=%d";
1984*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_paparambwver)[] = "paparambwver=%d";
1985*4882a593Smuzhiyun 
1986*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_uuid)[] = "uuid=%s";
1987*4882a593Smuzhiyun 
1988*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_wowlgpio)[] = "wowl_gpio=%d";
1989*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_wowlgpiopol)[] = "wowl_gpiopol=%d";
1990*4882a593Smuzhiyun 
1991*4882a593Smuzhiyun static const char BCMATTACHDATA(rstr_ag0)[] = "ag0";
1992*4882a593Smuzhiyun static const char BCMATTACHDATA(rstr_sromrev)[] = "sromrev";
1993*4882a593Smuzhiyun 
1994*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_paparamrpcalvars)[][20] =
1995*4882a593Smuzhiyun 	{"rpcal2g=0x%x", "rpcal5gb0=0x%x", "rpcal5gb1=0x%x",
1996*4882a593Smuzhiyun 	"rpcal5gb2=0x%x", "rpcal5gb3=0x%x"};
1997*4882a593Smuzhiyun 
1998*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_gpdn)[] = "gpdn=0x%x";
1999*4882a593Smuzhiyun 
2000*4882a593Smuzhiyun /* SROM V13 PA */
2001*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_sr13pa2ga)[] = "pa2ga%d=0x%x,0x%x,0x%x,0x%x";
2002*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_maxp5gba)[] = "maxp5gb%da%d=0x%x";
2003*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_sr13pa5ga)[] = "pa5ga%d=%s";
2004*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_sr13pa5gbwa)[] = "pa5g%da%d=%s";
2005*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_pa2g40a)[] = "pa2g40a%d=0x%x,0x%x,0x%x,0x%x";
2006*4882a593Smuzhiyun 
2007*4882a593Smuzhiyun /* RSSI Cal parameters */
2008*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_rssicalfrqg)[] =
2009*4882a593Smuzhiyun 	"rssi_cal_freq_grp_2g=0x%x0x%x0x%x0x%x0x%x0x%x0x%x";
2010*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_rssidelta2g)[] =
2011*4882a593Smuzhiyun 	"rssi_delta_2gb%d=%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d";
2012*4882a593Smuzhiyun static const char BCMATTACHDATA(vstr_rssidelta5g)[] =
2013*4882a593Smuzhiyun 	"rssi_delta_5g%s=%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d";
2014*4882a593Smuzhiyun 
2015*4882a593Smuzhiyun uint8 patch_pair = 0;
2016*4882a593Smuzhiyun 
2017*4882a593Smuzhiyun /* For dongle HW, accept partial calibration parameters */
2018*4882a593Smuzhiyun #if defined(BCMSDIODEV) || defined(BCMUSBDEV) || defined(BCMDONGLEHOST)
2019*4882a593Smuzhiyun #define BCMDONGLECASE(n) case n:
2020*4882a593Smuzhiyun #else
2021*4882a593Smuzhiyun #define BCMDONGLECASE(n)
2022*4882a593Smuzhiyun #endif
2023*4882a593Smuzhiyun 
2024*4882a593Smuzhiyun #ifdef BCM_BOOTLOADER
2025*4882a593Smuzhiyun /* The format of the PMUREGS OTP Tuple ->
2026*4882a593Smuzhiyun  * 1 byte -> Lower 5 bits has the address of the register
2027*4882a593Smuzhiyun  *                 Higher 3 bits has the mode of the register like
2028*4882a593Smuzhiyun  *                 PLL, ChipCtrl, RegCtrl, UpDwn or Dependency mask
2029*4882a593Smuzhiyun  * 4 bytes -> Value of the register to be updated.
2030*4882a593Smuzhiyun  */
2031*4882a593Smuzhiyun #define PMUREGS_MODE_MASK	0xE0
2032*4882a593Smuzhiyun #define PMUREGS_MODE_SHIFT	5
2033*4882a593Smuzhiyun #define PMUREGS_ADDR_MASK	0x1F
2034*4882a593Smuzhiyun #define PMUREGS_TPL_SIZE	5
2035*4882a593Smuzhiyun 
2036*4882a593Smuzhiyun enum {
2037*4882a593Smuzhiyun 	PMU_PLLREG_MODE,
2038*4882a593Smuzhiyun 	PMU_CCREG_MODE,
2039*4882a593Smuzhiyun 	PMU_VOLTREG_MODE,
2040*4882a593Smuzhiyun 	PMU_RES_TIME_MODE,
2041*4882a593Smuzhiyun 	PMU_RESDEPEND_MODE
2042*4882a593Smuzhiyun };
2043*4882a593Smuzhiyun 
2044*4882a593Smuzhiyun #define USBREGS_TPL_SIZE	5
2045*4882a593Smuzhiyun enum {
2046*4882a593Smuzhiyun 	USB_DEV_CTRL_REG,
2047*4882a593Smuzhiyun 	HSIC_PHY_CTRL1_REG,
2048*4882a593Smuzhiyun 	HSIC_PHY_CTRL2_REG
2049*4882a593Smuzhiyun };
2050*4882a593Smuzhiyun 
2051*4882a593Smuzhiyun #define USBRDY_DLY_TYPE	0x8000	/* Bit indicating if the byte is pre or post delay value */
2052*4882a593Smuzhiyun #define USBRDY_DLY_MASK	0x7FFF	/* Bits indicating the amount of delay */
2053*4882a593Smuzhiyun #define USBRDY_MAXOTP_SIZE	5	/* Max size of the OTP parameter */
2054*4882a593Smuzhiyun 
2055*4882a593Smuzhiyun #endif /* BCM_BOOTLOADER */
2056*4882a593Smuzhiyun 
2057*4882a593Smuzhiyun static uint
2058*4882a593Smuzhiyun BCMATTACHFN(get_max_cis_size)(si_t *sih)
2059*4882a593Smuzhiyun {
2060*4882a593Smuzhiyun 	uint max_cis_size;
2061*4882a593Smuzhiyun 	void *oh;
2062*4882a593Smuzhiyun 
2063*4882a593Smuzhiyun 	max_cis_size = (sih && sih->ccrev >= 49) ? CIS_SIZE_12K : CIS_SIZE;
2064*4882a593Smuzhiyun 	if (sih && (oh = otp_init(sih)) != NULL) {
2065*4882a593Smuzhiyun 		max_cis_size -= otp_avsbitslen(oh);
2066*4882a593Smuzhiyun 	}
2067*4882a593Smuzhiyun 	return max_cis_size;
2068*4882a593Smuzhiyun }
2069*4882a593Smuzhiyun 
2070*4882a593Smuzhiyun #ifndef BCM_BOOTLOADER
2071*4882a593Smuzhiyun static uint32
2072*4882a593Smuzhiyun BCMATTACHFN(srom_data2value)(uint8 *p, uint8 len)
2073*4882a593Smuzhiyun {
2074*4882a593Smuzhiyun 	uint8 pos = 0;
2075*4882a593Smuzhiyun 	uint32 value = 0;
2076*4882a593Smuzhiyun 
2077*4882a593Smuzhiyun 	ASSERT(len <= 4);
2078*4882a593Smuzhiyun 
2079*4882a593Smuzhiyun 	while (pos < len) {
2080*4882a593Smuzhiyun 		value += (p[pos] << (pos * 8));
2081*4882a593Smuzhiyun 		pos++;
2082*4882a593Smuzhiyun 	}
2083*4882a593Smuzhiyun 
2084*4882a593Smuzhiyun 	return value;
2085*4882a593Smuzhiyun }
2086*4882a593Smuzhiyun #endif /* BCM_BOOTLOADER */
2087*4882a593Smuzhiyun 
2088*4882a593Smuzhiyun /**
2089*4882a593Smuzhiyun  * Both SROM and OTP contain variables in 'CIS' format, whereas the rest of the firmware works with
2090*4882a593Smuzhiyun  * 'variable/value' string pairs.
2091*4882a593Smuzhiyun  */
2092*4882a593Smuzhiyun int
2093*4882a593Smuzhiyun BCMATTACHFN(srom_parsecis)(si_t *sih, osl_t *osh, uint8 *pcis[], uint ciscnt, char **vars,
2094*4882a593Smuzhiyun 	uint *count)
2095*4882a593Smuzhiyun {
2096*4882a593Smuzhiyun 	char eabuf[32];
2097*4882a593Smuzhiyun 	char eabuf2[32];
2098*4882a593Smuzhiyun 	char *base;
2099*4882a593Smuzhiyun 	varbuf_t b;
2100*4882a593Smuzhiyun 	uint8 *cis, tup, tlen, sromrev = 1;
2101*4882a593Smuzhiyun 	uint i;
2102*4882a593Smuzhiyun 	uint16 j;
2103*4882a593Smuzhiyun #ifndef BCM_BOOTLOADER
2104*4882a593Smuzhiyun 	bool ag_init = FALSE;
2105*4882a593Smuzhiyun #endif
2106*4882a593Smuzhiyun 	uint32 w32;
2107*4882a593Smuzhiyun 	uint funcid;
2108*4882a593Smuzhiyun 	uint cisnum;
2109*4882a593Smuzhiyun 	int32 boardnum;
2110*4882a593Smuzhiyun 	int err;
2111*4882a593Smuzhiyun 	bool standard_cis;
2112*4882a593Smuzhiyun 	uint max_cis_size;
2113*4882a593Smuzhiyun 	uint var_cis_size = 0;
2114*4882a593Smuzhiyun 
2115*4882a593Smuzhiyun 	ASSERT(count != NULL);
2116*4882a593Smuzhiyun 
2117*4882a593Smuzhiyun 	if (vars == NULL) {
2118*4882a593Smuzhiyun 		ASSERT(0);	/* crash debug images for investigation */
2119*4882a593Smuzhiyun 		return BCME_BADARG;
2120*4882a593Smuzhiyun 	}
2121*4882a593Smuzhiyun 
2122*4882a593Smuzhiyun 	boardnum = -1;
2123*4882a593Smuzhiyun 
2124*4882a593Smuzhiyun 	/* freed in same function */
2125*4882a593Smuzhiyun 	max_cis_size = get_max_cis_size(sih);
2126*4882a593Smuzhiyun 	var_cis_size = *count + ((max_cis_size + 2u) * ciscnt);
2127*4882a593Smuzhiyun 
2128*4882a593Smuzhiyun 	ASSERT(var_cis_size <= MAXSZ_NVRAM_VARS);
2129*4882a593Smuzhiyun 
2130*4882a593Smuzhiyun 	base = MALLOC_NOPERSIST(osh, var_cis_size);
2131*4882a593Smuzhiyun 	ASSERT(base != NULL);
2132*4882a593Smuzhiyun 	if (!base)
2133*4882a593Smuzhiyun 		return -2;
2134*4882a593Smuzhiyun 
2135*4882a593Smuzhiyun 	varbuf_init(&b, base, var_cis_size);
2136*4882a593Smuzhiyun 	bzero(base, var_cis_size);
2137*4882a593Smuzhiyun 	/* Append from vars if there's already something inside */
2138*4882a593Smuzhiyun 	if (*vars && **vars && (*count >= 3)) {
2139*4882a593Smuzhiyun 		/* back off \0 at the end, leaving only one \0 for the last param */
2140*4882a593Smuzhiyun 		while (((*vars)[(*count)-1] == '\0') && ((*vars)[(*count)-2] == '\0'))
2141*4882a593Smuzhiyun 			(*count)--;
2142*4882a593Smuzhiyun 
2143*4882a593Smuzhiyun 		bcopy(*vars, base, *count);
2144*4882a593Smuzhiyun 		b.buf += *count;
2145*4882a593Smuzhiyun 	}
2146*4882a593Smuzhiyun 	eabuf[0] = '\0';
2147*4882a593Smuzhiyun 	eabuf2[0] = '\0';
2148*4882a593Smuzhiyun 	for (cisnum = 0; cisnum < ciscnt; cisnum++) {
2149*4882a593Smuzhiyun 		cis = *pcis++;
2150*4882a593Smuzhiyun 		i = 0;
2151*4882a593Smuzhiyun 		funcid = 0;
2152*4882a593Smuzhiyun 		standard_cis = TRUE;
2153*4882a593Smuzhiyun 		do {
2154*4882a593Smuzhiyun 			if (standard_cis) {
2155*4882a593Smuzhiyun 				tup = cis[i++];
2156*4882a593Smuzhiyun 				if (tup == CISTPL_NULL || tup == CISTPL_END)
2157*4882a593Smuzhiyun 					tlen = 0;
2158*4882a593Smuzhiyun 				else
2159*4882a593Smuzhiyun 					tlen = cis[i++];
2160*4882a593Smuzhiyun 			} else {
2161*4882a593Smuzhiyun 				if (cis[i] == CISTPL_NULL || cis[i] == CISTPL_END) {
2162*4882a593Smuzhiyun 					tlen = 0;
2163*4882a593Smuzhiyun 					tup = cis[i];
2164*4882a593Smuzhiyun 				} else {
2165*4882a593Smuzhiyun 					tlen = cis[i];
2166*4882a593Smuzhiyun 					tup = CISTPL_BRCM_HNBU;
2167*4882a593Smuzhiyun 				}
2168*4882a593Smuzhiyun 				++i;
2169*4882a593Smuzhiyun 			}
2170*4882a593Smuzhiyun 			if ((i + tlen) >= max_cis_size)
2171*4882a593Smuzhiyun 				break;
2172*4882a593Smuzhiyun 
2173*4882a593Smuzhiyun 			switch (tup) {
2174*4882a593Smuzhiyun 			case CISTPL_VERS_1:
2175*4882a593Smuzhiyun 				/* assume the strings are good if the version field checks out */
2176*4882a593Smuzhiyun 				if (((cis[i + 1] << 8) + cis[i]) >= 0x0008) {
2177*4882a593Smuzhiyun 					varbuf_append(&b, vstr_manf, &cis[i + 2]);
2178*4882a593Smuzhiyun 					varbuf_append(&b, vstr_productname,
2179*4882a593Smuzhiyun 					              &cis[i + 3 + strlen((char *)&cis[i + 2])]);
2180*4882a593Smuzhiyun 					break;
2181*4882a593Smuzhiyun 				}
2182*4882a593Smuzhiyun 
2183*4882a593Smuzhiyun 			case CISTPL_MANFID:
2184*4882a593Smuzhiyun 				varbuf_append(&b, vstr_manfid, (cis[i + 1] << 8) + cis[i]);
2185*4882a593Smuzhiyun 				varbuf_append(&b, vstr_prodid, (cis[i + 3] << 8) + cis[i + 2]);
2186*4882a593Smuzhiyun 				break;
2187*4882a593Smuzhiyun 
2188*4882a593Smuzhiyun 			case CISTPL_FUNCID:
2189*4882a593Smuzhiyun 				funcid = cis[i];
2190*4882a593Smuzhiyun 				break;
2191*4882a593Smuzhiyun 
2192*4882a593Smuzhiyun 			case CISTPL_FUNCE:
2193*4882a593Smuzhiyun 				switch (funcid) {
2194*4882a593Smuzhiyun 				case CISTPL_FID_SDIO:
2195*4882a593Smuzhiyun #ifdef BCMSDIO
2196*4882a593Smuzhiyun 					if (cis[i] == 0) {
2197*4882a593Smuzhiyun 						uint8 spd = cis[i + 3];
2198*4882a593Smuzhiyun 						static int lbase[] = {
2199*4882a593Smuzhiyun 							-1, 10, 12, 13, 15, 20, 25, 30,
2200*4882a593Smuzhiyun 							35, 40, 45, 50, 55, 60, 70, 80
2201*4882a593Smuzhiyun 						};
2202*4882a593Smuzhiyun 						static int mult[] = {
2203*4882a593Smuzhiyun 							10, 100, 1000, 10000,
2204*4882a593Smuzhiyun 							-1, -1, -1, -1
2205*4882a593Smuzhiyun 						};
2206*4882a593Smuzhiyun 						ASSERT((mult[spd & 0x7] != -1) &&
2207*4882a593Smuzhiyun 						       (lbase[(spd >> 3) & 0x0f]));
2208*4882a593Smuzhiyun 						varbuf_append(&b, vstr_sdmaxblk[0],
2209*4882a593Smuzhiyun 						              (cis[i + 2] << 8) + cis[i + 1]);
2210*4882a593Smuzhiyun 						varbuf_append(&b, vstr_sdmaxspeed,
2211*4882a593Smuzhiyun 						              (mult[spd & 0x7] *
2212*4882a593Smuzhiyun 						               lbase[(spd >> 3) & 0x0f]));
2213*4882a593Smuzhiyun 					} else if (cis[i] == 1) {
2214*4882a593Smuzhiyun 						varbuf_append(&b, vstr_sdmaxblk[cisnum],
2215*4882a593Smuzhiyun 						              (cis[i + 13] << 8) | cis[i + 12]);
2216*4882a593Smuzhiyun 					}
2217*4882a593Smuzhiyun #endif /* BCMSDIO */
2218*4882a593Smuzhiyun 					funcid = 0;
2219*4882a593Smuzhiyun 					break;
2220*4882a593Smuzhiyun 				default:
2221*4882a593Smuzhiyun 					/* set macaddr if HNBU_MACADDR not seen yet */
2222*4882a593Smuzhiyun 					if (eabuf[0] == '\0' && cis[i] == LAN_NID &&
2223*4882a593Smuzhiyun 						!(ETHER_ISNULLADDR(&cis[i + 2])) &&
2224*4882a593Smuzhiyun 						!(ETHER_ISMULTI(&cis[i + 2]))) {
2225*4882a593Smuzhiyun 						ASSERT(cis[i + 1] == ETHER_ADDR_LEN);
2226*4882a593Smuzhiyun 						bcm_ether_ntoa((struct ether_addr *)&cis[i + 2],
2227*4882a593Smuzhiyun 						               eabuf);
2228*4882a593Smuzhiyun 
2229*4882a593Smuzhiyun 						/* set boardnum if HNBU_BOARDNUM not seen yet */
2230*4882a593Smuzhiyun 						if (boardnum == -1)
2231*4882a593Smuzhiyun 							boardnum = (cis[i + 6] << 8) + cis[i + 7];
2232*4882a593Smuzhiyun 					}
2233*4882a593Smuzhiyun 					break;
2234*4882a593Smuzhiyun 				}
2235*4882a593Smuzhiyun 				break;
2236*4882a593Smuzhiyun 
2237*4882a593Smuzhiyun 			case CISTPL_CFTABLE:
2238*4882a593Smuzhiyun 				varbuf_append(&b, vstr_regwindowsz, (cis[i + 7] << 8) | cis[i + 6]);
2239*4882a593Smuzhiyun 				break;
2240*4882a593Smuzhiyun 
2241*4882a593Smuzhiyun 			case CISTPL_BRCM_HNBU:
2242*4882a593Smuzhiyun 				switch (cis[i]) {
2243*4882a593Smuzhiyun 				case HNBU_SROMREV:
2244*4882a593Smuzhiyun 					sromrev = cis[i + 1];
2245*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sromrev, sromrev);
2246*4882a593Smuzhiyun 					break;
2247*4882a593Smuzhiyun 
2248*4882a593Smuzhiyun 				case HNBU_XTALFREQ:
2249*4882a593Smuzhiyun 					varbuf_append(&b, vstr_xtalfreq,
2250*4882a593Smuzhiyun 					              (cis[i + 4] << 24) |
2251*4882a593Smuzhiyun 					              (cis[i + 3] << 16) |
2252*4882a593Smuzhiyun 					              (cis[i + 2] << 8) |
2253*4882a593Smuzhiyun 					              cis[i + 1]);
2254*4882a593Smuzhiyun 					break;
2255*4882a593Smuzhiyun 
2256*4882a593Smuzhiyun 				case HNBU_CHIPID:
2257*4882a593Smuzhiyun 					varbuf_append(&b, vstr_vendid, (cis[i + 2] << 8) +
2258*4882a593Smuzhiyun 					              cis[i + 1]);
2259*4882a593Smuzhiyun 					varbuf_append(&b, vstr_devid, (cis[i + 4] << 8) +
2260*4882a593Smuzhiyun 					              cis[i + 3]);
2261*4882a593Smuzhiyun 					if (tlen >= 7) {
2262*4882a593Smuzhiyun 						varbuf_append(&b, vstr_chiprev,
2263*4882a593Smuzhiyun 						              (cis[i + 6] << 8) + cis[i + 5]);
2264*4882a593Smuzhiyun 					}
2265*4882a593Smuzhiyun 					if (tlen >= 9) {
2266*4882a593Smuzhiyun 						varbuf_append(&b, vstr_subvendid,
2267*4882a593Smuzhiyun 						              (cis[i + 8] << 8) + cis[i + 7]);
2268*4882a593Smuzhiyun 					}
2269*4882a593Smuzhiyun 					if (tlen >= 11) {
2270*4882a593Smuzhiyun 						varbuf_append(&b, vstr_subdevid,
2271*4882a593Smuzhiyun 						              (cis[i + 10] << 8) + cis[i + 9]);
2272*4882a593Smuzhiyun 						/* subdevid doubles for boardtype */
2273*4882a593Smuzhiyun 						varbuf_append(&b, vstr_boardtype,
2274*4882a593Smuzhiyun 						              (cis[i + 10] << 8) + cis[i + 9]);
2275*4882a593Smuzhiyun 					}
2276*4882a593Smuzhiyun 					break;
2277*4882a593Smuzhiyun 
2278*4882a593Smuzhiyun 				case HNBU_BOARDNUM:
2279*4882a593Smuzhiyun 					boardnum = (cis[i + 2] << 8) + cis[i + 1];
2280*4882a593Smuzhiyun 					break;
2281*4882a593Smuzhiyun 
2282*4882a593Smuzhiyun 				case HNBU_PATCH: {
2283*4882a593Smuzhiyun 					char vstr_paddr[16];
2284*4882a593Smuzhiyun 					char vstr_pdata[16];
2285*4882a593Smuzhiyun 
2286*4882a593Smuzhiyun 					/* retrieve the patch pairs
2287*4882a593Smuzhiyun 					 * from tlen/6; where 6 is
2288*4882a593Smuzhiyun 					 * sizeof(patch addr(2)) +
2289*4882a593Smuzhiyun 					 * sizeof(patch data(4)).
2290*4882a593Smuzhiyun 					 */
2291*4882a593Smuzhiyun 					patch_pair = tlen/6;
2292*4882a593Smuzhiyun 
2293*4882a593Smuzhiyun 					for (j = 0; j < patch_pair; j++) {
2294*4882a593Smuzhiyun 						snprintf(vstr_paddr, sizeof(vstr_paddr),
2295*4882a593Smuzhiyun 							rstr_paddr, j);
2296*4882a593Smuzhiyun 						snprintf(vstr_pdata, sizeof(vstr_pdata),
2297*4882a593Smuzhiyun 							rstr_pdata, j);
2298*4882a593Smuzhiyun 
2299*4882a593Smuzhiyun 						varbuf_append(&b, vstr_paddr,
2300*4882a593Smuzhiyun 							(cis[i + (j*6) + 2] << 8) |
2301*4882a593Smuzhiyun 							cis[i + (j*6) + 1]);
2302*4882a593Smuzhiyun 
2303*4882a593Smuzhiyun 						varbuf_append(&b, vstr_pdata,
2304*4882a593Smuzhiyun 							(cis[i + (j*6) + 6] << 24) |
2305*4882a593Smuzhiyun 							(cis[i + (j*6) + 5] << 16) |
2306*4882a593Smuzhiyun 							(cis[i + (j*6) + 4] << 8) |
2307*4882a593Smuzhiyun 							cis[i + (j*6) + 3]);
2308*4882a593Smuzhiyun 					}
2309*4882a593Smuzhiyun 					break;
2310*4882a593Smuzhiyun 				}
2311*4882a593Smuzhiyun 
2312*4882a593Smuzhiyun 				case HNBU_BOARDREV:
2313*4882a593Smuzhiyun 					if (tlen == 2)
2314*4882a593Smuzhiyun 						varbuf_append(&b, vstr_boardrev, cis[i + 1]);
2315*4882a593Smuzhiyun 					else
2316*4882a593Smuzhiyun 						varbuf_append(&b, vstr_boardrev,
2317*4882a593Smuzhiyun 							(cis[i + 2] << 8) + cis[i + 1]);
2318*4882a593Smuzhiyun 					break;
2319*4882a593Smuzhiyun 
2320*4882a593Smuzhiyun 				case HNBU_BOARDFLAGS:
2321*4882a593Smuzhiyun 					w32 = (cis[i + 2] << 8) + cis[i + 1];
2322*4882a593Smuzhiyun 					if (tlen >= 5)
2323*4882a593Smuzhiyun 						w32 |= ((cis[i + 4] << 24) + (cis[i + 3] << 16));
2324*4882a593Smuzhiyun 					varbuf_append(&b, vstr_boardflags, w32);
2325*4882a593Smuzhiyun 
2326*4882a593Smuzhiyun 					if (tlen >= 7) {
2327*4882a593Smuzhiyun 						w32 = (cis[i + 6] << 8) + cis[i + 5];
2328*4882a593Smuzhiyun 						if (tlen >= 9)
2329*4882a593Smuzhiyun 							w32 |= ((cis[i + 8] << 24) +
2330*4882a593Smuzhiyun 								(cis[i + 7] << 16));
2331*4882a593Smuzhiyun 						varbuf_append(&b, vstr_boardflags2, w32);
2332*4882a593Smuzhiyun 					}
2333*4882a593Smuzhiyun 					if (tlen >= 11) {
2334*4882a593Smuzhiyun 						w32 = (cis[i + 10] << 8) + cis[i + 9];
2335*4882a593Smuzhiyun 						if (tlen >= 13)
2336*4882a593Smuzhiyun 							w32 |= ((cis[i + 12] << 24) +
2337*4882a593Smuzhiyun 								(cis[i + 11] << 16));
2338*4882a593Smuzhiyun 						varbuf_append(&b, vstr_boardflags3, w32);
2339*4882a593Smuzhiyun 					}
2340*4882a593Smuzhiyun 					if (tlen >= 15) {
2341*4882a593Smuzhiyun 						w32 = (cis[i + 14] << 8) + cis[i + 13];
2342*4882a593Smuzhiyun 						if (tlen >= 17)
2343*4882a593Smuzhiyun 							w32 |= ((cis[i + 16] << 24) +
2344*4882a593Smuzhiyun 								(cis[i + 15] << 16));
2345*4882a593Smuzhiyun 						varbuf_append(&b, vstr_boardflags4, w32);
2346*4882a593Smuzhiyun 					}
2347*4882a593Smuzhiyun 					if (tlen >= 19) {
2348*4882a593Smuzhiyun 						w32 = (cis[i + 18] << 8) + cis[i + 17];
2349*4882a593Smuzhiyun 						if (tlen >= 21)
2350*4882a593Smuzhiyun 							w32 |= ((cis[i + 20] << 24) +
2351*4882a593Smuzhiyun 								(cis[i + 19] << 16));
2352*4882a593Smuzhiyun 						varbuf_append(&b, vstr_boardflags5, w32);
2353*4882a593Smuzhiyun 					}
2354*4882a593Smuzhiyun 					break;
2355*4882a593Smuzhiyun 
2356*4882a593Smuzhiyun 				case HNBU_USBFS:
2357*4882a593Smuzhiyun 					varbuf_append(&b, vstr_usbfs, cis[i + 1]);
2358*4882a593Smuzhiyun 					break;
2359*4882a593Smuzhiyun 
2360*4882a593Smuzhiyun 				case HNBU_BOARDTYPE:
2361*4882a593Smuzhiyun 					varbuf_append(&b, vstr_boardtype,
2362*4882a593Smuzhiyun 					              (cis[i + 2] << 8) + cis[i + 1]);
2363*4882a593Smuzhiyun 					break;
2364*4882a593Smuzhiyun 
2365*4882a593Smuzhiyun 				case HNBU_HNBUCIS:
2366*4882a593Smuzhiyun 					/*
2367*4882a593Smuzhiyun 					 * what follows is a nonstandard HNBU CIS
2368*4882a593Smuzhiyun 					 * that lacks CISTPL_BRCM_HNBU tags
2369*4882a593Smuzhiyun 					 *
2370*4882a593Smuzhiyun 					 * skip 0xff (end of standard CIS)
2371*4882a593Smuzhiyun 					 * after this tuple
2372*4882a593Smuzhiyun 					 */
2373*4882a593Smuzhiyun 					tlen++;
2374*4882a593Smuzhiyun 					standard_cis = FALSE;
2375*4882a593Smuzhiyun 					break;
2376*4882a593Smuzhiyun 
2377*4882a593Smuzhiyun 				case HNBU_USBEPNUM:
2378*4882a593Smuzhiyun 					varbuf_append(&b, vstr_usbepnum,
2379*4882a593Smuzhiyun 						(cis[i + 2] << 8) | cis[i + 1]);
2380*4882a593Smuzhiyun 					break;
2381*4882a593Smuzhiyun 
2382*4882a593Smuzhiyun 				case HNBU_PATCH_AUTOINC: {
2383*4882a593Smuzhiyun 					char vstr_paddr[16];
2384*4882a593Smuzhiyun 					char vstr_pdata[16];
2385*4882a593Smuzhiyun 					uint32 addr_inc;
2386*4882a593Smuzhiyun 					uint8 pcnt;
2387*4882a593Smuzhiyun 
2388*4882a593Smuzhiyun 					addr_inc = (cis[i + 4] << 24) |
2389*4882a593Smuzhiyun 						(cis[i + 3] << 16) |
2390*4882a593Smuzhiyun 						(cis[i + 2] << 8) |
2391*4882a593Smuzhiyun 						(cis[i + 1]);
2392*4882a593Smuzhiyun 
2393*4882a593Smuzhiyun 					pcnt = (tlen - 5)/4;
2394*4882a593Smuzhiyun 					for (j = 0; j < pcnt; j++) {
2395*4882a593Smuzhiyun 						snprintf(vstr_paddr, sizeof(vstr_paddr),
2396*4882a593Smuzhiyun 							rstr_paddr, j + patch_pair);
2397*4882a593Smuzhiyun 						snprintf(vstr_pdata, sizeof(vstr_pdata),
2398*4882a593Smuzhiyun 							rstr_pdata, j + patch_pair);
2399*4882a593Smuzhiyun 
2400*4882a593Smuzhiyun 						varbuf_append(&b, vstr_paddr, addr_inc);
2401*4882a593Smuzhiyun 						varbuf_append(&b, vstr_pdata,
2402*4882a593Smuzhiyun 							(cis[i + (j*4) + 8] << 24) |
2403*4882a593Smuzhiyun 							(cis[i + (j*4) + 7] << 16) |
2404*4882a593Smuzhiyun 							(cis[i + (j*4) + 6] << 8) |
2405*4882a593Smuzhiyun 							cis[i + (j*4) + 5]);
2406*4882a593Smuzhiyun 						addr_inc += 4;
2407*4882a593Smuzhiyun 					}
2408*4882a593Smuzhiyun 					patch_pair += pcnt;
2409*4882a593Smuzhiyun 					break;
2410*4882a593Smuzhiyun 				}
2411*4882a593Smuzhiyun 				case HNBU_PATCH2: {
2412*4882a593Smuzhiyun 					char vstr_paddr[16];
2413*4882a593Smuzhiyun 					char vstr_pdata[16];
2414*4882a593Smuzhiyun 
2415*4882a593Smuzhiyun 					/* retrieve the patch pairs
2416*4882a593Smuzhiyun 					 * from tlen/8; where 8 is
2417*4882a593Smuzhiyun 					 * sizeof(patch addr(4)) +
2418*4882a593Smuzhiyun 					 * sizeof(patch data(4)).
2419*4882a593Smuzhiyun 					 */
2420*4882a593Smuzhiyun 					patch_pair = tlen/8;
2421*4882a593Smuzhiyun 
2422*4882a593Smuzhiyun 					for (j = 0; j < patch_pair; j++) {
2423*4882a593Smuzhiyun 						snprintf(vstr_paddr, sizeof(vstr_paddr),
2424*4882a593Smuzhiyun 							rstr_paddr, j);
2425*4882a593Smuzhiyun 						snprintf(vstr_pdata, sizeof(vstr_pdata),
2426*4882a593Smuzhiyun 							rstr_pdata, j);
2427*4882a593Smuzhiyun 
2428*4882a593Smuzhiyun 						varbuf_append(&b, vstr_paddr,
2429*4882a593Smuzhiyun 							(cis[i + (j*8) + 4] << 24) |
2430*4882a593Smuzhiyun 							(cis[i + (j*8) + 3] << 16) |
2431*4882a593Smuzhiyun 							(cis[i + (j*8) + 2] << 8) |
2432*4882a593Smuzhiyun 							cis[i + (j*8) + 1]);
2433*4882a593Smuzhiyun 
2434*4882a593Smuzhiyun 						varbuf_append(&b, vstr_pdata,
2435*4882a593Smuzhiyun 							(cis[i + (j*8) + 8] << 24) |
2436*4882a593Smuzhiyun 							(cis[i + (j*8) + 7] << 16) |
2437*4882a593Smuzhiyun 							(cis[i + (j*8) + 6] << 8) |
2438*4882a593Smuzhiyun 							cis[i + (j*8) + 5]);
2439*4882a593Smuzhiyun 					}
2440*4882a593Smuzhiyun 					break;
2441*4882a593Smuzhiyun 				}
2442*4882a593Smuzhiyun 				case HNBU_PATCH_AUTOINC8: {
2443*4882a593Smuzhiyun 					char vstr_paddr[16];
2444*4882a593Smuzhiyun 					char vstr_pdatah[16];
2445*4882a593Smuzhiyun 					char vstr_pdatal[16];
2446*4882a593Smuzhiyun 					uint32 addr_inc;
2447*4882a593Smuzhiyun 					uint8 pcnt;
2448*4882a593Smuzhiyun 
2449*4882a593Smuzhiyun 					addr_inc = (cis[i + 4] << 24) |
2450*4882a593Smuzhiyun 						(cis[i + 3] << 16) |
2451*4882a593Smuzhiyun 						(cis[i + 2] << 8) |
2452*4882a593Smuzhiyun 						(cis[i + 1]);
2453*4882a593Smuzhiyun 
2454*4882a593Smuzhiyun 					pcnt = (tlen - 5)/8;
2455*4882a593Smuzhiyun 					for (j = 0; j < pcnt; j++) {
2456*4882a593Smuzhiyun 						snprintf(vstr_paddr, sizeof(vstr_paddr),
2457*4882a593Smuzhiyun 							rstr_paddr, j + patch_pair);
2458*4882a593Smuzhiyun 						snprintf(vstr_pdatah, sizeof(vstr_pdatah),
2459*4882a593Smuzhiyun 							rstr_pdatah, j + patch_pair);
2460*4882a593Smuzhiyun 						snprintf(vstr_pdatal, sizeof(vstr_pdatal),
2461*4882a593Smuzhiyun 							rstr_pdatal, j + patch_pair);
2462*4882a593Smuzhiyun 
2463*4882a593Smuzhiyun 						varbuf_append(&b, vstr_paddr, addr_inc);
2464*4882a593Smuzhiyun 						varbuf_append(&b, vstr_pdatal,
2465*4882a593Smuzhiyun 							(cis[i + (j*8) + 8] << 24) |
2466*4882a593Smuzhiyun 							(cis[i + (j*8) + 7] << 16) |
2467*4882a593Smuzhiyun 							(cis[i + (j*8) + 6] << 8) |
2468*4882a593Smuzhiyun 							cis[i + (j*8) + 5]);
2469*4882a593Smuzhiyun 						varbuf_append(&b, vstr_pdatah,
2470*4882a593Smuzhiyun 							(cis[i + (j*8) + 12] << 24) |
2471*4882a593Smuzhiyun 							(cis[i + (j*8) + 11] << 16) |
2472*4882a593Smuzhiyun 							(cis[i + (j*8) + 10] << 8) |
2473*4882a593Smuzhiyun 							cis[i + (j*8) + 9]);
2474*4882a593Smuzhiyun 						addr_inc += 8;
2475*4882a593Smuzhiyun 					}
2476*4882a593Smuzhiyun 					patch_pair += pcnt;
2477*4882a593Smuzhiyun 					break;
2478*4882a593Smuzhiyun 				}
2479*4882a593Smuzhiyun 				case HNBU_PATCH8: {
2480*4882a593Smuzhiyun 					char vstr_paddr[16];
2481*4882a593Smuzhiyun 					char vstr_pdatah[16];
2482*4882a593Smuzhiyun 					char vstr_pdatal[16];
2483*4882a593Smuzhiyun 
2484*4882a593Smuzhiyun 					/* retrieve the patch pairs
2485*4882a593Smuzhiyun 					 * from tlen/8; where 8 is
2486*4882a593Smuzhiyun 					 * sizeof(patch addr(4)) +
2487*4882a593Smuzhiyun 					 * sizeof(patch data(4)).
2488*4882a593Smuzhiyun 					 */
2489*4882a593Smuzhiyun 					patch_pair = tlen/12;
2490*4882a593Smuzhiyun 
2491*4882a593Smuzhiyun 					for (j = 0; j < patch_pair; j++) {
2492*4882a593Smuzhiyun 						snprintf(vstr_paddr, sizeof(vstr_paddr),
2493*4882a593Smuzhiyun 							rstr_paddr, j);
2494*4882a593Smuzhiyun 						snprintf(vstr_pdatah, sizeof(vstr_pdatah),
2495*4882a593Smuzhiyun 							rstr_pdatah, j);
2496*4882a593Smuzhiyun 						snprintf(vstr_pdatal, sizeof(vstr_pdatal),
2497*4882a593Smuzhiyun 							rstr_pdatal, j);
2498*4882a593Smuzhiyun 
2499*4882a593Smuzhiyun 						varbuf_append(&b, vstr_paddr,
2500*4882a593Smuzhiyun 							(cis[i + (j*12) + 4] << 24) |
2501*4882a593Smuzhiyun 							(cis[i + (j*12) + 3] << 16) |
2502*4882a593Smuzhiyun 							(cis[i + (j*12) + 2] << 8) |
2503*4882a593Smuzhiyun 							cis[i + (j*12) + 1]);
2504*4882a593Smuzhiyun 
2505*4882a593Smuzhiyun 						varbuf_append(&b, vstr_pdatal,
2506*4882a593Smuzhiyun 							(cis[i + (j*12) + 8] << 24) |
2507*4882a593Smuzhiyun 							(cis[i + (j*12) + 7] << 16) |
2508*4882a593Smuzhiyun 							(cis[i + (j*12) + 6] << 8) |
2509*4882a593Smuzhiyun 							cis[i + (j*12) + 5]);
2510*4882a593Smuzhiyun 
2511*4882a593Smuzhiyun 						varbuf_append(&b, vstr_pdatah,
2512*4882a593Smuzhiyun 							(cis[i + (j*12) + 12] << 24) |
2513*4882a593Smuzhiyun 							(cis[i + (j*12) + 11] << 16) |
2514*4882a593Smuzhiyun 							(cis[i + (j*12) + 10] << 8) |
2515*4882a593Smuzhiyun 							cis[i + (j*12) + 9]);
2516*4882a593Smuzhiyun 					}
2517*4882a593Smuzhiyun 					break;
2518*4882a593Smuzhiyun 				}
2519*4882a593Smuzhiyun 				case HNBU_USBFLAGS:
2520*4882a593Smuzhiyun 					varbuf_append(&b, vstr_usbflags,
2521*4882a593Smuzhiyun 					              (cis[i + 4] << 24) |
2522*4882a593Smuzhiyun 					              (cis[i + 3] << 16) |
2523*4882a593Smuzhiyun 					              (cis[i + 2] << 8) |
2524*4882a593Smuzhiyun 					              cis[i + 1]);
2525*4882a593Smuzhiyun 					break;
2526*4882a593Smuzhiyun #ifdef BCM_BOOTLOADER
2527*4882a593Smuzhiyun 				case HNBU_MDIOEX_REGLIST:
2528*4882a593Smuzhiyun 				case HNBU_MDIO_REGLIST: {
2529*4882a593Smuzhiyun 					/* Format: addr (8 bits) | val (16 bits) */
2530*4882a593Smuzhiyun 					const uint8 msize = 3;
2531*4882a593Smuzhiyun 					char mdiostr[24];
2532*4882a593Smuzhiyun 					const char *mdiodesc;
2533*4882a593Smuzhiyun 					uint8 *st;
2534*4882a593Smuzhiyun 
2535*4882a593Smuzhiyun 					mdiodesc = (cis[i] == HNBU_MDIO_REGLIST) ?
2536*4882a593Smuzhiyun 						vstr_mdio : vstr_mdioex;
2537*4882a593Smuzhiyun 
2538*4882a593Smuzhiyun 					ASSERT(((tlen - 1) % msize) == 0);
2539*4882a593Smuzhiyun 
2540*4882a593Smuzhiyun 					st = &cis[i + 1]; /* start of reg list */
2541*4882a593Smuzhiyun 					for (j = 0; j < (tlen - 1); j += msize, st += msize) {
2542*4882a593Smuzhiyun 						snprintf(mdiostr, sizeof(mdiostr),
2543*4882a593Smuzhiyun 							mdiodesc, st[0]);
2544*4882a593Smuzhiyun 						varbuf_append(&b, mdiostr, (st[2] << 8) | st[1]);
2545*4882a593Smuzhiyun 					}
2546*4882a593Smuzhiyun 					break;
2547*4882a593Smuzhiyun 				}
2548*4882a593Smuzhiyun 				case HNBU_BRMIN:
2549*4882a593Smuzhiyun 					varbuf_append(&b, vstr_brmin,
2550*4882a593Smuzhiyun 					              (cis[i + 4] << 24) |
2551*4882a593Smuzhiyun 					              (cis[i + 3] << 16) |
2552*4882a593Smuzhiyun 					              (cis[i + 2] << 8) |
2553*4882a593Smuzhiyun 					              cis[i + 1]);
2554*4882a593Smuzhiyun 					break;
2555*4882a593Smuzhiyun 
2556*4882a593Smuzhiyun 				case HNBU_BRMAX:
2557*4882a593Smuzhiyun 					varbuf_append(&b, vstr_brmax,
2558*4882a593Smuzhiyun 					              (cis[i + 4] << 24) |
2559*4882a593Smuzhiyun 					              (cis[i + 3] << 16) |
2560*4882a593Smuzhiyun 					              (cis[i + 2] << 8) |
2561*4882a593Smuzhiyun 					              cis[i + 1]);
2562*4882a593Smuzhiyun 					break;
2563*4882a593Smuzhiyun #endif /* BCM_BOOTLOADER */
2564*4882a593Smuzhiyun 
2565*4882a593Smuzhiyun 				case HNBU_RDLID:
2566*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rdlid,
2567*4882a593Smuzhiyun 					              (cis[i + 2] << 8) | cis[i + 1]);
2568*4882a593Smuzhiyun 					break;
2569*4882a593Smuzhiyun 
2570*4882a593Smuzhiyun 				case HNBU_GCI_CCR: {
2571*4882a593Smuzhiyun 					/* format:
2572*4882a593Smuzhiyun 					 * |0x80|	<== brcm
2573*4882a593Smuzhiyun 					 * |len|	<== variable, multiple of 5
2574*4882a593Smuzhiyun 					 * |tup|	<== tupletype
2575*4882a593Smuzhiyun 					 * |ccreg_ix0|	<== ix of ccreg [1byte]
2576*4882a593Smuzhiyun 					 * |ccreg_val0|	<== corr value [4bytes]
2577*4882a593Smuzhiyun 					 *	---
2578*4882a593Smuzhiyun 					 * Multiple registers are possible. for eg: we
2579*4882a593Smuzhiyun 					 *	can specify reg_ix3val3 and reg_ix5val5, etc
2580*4882a593Smuzhiyun 					 */
2581*4882a593Smuzhiyun 					char vstr_gci_ccreg_entry[16];
2582*4882a593Smuzhiyun 					uint8 num_entries = 0;
2583*4882a593Smuzhiyun 
2584*4882a593Smuzhiyun 					/* retrieve the index-value pairs
2585*4882a593Smuzhiyun 					 * from tlen/5; where 5 is
2586*4882a593Smuzhiyun 					 * sizeof(ccreg_ix(1)) +
2587*4882a593Smuzhiyun 					 * sizeof(ccreg_val(4)).
2588*4882a593Smuzhiyun 					 */
2589*4882a593Smuzhiyun 					num_entries = tlen/5;
2590*4882a593Smuzhiyun 
2591*4882a593Smuzhiyun 					for (j = 0; j < num_entries; j++) {
2592*4882a593Smuzhiyun 						snprintf(vstr_gci_ccreg_entry,
2593*4882a593Smuzhiyun 							sizeof(vstr_gci_ccreg_entry),
2594*4882a593Smuzhiyun 							rstr_gci_ccreg_entry,
2595*4882a593Smuzhiyun 							cis[i + (j*5) + 1]);
2596*4882a593Smuzhiyun 
2597*4882a593Smuzhiyun 						varbuf_append(&b, vstr_gci_ccreg_entry,
2598*4882a593Smuzhiyun 							(cis[i + (j*5) + 5] << 24) |
2599*4882a593Smuzhiyun 							(cis[i + (j*5) + 4] << 16) |
2600*4882a593Smuzhiyun 							(cis[i + (j*5) + 3] << 8) |
2601*4882a593Smuzhiyun 							cis[i + (j*5) + 2]);
2602*4882a593Smuzhiyun 					}
2603*4882a593Smuzhiyun 					break;
2604*4882a593Smuzhiyun 				}
2605*4882a593Smuzhiyun 
2606*4882a593Smuzhiyun #ifdef BCM_BOOTLOADER
2607*4882a593Smuzhiyun 				case HNBU_RDLRNDIS:
2608*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rdlrndis, cis[i + 1]);
2609*4882a593Smuzhiyun 					break;
2610*4882a593Smuzhiyun 
2611*4882a593Smuzhiyun 				case HNBU_RDLRWU:
2612*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rdlrwu, cis[i + 1]);
2613*4882a593Smuzhiyun 					break;
2614*4882a593Smuzhiyun 
2615*4882a593Smuzhiyun 				case HNBU_RDLSN:
2616*4882a593Smuzhiyun 					if (tlen >= 5)
2617*4882a593Smuzhiyun 						varbuf_append(&b, vstr_rdlsn,
2618*4882a593Smuzhiyun 						              (cis[i + 4] << 24) |
2619*4882a593Smuzhiyun 						              (cis[i + 3] << 16) |
2620*4882a593Smuzhiyun 						              (cis[i + 2] << 8) |
2621*4882a593Smuzhiyun 						              cis[i + 1]);
2622*4882a593Smuzhiyun 					else
2623*4882a593Smuzhiyun 						varbuf_append(&b, vstr_rdlsn,
2624*4882a593Smuzhiyun 						              (cis[i + 2] << 8) |
2625*4882a593Smuzhiyun 						              cis[i + 1]);
2626*4882a593Smuzhiyun 					break;
2627*4882a593Smuzhiyun 
2628*4882a593Smuzhiyun 				case HNBU_PMUREGS: {
2629*4882a593Smuzhiyun 					uint8 offset = 1, mode_addr, mode, addr;
2630*4882a593Smuzhiyun 					const char *fmt;
2631*4882a593Smuzhiyun 
2632*4882a593Smuzhiyun 					do {
2633*4882a593Smuzhiyun 						mode_addr = cis[i+offset];
2634*4882a593Smuzhiyun 
2635*4882a593Smuzhiyun 						mode = (mode_addr & PMUREGS_MODE_MASK)
2636*4882a593Smuzhiyun 							>> PMUREGS_MODE_SHIFT;
2637*4882a593Smuzhiyun 						addr = mode_addr & PMUREGS_ADDR_MASK;
2638*4882a593Smuzhiyun 
2639*4882a593Smuzhiyun 						switch (mode) {
2640*4882a593Smuzhiyun 						case PMU_PLLREG_MODE:
2641*4882a593Smuzhiyun 							fmt = vstr_pllreg;
2642*4882a593Smuzhiyun 							break;
2643*4882a593Smuzhiyun 						case PMU_CCREG_MODE:
2644*4882a593Smuzhiyun 							fmt = vstr_ccreg;
2645*4882a593Smuzhiyun 							break;
2646*4882a593Smuzhiyun 						case PMU_VOLTREG_MODE:
2647*4882a593Smuzhiyun 							fmt = vstr_regctrl;
2648*4882a593Smuzhiyun 							break;
2649*4882a593Smuzhiyun 						case PMU_RES_TIME_MODE:
2650*4882a593Smuzhiyun 							fmt = vstr_time;
2651*4882a593Smuzhiyun 							break;
2652*4882a593Smuzhiyun 						case PMU_RESDEPEND_MODE:
2653*4882a593Smuzhiyun 							fmt = vstr_depreg;
2654*4882a593Smuzhiyun 							break;
2655*4882a593Smuzhiyun 						default:
2656*4882a593Smuzhiyun 							fmt = NULL;
2657*4882a593Smuzhiyun 							break;
2658*4882a593Smuzhiyun 						}
2659*4882a593Smuzhiyun 
2660*4882a593Smuzhiyun 						if (fmt != NULL) {
2661*4882a593Smuzhiyun 							varbuf_append(&b, fmt, addr,
2662*4882a593Smuzhiyun 								(cis[i + offset + 4] << 24) |
2663*4882a593Smuzhiyun 								(cis[i + offset + 3] << 16) |
2664*4882a593Smuzhiyun 								(cis[i + offset + 2] << 8) |
2665*4882a593Smuzhiyun 								cis[i + offset + 1]);
2666*4882a593Smuzhiyun 						}
2667*4882a593Smuzhiyun 
2668*4882a593Smuzhiyun 						offset += PMUREGS_TPL_SIZE;
2669*4882a593Smuzhiyun 					} while (offset < tlen);
2670*4882a593Smuzhiyun 					break;
2671*4882a593Smuzhiyun 				}
2672*4882a593Smuzhiyun 
2673*4882a593Smuzhiyun 				case HNBU_USBREGS: {
2674*4882a593Smuzhiyun 					uint8 offset = 1, usb_reg;
2675*4882a593Smuzhiyun 					const char *fmt;
2676*4882a593Smuzhiyun 
2677*4882a593Smuzhiyun 					do {
2678*4882a593Smuzhiyun 						usb_reg = cis[i+offset];
2679*4882a593Smuzhiyun 
2680*4882a593Smuzhiyun 						switch (usb_reg) {
2681*4882a593Smuzhiyun 						case USB_DEV_CTRL_REG:
2682*4882a593Smuzhiyun 							fmt = vstr_usbdevctrl;
2683*4882a593Smuzhiyun 							break;
2684*4882a593Smuzhiyun 						case HSIC_PHY_CTRL1_REG:
2685*4882a593Smuzhiyun 							fmt = vstr_hsicphyctrl1;
2686*4882a593Smuzhiyun 							break;
2687*4882a593Smuzhiyun 						case HSIC_PHY_CTRL2_REG:
2688*4882a593Smuzhiyun 							fmt = vstr_hsicphyctrl2;
2689*4882a593Smuzhiyun 							break;
2690*4882a593Smuzhiyun 						default:
2691*4882a593Smuzhiyun 							fmt = NULL;
2692*4882a593Smuzhiyun 							break;
2693*4882a593Smuzhiyun 						}
2694*4882a593Smuzhiyun 
2695*4882a593Smuzhiyun 						if (fmt != NULL) {
2696*4882a593Smuzhiyun 							varbuf_append(&b, fmt,
2697*4882a593Smuzhiyun 								(cis[i + offset + 4] << 24) |
2698*4882a593Smuzhiyun 								(cis[i + offset + 3] << 16) |
2699*4882a593Smuzhiyun 								(cis[i + offset + 2] << 8) |
2700*4882a593Smuzhiyun 								cis[i + offset + 1]);
2701*4882a593Smuzhiyun 						}
2702*4882a593Smuzhiyun 
2703*4882a593Smuzhiyun 						offset += USBREGS_TPL_SIZE;
2704*4882a593Smuzhiyun 					} while (offset < tlen);
2705*4882a593Smuzhiyun 					break;
2706*4882a593Smuzhiyun 				}
2707*4882a593Smuzhiyun 
2708*4882a593Smuzhiyun 				case HNBU_USBRDY:
2709*4882a593Smuzhiyun 					/* The first byte of this tuple indicate if the host
2710*4882a593Smuzhiyun 					 * needs to be informed about the readiness of
2711*4882a593Smuzhiyun 					 * the HSIC/USB for enumeration on which GPIO should
2712*4882a593Smuzhiyun 					 * the device assert this event.
2713*4882a593Smuzhiyun 					 */
2714*4882a593Smuzhiyun 					varbuf_append(&b, vstr_usbrdy, cis[i + 1]);
2715*4882a593Smuzhiyun 
2716*4882a593Smuzhiyun 					/* The following fields in this OTP are optional.
2717*4882a593Smuzhiyun 					 * The remaining bytes will indicate the delay required
2718*4882a593Smuzhiyun 					 * before and/or after the ch_init(). The delay is defined
2719*4882a593Smuzhiyun 					 * using 16-bits of this the MSB(bit15 of 15:0) will be
2720*4882a593Smuzhiyun 					 * used indicate if the parameter is for Pre or Post delay.
2721*4882a593Smuzhiyun 					 */
2722*4882a593Smuzhiyun 					for (j = 2; j < USBRDY_MAXOTP_SIZE && j < tlen;
2723*4882a593Smuzhiyun 						j += 2) {
2724*4882a593Smuzhiyun 						uint16 usb_delay;
2725*4882a593Smuzhiyun 
2726*4882a593Smuzhiyun 						usb_delay = cis[i + j] | (cis[i + j + 1] << 8);
2727*4882a593Smuzhiyun 
2728*4882a593Smuzhiyun 						/* The bit-15 of the delay field will indicate the
2729*4882a593Smuzhiyun 						 * type of delay (pre or post).
2730*4882a593Smuzhiyun 						 */
2731*4882a593Smuzhiyun 						if (usb_delay & USBRDY_DLY_TYPE) {
2732*4882a593Smuzhiyun 							varbuf_append(&b, vstr_usbpostdly,
2733*4882a593Smuzhiyun 							(usb_delay & USBRDY_DLY_MASK));
2734*4882a593Smuzhiyun 						} else {
2735*4882a593Smuzhiyun 							varbuf_append(&b, vstr_usbpredly,
2736*4882a593Smuzhiyun 							(usb_delay & USBRDY_DLY_MASK));
2737*4882a593Smuzhiyun 						}
2738*4882a593Smuzhiyun 					}
2739*4882a593Smuzhiyun 					break;
2740*4882a593Smuzhiyun 
2741*4882a593Smuzhiyun 				case HNBU_BLDR_TIMEOUT:
2742*4882a593Smuzhiyun 					/* The Delay after USBConnect for timeout till dongle
2743*4882a593Smuzhiyun 					 * receives get_descriptor request.
2744*4882a593Smuzhiyun 					 */
2745*4882a593Smuzhiyun 					varbuf_append(&b, vstr_bldr_reset_timeout,
2746*4882a593Smuzhiyun 						(cis[i + 1] | (cis[i + 2] << 8)));
2747*4882a593Smuzhiyun 					break;
2748*4882a593Smuzhiyun 
2749*4882a593Smuzhiyun 				case HNBU_MUXENAB:
2750*4882a593Smuzhiyun 					varbuf_append(&b, vstr_muxenab, cis[i + 1]);
2751*4882a593Smuzhiyun 					break;
2752*4882a593Smuzhiyun 				case HNBU_PUBKEY: {
2753*4882a593Smuzhiyun 					/* The public key is in binary format in OTP,
2754*4882a593Smuzhiyun 					 * convert to string format before appending
2755*4882a593Smuzhiyun 					 * buffer string.
2756*4882a593Smuzhiyun 					 *  public key(12 bytes) + crc (1byte) = 129
2757*4882a593Smuzhiyun 					 */
2758*4882a593Smuzhiyun 					unsigned char a[300];
2759*4882a593Smuzhiyun 					int k;
2760*4882a593Smuzhiyun 
2761*4882a593Smuzhiyun 					for (k = 1, j = 0; k < 129; k++)
2762*4882a593Smuzhiyun 						j += snprintf((char *)(a + j),
2763*4882a593Smuzhiyun 							sizeof(a) - j,
2764*4882a593Smuzhiyun 							"%02x", cis[i + k]);
2765*4882a593Smuzhiyun 
2766*4882a593Smuzhiyun 					a[256] = 0;
2767*4882a593Smuzhiyun 
2768*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pubkey, a);
2769*4882a593Smuzhiyun 					break;
2770*4882a593Smuzhiyun 				}
2771*4882a593Smuzhiyun #else
2772*4882a593Smuzhiyun 				case HNBU_AA:
2773*4882a593Smuzhiyun 					varbuf_append(&b, vstr_aa2g, cis[i + 1]);
2774*4882a593Smuzhiyun 					if (tlen >= 3)
2775*4882a593Smuzhiyun 						varbuf_append(&b, vstr_aa5g, cis[i + 2]);
2776*4882a593Smuzhiyun 					break;
2777*4882a593Smuzhiyun 
2778*4882a593Smuzhiyun 				case HNBU_AG:
2779*4882a593Smuzhiyun 					varbuf_append(&b, vstr_ag, 0, cis[i + 1]);
2780*4882a593Smuzhiyun 					if (tlen >= 3)
2781*4882a593Smuzhiyun 						varbuf_append(&b, vstr_ag, 1, cis[i + 2]);
2782*4882a593Smuzhiyun 					if (tlen >= 4)
2783*4882a593Smuzhiyun 						varbuf_append(&b, vstr_ag, 2, cis[i + 3]);
2784*4882a593Smuzhiyun 					if (tlen >= 5)
2785*4882a593Smuzhiyun 						varbuf_append(&b, vstr_ag, 3, cis[i + 4]);
2786*4882a593Smuzhiyun 					ag_init = TRUE;
2787*4882a593Smuzhiyun 					break;
2788*4882a593Smuzhiyun 
2789*4882a593Smuzhiyun 				case HNBU_ANT5G:
2790*4882a593Smuzhiyun 					varbuf_append(&b, vstr_aa5g, cis[i + 1]);
2791*4882a593Smuzhiyun 					varbuf_append(&b, vstr_ag, 1, cis[i + 2]);
2792*4882a593Smuzhiyun 					break;
2793*4882a593Smuzhiyun 
2794*4882a593Smuzhiyun 				case HNBU_CC:
2795*4882a593Smuzhiyun 					ASSERT(sromrev == 1);
2796*4882a593Smuzhiyun 					varbuf_append(&b, vstr_cc, cis[i + 1]);
2797*4882a593Smuzhiyun 					break;
2798*4882a593Smuzhiyun 
2799*4882a593Smuzhiyun 				case HNBU_PAPARMS: {
2800*4882a593Smuzhiyun 					uint8 pa0_lo_offset = 0;
2801*4882a593Smuzhiyun 					switch (tlen) {
2802*4882a593Smuzhiyun 					case 2:
2803*4882a593Smuzhiyun 						ASSERT(sromrev == 1);
2804*4882a593Smuzhiyun 						varbuf_append(&b, vstr_pa0maxpwr, cis[i + 1]);
2805*4882a593Smuzhiyun 						break;
2806*4882a593Smuzhiyun 					/* case 16:
2807*4882a593Smuzhiyun 						ASSERT(sromrev >= 11);
2808*4882a593Smuzhiyun 						for (j = 0; j < 3; j++) {
2809*4882a593Smuzhiyun 						varbuf_append(&b, vstr_pa0b_lo[j],
2810*4882a593Smuzhiyun 								(cis[i + (j * 2) + 11] << 8) +
2811*4882a593Smuzhiyun 								cis[i + (j * 2) + 10]);
2812*4882a593Smuzhiyun 						}
2813*4882a593Smuzhiyun 						 FALLTHROUGH
2814*4882a593Smuzhiyun 					*/
2815*4882a593Smuzhiyun 					case 10:
2816*4882a593Smuzhiyun 					case 16:
2817*4882a593Smuzhiyun 						ASSERT(sromrev >= 2);
2818*4882a593Smuzhiyun 						varbuf_append(&b, vstr_opo, cis[i + 9]);
2819*4882a593Smuzhiyun 						if (tlen >= 13 && pa0_lo_offset == 0)
2820*4882a593Smuzhiyun 							pa0_lo_offset = 9;
2821*4882a593Smuzhiyun 						/* FALLTHROUGH */
2822*4882a593Smuzhiyun 					case 9:
2823*4882a593Smuzhiyun 					case 15:
2824*4882a593Smuzhiyun 						varbuf_append(&b, vstr_pa0maxpwr, cis[i + 8]);
2825*4882a593Smuzhiyun 						if (tlen >= 13 && pa0_lo_offset == 0)
2826*4882a593Smuzhiyun 							pa0_lo_offset = 8;
2827*4882a593Smuzhiyun 						/* FALLTHROUGH */
2828*4882a593Smuzhiyun 					BCMDONGLECASE(8)
2829*4882a593Smuzhiyun 					BCMDONGLECASE(14)
2830*4882a593Smuzhiyun 						varbuf_append(&b, vstr_pa0itssit, cis[i + 7]);
2831*4882a593Smuzhiyun 						varbuf_append(&b, vstr_maxp2ga, 0, cis[i + 7]);
2832*4882a593Smuzhiyun 						if (tlen >= 13 && pa0_lo_offset == 0)
2833*4882a593Smuzhiyun 							pa0_lo_offset = 7;
2834*4882a593Smuzhiyun 						/* FALLTHROUGH */
2835*4882a593Smuzhiyun 					BCMDONGLECASE(7)
2836*4882a593Smuzhiyun 					BCMDONGLECASE(13)
2837*4882a593Smuzhiyun 					        for (j = 0; j < 3; j++) {
2838*4882a593Smuzhiyun 							varbuf_append(&b, vstr_pa0b[j],
2839*4882a593Smuzhiyun 							              (cis[i + (j * 2) + 2] << 8) +
2840*4882a593Smuzhiyun 							              cis[i + (j * 2) + 1]);
2841*4882a593Smuzhiyun 						}
2842*4882a593Smuzhiyun 						if (tlen >= 13 && pa0_lo_offset == 0)
2843*4882a593Smuzhiyun 							pa0_lo_offset = 6;
2844*4882a593Smuzhiyun 
2845*4882a593Smuzhiyun 						if (tlen >= 13 && pa0_lo_offset != 0) {
2846*4882a593Smuzhiyun 							for (j = 0; j < 3; j++) {
2847*4882a593Smuzhiyun 								varbuf_append(&b, vstr_pa0b_lo[j],
2848*4882a593Smuzhiyun 								 (cis[pa0_lo_offset+i+(j*2)+2]<<8)+
2849*4882a593Smuzhiyun 								 cis[pa0_lo_offset+i+(j*2)+1]);
2850*4882a593Smuzhiyun 							}
2851*4882a593Smuzhiyun 						}
2852*4882a593Smuzhiyun 						break;
2853*4882a593Smuzhiyun 					default:
2854*4882a593Smuzhiyun 						ASSERT((tlen == 2) || (tlen == 9) || (tlen == 10) ||
2855*4882a593Smuzhiyun 							(tlen == 15) || (tlen == 16));
2856*4882a593Smuzhiyun 						break;
2857*4882a593Smuzhiyun 					}
2858*4882a593Smuzhiyun 					break;
2859*4882a593Smuzhiyun 				}
2860*4882a593Smuzhiyun 				case HNBU_PAPARMS5G:
2861*4882a593Smuzhiyun 					ASSERT((sromrev == 2) || (sromrev == 3));
2862*4882a593Smuzhiyun 					switch (tlen) {
2863*4882a593Smuzhiyun 					case 23:
2864*4882a593Smuzhiyun 						varbuf_append(&b, vstr_pa1himaxpwr, cis[i + 22]);
2865*4882a593Smuzhiyun 						varbuf_append(&b, vstr_pa1lomaxpwr, cis[i + 21]);
2866*4882a593Smuzhiyun 						varbuf_append(&b, vstr_pa1maxpwr, cis[i + 20]);
2867*4882a593Smuzhiyun 						/* FALLTHROUGH */
2868*4882a593Smuzhiyun 					case 20:
2869*4882a593Smuzhiyun 						varbuf_append(&b, vstr_pa1itssit, cis[i + 19]);
2870*4882a593Smuzhiyun 						/* FALLTHROUGH */
2871*4882a593Smuzhiyun 					case 19:
2872*4882a593Smuzhiyun 						for (j = 0; j < 3; j++) {
2873*4882a593Smuzhiyun 							varbuf_append(&b, vstr_pa1b[j],
2874*4882a593Smuzhiyun 							              (cis[i + (j * 2) + 2] << 8) +
2875*4882a593Smuzhiyun 							              cis[i + (j * 2) + 1]);
2876*4882a593Smuzhiyun 						}
2877*4882a593Smuzhiyun 						for (j = 3; j < 6; j++) {
2878*4882a593Smuzhiyun 							varbuf_append(&b, vstr_pa1lob[j - 3],
2879*4882a593Smuzhiyun 							              (cis[i + (j * 2) + 2] << 8) +
2880*4882a593Smuzhiyun 							              cis[i + (j * 2) + 1]);
2881*4882a593Smuzhiyun 						}
2882*4882a593Smuzhiyun 						for (j = 6; j < 9; j++) {
2883*4882a593Smuzhiyun 							varbuf_append(&b, vstr_pa1hib[j - 6],
2884*4882a593Smuzhiyun 							              (cis[i + (j * 2) + 2] << 8) +
2885*4882a593Smuzhiyun 							              cis[i + (j * 2) + 1]);
2886*4882a593Smuzhiyun 						}
2887*4882a593Smuzhiyun 						break;
2888*4882a593Smuzhiyun 					default:
2889*4882a593Smuzhiyun 						ASSERT((tlen == 19) ||
2890*4882a593Smuzhiyun 						       (tlen == 20) || (tlen == 23));
2891*4882a593Smuzhiyun 						break;
2892*4882a593Smuzhiyun 					}
2893*4882a593Smuzhiyun 					break;
2894*4882a593Smuzhiyun 
2895*4882a593Smuzhiyun 				case HNBU_OEM:
2896*4882a593Smuzhiyun 					ASSERT(sromrev == 1);
2897*4882a593Smuzhiyun 					varbuf_append(&b, vstr_oem,
2898*4882a593Smuzhiyun 					              cis[i + 1], cis[i + 2],
2899*4882a593Smuzhiyun 					              cis[i + 3], cis[i + 4],
2900*4882a593Smuzhiyun 					              cis[i + 5], cis[i + 6],
2901*4882a593Smuzhiyun 					              cis[i + 7], cis[i + 8]);
2902*4882a593Smuzhiyun 					break;
2903*4882a593Smuzhiyun 
2904*4882a593Smuzhiyun 				case HNBU_CCODE:
2905*4882a593Smuzhiyun 					ASSERT(sromrev > 1);
2906*4882a593Smuzhiyun 					if ((cis[i + 1] == 0) || (cis[i + 2] == 0))
2907*4882a593Smuzhiyun 						varbuf_append(&b, vstr_noccode);
2908*4882a593Smuzhiyun 					else
2909*4882a593Smuzhiyun 						varbuf_append(&b, vstr_ccode,
2910*4882a593Smuzhiyun 						              cis[i + 1], cis[i + 2]);
2911*4882a593Smuzhiyun 					varbuf_append(&b, vstr_cctl, cis[i + 3]);
2912*4882a593Smuzhiyun 					break;
2913*4882a593Smuzhiyun 
2914*4882a593Smuzhiyun 				case HNBU_CCKPO:
2915*4882a593Smuzhiyun 					ASSERT(sromrev > 2);
2916*4882a593Smuzhiyun 					varbuf_append(&b, vstr_cckpo,
2917*4882a593Smuzhiyun 					              (cis[i + 2] << 8) | cis[i + 1]);
2918*4882a593Smuzhiyun 					break;
2919*4882a593Smuzhiyun 
2920*4882a593Smuzhiyun 				case HNBU_OFDMPO:
2921*4882a593Smuzhiyun 					ASSERT(sromrev > 2);
2922*4882a593Smuzhiyun 					varbuf_append(&b, vstr_ofdmpo,
2923*4882a593Smuzhiyun 					              (cis[i + 4] << 24) |
2924*4882a593Smuzhiyun 					              (cis[i + 3] << 16) |
2925*4882a593Smuzhiyun 					              (cis[i + 2] << 8) |
2926*4882a593Smuzhiyun 					              cis[i + 1]);
2927*4882a593Smuzhiyun 					break;
2928*4882a593Smuzhiyun 
2929*4882a593Smuzhiyun 				case HNBU_WPS:
2930*4882a593Smuzhiyun 					varbuf_append(&b, vstr_wpsgpio, cis[i + 1]);
2931*4882a593Smuzhiyun 					if (tlen >= 3)
2932*4882a593Smuzhiyun 						varbuf_append(&b, vstr_wpsled, cis[i + 2]);
2933*4882a593Smuzhiyun 					break;
2934*4882a593Smuzhiyun 
2935*4882a593Smuzhiyun 				case HNBU_RSSISMBXA2G:
2936*4882a593Smuzhiyun 					ASSERT(sromrev == 3);
2937*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rssismf2g, cis[i + 1] & 0xf);
2938*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rssismc2g, (cis[i + 1] >> 4) & 0xf);
2939*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rssisav2g, cis[i + 2] & 0x7);
2940*4882a593Smuzhiyun 					varbuf_append(&b, vstr_bxa2g, (cis[i + 2] >> 3) & 0x3);
2941*4882a593Smuzhiyun 					break;
2942*4882a593Smuzhiyun 
2943*4882a593Smuzhiyun 				case HNBU_RSSISMBXA5G:
2944*4882a593Smuzhiyun 					ASSERT(sromrev == 3);
2945*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rssismf5g, cis[i + 1] & 0xf);
2946*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rssismc5g, (cis[i + 1] >> 4) & 0xf);
2947*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rssisav5g, cis[i + 2] & 0x7);
2948*4882a593Smuzhiyun 					varbuf_append(&b, vstr_bxa5g, (cis[i + 2] >> 3) & 0x3);
2949*4882a593Smuzhiyun 					break;
2950*4882a593Smuzhiyun 
2951*4882a593Smuzhiyun 				case HNBU_TRI2G:
2952*4882a593Smuzhiyun 					ASSERT(sromrev == 3);
2953*4882a593Smuzhiyun 					varbuf_append(&b, vstr_tri2g, cis[i + 1]);
2954*4882a593Smuzhiyun 					break;
2955*4882a593Smuzhiyun 
2956*4882a593Smuzhiyun 				case HNBU_TRI5G:
2957*4882a593Smuzhiyun 					ASSERT(sromrev == 3);
2958*4882a593Smuzhiyun 					varbuf_append(&b, vstr_tri5gl, cis[i + 1]);
2959*4882a593Smuzhiyun 					varbuf_append(&b, vstr_tri5g, cis[i + 2]);
2960*4882a593Smuzhiyun 					varbuf_append(&b, vstr_tri5gh, cis[i + 3]);
2961*4882a593Smuzhiyun 					break;
2962*4882a593Smuzhiyun 
2963*4882a593Smuzhiyun 				case HNBU_RXPO2G:
2964*4882a593Smuzhiyun 					ASSERT(sromrev == 3);
2965*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxpo2g, cis[i + 1]);
2966*4882a593Smuzhiyun 					break;
2967*4882a593Smuzhiyun 
2968*4882a593Smuzhiyun 				case HNBU_RXPO5G:
2969*4882a593Smuzhiyun 					ASSERT(sromrev == 3);
2970*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxpo5g, cis[i + 1]);
2971*4882a593Smuzhiyun 					break;
2972*4882a593Smuzhiyun 
2973*4882a593Smuzhiyun 				case HNBU_MACADDR:
2974*4882a593Smuzhiyun 					if (!(ETHER_ISNULLADDR(&cis[i+1])) &&
2975*4882a593Smuzhiyun 					    !(ETHER_ISMULTI(&cis[i+1]))) {
2976*4882a593Smuzhiyun 						bcm_ether_ntoa((struct ether_addr *)&cis[i + 1],
2977*4882a593Smuzhiyun 						               eabuf);
2978*4882a593Smuzhiyun 
2979*4882a593Smuzhiyun 						/* set boardnum if HNBU_BOARDNUM not seen yet */
2980*4882a593Smuzhiyun 						if (boardnum == -1)
2981*4882a593Smuzhiyun 							boardnum = (cis[i + 5] << 8) + cis[i + 6];
2982*4882a593Smuzhiyun 					}
2983*4882a593Smuzhiyun 					break;
2984*4882a593Smuzhiyun 
2985*4882a593Smuzhiyun 				case HNBU_CHAINSWITCH:
2986*4882a593Smuzhiyun 					varbuf_append(&b, vstr_txchain, cis[i + 1]);
2987*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxchain, cis[i + 2]);
2988*4882a593Smuzhiyun 					varbuf_append(&b, vstr_antswitch,
2989*4882a593Smuzhiyun 					      (cis[i + 4] << 8) + cis[i + 3]);
2990*4882a593Smuzhiyun 					break;
2991*4882a593Smuzhiyun 
2992*4882a593Smuzhiyun 				case HNBU_ELNA2G:
2993*4882a593Smuzhiyun 					varbuf_append(&b, vstr_elna2g, cis[i + 1]);
2994*4882a593Smuzhiyun 					break;
2995*4882a593Smuzhiyun 
2996*4882a593Smuzhiyun 				case HNBU_ELNA5G:
2997*4882a593Smuzhiyun 					varbuf_append(&b, vstr_elna5g, cis[i + 1]);
2998*4882a593Smuzhiyun 					break;
2999*4882a593Smuzhiyun 
3000*4882a593Smuzhiyun 				case HNBU_REGREV:
3001*4882a593Smuzhiyun 					varbuf_append(&b, vstr_regrev,
3002*4882a593Smuzhiyun 						srom_data2value(&cis[i + 1], tlen - 1));
3003*4882a593Smuzhiyun 					break;
3004*4882a593Smuzhiyun 
3005*4882a593Smuzhiyun 				case HNBU_FEM: {
3006*4882a593Smuzhiyun 					uint16 fem = (cis[i + 2] << 8) + cis[i + 1];
3007*4882a593Smuzhiyun 					varbuf_append(&b, vstr_antswctl2g, (fem &
3008*4882a593Smuzhiyun 						SROM8_FEM_ANTSWLUT_MASK) >>
3009*4882a593Smuzhiyun 						SROM8_FEM_ANTSWLUT_SHIFT);
3010*4882a593Smuzhiyun 					varbuf_append(&b, vstr_triso2g, (fem &
3011*4882a593Smuzhiyun 						SROM8_FEM_TR_ISO_MASK) >>
3012*4882a593Smuzhiyun 						SROM8_FEM_TR_ISO_SHIFT);
3013*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pdetrange2g, (fem &
3014*4882a593Smuzhiyun 						SROM8_FEM_PDET_RANGE_MASK) >>
3015*4882a593Smuzhiyun 						SROM8_FEM_PDET_RANGE_SHIFT);
3016*4882a593Smuzhiyun 					varbuf_append(&b, vstr_extpagain2g, (fem &
3017*4882a593Smuzhiyun 						SROM8_FEM_EXTPA_GAIN_MASK) >>
3018*4882a593Smuzhiyun 						SROM8_FEM_EXTPA_GAIN_SHIFT);
3019*4882a593Smuzhiyun 					varbuf_append(&b, vstr_tssipos2g, (fem &
3020*4882a593Smuzhiyun 						SROM8_FEM_TSSIPOS_MASK) >>
3021*4882a593Smuzhiyun 						SROM8_FEM_TSSIPOS_SHIFT);
3022*4882a593Smuzhiyun 					if (tlen < 5) break;
3023*4882a593Smuzhiyun 
3024*4882a593Smuzhiyun 					fem = (cis[i + 4] << 8) + cis[i + 3];
3025*4882a593Smuzhiyun 					varbuf_append(&b, vstr_antswctl5g, (fem &
3026*4882a593Smuzhiyun 						SROM8_FEM_ANTSWLUT_MASK) >>
3027*4882a593Smuzhiyun 						SROM8_FEM_ANTSWLUT_SHIFT);
3028*4882a593Smuzhiyun 					varbuf_append(&b, vstr_triso5g, (fem &
3029*4882a593Smuzhiyun 						SROM8_FEM_TR_ISO_MASK) >>
3030*4882a593Smuzhiyun 						SROM8_FEM_TR_ISO_SHIFT);
3031*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pdetrange5g, (fem &
3032*4882a593Smuzhiyun 						SROM8_FEM_PDET_RANGE_MASK) >>
3033*4882a593Smuzhiyun 						SROM8_FEM_PDET_RANGE_SHIFT);
3034*4882a593Smuzhiyun 					varbuf_append(&b, vstr_extpagain5g, (fem &
3035*4882a593Smuzhiyun 						SROM8_FEM_EXTPA_GAIN_MASK) >>
3036*4882a593Smuzhiyun 						SROM8_FEM_EXTPA_GAIN_SHIFT);
3037*4882a593Smuzhiyun 					varbuf_append(&b, vstr_tssipos5g, (fem &
3038*4882a593Smuzhiyun 						SROM8_FEM_TSSIPOS_MASK) >>
3039*4882a593Smuzhiyun 						SROM8_FEM_TSSIPOS_SHIFT);
3040*4882a593Smuzhiyun 					break;
3041*4882a593Smuzhiyun 				}
3042*4882a593Smuzhiyun 
3043*4882a593Smuzhiyun 				case HNBU_PAPARMS_C0:
3044*4882a593Smuzhiyun 					varbuf_append(&b, vstr_maxp2ga, 0, cis[i + 1]);
3045*4882a593Smuzhiyun 					varbuf_append(&b, vstr_itt2ga0, cis[i + 2]);
3046*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pa, 2, 0, 0,
3047*4882a593Smuzhiyun 						(cis[i + 4] << 8) + cis[i + 3]);
3048*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pa, 2, 1, 0,
3049*4882a593Smuzhiyun 						(cis[i + 6] << 8) + cis[i + 5]);
3050*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pa, 2, 2, 0,
3051*4882a593Smuzhiyun 						(cis[i + 8] << 8) + cis[i + 7]);
3052*4882a593Smuzhiyun 					if (tlen < 31) break;
3053*4882a593Smuzhiyun 
3054*4882a593Smuzhiyun 					varbuf_append(&b, vstr_maxp5ga0, cis[i + 9]);
3055*4882a593Smuzhiyun 					varbuf_append(&b, vstr_itt5ga0, cis[i + 10]);
3056*4882a593Smuzhiyun 					varbuf_append(&b, vstr_maxp5gha0, cis[i + 11]);
3057*4882a593Smuzhiyun 					varbuf_append(&b, vstr_maxp5gla0, cis[i + 12]);
3058*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pa, 5, 0, 0,
3059*4882a593Smuzhiyun 						(cis[i + 14] << 8) + cis[i + 13]);
3060*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pa, 5, 1, 0,
3061*4882a593Smuzhiyun 						(cis[i + 16] << 8) + cis[i + 15]);
3062*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pa, 5, 2, 0,
3063*4882a593Smuzhiyun 						(cis[i + 18] << 8) + cis[i + 17]);
3064*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pahl, 5, 'l', 0, 0,
3065*4882a593Smuzhiyun 						(cis[i + 20] << 8) + cis[i + 19]);
3066*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pahl, 5, 'l', 1, 0,
3067*4882a593Smuzhiyun 						(cis[i + 22] << 8) + cis[i + 21]);
3068*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pahl, 5, 'l', 2, 0,
3069*4882a593Smuzhiyun 						(cis[i + 24] << 8) + cis[i + 23]);
3070*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pahl, 5, 'h', 0, 0,
3071*4882a593Smuzhiyun 						(cis[i + 26] << 8) + cis[i + 25]);
3072*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pahl, 5, 'h', 1, 0,
3073*4882a593Smuzhiyun 						(cis[i + 28] << 8) + cis[i + 27]);
3074*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pahl, 5, 'h', 2, 0,
3075*4882a593Smuzhiyun 						(cis[i + 30] << 8) + cis[i + 29]);
3076*4882a593Smuzhiyun 					break;
3077*4882a593Smuzhiyun 
3078*4882a593Smuzhiyun 				case HNBU_PAPARMS_C1:
3079*4882a593Smuzhiyun 					varbuf_append(&b, vstr_maxp2ga, 1, cis[i + 1]);
3080*4882a593Smuzhiyun 					varbuf_append(&b, vstr_itt2ga1, cis[i + 2]);
3081*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pa, 2, 0, 1,
3082*4882a593Smuzhiyun 						(cis[i + 4] << 8) + cis[i + 3]);
3083*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pa, 2, 1, 1,
3084*4882a593Smuzhiyun 						(cis[i + 6] << 8) + cis[i + 5]);
3085*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pa, 2, 2, 1,
3086*4882a593Smuzhiyun 						(cis[i + 8] << 8) + cis[i + 7]);
3087*4882a593Smuzhiyun 					if (tlen < 31) break;
3088*4882a593Smuzhiyun 
3089*4882a593Smuzhiyun 					varbuf_append(&b, vstr_maxp5ga1, cis[i + 9]);
3090*4882a593Smuzhiyun 					varbuf_append(&b, vstr_itt5ga1, cis[i + 10]);
3091*4882a593Smuzhiyun 					varbuf_append(&b, vstr_maxp5gha1, cis[i + 11]);
3092*4882a593Smuzhiyun 					varbuf_append(&b, vstr_maxp5gla1, cis[i + 12]);
3093*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pa, 5, 0, 1,
3094*4882a593Smuzhiyun 						(cis[i + 14] << 8) + cis[i + 13]);
3095*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pa, 5, 1, 1,
3096*4882a593Smuzhiyun 						(cis[i + 16] << 8) + cis[i + 15]);
3097*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pa, 5, 2, 1,
3098*4882a593Smuzhiyun 						(cis[i + 18] << 8) + cis[i + 17]);
3099*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pahl, 5, 'l', 0, 1,
3100*4882a593Smuzhiyun 						(cis[i + 20] << 8) + cis[i + 19]);
3101*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pahl, 5, 'l', 1, 1,
3102*4882a593Smuzhiyun 						(cis[i + 22] << 8) + cis[i + 21]);
3103*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pahl, 5, 'l', 2, 1,
3104*4882a593Smuzhiyun 						(cis[i + 24] << 8) + cis[i + 23]);
3105*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pahl, 5, 'h', 0, 1,
3106*4882a593Smuzhiyun 						(cis[i + 26] << 8) + cis[i + 25]);
3107*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pahl, 5, 'h', 1, 1,
3108*4882a593Smuzhiyun 						(cis[i + 28] << 8) + cis[i + 27]);
3109*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pahl, 5, 'h', 2, 1,
3110*4882a593Smuzhiyun 						(cis[i + 30] << 8) + cis[i + 29]);
3111*4882a593Smuzhiyun 					break;
3112*4882a593Smuzhiyun 
3113*4882a593Smuzhiyun 				case HNBU_PO_CCKOFDM:
3114*4882a593Smuzhiyun 					varbuf_append(&b, vstr_cck2gpo,
3115*4882a593Smuzhiyun 						(cis[i + 2] << 8) + cis[i + 1]);
3116*4882a593Smuzhiyun 					varbuf_append(&b, vstr_ofdm2gpo,
3117*4882a593Smuzhiyun 						(cis[i + 6] << 24) + (cis[i + 5] << 16) +
3118*4882a593Smuzhiyun 						(cis[i + 4] << 8) + cis[i + 3]);
3119*4882a593Smuzhiyun 					if (tlen < 19) break;
3120*4882a593Smuzhiyun 
3121*4882a593Smuzhiyun 					varbuf_append(&b, vstr_ofdm5gpo,
3122*4882a593Smuzhiyun 						(cis[i + 10] << 24) + (cis[i + 9] << 16) +
3123*4882a593Smuzhiyun 						(cis[i + 8] << 8) + cis[i + 7]);
3124*4882a593Smuzhiyun 					varbuf_append(&b, vstr_ofdm5glpo,
3125*4882a593Smuzhiyun 						(cis[i + 14] << 24) + (cis[i + 13] << 16) +
3126*4882a593Smuzhiyun 						(cis[i + 12] << 8) + cis[i + 11]);
3127*4882a593Smuzhiyun 					varbuf_append(&b, vstr_ofdm5ghpo,
3128*4882a593Smuzhiyun 						(cis[i + 18] << 24) + (cis[i + 17] << 16) +
3129*4882a593Smuzhiyun 						(cis[i + 16] << 8) + cis[i + 15]);
3130*4882a593Smuzhiyun 					break;
3131*4882a593Smuzhiyun 
3132*4882a593Smuzhiyun 				case HNBU_PO_MCS2G:
3133*4882a593Smuzhiyun 					for (j = 0; j <= (tlen/2); j++) {
3134*4882a593Smuzhiyun 						varbuf_append(&b, vstr_mcspo, 2, j,
3135*4882a593Smuzhiyun 							(cis[i + 2 + 2*j] << 8) + cis[i + 1 + 2*j]);
3136*4882a593Smuzhiyun 					}
3137*4882a593Smuzhiyun 					break;
3138*4882a593Smuzhiyun 
3139*4882a593Smuzhiyun 				case HNBU_PO_MCS5GM:
3140*4882a593Smuzhiyun 					for (j = 0; j <= (tlen/2); j++) {
3141*4882a593Smuzhiyun 						varbuf_append(&b, vstr_mcspo, 5, j,
3142*4882a593Smuzhiyun 							(cis[i + 2 + 2*j] << 8) + cis[i + 1 + 2*j]);
3143*4882a593Smuzhiyun 					}
3144*4882a593Smuzhiyun 					break;
3145*4882a593Smuzhiyun 
3146*4882a593Smuzhiyun 				case HNBU_PO_MCS5GLH:
3147*4882a593Smuzhiyun 					for (j = 0; j <= (tlen/4); j++) {
3148*4882a593Smuzhiyun 						varbuf_append(&b, vstr_mcspohl, 5, 'l', j,
3149*4882a593Smuzhiyun 							(cis[i + 2 + 2*j] << 8) + cis[i + 1 + 2*j]);
3150*4882a593Smuzhiyun 					}
3151*4882a593Smuzhiyun 
3152*4882a593Smuzhiyun 					for (j = 0; j <= (tlen/4); j++) {
3153*4882a593Smuzhiyun 						varbuf_append(&b, vstr_mcspohl, 5, 'h', j,
3154*4882a593Smuzhiyun 							(cis[i + ((tlen/2)+2) + 2*j] << 8) +
3155*4882a593Smuzhiyun 							cis[i + ((tlen/2)+1) + 2*j]);
3156*4882a593Smuzhiyun 					}
3157*4882a593Smuzhiyun 
3158*4882a593Smuzhiyun 					break;
3159*4882a593Smuzhiyun 
3160*4882a593Smuzhiyun 				case HNBU_PO_CDD:
3161*4882a593Smuzhiyun 					varbuf_append(&b, vstr_cddpo,
3162*4882a593Smuzhiyun 					              (cis[i + 2] << 8) + cis[i + 1]);
3163*4882a593Smuzhiyun 					break;
3164*4882a593Smuzhiyun 
3165*4882a593Smuzhiyun 				case HNBU_PO_STBC:
3166*4882a593Smuzhiyun 					varbuf_append(&b, vstr_stbcpo,
3167*4882a593Smuzhiyun 					              (cis[i + 2] << 8) + cis[i + 1]);
3168*4882a593Smuzhiyun 					break;
3169*4882a593Smuzhiyun 
3170*4882a593Smuzhiyun 				case HNBU_PO_40M:
3171*4882a593Smuzhiyun 					varbuf_append(&b, vstr_bw40po,
3172*4882a593Smuzhiyun 					              (cis[i + 2] << 8) + cis[i + 1]);
3173*4882a593Smuzhiyun 					break;
3174*4882a593Smuzhiyun 
3175*4882a593Smuzhiyun 				case HNBU_PO_40MDUP:
3176*4882a593Smuzhiyun 					varbuf_append(&b, vstr_bwduppo,
3177*4882a593Smuzhiyun 					              (cis[i + 2] << 8) + cis[i + 1]);
3178*4882a593Smuzhiyun 					break;
3179*4882a593Smuzhiyun 
3180*4882a593Smuzhiyun 				case HNBU_OFDMPO5G:
3181*4882a593Smuzhiyun 					varbuf_append(&b, vstr_ofdm5gpo,
3182*4882a593Smuzhiyun 						(cis[i + 4] << 24) + (cis[i + 3] << 16) +
3183*4882a593Smuzhiyun 						(cis[i + 2] << 8) + cis[i + 1]);
3184*4882a593Smuzhiyun 					varbuf_append(&b, vstr_ofdm5glpo,
3185*4882a593Smuzhiyun 						(cis[i + 8] << 24) + (cis[i + 7] << 16) +
3186*4882a593Smuzhiyun 						(cis[i + 6] << 8) + cis[i + 5]);
3187*4882a593Smuzhiyun 					varbuf_append(&b, vstr_ofdm5ghpo,
3188*4882a593Smuzhiyun 						(cis[i + 12] << 24) + (cis[i + 11] << 16) +
3189*4882a593Smuzhiyun 						(cis[i + 10] << 8) + cis[i + 9]);
3190*4882a593Smuzhiyun 					break;
3191*4882a593Smuzhiyun 				/* Power per rate for SROM V9 */
3192*4882a593Smuzhiyun 				case HNBU_CCKBW202GPO:
3193*4882a593Smuzhiyun 					varbuf_append(&b, vstr_cckbw202gpo[0],
3194*4882a593Smuzhiyun 						((cis[i + 2] << 8) + cis[i + 1]));
3195*4882a593Smuzhiyun 					if (tlen > 4)
3196*4882a593Smuzhiyun 						varbuf_append(&b, vstr_cckbw202gpo[1],
3197*4882a593Smuzhiyun 							((cis[i + 4] << 8) + cis[i + 3]));
3198*4882a593Smuzhiyun 					if (tlen > 6)
3199*4882a593Smuzhiyun 						varbuf_append(&b, vstr_cckbw202gpo[2],
3200*4882a593Smuzhiyun 							((cis[i + 6] << 8) + cis[i + 5]));
3201*4882a593Smuzhiyun 					break;
3202*4882a593Smuzhiyun 
3203*4882a593Smuzhiyun 				case HNBU_LEGOFDMBW202GPO:
3204*4882a593Smuzhiyun 					varbuf_append(&b, vstr_legofdmbw202gpo[0],
3205*4882a593Smuzhiyun 						((cis[i + 4] << 24) + (cis[i + 3] << 16) +
3206*4882a593Smuzhiyun 						(cis[i + 2] << 8) + cis[i + 1]));
3207*4882a593Smuzhiyun 					if (tlen > 6)  {
3208*4882a593Smuzhiyun 						varbuf_append(&b, vstr_legofdmbw202gpo[1],
3209*4882a593Smuzhiyun 							((cis[i + 8] << 24) + (cis[i + 7] << 16) +
3210*4882a593Smuzhiyun 							(cis[i + 6] << 8) + cis[i + 5]));
3211*4882a593Smuzhiyun 					}
3212*4882a593Smuzhiyun 					break;
3213*4882a593Smuzhiyun 
3214*4882a593Smuzhiyun 				case HNBU_LEGOFDMBW205GPO:
3215*4882a593Smuzhiyun 					for (j = 0; j < 6; j++) {
3216*4882a593Smuzhiyun 						if (tlen < (2 + 4 * j))
3217*4882a593Smuzhiyun 							break;
3218*4882a593Smuzhiyun 						varbuf_append(&b, vstr_legofdmbw205gpo[j],
3219*4882a593Smuzhiyun 							((cis[4 * j + i + 4] << 24)
3220*4882a593Smuzhiyun 							+ (cis[4 * j + i + 3] << 16)
3221*4882a593Smuzhiyun 							+ (cis[4 * j + i + 2] << 8)
3222*4882a593Smuzhiyun 							+ cis[4 * j + i + 1]));
3223*4882a593Smuzhiyun 					}
3224*4882a593Smuzhiyun 					break;
3225*4882a593Smuzhiyun 
3226*4882a593Smuzhiyun 				case HNBU_MCS2GPO:
3227*4882a593Smuzhiyun 					for (j = 0; j < 4; j++) {
3228*4882a593Smuzhiyun 						if (tlen < (2 + 4 * j))
3229*4882a593Smuzhiyun 							break;
3230*4882a593Smuzhiyun 						varbuf_append(&b, vstr_mcs2gpo[j],
3231*4882a593Smuzhiyun 							((cis[4 * j + i + 4] << 24)
3232*4882a593Smuzhiyun 							+ (cis[4 * j + i + 3] << 16)
3233*4882a593Smuzhiyun 							+ (cis[4 * j + i + 2] << 8)
3234*4882a593Smuzhiyun 							+ cis[4 * j + i + 1]));
3235*4882a593Smuzhiyun 					}
3236*4882a593Smuzhiyun 					break;
3237*4882a593Smuzhiyun 
3238*4882a593Smuzhiyun 				case HNBU_MCS5GLPO:
3239*4882a593Smuzhiyun 					for (j = 0; j < 3; j++) {
3240*4882a593Smuzhiyun 						if (tlen < (2 + 4 * j))
3241*4882a593Smuzhiyun 							break;
3242*4882a593Smuzhiyun 						varbuf_append(&b, vstr_mcs5glpo[j],
3243*4882a593Smuzhiyun 							((cis[4 * j + i + 4] << 24)
3244*4882a593Smuzhiyun 							+ (cis[4 * j + i + 3] << 16)
3245*4882a593Smuzhiyun 							+ (cis[4 * j + i + 2] << 8)
3246*4882a593Smuzhiyun 							+ cis[4 * j + i + 1]));
3247*4882a593Smuzhiyun 					}
3248*4882a593Smuzhiyun 					break;
3249*4882a593Smuzhiyun 
3250*4882a593Smuzhiyun 				case HNBU_MCS5GMPO:
3251*4882a593Smuzhiyun 					for (j = 0; j < 3; j++) {
3252*4882a593Smuzhiyun 						if (tlen < (2 + 4 * j))
3253*4882a593Smuzhiyun 							break;
3254*4882a593Smuzhiyun 						varbuf_append(&b, vstr_mcs5gmpo[j],
3255*4882a593Smuzhiyun 							((cis[4 * j + i + 4] << 24)
3256*4882a593Smuzhiyun 							+ (cis[4 * j + i + 3] << 16)
3257*4882a593Smuzhiyun 							+ (cis[4 * j + i + 2] << 8)
3258*4882a593Smuzhiyun 							+ cis[4 * j + i + 1]));
3259*4882a593Smuzhiyun 					}
3260*4882a593Smuzhiyun 					break;
3261*4882a593Smuzhiyun 
3262*4882a593Smuzhiyun 				case HNBU_MCS5GHPO:
3263*4882a593Smuzhiyun 					for (j = 0; j < 3; j++) {
3264*4882a593Smuzhiyun 						if (tlen < (2 + 4 * j))
3265*4882a593Smuzhiyun 							break;
3266*4882a593Smuzhiyun 						varbuf_append(&b, vstr_mcs5ghpo[j],
3267*4882a593Smuzhiyun 							((cis[4 * j + i + 4] << 24)
3268*4882a593Smuzhiyun 							+ (cis[4 * j + i + 3] << 16)
3269*4882a593Smuzhiyun 							+ (cis[4 * j + i + 2] << 8)
3270*4882a593Smuzhiyun 							+ cis[4 * j + i + 1]));
3271*4882a593Smuzhiyun 					}
3272*4882a593Smuzhiyun 					break;
3273*4882a593Smuzhiyun 
3274*4882a593Smuzhiyun 				case HNBU_MCS32PO:
3275*4882a593Smuzhiyun 					varbuf_append(&b, vstr_mcs32po,
3276*4882a593Smuzhiyun 						(cis[i + 2] << 8) + cis[i + 1]);
3277*4882a593Smuzhiyun 					break;
3278*4882a593Smuzhiyun 
3279*4882a593Smuzhiyun 				case HNBU_LEG40DUPPO:
3280*4882a593Smuzhiyun 					varbuf_append(&b, vstr_legofdm40duppo,
3281*4882a593Smuzhiyun 						(cis[i + 2] << 8) + cis[i + 1]);
3282*4882a593Smuzhiyun 					break;
3283*4882a593Smuzhiyun 
3284*4882a593Smuzhiyun 				case HNBU_CUSTOM1:
3285*4882a593Smuzhiyun 					varbuf_append(&b, vstr_custom, 1, ((cis[i + 4] << 24) +
3286*4882a593Smuzhiyun 						(cis[i + 3] << 16) + (cis[i + 2] << 8) +
3287*4882a593Smuzhiyun 						cis[i + 1]));
3288*4882a593Smuzhiyun 					break;
3289*4882a593Smuzhiyun 
3290*4882a593Smuzhiyun #if defined(BCMSDIO) || defined(BCMCCISSR3)
3291*4882a593Smuzhiyun 				case HNBU_SROM3SWRGN:
3292*4882a593Smuzhiyun 					if (tlen >= 73) {
3293*4882a593Smuzhiyun 						uint16 srom[35];
3294*4882a593Smuzhiyun 						uint8 srev = cis[i + 1 + 70];
3295*4882a593Smuzhiyun 						ASSERT(srev == 3);
3296*4882a593Smuzhiyun 						/* make tuple value 16-bit aligned and parse it */
3297*4882a593Smuzhiyun 						bcopy(&cis[i + 1], srom, sizeof(srom));
3298*4882a593Smuzhiyun 						_initvars_srom_pci(srev, srom, SROM3_SWRGN_OFF, &b);
3299*4882a593Smuzhiyun 						/* 2.4G antenna gain is included in SROM */
3300*4882a593Smuzhiyun 						ag_init = TRUE;
3301*4882a593Smuzhiyun 						/* Ethernet MAC address is included in SROM */
3302*4882a593Smuzhiyun 						eabuf[0] = 0;
3303*4882a593Smuzhiyun 						/* why boardnum is not -1? */
3304*4882a593Smuzhiyun 						boardnum = -1;
3305*4882a593Smuzhiyun 					}
3306*4882a593Smuzhiyun 					/* create extra variables */
3307*4882a593Smuzhiyun 					if (tlen >= 75)
3308*4882a593Smuzhiyun 						varbuf_append(&b, vstr_vendid,
3309*4882a593Smuzhiyun 						              (cis[i + 1 + 73] << 8) +
3310*4882a593Smuzhiyun 						              cis[i + 1 + 72]);
3311*4882a593Smuzhiyun 					if (tlen >= 77)
3312*4882a593Smuzhiyun 						varbuf_append(&b, vstr_devid,
3313*4882a593Smuzhiyun 						              (cis[i + 1 + 75] << 8) +
3314*4882a593Smuzhiyun 						              cis[i + 1 + 74]);
3315*4882a593Smuzhiyun 					if (tlen >= 79)
3316*4882a593Smuzhiyun 						varbuf_append(&b, vstr_xtalfreq,
3317*4882a593Smuzhiyun 						              (cis[i + 1 + 77] << 8) +
3318*4882a593Smuzhiyun 						              cis[i + 1 + 76]);
3319*4882a593Smuzhiyun 					break;
3320*4882a593Smuzhiyun #endif	/* BCMSDIO || BCMCCISSR3 */
3321*4882a593Smuzhiyun 
3322*4882a593Smuzhiyun 				case HNBU_CCKFILTTYPE:
3323*4882a593Smuzhiyun 					varbuf_append(&b, vstr_cckdigfilttype,
3324*4882a593Smuzhiyun 						(cis[i + 1]));
3325*4882a593Smuzhiyun 					break;
3326*4882a593Smuzhiyun 
3327*4882a593Smuzhiyun 				case HNBU_TEMPTHRESH:
3328*4882a593Smuzhiyun 					varbuf_append(&b, vstr_tempthresh,
3329*4882a593Smuzhiyun 						(cis[i + 1]));
3330*4882a593Smuzhiyun 					/* period in msb nibble */
3331*4882a593Smuzhiyun 					varbuf_append(&b, vstr_temps_period,
3332*4882a593Smuzhiyun 						(cis[i + 2] & SROM11_TEMPS_PERIOD_MASK) >>
3333*4882a593Smuzhiyun 						SROM11_TEMPS_PERIOD_SHIFT);
3334*4882a593Smuzhiyun 					/* hysterisis in lsb nibble */
3335*4882a593Smuzhiyun 					varbuf_append(&b, vstr_temps_hysteresis,
3336*4882a593Smuzhiyun 						(cis[i + 2] & SROM11_TEMPS_HYSTERESIS_MASK) >>
3337*4882a593Smuzhiyun 						SROM11_TEMPS_HYSTERESIS_SHIFT);
3338*4882a593Smuzhiyun 					if (tlen >= 4) {
3339*4882a593Smuzhiyun 						varbuf_append(&b, vstr_tempoffset,
3340*4882a593Smuzhiyun 						(cis[i + 3]));
3341*4882a593Smuzhiyun 						varbuf_append(&b, vstr_tempsense_slope,
3342*4882a593Smuzhiyun 						(cis[i + 4]));
3343*4882a593Smuzhiyun 						varbuf_append(&b, vstr_temp_corrx,
3344*4882a593Smuzhiyun 						(cis[i + 5] & SROM11_TEMPCORRX_MASK) >>
3345*4882a593Smuzhiyun 						SROM11_TEMPCORRX_SHIFT);
3346*4882a593Smuzhiyun 						varbuf_append(&b, vstr_tempsense_option,
3347*4882a593Smuzhiyun 						(cis[i + 5] & SROM11_TEMPSENSE_OPTION_MASK) >>
3348*4882a593Smuzhiyun 						SROM11_TEMPSENSE_OPTION_SHIFT);
3349*4882a593Smuzhiyun 						varbuf_append(&b, vstr_phycal_tempdelta,
3350*4882a593Smuzhiyun 						(cis[i + 6]));
3351*4882a593Smuzhiyun 					}
3352*4882a593Smuzhiyun 					break;
3353*4882a593Smuzhiyun 
3354*4882a593Smuzhiyun 				case HNBU_FEM_CFG: {
3355*4882a593Smuzhiyun 					/* fem_cfg1 */
3356*4882a593Smuzhiyun 					uint16 fem_cfg = (cis[i + 2] << 8) + cis[i + 1];
3357*4882a593Smuzhiyun 					varbuf_append(&b, vstr_femctrl,
3358*4882a593Smuzhiyun 						(fem_cfg & SROM11_FEMCTRL_MASK) >>
3359*4882a593Smuzhiyun 						SROM11_FEMCTRL_SHIFT);
3360*4882a593Smuzhiyun 					varbuf_append(&b, vstr_papdcap, 2,
3361*4882a593Smuzhiyun 						(fem_cfg & SROM11_PAPDCAP_MASK) >>
3362*4882a593Smuzhiyun 						SROM11_PAPDCAP_SHIFT);
3363*4882a593Smuzhiyun 					varbuf_append(&b, vstr_tworangetssi, 2,
3364*4882a593Smuzhiyun 						(fem_cfg & SROM11_TWORANGETSSI_MASK) >>
3365*4882a593Smuzhiyun 						SROM11_TWORANGETSSI_SHIFT);
3366*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pdgaing, 2,
3367*4882a593Smuzhiyun 						(fem_cfg & SROM11_PDGAIN_MASK) >>
3368*4882a593Smuzhiyun 						SROM11_PDGAIN_SHIFT);
3369*4882a593Smuzhiyun 					varbuf_append(&b, vstr_epagaing, 2,
3370*4882a593Smuzhiyun 						(fem_cfg & SROM11_EPAGAIN_MASK) >>
3371*4882a593Smuzhiyun 						SROM11_EPAGAIN_SHIFT);
3372*4882a593Smuzhiyun 					varbuf_append(&b, vstr_tssiposslopeg, 2,
3373*4882a593Smuzhiyun 						(fem_cfg & SROM11_TSSIPOSSLOPE_MASK) >>
3374*4882a593Smuzhiyun 						SROM11_TSSIPOSSLOPE_SHIFT);
3375*4882a593Smuzhiyun 					/* fem_cfg2 */
3376*4882a593Smuzhiyun 					fem_cfg = (cis[i + 4] << 8) + cis[i + 3];
3377*4882a593Smuzhiyun 					varbuf_append(&b, vstr_gainctrlsph,
3378*4882a593Smuzhiyun 						(fem_cfg & SROM11_GAINCTRLSPH_MASK) >>
3379*4882a593Smuzhiyun 						SROM11_GAINCTRLSPH_SHIFT);
3380*4882a593Smuzhiyun 					varbuf_append(&b, vstr_papdcap, 5,
3381*4882a593Smuzhiyun 						(fem_cfg & SROM11_PAPDCAP_MASK) >>
3382*4882a593Smuzhiyun 						SROM11_PAPDCAP_SHIFT);
3383*4882a593Smuzhiyun 					varbuf_append(&b, vstr_tworangetssi, 5,
3384*4882a593Smuzhiyun 						(fem_cfg & SROM11_TWORANGETSSI_MASK) >>
3385*4882a593Smuzhiyun 						SROM11_TWORANGETSSI_SHIFT);
3386*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pdgaing, 5,
3387*4882a593Smuzhiyun 						(fem_cfg & SROM11_PDGAIN_MASK) >>
3388*4882a593Smuzhiyun 						SROM11_PDGAIN_SHIFT);
3389*4882a593Smuzhiyun 					varbuf_append(&b, vstr_epagaing, 5,
3390*4882a593Smuzhiyun 						(fem_cfg & SROM11_EPAGAIN_MASK) >>
3391*4882a593Smuzhiyun 						SROM11_EPAGAIN_SHIFT);
3392*4882a593Smuzhiyun 					varbuf_append(&b, vstr_tssiposslopeg, 5,
3393*4882a593Smuzhiyun 						(fem_cfg & SROM11_TSSIPOSSLOPE_MASK) >>
3394*4882a593Smuzhiyun 						SROM11_TSSIPOSSLOPE_SHIFT);
3395*4882a593Smuzhiyun 					break;
3396*4882a593Smuzhiyun 				}
3397*4882a593Smuzhiyun 
3398*4882a593Smuzhiyun 				case HNBU_ACPA_C0: {
3399*4882a593Smuzhiyun 					const int a = 0;
3400*4882a593Smuzhiyun 
3401*4882a593Smuzhiyun #ifndef OTP_SKIP_MAXP_PAPARAMS
3402*4882a593Smuzhiyun 					varbuf_append(&b, vstr_subband5gver,
3403*4882a593Smuzhiyun 					              (cis[i + 2] << 8) + cis[i + 1]);
3404*4882a593Smuzhiyun 					/* maxp2g */
3405*4882a593Smuzhiyun 					/* Decoupling this touple to program from NVRAM */
3406*4882a593Smuzhiyun 					varbuf_append(&b, vstr_maxp2ga, a,
3407*4882a593Smuzhiyun 						(cis[i + 4] << 8) + cis[i + 3]);
3408*4882a593Smuzhiyun #endif /* OTP_SKIP_MAXP_PAPARAMS */
3409*4882a593Smuzhiyun 					/* pa2g */
3410*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pa2ga, a,
3411*4882a593Smuzhiyun 						(cis[i + 6] << 8) + cis[i + 5],
3412*4882a593Smuzhiyun 						(cis[i + 8] << 8) + cis[i + 7],
3413*4882a593Smuzhiyun 						(cis[i + 10] << 8) + cis[i + 9]);
3414*4882a593Smuzhiyun #ifndef OTP_SKIP_MAXP_PAPARAMS
3415*4882a593Smuzhiyun 					/* maxp5g */
3416*4882a593Smuzhiyun 					varbuf_append(&b, vstr_maxp5ga, a,
3417*4882a593Smuzhiyun 						cis[i + 11],
3418*4882a593Smuzhiyun 						cis[i + 12],
3419*4882a593Smuzhiyun 						cis[i + 13],
3420*4882a593Smuzhiyun 						cis[i + 14]);
3421*4882a593Smuzhiyun #endif /* OTP_SKIP_MAXP_PAPARAMS */
3422*4882a593Smuzhiyun 					/* pa5g */
3423*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pa5ga, a,
3424*4882a593Smuzhiyun 						(cis[i + 16] << 8) + cis[i + 15],
3425*4882a593Smuzhiyun 						(cis[i + 18] << 8) + cis[i + 17],
3426*4882a593Smuzhiyun 						(cis[i + 20] << 8) + cis[i + 19],
3427*4882a593Smuzhiyun 						(cis[i + 22] << 8) + cis[i + 21],
3428*4882a593Smuzhiyun 						(cis[i + 24] << 8) + cis[i + 23],
3429*4882a593Smuzhiyun 						(cis[i + 26] << 8) + cis[i + 25],
3430*4882a593Smuzhiyun 						(cis[i + 28] << 8) + cis[i + 27],
3431*4882a593Smuzhiyun 						(cis[i + 30] << 8) + cis[i + 29],
3432*4882a593Smuzhiyun 						(cis[i + 32] << 8) + cis[i + 31],
3433*4882a593Smuzhiyun 						(cis[i + 34] << 8) + cis[i + 33],
3434*4882a593Smuzhiyun 						(cis[i + 36] << 8) + cis[i + 35],
3435*4882a593Smuzhiyun 						(cis[i + 38] << 8) + cis[i + 37]);
3436*4882a593Smuzhiyun 					break;
3437*4882a593Smuzhiyun 				}
3438*4882a593Smuzhiyun 
3439*4882a593Smuzhiyun 				case HNBU_ACPA_C1: {
3440*4882a593Smuzhiyun 					const int a = 1;
3441*4882a593Smuzhiyun 
3442*4882a593Smuzhiyun #ifndef OTP_SKIP_MAXP_PAPARAMS
3443*4882a593Smuzhiyun 					/* maxp2g */
3444*4882a593Smuzhiyun 					/* Decoupling this touple to program from NVRAM */
3445*4882a593Smuzhiyun 					varbuf_append(&b, vstr_maxp2ga, a,
3446*4882a593Smuzhiyun 						(cis[i + 2] << 8) + cis[i + 1]);
3447*4882a593Smuzhiyun #endif /* OTP_SKIP_MAXP_PAPARAMS */
3448*4882a593Smuzhiyun 					/* pa2g */
3449*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pa2ga, a,
3450*4882a593Smuzhiyun 						(cis[i + 4] << 8) + cis[i + 3],
3451*4882a593Smuzhiyun 						(cis[i + 6] << 8) + cis[i + 5],
3452*4882a593Smuzhiyun 						(cis[i + 8] << 8) + cis[i + 7]);
3453*4882a593Smuzhiyun #ifndef OTP_SKIP_MAXP_PAPARAMS
3454*4882a593Smuzhiyun 					/* maxp5g */
3455*4882a593Smuzhiyun 					varbuf_append(&b, vstr_maxp5ga, a,
3456*4882a593Smuzhiyun 						cis[i + 9],
3457*4882a593Smuzhiyun 						cis[i + 10],
3458*4882a593Smuzhiyun 						cis[i + 11],
3459*4882a593Smuzhiyun 						cis[i + 12]);
3460*4882a593Smuzhiyun #endif /* OTP_SKIP_MAXP_PAPARAMS */
3461*4882a593Smuzhiyun 					/* pa5g */
3462*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pa5ga, a,
3463*4882a593Smuzhiyun 						(cis[i + 14] << 8) + cis[i + 13],
3464*4882a593Smuzhiyun 						(cis[i + 16] << 8) + cis[i + 15],
3465*4882a593Smuzhiyun 						(cis[i + 18] << 8) + cis[i + 17],
3466*4882a593Smuzhiyun 						(cis[i + 20] << 8) + cis[i + 19],
3467*4882a593Smuzhiyun 						(cis[i + 22] << 8) + cis[i + 21],
3468*4882a593Smuzhiyun 						(cis[i + 24] << 8) + cis[i + 23],
3469*4882a593Smuzhiyun 						(cis[i + 26] << 8) + cis[i + 25],
3470*4882a593Smuzhiyun 						(cis[i + 28] << 8) + cis[i + 27],
3471*4882a593Smuzhiyun 						(cis[i + 30] << 8) + cis[i + 29],
3472*4882a593Smuzhiyun 						(cis[i + 32] << 8) + cis[i + 31],
3473*4882a593Smuzhiyun 						(cis[i + 34] << 8) + cis[i + 33],
3474*4882a593Smuzhiyun 						(cis[i + 36] << 8) + cis[i + 35]);
3475*4882a593Smuzhiyun 					break;
3476*4882a593Smuzhiyun 				}
3477*4882a593Smuzhiyun 
3478*4882a593Smuzhiyun 				case HNBU_ACPA_C2: {
3479*4882a593Smuzhiyun 					const int a = 2;
3480*4882a593Smuzhiyun 
3481*4882a593Smuzhiyun #ifndef OTP_SKIP_MAXP_PAPARAMS
3482*4882a593Smuzhiyun 					/* maxp2g */
3483*4882a593Smuzhiyun 					/* Decoupling this touple to program from NVRAM */
3484*4882a593Smuzhiyun 					varbuf_append(&b, vstr_maxp2ga, a,
3485*4882a593Smuzhiyun 						(cis[i + 2] << 8) + cis[i + 1]);
3486*4882a593Smuzhiyun #endif /* OTP_SKIP_MAXP_PAPARAMS */
3487*4882a593Smuzhiyun 					/* pa2g */
3488*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pa2ga, a,
3489*4882a593Smuzhiyun 						(cis[i + 4] << 8) + cis[i + 3],
3490*4882a593Smuzhiyun 						(cis[i + 6] << 8) + cis[i + 5],
3491*4882a593Smuzhiyun 						(cis[i + 8] << 8) + cis[i + 7]);
3492*4882a593Smuzhiyun #ifndef OTP_SKIP_MAXP_PAPARAMS
3493*4882a593Smuzhiyun 					/* maxp5g */
3494*4882a593Smuzhiyun 					varbuf_append(&b, vstr_maxp5ga, a,
3495*4882a593Smuzhiyun 						cis[i + 9],
3496*4882a593Smuzhiyun 						cis[i + 10],
3497*4882a593Smuzhiyun 						cis[i + 11],
3498*4882a593Smuzhiyun 						cis[i + 12]);
3499*4882a593Smuzhiyun #endif /* OTP_SKIP_MAXP_PAPARAMS */
3500*4882a593Smuzhiyun 					/* pa5g */
3501*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pa5ga, a,
3502*4882a593Smuzhiyun 						(cis[i + 14] << 8) + cis[i + 13],
3503*4882a593Smuzhiyun 						(cis[i + 16] << 8) + cis[i + 15],
3504*4882a593Smuzhiyun 						(cis[i + 18] << 8) + cis[i + 17],
3505*4882a593Smuzhiyun 						(cis[i + 20] << 8) + cis[i + 19],
3506*4882a593Smuzhiyun 						(cis[i + 22] << 8) + cis[i + 21],
3507*4882a593Smuzhiyun 						(cis[i + 24] << 8) + cis[i + 23],
3508*4882a593Smuzhiyun 						(cis[i + 26] << 8) + cis[i + 25],
3509*4882a593Smuzhiyun 						(cis[i + 28] << 8) + cis[i + 27],
3510*4882a593Smuzhiyun 						(cis[i + 30] << 8) + cis[i + 29],
3511*4882a593Smuzhiyun 						(cis[i + 32] << 8) + cis[i + 31],
3512*4882a593Smuzhiyun 						(cis[i + 34] << 8) + cis[i + 33],
3513*4882a593Smuzhiyun 						(cis[i + 36] << 8) + cis[i + 35]);
3514*4882a593Smuzhiyun 					break;
3515*4882a593Smuzhiyun 				}
3516*4882a593Smuzhiyun 
3517*4882a593Smuzhiyun 				case HNBU_MEAS_PWR:
3518*4882a593Smuzhiyun 					varbuf_append(&b, vstr_measpower, cis[i + 1]);
3519*4882a593Smuzhiyun 					varbuf_append(&b, vstr_measpowerX, 1, (cis[i + 2]));
3520*4882a593Smuzhiyun 					varbuf_append(&b, vstr_measpowerX, 2, (cis[i + 3]));
3521*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rawtempsense,
3522*4882a593Smuzhiyun 						((cis[i + 5] & 0x1) << 8) + cis[i + 4]);
3523*4882a593Smuzhiyun 					break;
3524*4882a593Smuzhiyun 
3525*4882a593Smuzhiyun 				case HNBU_PDOFF:
3526*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pdoffsetma, 40, 0,
3527*4882a593Smuzhiyun 					      (cis[i + 2] << 8) + cis[i + 1]);
3528*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pdoffsetma, 40, 1,
3529*4882a593Smuzhiyun 					      (cis[i + 4] << 8) + cis[i + 3]);
3530*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pdoffsetma, 40, 2,
3531*4882a593Smuzhiyun 					      (cis[i + 6] << 8) + cis[i + 5]);
3532*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pdoffsetma, 80, 0,
3533*4882a593Smuzhiyun 					      (cis[i + 8] << 8) + cis[i + 7]);
3534*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pdoffsetma, 80, 1,
3535*4882a593Smuzhiyun 					      (cis[i + 10] << 8) + cis[i + 9]);
3536*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pdoffsetma, 80, 2,
3537*4882a593Smuzhiyun 					      (cis[i + 12] << 8) + cis[i + 11]);
3538*4882a593Smuzhiyun 					break;
3539*4882a593Smuzhiyun 
3540*4882a593Smuzhiyun 				case HNBU_ACPPR_2GPO:
3541*4882a593Smuzhiyun 					varbuf_append(&b, vstr_dot11agofdmhrbw202gpo,
3542*4882a593Smuzhiyun 					              (cis[i + 2] << 8) + cis[i + 1]);
3543*4882a593Smuzhiyun 					varbuf_append(&b, vstr_ofdmlrbw202gpo,
3544*4882a593Smuzhiyun 					              (cis[i + 4] << 8) + cis[i + 3]);
3545*4882a593Smuzhiyun 
3546*4882a593Smuzhiyun 					if (tlen < 13) break;
3547*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb20in40dot11agofdm2gpo,
3548*4882a593Smuzhiyun 					              (cis[i + 6] << 8) + cis[i + 5]);
3549*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb20in80dot11agofdm2gpo,
3550*4882a593Smuzhiyun 					              (cis[i + 8] << 8) + cis[i + 7]);
3551*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb20in40ofdmlrbw202gpo,
3552*4882a593Smuzhiyun 					              (cis[i + 10] << 8) + cis[i + 9]);
3553*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb20in80ofdmlrbw202gpo,
3554*4882a593Smuzhiyun 					              (cis[i + 12] << 8) + cis[i + 11]);
3555*4882a593Smuzhiyun 					break;
3556*4882a593Smuzhiyun 
3557*4882a593Smuzhiyun 				case HNBU_ACPPR_5GPO:
3558*4882a593Smuzhiyun 					varbuf_append(&b, vstr_mcsbw805gpo, 'l',
3559*4882a593Smuzhiyun 						(cis[i + 4] << 24) + (cis[i + 3] << 16) +
3560*4882a593Smuzhiyun 						(cis[i + 2] << 8) + cis[i + 1]);
3561*4882a593Smuzhiyun 					varbuf_append(&b, vstr_mcsbw1605gpo, 'l',
3562*4882a593Smuzhiyun 						(cis[i + 8] << 24) + (cis[i + 7] << 16) +
3563*4882a593Smuzhiyun 						(cis[i + 6] << 8) + cis[i + 5]);
3564*4882a593Smuzhiyun 					varbuf_append(&b, vstr_mcsbw805gpo, 'm',
3565*4882a593Smuzhiyun 						(cis[i + 12] << 24) + (cis[i + 11] << 16) +
3566*4882a593Smuzhiyun 						(cis[i + 10] << 8) + cis[i + 9]);
3567*4882a593Smuzhiyun 					varbuf_append(&b, vstr_mcsbw1605gpo, 'm',
3568*4882a593Smuzhiyun 						(cis[i + 16] << 24) + (cis[i + 15] << 16) +
3569*4882a593Smuzhiyun 						(cis[i + 14] << 8) + cis[i + 13]);
3570*4882a593Smuzhiyun 					varbuf_append(&b, vstr_mcsbw805gpo, 'h',
3571*4882a593Smuzhiyun 						(cis[i + 20] << 24) + (cis[i + 19] << 16) +
3572*4882a593Smuzhiyun 						(cis[i + 18] << 8) + cis[i + 17]);
3573*4882a593Smuzhiyun 					varbuf_append(&b, vstr_mcsbw1605gpo, 'h',
3574*4882a593Smuzhiyun 						(cis[i + 24] << 24) + (cis[i + 23] << 16) +
3575*4882a593Smuzhiyun 						(cis[i + 22] << 8) + cis[i + 21]);
3576*4882a593Smuzhiyun 					varbuf_append(&b, vstr_mcslr5gpo, 'l',
3577*4882a593Smuzhiyun 					              (cis[i + 26] << 8) + cis[i + 25]);
3578*4882a593Smuzhiyun 					varbuf_append(&b, vstr_mcslr5gpo, 'm',
3579*4882a593Smuzhiyun 					              (cis[i + 28] << 8) + cis[i + 27]);
3580*4882a593Smuzhiyun 					varbuf_append(&b, vstr_mcslr5gpo, 'h',
3581*4882a593Smuzhiyun 					              (cis[i + 30] << 8) + cis[i + 29]);
3582*4882a593Smuzhiyun 
3583*4882a593Smuzhiyun 					if (tlen < 51) break;
3584*4882a593Smuzhiyun 					varbuf_append(&b, vstr_mcsbw80p805gpo, 'l',
3585*4882a593Smuzhiyun 						(cis[i + 34] << 24) + (cis[i + 33] << 16) +
3586*4882a593Smuzhiyun 						(cis[i + 32] << 8) + cis[i + 31]);
3587*4882a593Smuzhiyun 					varbuf_append(&b, vstr_mcsbw80p805gpo, 'm',
3588*4882a593Smuzhiyun 						(cis[i + 38] << 24) + (cis[i + 37] << 16) +
3589*4882a593Smuzhiyun 						(cis[i + 36] << 8) + cis[i + 35]);
3590*4882a593Smuzhiyun 					varbuf_append(&b, vstr_mcsbw80p805gpo, 'h',
3591*4882a593Smuzhiyun 						(cis[i + 42] << 24) + (cis[i + 41] << 16) +
3592*4882a593Smuzhiyun 						(cis[i + 40] << 8) + cis[i + 39]);
3593*4882a593Smuzhiyun 					varbuf_append(&b, vstr_mcsbw80p805g1po, 'x',
3594*4882a593Smuzhiyun 						(cis[i + 46] << 24) + (cis[i + 45] << 16) +
3595*4882a593Smuzhiyun 						(cis[i + 44] << 8) + cis[i + 43]);
3596*4882a593Smuzhiyun 					varbuf_append(&b, vstr_mcslr5g1po, 'x',
3597*4882a593Smuzhiyun 					              (cis[i + 48] << 8) + cis[i + 47]);
3598*4882a593Smuzhiyun 					varbuf_append(&b, vstr_mcslr5g80p80po,
3599*4882a593Smuzhiyun 					              (cis[i + 50] << 8) + cis[i + 49]);
3600*4882a593Smuzhiyun 					varbuf_append(&b, vstr_mcsbw805g1po, 'x',
3601*4882a593Smuzhiyun 						(cis[i + 54] << 24) + (cis[i + 53] << 16) +
3602*4882a593Smuzhiyun 						(cis[i + 52] << 8) + cis[i + 51]);
3603*4882a593Smuzhiyun 					varbuf_append(&b, vstr_mcsbw1605g1po, 'x',
3604*4882a593Smuzhiyun 						(cis[i + 58] << 24) + (cis[i + 57] << 16) +
3605*4882a593Smuzhiyun 						(cis[i + 56] << 8) + cis[i + 55]);
3606*4882a593Smuzhiyun 
3607*4882a593Smuzhiyun 					break;
3608*4882a593Smuzhiyun 
3609*4882a593Smuzhiyun 				case HNBU_MCS5Gx1PO:
3610*4882a593Smuzhiyun 					varbuf_append(&b, vstr_mcsbw205g1po, 'x',
3611*4882a593Smuzhiyun 						(cis[i + 4] << 24) + (cis[i + 3] << 16) +
3612*4882a593Smuzhiyun 						(cis[i + 2] << 8) + cis[i + 1]);
3613*4882a593Smuzhiyun 					varbuf_append(&b, vstr_mcsbw405g1po, 'x',
3614*4882a593Smuzhiyun 						(cis[i + 8] << 24) + (cis[i + 7] << 16) +
3615*4882a593Smuzhiyun 						(cis[i + 6] << 8) + cis[i + 5]);
3616*4882a593Smuzhiyun 					break;
3617*4882a593Smuzhiyun 
3618*4882a593Smuzhiyun 				case HNBU_ACPPR_SBPO:
3619*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb20in40rpo, 'h',
3620*4882a593Smuzhiyun 					              (cis[i + 2] << 8) + cis[i + 1]);
3621*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb20in80and160r5gpo, 'h', 'l',
3622*4882a593Smuzhiyun 					              (cis[i + 4] << 8) + cis[i + 3]);
3623*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb40and80r5gpo, 'h', 'l',
3624*4882a593Smuzhiyun 					              (cis[i + 6] << 8) + cis[i + 5]);
3625*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb20in80and160r5gpo, 'h', 'm',
3626*4882a593Smuzhiyun 					              (cis[i + 8] << 8) + cis[i + 7]);
3627*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb40and80r5gpo, 'h', 'm',
3628*4882a593Smuzhiyun 					              (cis[i + 10] << 8) + cis[i + 9]);
3629*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb20in80and160r5gpo, 'h', 'h',
3630*4882a593Smuzhiyun 					              (cis[i + 12] << 8) + cis[i + 11]);
3631*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb40and80r5gpo, 'h', 'h',
3632*4882a593Smuzhiyun 					              (cis[i + 14] << 8) + cis[i + 13]);
3633*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb20in40rpo, 'l',
3634*4882a593Smuzhiyun 					              (cis[i + 16] << 8) + cis[i + 15]);
3635*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb20in80and160r5gpo, 'l', 'l',
3636*4882a593Smuzhiyun 					              (cis[i + 18] << 8) + cis[i + 17]);
3637*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb40and80r5gpo, 'l', 'l',
3638*4882a593Smuzhiyun 					              (cis[i + 20] << 8) + cis[i + 19]);
3639*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb20in80and160r5gpo, 'l', 'm',
3640*4882a593Smuzhiyun 					              (cis[i + 22] << 8) + cis[i + 21]);
3641*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb40and80r5gpo, 'l', 'm',
3642*4882a593Smuzhiyun 					              (cis[i + 24] << 8) + cis[i + 23]);
3643*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb20in80and160r5gpo, 'l', 'h',
3644*4882a593Smuzhiyun 					              (cis[i + 26] << 8) + cis[i + 25]);
3645*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb40and80r5gpo, 'l', 'h',
3646*4882a593Smuzhiyun 					              (cis[i + 28] << 8) + cis[i + 27]);
3647*4882a593Smuzhiyun 					varbuf_append(&b, vstr_dot11agduprpo, 'h',
3648*4882a593Smuzhiyun 						(cis[i + 32] << 24) + (cis[i + 31] << 16) +
3649*4882a593Smuzhiyun 						(cis[i + 30] << 8) + cis[i + 29]);
3650*4882a593Smuzhiyun 					varbuf_append(&b, vstr_dot11agduprpo, 'l',
3651*4882a593Smuzhiyun 						(cis[i + 36] << 24) + (cis[i + 35] << 16) +
3652*4882a593Smuzhiyun 						(cis[i + 34] << 8) + cis[i + 33]);
3653*4882a593Smuzhiyun 
3654*4882a593Smuzhiyun 					if (tlen < 49) break;
3655*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb20in40and80rpo, 'h',
3656*4882a593Smuzhiyun 						(cis[i + 38] << 8) + cis[i + 37]);
3657*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb20in40and80rpo, 'l',
3658*4882a593Smuzhiyun 						(cis[i + 40] << 8) + cis[i + 39]);
3659*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb20in80and160r5g1po, 'h', 'x',
3660*4882a593Smuzhiyun 						(cis[i + 42] << 8) + cis[i + 41]);
3661*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb20in80and160r5g1po, 'l', 'x',
3662*4882a593Smuzhiyun 						(cis[i + 44] << 8) + cis[i + 43]);
3663*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb40and80r5g1po, 'h', 'x',
3664*4882a593Smuzhiyun 						(cis[i + 46] << 8) + cis[i + 45]);
3665*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb40and80r5g1po, 'l', 'x',
3666*4882a593Smuzhiyun 						(cis[i + 48] << 8) + cis[i + 47]);
3667*4882a593Smuzhiyun 					break;
3668*4882a593Smuzhiyun 
3669*4882a593Smuzhiyun 				case HNBU_ACPPR_SB8080_PO:
3670*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb2040and80in80p80r5gpo, 'h', 'l',
3671*4882a593Smuzhiyun 						(cis[i + 2] << 8) + cis[i + 1]);
3672*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb2040and80in80p80r5gpo, 'l', 'l',
3673*4882a593Smuzhiyun 						(cis[i + 4] << 8) + cis[i + 3]);
3674*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb2040and80in80p80r5gpo, 'h', 'm',
3675*4882a593Smuzhiyun 						(cis[i + 6] << 8) + cis[i + 5]);
3676*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb2040and80in80p80r5gpo, 'l', 'm',
3677*4882a593Smuzhiyun 						(cis[i + 8] << 8) + cis[i + 7]);
3678*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb2040and80in80p80r5gpo, 'h', 'h',
3679*4882a593Smuzhiyun 						(cis[i + 10] << 8) + cis[i + 9]);
3680*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb2040and80in80p80r5gpo, 'l', 'h',
3681*4882a593Smuzhiyun 						(cis[i + 12] << 8) + cis[i + 11]);
3682*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb2040and80in80p80r5g1po, 'h', 'x',
3683*4882a593Smuzhiyun 						(cis[i + 14] << 8) + cis[i + 13]);
3684*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb2040and80in80p80r5g1po, 'l', 'x',
3685*4882a593Smuzhiyun 						(cis[i + 16] << 8) + cis[i + 15]);
3686*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb20in80p80r5gpo, 'h',
3687*4882a593Smuzhiyun 						(cis[i + 18] << 8) + cis[i + 17]);
3688*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sb20in80p80r5gpo, 'l',
3689*4882a593Smuzhiyun 						(cis[i + 20] << 8) + cis[i + 19]);
3690*4882a593Smuzhiyun 					varbuf_append(&b, vstr_dot11agduppo,
3691*4882a593Smuzhiyun 						(cis[i + 22] << 8) + cis[i + 21]);
3692*4882a593Smuzhiyun 					break;
3693*4882a593Smuzhiyun 
3694*4882a593Smuzhiyun 				case HNBU_NOISELVL:
3695*4882a593Smuzhiyun 					/* noiselvl2g */
3696*4882a593Smuzhiyun 					varbuf_append(&b, vstr_noiselvl2ga, 0,
3697*4882a593Smuzhiyun 					              (cis[i + 1] & 0x1f));
3698*4882a593Smuzhiyun 					varbuf_append(&b, vstr_noiselvl2ga, 1,
3699*4882a593Smuzhiyun 					              (cis[i + 2] & 0x1f));
3700*4882a593Smuzhiyun 					varbuf_append(&b, vstr_noiselvl2ga, 2,
3701*4882a593Smuzhiyun 					              (cis[i + 3] & 0x1f));
3702*4882a593Smuzhiyun 					/* noiselvl5g */
3703*4882a593Smuzhiyun 					varbuf_append(&b, vstr_noiselvl5ga, 0,
3704*4882a593Smuzhiyun 					              (cis[i + 4] & 0x1f),
3705*4882a593Smuzhiyun 					              (cis[i + 5] & 0x1f),
3706*4882a593Smuzhiyun 					              (cis[i + 6] & 0x1f),
3707*4882a593Smuzhiyun 					              (cis[i + 7] & 0x1f));
3708*4882a593Smuzhiyun 					varbuf_append(&b, vstr_noiselvl5ga, 1,
3709*4882a593Smuzhiyun 					              (cis[i + 8] & 0x1f),
3710*4882a593Smuzhiyun 					              (cis[i + 9] & 0x1f),
3711*4882a593Smuzhiyun 					              (cis[i + 10] & 0x1f),
3712*4882a593Smuzhiyun 					              (cis[i + 11] & 0x1f));
3713*4882a593Smuzhiyun 					varbuf_append(&b, vstr_noiselvl5ga, 2,
3714*4882a593Smuzhiyun 					              (cis[i + 12] & 0x1f),
3715*4882a593Smuzhiyun 					              (cis[i + 13] & 0x1f),
3716*4882a593Smuzhiyun 					              (cis[i + 14] & 0x1f),
3717*4882a593Smuzhiyun 					              (cis[i + 15] & 0x1f));
3718*4882a593Smuzhiyun 					break;
3719*4882a593Smuzhiyun 
3720*4882a593Smuzhiyun 				case HNBU_RXGAIN_ERR:
3721*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainerr2ga, 0,
3722*4882a593Smuzhiyun 					              (cis[i + 1] & 0x3f));
3723*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainerr2ga, 1,
3724*4882a593Smuzhiyun 					              (cis[i + 2] & 0x1f));
3725*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainerr2ga, 2,
3726*4882a593Smuzhiyun 					              (cis[i + 3] & 0x1f));
3727*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainerr5ga, 0,
3728*4882a593Smuzhiyun 					              (cis[i + 4] & 0x3f),
3729*4882a593Smuzhiyun 					              (cis[i + 5] & 0x3f),
3730*4882a593Smuzhiyun 					              (cis[i + 6] & 0x3f),
3731*4882a593Smuzhiyun 					              (cis[i + 7] & 0x3f));
3732*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainerr5ga, 1,
3733*4882a593Smuzhiyun 					              (cis[i + 8] & 0x1f),
3734*4882a593Smuzhiyun 					              (cis[i + 9] & 0x1f),
3735*4882a593Smuzhiyun 					              (cis[i + 10] & 0x1f),
3736*4882a593Smuzhiyun 					              (cis[i + 11] & 0x1f));
3737*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainerr5ga, 2,
3738*4882a593Smuzhiyun 					              (cis[i + 12] & 0x1f),
3739*4882a593Smuzhiyun 					              (cis[i + 13] & 0x1f),
3740*4882a593Smuzhiyun 					              (cis[i + 14] & 0x1f),
3741*4882a593Smuzhiyun 					              (cis[i + 15] & 0x1f));
3742*4882a593Smuzhiyun 					break;
3743*4882a593Smuzhiyun 
3744*4882a593Smuzhiyun 				case HNBU_AGBGA:
3745*4882a593Smuzhiyun 					varbuf_append(&b, vstr_agbg, 0, cis[i + 1]);
3746*4882a593Smuzhiyun 					varbuf_append(&b, vstr_agbg, 1, cis[i + 2]);
3747*4882a593Smuzhiyun 					varbuf_append(&b, vstr_agbg, 2, cis[i + 3]);
3748*4882a593Smuzhiyun 					varbuf_append(&b, vstr_aga, 0, cis[i + 4]);
3749*4882a593Smuzhiyun 					varbuf_append(&b, vstr_aga, 1, cis[i + 5]);
3750*4882a593Smuzhiyun 					varbuf_append(&b, vstr_aga, 2, cis[i + 6]);
3751*4882a593Smuzhiyun 					break;
3752*4882a593Smuzhiyun 
3753*4882a593Smuzhiyun 				case HNBU_ACRXGAINS_C0: {
3754*4882a593Smuzhiyun 					int a = 0;
3755*4882a593Smuzhiyun 
3756*4882a593Smuzhiyun 					/* rxgains */
3757*4882a593Smuzhiyun 					uint16 rxgains = (cis[i + 2] << 8) + cis[i + 1];
3758*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgtrelnabypa, 5, a,
3759*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS5GTRELNABYPA_MASK) >>
3760*4882a593Smuzhiyun 						SROM11_RXGAINS5GTRELNABYPA_SHIFT);
3761*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgtrisoa, 5, a,
3762*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS5GTRISOA_MASK) >>
3763*4882a593Smuzhiyun 						SROM11_RXGAINS5GTRISOA_SHIFT);
3764*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgelnagaina, 5, a,
3765*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS5GELNAGAINA_MASK) >>
3766*4882a593Smuzhiyun 						SROM11_RXGAINS5GELNAGAINA_SHIFT);
3767*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgtrelnabypa, 2, a,
3768*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS2GTRELNABYPA_MASK) >>
3769*4882a593Smuzhiyun 						SROM11_RXGAINS2GTRELNABYPA_SHIFT);
3770*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgtrisoa, 2, a,
3771*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS2GTRISOA_MASK) >>
3772*4882a593Smuzhiyun 						SROM11_RXGAINS2GTRISOA_SHIFT);
3773*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgelnagaina, 2, a,
3774*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS2GELNAGAINA_MASK) >>
3775*4882a593Smuzhiyun 						SROM11_RXGAINS2GELNAGAINA_SHIFT);
3776*4882a593Smuzhiyun 					/* rxgains1 */
3777*4882a593Smuzhiyun 					rxgains = (cis[i + 4] << 8) + cis[i + 3];
3778*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgxtrelnabypa, 5, 'h', a,
3779*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS5GTRELNABYPA_MASK) >>
3780*4882a593Smuzhiyun 						SROM11_RXGAINS5GTRELNABYPA_SHIFT);
3781*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgxtrisoa, 5, 'h', a,
3782*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS5GTRISOA_MASK) >>
3783*4882a593Smuzhiyun 						SROM11_RXGAINS5GTRISOA_SHIFT);
3784*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgxelnagaina, 5, 'h', a,
3785*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS5GELNAGAINA_MASK) >>
3786*4882a593Smuzhiyun 						SROM11_RXGAINS5GELNAGAINA_SHIFT);
3787*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgxtrelnabypa, 5, 'm', a,
3788*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS5GTRELNABYPA_MASK) >>
3789*4882a593Smuzhiyun 						SROM11_RXGAINS5GTRELNABYPA_SHIFT);
3790*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgxtrisoa, 5, 'm', a,
3791*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS5GTRISOA_MASK) >>
3792*4882a593Smuzhiyun 						SROM11_RXGAINS5GTRISOA_SHIFT);
3793*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgxelnagaina, 5, 'm', a,
3794*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS5GELNAGAINA_MASK) >>
3795*4882a593Smuzhiyun 						SROM11_RXGAINS5GELNAGAINA_SHIFT);
3796*4882a593Smuzhiyun 					break;
3797*4882a593Smuzhiyun 				}
3798*4882a593Smuzhiyun 
3799*4882a593Smuzhiyun 				case HNBU_ACRXGAINS_C1: {
3800*4882a593Smuzhiyun 					int a = 1;
3801*4882a593Smuzhiyun 
3802*4882a593Smuzhiyun 					/* rxgains */
3803*4882a593Smuzhiyun 					uint16 rxgains = (cis[i + 2] << 8) + cis[i + 1];
3804*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgtrelnabypa, 5, a,
3805*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS5GTRELNABYPA_MASK) >>
3806*4882a593Smuzhiyun 						SROM11_RXGAINS5GTRELNABYPA_SHIFT);
3807*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgtrisoa, 5, a,
3808*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS5GTRISOA_MASK) >>
3809*4882a593Smuzhiyun 						SROM11_RXGAINS5GTRISOA_SHIFT);
3810*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgelnagaina, 5, a,
3811*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS5GELNAGAINA_MASK) >>
3812*4882a593Smuzhiyun 						SROM11_RXGAINS5GELNAGAINA_SHIFT);
3813*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgtrelnabypa, 2, a,
3814*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS2GTRELNABYPA_MASK) >>
3815*4882a593Smuzhiyun 						SROM11_RXGAINS2GTRELNABYPA_SHIFT);
3816*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgtrisoa, 2, a,
3817*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS2GTRISOA_MASK) >>
3818*4882a593Smuzhiyun 						SROM11_RXGAINS2GTRISOA_SHIFT);
3819*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgelnagaina, 2, a,
3820*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS2GELNAGAINA_MASK) >>
3821*4882a593Smuzhiyun 						SROM11_RXGAINS2GELNAGAINA_SHIFT);
3822*4882a593Smuzhiyun 					/* rxgains1 */
3823*4882a593Smuzhiyun 					rxgains = (cis[i + 4] << 8) + cis[i + 3];
3824*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgxtrelnabypa, 5, 'h', a,
3825*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS5GTRELNABYPA_MASK) >>
3826*4882a593Smuzhiyun 						SROM11_RXGAINS5GTRELNABYPA_SHIFT);
3827*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgxtrisoa, 5, 'h', a,
3828*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS5GTRISOA_MASK) >>
3829*4882a593Smuzhiyun 						SROM11_RXGAINS5GTRISOA_SHIFT);
3830*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgxelnagaina, 5, 'h', a,
3831*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS5GELNAGAINA_MASK) >>
3832*4882a593Smuzhiyun 						SROM11_RXGAINS5GELNAGAINA_SHIFT);
3833*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgxtrelnabypa, 5, 'm', a,
3834*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS5GTRELNABYPA_MASK) >>
3835*4882a593Smuzhiyun 						SROM11_RXGAINS5GTRELNABYPA_SHIFT);
3836*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgxtrisoa, 5, 'm', a,
3837*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS5GTRISOA_MASK) >>
3838*4882a593Smuzhiyun 						SROM11_RXGAINS5GTRISOA_SHIFT);
3839*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgxelnagaina, 5, 'm', a,
3840*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS5GELNAGAINA_MASK) >>
3841*4882a593Smuzhiyun 						SROM11_RXGAINS5GELNAGAINA_SHIFT);
3842*4882a593Smuzhiyun 					break;
3843*4882a593Smuzhiyun 				}
3844*4882a593Smuzhiyun 
3845*4882a593Smuzhiyun 				case HNBU_ACRXGAINS_C2: {
3846*4882a593Smuzhiyun 					int a = 2;
3847*4882a593Smuzhiyun 
3848*4882a593Smuzhiyun 					/* rxgains */
3849*4882a593Smuzhiyun 					uint16 rxgains = (cis[i + 2] << 8) + cis[i + 1];
3850*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgtrelnabypa, 5, a,
3851*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS5GTRELNABYPA_MASK) >>
3852*4882a593Smuzhiyun 						SROM11_RXGAINS5GTRELNABYPA_SHIFT);
3853*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgtrisoa, 5, a,
3854*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS5GTRISOA_MASK) >>
3855*4882a593Smuzhiyun 						SROM11_RXGAINS5GTRISOA_SHIFT);
3856*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgelnagaina, 5, a,
3857*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS5GELNAGAINA_MASK) >>
3858*4882a593Smuzhiyun 						SROM11_RXGAINS5GELNAGAINA_SHIFT);
3859*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgtrelnabypa, 2, a,
3860*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS2GTRELNABYPA_MASK) >>
3861*4882a593Smuzhiyun 						SROM11_RXGAINS2GTRELNABYPA_SHIFT);
3862*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgtrisoa, 2, a,
3863*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS2GTRISOA_MASK) >>
3864*4882a593Smuzhiyun 						SROM11_RXGAINS2GTRISOA_SHIFT);
3865*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgelnagaina, 2, a,
3866*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS2GELNAGAINA_MASK) >>
3867*4882a593Smuzhiyun 						SROM11_RXGAINS2GELNAGAINA_SHIFT);
3868*4882a593Smuzhiyun 					/* rxgains1 */
3869*4882a593Smuzhiyun 					rxgains = (cis[i + 4] << 8) + cis[i + 3];
3870*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgxtrelnabypa, 5, 'h', a,
3871*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS5GTRELNABYPA_MASK) >>
3872*4882a593Smuzhiyun 						SROM11_RXGAINS5GTRELNABYPA_SHIFT);
3873*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgxtrisoa, 5, 'h', a,
3874*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS5GTRISOA_MASK) >>
3875*4882a593Smuzhiyun 						SROM11_RXGAINS5GTRISOA_SHIFT);
3876*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgxelnagaina, 5, 'h', a,
3877*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS5GELNAGAINA_MASK) >>
3878*4882a593Smuzhiyun 						SROM11_RXGAINS5GELNAGAINA_SHIFT);
3879*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgxtrelnabypa, 5, 'm', a,
3880*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS5GTRELNABYPA_MASK) >>
3881*4882a593Smuzhiyun 						SROM11_RXGAINS5GTRELNABYPA_SHIFT);
3882*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgxtrisoa, 5, 'm', a,
3883*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS5GTRISOA_MASK) >>
3884*4882a593Smuzhiyun 						SROM11_RXGAINS5GTRISOA_SHIFT);
3885*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rxgainsgxelnagaina, 5, 'm', a,
3886*4882a593Smuzhiyun 						(rxgains & SROM11_RXGAINS5GELNAGAINA_MASK) >>
3887*4882a593Smuzhiyun 						SROM11_RXGAINS5GELNAGAINA_SHIFT);
3888*4882a593Smuzhiyun 					break;
3889*4882a593Smuzhiyun 				}
3890*4882a593Smuzhiyun 
3891*4882a593Smuzhiyun 				case HNBU_TXDUTY: {
3892*4882a593Smuzhiyun 					varbuf_append(&b, vstr_txduty_ofdm, 40,
3893*4882a593Smuzhiyun 					              (cis[i + 2] << 8) + cis[i + 1]);
3894*4882a593Smuzhiyun 					varbuf_append(&b, vstr_txduty_thresh, 40,
3895*4882a593Smuzhiyun 					              (cis[i + 4] << 8) + cis[i + 3]);
3896*4882a593Smuzhiyun 					varbuf_append(&b, vstr_txduty_ofdm, 80,
3897*4882a593Smuzhiyun 					              (cis[i + 6] << 8) + cis[i + 5]);
3898*4882a593Smuzhiyun 					varbuf_append(&b, vstr_txduty_thresh, 80,
3899*4882a593Smuzhiyun 					              (cis[i + 8] << 8) + cis[i + 7]);
3900*4882a593Smuzhiyun 					break;
3901*4882a593Smuzhiyun 				}
3902*4882a593Smuzhiyun 
3903*4882a593Smuzhiyun 				case HNBU_UUID: {
3904*4882a593Smuzhiyun 					/* uuid format 12345678-1234-5678-1234-567812345678 */
3905*4882a593Smuzhiyun 
3906*4882a593Smuzhiyun 					char uuidstr[37]; /* 32 ids, 4 '-', 1 Null */
3907*4882a593Smuzhiyun 
3908*4882a593Smuzhiyun 					snprintf(uuidstr, sizeof(uuidstr),
3909*4882a593Smuzhiyun 						rstr_uuidstr,
3910*4882a593Smuzhiyun 						cis[i + 1], cis[i + 2], cis[i + 3], cis[i + 4],
3911*4882a593Smuzhiyun 						cis[i + 5], cis[i + 6], cis[i + 7], cis[i + 8],
3912*4882a593Smuzhiyun 						cis[i + 9], cis[i + 10], cis[i + 11], cis[i + 12],
3913*4882a593Smuzhiyun 						cis[i + 13], cis[i + 14], cis[i + 15], cis[i + 16]);
3914*4882a593Smuzhiyun 
3915*4882a593Smuzhiyun 					varbuf_append(&b, vstr_uuid, uuidstr);
3916*4882a593Smuzhiyun 					break;
3917*4882a593Smuzhiyun 				}
3918*4882a593Smuzhiyun 
3919*4882a593Smuzhiyun 				case HNBU_WOWLGPIO:
3920*4882a593Smuzhiyun 					varbuf_append(&b, vstr_wowlgpio, ((cis[i + 1]) & 0x7F));
3921*4882a593Smuzhiyun 					varbuf_append(&b, vstr_wowlgpiopol,
3922*4882a593Smuzhiyun 						(((cis[i + 1]) >> 7) & 0x1));
3923*4882a593Smuzhiyun 					break;
3924*4882a593Smuzhiyun 
3925*4882a593Smuzhiyun #endif /* !BCM_BOOTLOADER */
3926*4882a593Smuzhiyun #ifdef BCMUSBDEV_COMPOSITE
3927*4882a593Smuzhiyun 				case HNBU_USBDESC_COMPOSITE:
3928*4882a593Smuzhiyun 					varbuf_append(&b, vstr_usbdesc_composite,
3929*4882a593Smuzhiyun 						(cis[i + 2] << 8) | cis[i + 1]);
3930*4882a593Smuzhiyun 					break;
3931*4882a593Smuzhiyun #endif /* BCMUSBDEV_COMPOSITE */
3932*4882a593Smuzhiyun 				case HNBU_USBUTMI_CTL:
3933*4882a593Smuzhiyun 					varbuf_append(&b, vstr_usbutmi_ctl,
3934*4882a593Smuzhiyun 						(cis[i + 2] << 8) | cis[i + 1]);
3935*4882a593Smuzhiyun 					break;
3936*4882a593Smuzhiyun 
3937*4882a593Smuzhiyun 				case HNBU_USBSSPHY_UTMI_CTL0:
3938*4882a593Smuzhiyun 					varbuf_append(&b, vstr_usbssphy_utmi_ctl0,
3939*4882a593Smuzhiyun 						(cis[i + 4] << 24) | (cis[i + 3] << 16) |
3940*4882a593Smuzhiyun 						(cis[i + 2] << 8) | cis[i + 1]);
3941*4882a593Smuzhiyun 					break;
3942*4882a593Smuzhiyun 
3943*4882a593Smuzhiyun 				case HNBU_USBSSPHY_UTMI_CTL1:
3944*4882a593Smuzhiyun 					varbuf_append(&b, vstr_usbssphy_utmi_ctl1,
3945*4882a593Smuzhiyun 						(cis[i + 4] << 24) | (cis[i + 3] << 16) |
3946*4882a593Smuzhiyun 						(cis[i + 2] << 8) | cis[i + 1]);
3947*4882a593Smuzhiyun 					break;
3948*4882a593Smuzhiyun 
3949*4882a593Smuzhiyun 				case HNBU_USBSSPHY_UTMI_CTL2:
3950*4882a593Smuzhiyun 					varbuf_append(&b, vstr_usbssphy_utmi_ctl2,
3951*4882a593Smuzhiyun 						(cis[i + 4] << 24) | (cis[i + 3] << 16) |
3952*4882a593Smuzhiyun 						(cis[i + 2] << 8) | cis[i + 1]);
3953*4882a593Smuzhiyun 					break;
3954*4882a593Smuzhiyun 
3955*4882a593Smuzhiyun 				case HNBU_USBSSPHY_SLEEP0:
3956*4882a593Smuzhiyun 					varbuf_append(&b, vstr_usbssphy_sleep0,
3957*4882a593Smuzhiyun 						(cis[i + 2] << 8) | cis[i + 1]);
3958*4882a593Smuzhiyun 					break;
3959*4882a593Smuzhiyun 
3960*4882a593Smuzhiyun 				case HNBU_USBSSPHY_SLEEP1:
3961*4882a593Smuzhiyun 					varbuf_append(&b, vstr_usbssphy_sleep1,
3962*4882a593Smuzhiyun 						(cis[i + 2] << 8) | cis[i + 1]);
3963*4882a593Smuzhiyun 					break;
3964*4882a593Smuzhiyun 
3965*4882a593Smuzhiyun 				case HNBU_USBSSPHY_SLEEP2:
3966*4882a593Smuzhiyun 					varbuf_append(&b, vstr_usbssphy_sleep2,
3967*4882a593Smuzhiyun 						(cis[i + 2] << 8) | cis[i + 1]);
3968*4882a593Smuzhiyun 					break;
3969*4882a593Smuzhiyun 
3970*4882a593Smuzhiyun 				case HNBU_USBSSPHY_SLEEP3:
3971*4882a593Smuzhiyun 					varbuf_append(&b, vstr_usbssphy_sleep3,
3972*4882a593Smuzhiyun 						(cis[i + 2] << 8) | cis[i + 1]);
3973*4882a593Smuzhiyun 					break;
3974*4882a593Smuzhiyun 				case HNBU_USBSSPHY_MDIO: {
3975*4882a593Smuzhiyun 					uint8 setnum;
3976*4882a593Smuzhiyun 					uint16 k;
3977*4882a593Smuzhiyun 
3978*4882a593Smuzhiyun 					setnum = (cis[i + 1])/4;
3979*4882a593Smuzhiyun 					if (setnum == 0)
3980*4882a593Smuzhiyun 						break;
3981*4882a593Smuzhiyun 					for (j = 0; j < setnum; j++) {
3982*4882a593Smuzhiyun 						k = j*12;
3983*4882a593Smuzhiyun 						varbuf_append(&b, vstr_usbssphy_mdio, j,
3984*4882a593Smuzhiyun 						(cis[i+4+k]<<16) | (cis[i+3+k]<<8) | cis[i+2+k],
3985*4882a593Smuzhiyun 						(cis[i+7+k]<<16) | (cis[i+6+k]<<8) | cis[i+5+k],
3986*4882a593Smuzhiyun 						(cis[i+10+k]<<16) | (cis[i+9+k]<<8) | cis[i+8+k],
3987*4882a593Smuzhiyun 						(cis[i+13+k]<<16) | (cis[i+12+k]<<8) | cis[i+11+k]);
3988*4882a593Smuzhiyun 					}
3989*4882a593Smuzhiyun 					break;
3990*4882a593Smuzhiyun 				}
3991*4882a593Smuzhiyun 				case HNBU_USB30PHY_NOSS:
3992*4882a593Smuzhiyun 					varbuf_append(&b, vstr_usb30phy_noss, cis[i + 1]);
3993*4882a593Smuzhiyun 					break;
3994*4882a593Smuzhiyun 				case HNBU_USB30PHY_U1U2:
3995*4882a593Smuzhiyun 					varbuf_append(&b, vstr_usb30phy_u1u2, cis[i + 1]);
3996*4882a593Smuzhiyun 					break;
3997*4882a593Smuzhiyun 				case HNBU_USB30PHY_REGS:
3998*4882a593Smuzhiyun 					varbuf_append(&b, vstr_usb30phy_regs, 0,
3999*4882a593Smuzhiyun 						cis[i+4]|cis[i+3]|cis[i+2]|cis[i+1],
4000*4882a593Smuzhiyun 						cis[i+8]|cis[i+7]|cis[i+6]|cis[i+5],
4001*4882a593Smuzhiyun 						cis[i+12]|cis[i+11]|cis[i+10]|cis[i+9],
4002*4882a593Smuzhiyun 						cis[i+16]|cis[i+15]|cis[i+14]|cis[i+13]);
4003*4882a593Smuzhiyun 					varbuf_append(&b, vstr_usb30phy_regs, 1,
4004*4882a593Smuzhiyun 						cis[i+20]|cis[i+19]|cis[i+18]|cis[i+17],
4005*4882a593Smuzhiyun 						cis[i+24]|cis[i+23]|cis[i+22]|cis[i+21],
4006*4882a593Smuzhiyun 						cis[i+28]|cis[i+27]|cis[i+26]|cis[i+25],
4007*4882a593Smuzhiyun 						cis[i+32]|cis[i+31]|cis[i+30]|cis[i+29]);
4008*4882a593Smuzhiyun 
4009*4882a593Smuzhiyun 					break;
4010*4882a593Smuzhiyun 
4011*4882a593Smuzhiyun 				case HNBU_PDOFF_2G: {
4012*4882a593Smuzhiyun 					uint16 pdoff_2g = (cis[i + 2] << 8) + cis[i + 1];
4013*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pdoffset2gma, 40, 0,
4014*4882a593Smuzhiyun 						(pdoff_2g & SROM11_PDOFF_2G_40M_A0_MASK) >>
4015*4882a593Smuzhiyun 						SROM11_PDOFF_2G_40M_A0_SHIFT);
4016*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pdoffset2gma, 40, 1,
4017*4882a593Smuzhiyun 						(pdoff_2g & SROM11_PDOFF_2G_40M_A1_MASK) >>
4018*4882a593Smuzhiyun 						SROM11_PDOFF_2G_40M_A1_SHIFT);
4019*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pdoffset2gma, 40, 2,
4020*4882a593Smuzhiyun 						(pdoff_2g & SROM11_PDOFF_2G_40M_A2_MASK) >>
4021*4882a593Smuzhiyun 						SROM11_PDOFF_2G_40M_A2_SHIFT);
4022*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pdoffset2gmvalid, 40,
4023*4882a593Smuzhiyun 						(pdoff_2g & SROM11_PDOFF_2G_40M_VALID_MASK) >>
4024*4882a593Smuzhiyun 						SROM11_PDOFF_2G_40M_VALID_SHIFT);
4025*4882a593Smuzhiyun 					break;
4026*4882a593Smuzhiyun 				}
4027*4882a593Smuzhiyun 
4028*4882a593Smuzhiyun 				case HNBU_ACPA_CCK_C0:
4029*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pa2gccka, 0,
4030*4882a593Smuzhiyun 					        (cis[i + 2] << 8) + cis[i + 1],
4031*4882a593Smuzhiyun 						(cis[i + 4] << 8) + cis[i + 3],
4032*4882a593Smuzhiyun 						(cis[i + 6] << 8) + cis[i + 5]);
4033*4882a593Smuzhiyun 					break;
4034*4882a593Smuzhiyun 
4035*4882a593Smuzhiyun 				case HNBU_ACPA_CCK_C1:
4036*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pa2gccka, 1,
4037*4882a593Smuzhiyun 						(cis[i + 2] << 8) + cis[i + 1],
4038*4882a593Smuzhiyun 						(cis[i + 4] << 8) + cis[i + 3],
4039*4882a593Smuzhiyun 						(cis[i + 6] << 8) + cis[i + 5]);
4040*4882a593Smuzhiyun 					break;
4041*4882a593Smuzhiyun 
4042*4882a593Smuzhiyun 				case HNBU_ACPA_40:
4043*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pa5gbw40a, 0,
4044*4882a593Smuzhiyun 					        (cis[i + 2] << 8) + cis[i + 1],
4045*4882a593Smuzhiyun 						(cis[i + 4] << 8) + cis[i + 3],
4046*4882a593Smuzhiyun 						(cis[i + 6] << 8) + cis[i + 5],
4047*4882a593Smuzhiyun 					        (cis[i + 8] << 8) + cis[i + 7],
4048*4882a593Smuzhiyun 						(cis[i + 10] << 8) + cis[i + 9],
4049*4882a593Smuzhiyun 						(cis[i + 12] << 8) + cis[i + 11],
4050*4882a593Smuzhiyun 					        (cis[i + 14] << 8) + cis[i + 13],
4051*4882a593Smuzhiyun 						(cis[i + 16] << 8) + cis[i + 15],
4052*4882a593Smuzhiyun 						(cis[i + 18] << 8) + cis[i + 17],
4053*4882a593Smuzhiyun 					        (cis[i + 20] << 8) + cis[i + 19],
4054*4882a593Smuzhiyun 						(cis[i + 22] << 8) + cis[i + 21],
4055*4882a593Smuzhiyun 						(cis[i + 24] << 8) + cis[i + 23]);
4056*4882a593Smuzhiyun 					break;
4057*4882a593Smuzhiyun 
4058*4882a593Smuzhiyun 				case HNBU_ACPA_80:
4059*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pa5gbw80a, 0,
4060*4882a593Smuzhiyun 					        (cis[i + 2] << 8) + cis[i + 1],
4061*4882a593Smuzhiyun 						(cis[i + 4] << 8) + cis[i + 3],
4062*4882a593Smuzhiyun 						(cis[i + 6] << 8) + cis[i + 5],
4063*4882a593Smuzhiyun 					        (cis[i + 8] << 8) + cis[i + 7],
4064*4882a593Smuzhiyun 						(cis[i + 10] << 8) + cis[i + 9],
4065*4882a593Smuzhiyun 						(cis[i + 12] << 8) + cis[i + 11],
4066*4882a593Smuzhiyun 					        (cis[i + 14] << 8) + cis[i + 13],
4067*4882a593Smuzhiyun 						(cis[i + 16] << 8) + cis[i + 15],
4068*4882a593Smuzhiyun 						(cis[i + 18] << 8) + cis[i + 17],
4069*4882a593Smuzhiyun 					        (cis[i + 20] << 8) + cis[i + 19],
4070*4882a593Smuzhiyun 						(cis[i + 22] << 8) + cis[i + 21],
4071*4882a593Smuzhiyun 						(cis[i + 24] << 8) + cis[i + 23]);
4072*4882a593Smuzhiyun 					break;
4073*4882a593Smuzhiyun 
4074*4882a593Smuzhiyun 				case HNBU_ACPA_4080:
4075*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pa5gbw4080a, 0,
4076*4882a593Smuzhiyun 					        (cis[i + 2] << 8) + cis[i + 1],
4077*4882a593Smuzhiyun 						(cis[i + 4] << 8) + cis[i + 3],
4078*4882a593Smuzhiyun 						(cis[i + 6] << 8) + cis[i + 5],
4079*4882a593Smuzhiyun 					        (cis[i + 8] << 8) + cis[i + 7],
4080*4882a593Smuzhiyun 						(cis[i + 10] << 8) + cis[i + 9],
4081*4882a593Smuzhiyun 						(cis[i + 12] << 8) + cis[i + 11],
4082*4882a593Smuzhiyun 					        (cis[i + 14] << 8) + cis[i + 13],
4083*4882a593Smuzhiyun 						(cis[i + 16] << 8) + cis[i + 15],
4084*4882a593Smuzhiyun 						(cis[i + 18] << 8) + cis[i + 17],
4085*4882a593Smuzhiyun 					        (cis[i + 20] << 8) + cis[i + 19],
4086*4882a593Smuzhiyun 						(cis[i + 22] << 8) + cis[i + 21],
4087*4882a593Smuzhiyun 						(cis[i + 24] << 8) + cis[i + 23]);
4088*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pa5gbw4080a, 1,
4089*4882a593Smuzhiyun 					        (cis[i + 26] << 8) + cis[i + 25],
4090*4882a593Smuzhiyun 						(cis[i + 28] << 8) + cis[i + 27],
4091*4882a593Smuzhiyun 						(cis[i + 30] << 8) + cis[i + 29],
4092*4882a593Smuzhiyun 					        (cis[i + 32] << 8) + cis[i + 31],
4093*4882a593Smuzhiyun 						(cis[i + 34] << 8) + cis[i + 33],
4094*4882a593Smuzhiyun 						(cis[i + 36] << 8) + cis[i + 35],
4095*4882a593Smuzhiyun 					        (cis[i + 38] << 8) + cis[i + 37],
4096*4882a593Smuzhiyun 						(cis[i + 40] << 8) + cis[i + 39],
4097*4882a593Smuzhiyun 						(cis[i + 42] << 8) + cis[i + 41],
4098*4882a593Smuzhiyun 					        (cis[i + 44] << 8) + cis[i + 43],
4099*4882a593Smuzhiyun 						(cis[i + 46] << 8) + cis[i + 45],
4100*4882a593Smuzhiyun 						(cis[i + 48] << 8) + cis[i + 47]);
4101*4882a593Smuzhiyun 					break;
4102*4882a593Smuzhiyun 
4103*4882a593Smuzhiyun 				case HNBU_ACPA_4X4C0:
4104*4882a593Smuzhiyun 				case HNBU_ACPA_4X4C1:
4105*4882a593Smuzhiyun 				case HNBU_ACPA_4X4C2:
4106*4882a593Smuzhiyun 				case HNBU_ACPA_4X4C3: {
4107*4882a593Smuzhiyun 					int core_num = 0;
4108*4882a593Smuzhiyun 					uint8 tuple = cis[i];
4109*4882a593Smuzhiyun 
4110*4882a593Smuzhiyun 					if (tuple == HNBU_ACPA_4X4C1) {
4111*4882a593Smuzhiyun 						core_num = 1;
4112*4882a593Smuzhiyun 					} else if (tuple == HNBU_ACPA_4X4C2) {
4113*4882a593Smuzhiyun 						core_num = 2;
4114*4882a593Smuzhiyun 					} else if (tuple == HNBU_ACPA_4X4C3) {
4115*4882a593Smuzhiyun 						core_num = 3;
4116*4882a593Smuzhiyun 					}
4117*4882a593Smuzhiyun 
4118*4882a593Smuzhiyun 					varbuf_append(&b, vstr_maxp2ga, core_num, cis[i + 1]);
4119*4882a593Smuzhiyun 					/* pa2g */
4120*4882a593Smuzhiyun 					varbuf_append(&b, vstr_sr13pa2ga, core_num,
4121*4882a593Smuzhiyun 						(cis[i + 3] << 8) + cis[i + 2],
4122*4882a593Smuzhiyun 						(cis[i + 5] << 8) + cis[i + 4],
4123*4882a593Smuzhiyun 						(cis[i + 7] << 8) + cis[i + 6],
4124*4882a593Smuzhiyun 						(cis[i + 9] << 8) + cis[i + 8]);
4125*4882a593Smuzhiyun 					/* pa2g40 */
4126*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pa2g40a, core_num,
4127*4882a593Smuzhiyun 						(cis[i + 11] << 8) + cis[i + 10],
4128*4882a593Smuzhiyun 						(cis[i + 13] << 8) + cis[i + 12],
4129*4882a593Smuzhiyun 						(cis[i + 15] << 8) + cis[i + 14],
4130*4882a593Smuzhiyun 						(cis[i + 17] << 8) + cis[i + 16]);
4131*4882a593Smuzhiyun 					for (j = 0; j < 5; j++) {
4132*4882a593Smuzhiyun 						varbuf_append(&b, vstr_maxp5gba, j, core_num,
4133*4882a593Smuzhiyun 							cis[i + j + 18]);
4134*4882a593Smuzhiyun 					}
4135*4882a593Smuzhiyun 					break;
4136*4882a593Smuzhiyun 				}
4137*4882a593Smuzhiyun 
4138*4882a593Smuzhiyun 				case HNBU_ACPA_BW20_4X4C0:
4139*4882a593Smuzhiyun 				case HNBU_ACPA_BW40_4X4C0:
4140*4882a593Smuzhiyun 				case HNBU_ACPA_BW80_4X4C0:
4141*4882a593Smuzhiyun 				case HNBU_ACPA_BW20_4X4C1:
4142*4882a593Smuzhiyun 				case HNBU_ACPA_BW40_4X4C1:
4143*4882a593Smuzhiyun 				case HNBU_ACPA_BW80_4X4C1:
4144*4882a593Smuzhiyun 				case HNBU_ACPA_BW20_4X4C2:
4145*4882a593Smuzhiyun 				case HNBU_ACPA_BW40_4X4C2:
4146*4882a593Smuzhiyun 				case HNBU_ACPA_BW80_4X4C2:
4147*4882a593Smuzhiyun 				case HNBU_ACPA_BW20_4X4C3:
4148*4882a593Smuzhiyun 				case HNBU_ACPA_BW40_4X4C3:
4149*4882a593Smuzhiyun 				case HNBU_ACPA_BW80_4X4C3: {
4150*4882a593Smuzhiyun 					int k = 0;
4151*4882a593Smuzhiyun 					char pabuf[140]; /* max: 20 '0x????'s + 19 ','s + 1 Null */
4152*4882a593Smuzhiyun 					int core_num = 0, buflen = 0;
4153*4882a593Smuzhiyun 					uint8 tuple = cis[i];
4154*4882a593Smuzhiyun 
4155*4882a593Smuzhiyun 					if (tuple == HNBU_ACPA_BW20_4X4C1 ||
4156*4882a593Smuzhiyun 						tuple == HNBU_ACPA_BW40_4X4C1 ||
4157*4882a593Smuzhiyun 						tuple == HNBU_ACPA_BW80_4X4C1) {
4158*4882a593Smuzhiyun 						core_num = 1;
4159*4882a593Smuzhiyun 					} else if (tuple == HNBU_ACPA_BW20_4X4C2 ||
4160*4882a593Smuzhiyun 						tuple == HNBU_ACPA_BW40_4X4C2 ||
4161*4882a593Smuzhiyun 						tuple == HNBU_ACPA_BW80_4X4C2) {
4162*4882a593Smuzhiyun 						core_num = 2;
4163*4882a593Smuzhiyun 					} else if (tuple == HNBU_ACPA_BW20_4X4C3 ||
4164*4882a593Smuzhiyun 						tuple == HNBU_ACPA_BW40_4X4C3 ||
4165*4882a593Smuzhiyun 						tuple == HNBU_ACPA_BW80_4X4C3) {
4166*4882a593Smuzhiyun 						core_num = 3;
4167*4882a593Smuzhiyun 					}
4168*4882a593Smuzhiyun 
4169*4882a593Smuzhiyun 					buflen = sizeof(pabuf);
4170*4882a593Smuzhiyun 					for (j = 0; j < 20; j++) { /* cis[i+1] - cis[i+40] */
4171*4882a593Smuzhiyun 						k += snprintf(pabuf+k, buflen-k, rstr_hex,
4172*4882a593Smuzhiyun 							((cis[i + (2*j) + 2] << 8) +
4173*4882a593Smuzhiyun 							cis[i + (2*j) + 1]));
4174*4882a593Smuzhiyun 						if (j < 19) {
4175*4882a593Smuzhiyun 							k += snprintf(pabuf+k, buflen-k,
4176*4882a593Smuzhiyun 								",");
4177*4882a593Smuzhiyun 						}
4178*4882a593Smuzhiyun 					}
4179*4882a593Smuzhiyun 
4180*4882a593Smuzhiyun 					if (tuple == HNBU_ACPA_BW20_4X4C0 ||
4181*4882a593Smuzhiyun 						tuple == HNBU_ACPA_BW20_4X4C1 ||
4182*4882a593Smuzhiyun 						tuple == HNBU_ACPA_BW20_4X4C2 ||
4183*4882a593Smuzhiyun 						tuple == HNBU_ACPA_BW20_4X4C3) {
4184*4882a593Smuzhiyun 						varbuf_append(&b, vstr_sr13pa5ga, core_num, pabuf);
4185*4882a593Smuzhiyun 					} else {
4186*4882a593Smuzhiyun 						int bw = 40;
4187*4882a593Smuzhiyun 
4188*4882a593Smuzhiyun 						if (tuple == HNBU_ACPA_BW80_4X4C0 ||
4189*4882a593Smuzhiyun 							tuple == HNBU_ACPA_BW80_4X4C1 ||
4190*4882a593Smuzhiyun 							tuple == HNBU_ACPA_BW80_4X4C2 ||
4191*4882a593Smuzhiyun 							tuple == HNBU_ACPA_BW80_4X4C3) {
4192*4882a593Smuzhiyun 							bw = 80;
4193*4882a593Smuzhiyun 						}
4194*4882a593Smuzhiyun 						varbuf_append(&b, vstr_sr13pa5gbwa, bw,
4195*4882a593Smuzhiyun 							core_num, pabuf);
4196*4882a593Smuzhiyun 					}
4197*4882a593Smuzhiyun 					break;
4198*4882a593Smuzhiyun 				}
4199*4882a593Smuzhiyun 
4200*4882a593Smuzhiyun 				case HNBU_RSSI_DELTA_2G_B0:
4201*4882a593Smuzhiyun 				case HNBU_RSSI_DELTA_2G_B1:
4202*4882a593Smuzhiyun 				case HNBU_RSSI_DELTA_2G_B2:
4203*4882a593Smuzhiyun 				case HNBU_RSSI_DELTA_2G_B3:
4204*4882a593Smuzhiyun 				case HNBU_RSSI_DELTA_2G_B4: {
4205*4882a593Smuzhiyun 					uint8 tuple = cis[i];
4206*4882a593Smuzhiyun 					uint8 grp;
4207*4882a593Smuzhiyun 					if (tuple  == HNBU_RSSI_DELTA_2G_B0) {
4208*4882a593Smuzhiyun 						grp = 0;
4209*4882a593Smuzhiyun 					} else if (tuple  == HNBU_RSSI_DELTA_2G_B1) {
4210*4882a593Smuzhiyun 						grp = 1;
4211*4882a593Smuzhiyun 					} else if (tuple  == HNBU_RSSI_DELTA_2G_B2) {
4212*4882a593Smuzhiyun 						grp = 2;
4213*4882a593Smuzhiyun 					} else if (tuple  == HNBU_RSSI_DELTA_2G_B3) {
4214*4882a593Smuzhiyun 						grp = 3;
4215*4882a593Smuzhiyun 					} else {
4216*4882a593Smuzhiyun 						grp = 4;
4217*4882a593Smuzhiyun 					}
4218*4882a593Smuzhiyun 					/* 2G Band Gourp = grp */
4219*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rssidelta2g, grp,
4220*4882a593Smuzhiyun 						cis[i + 1],  cis[i + 2],
4221*4882a593Smuzhiyun 						cis[i + 3],  cis[i + 4],
4222*4882a593Smuzhiyun 						cis[i + 5],  cis[i + 6],
4223*4882a593Smuzhiyun 						cis[i + 7],  cis[i + 8],
4224*4882a593Smuzhiyun 						cis[i + 9],  cis[i + 10],
4225*4882a593Smuzhiyun 						cis[i + 11], cis[i + 12],
4226*4882a593Smuzhiyun 						cis[i + 13], cis[i + 14],
4227*4882a593Smuzhiyun 						cis[i + 15], cis[i + 16]);
4228*4882a593Smuzhiyun 					break;
4229*4882a593Smuzhiyun 				}
4230*4882a593Smuzhiyun 
4231*4882a593Smuzhiyun 				case  HNBU_RSSI_CAL_FREQ_GRP_2G:
4232*4882a593Smuzhiyun 					/* 2G Band Gourp Defintion */
4233*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rssicalfrqg,
4234*4882a593Smuzhiyun 						cis[i + 1],  cis[i + 2],
4235*4882a593Smuzhiyun 						cis[i + 3],  cis[i + 4],
4236*4882a593Smuzhiyun 						cis[i + 5],  cis[i + 6],
4237*4882a593Smuzhiyun 						cis[i + 7]);
4238*4882a593Smuzhiyun 					break;
4239*4882a593Smuzhiyun 
4240*4882a593Smuzhiyun 				case HNBU_RSSI_DELTA_5GL:
4241*4882a593Smuzhiyun 				case HNBU_RSSI_DELTA_5GML:
4242*4882a593Smuzhiyun 				case HNBU_RSSI_DELTA_5GMU:
4243*4882a593Smuzhiyun 				case HNBU_RSSI_DELTA_5GH: {
4244*4882a593Smuzhiyun 					uint8 tuple = cis[i];
4245*4882a593Smuzhiyun 					char *band[] = {"l", "ml", "mu", "h"};
4246*4882a593Smuzhiyun 					char *pband;
4247*4882a593Smuzhiyun 					if (tuple == HNBU_RSSI_DELTA_5GL) {
4248*4882a593Smuzhiyun 						pband = band[0];
4249*4882a593Smuzhiyun 					} else if (tuple == HNBU_RSSI_DELTA_5GML) {
4250*4882a593Smuzhiyun 						pband = band[1];
4251*4882a593Smuzhiyun 					} else if (tuple == HNBU_RSSI_DELTA_5GMU) {
4252*4882a593Smuzhiyun 						pband = band[2];
4253*4882a593Smuzhiyun 					} else {
4254*4882a593Smuzhiyun 						pband = band[3];
4255*4882a593Smuzhiyun 					}
4256*4882a593Smuzhiyun 					/* 5G Band = band */
4257*4882a593Smuzhiyun 					varbuf_append(&b, vstr_rssidelta5g, pband,
4258*4882a593Smuzhiyun 						cis[i + 1],  cis[i + 2],
4259*4882a593Smuzhiyun 						cis[i + 3],  cis[i + 4],
4260*4882a593Smuzhiyun 						cis[i + 5],  cis[i + 6],
4261*4882a593Smuzhiyun 						cis[i + 7],  cis[i + 8],
4262*4882a593Smuzhiyun 						cis[i + 9],  cis[i + 10],
4263*4882a593Smuzhiyun 						cis[i + 11], cis[i + 12],
4264*4882a593Smuzhiyun 						cis[i + 13], cis[i + 14],
4265*4882a593Smuzhiyun 						cis[i + 15], cis[i + 16],
4266*4882a593Smuzhiyun 						cis[i + 17], cis[i + 17],
4267*4882a593Smuzhiyun 						cis[i + 19], cis[i + 20],
4268*4882a593Smuzhiyun 						cis[i + 21], cis[i + 22],
4269*4882a593Smuzhiyun 						cis[i + 9],  cis[i + 24]);
4270*4882a593Smuzhiyun 					break;
4271*4882a593Smuzhiyun 				}
4272*4882a593Smuzhiyun 
4273*4882a593Smuzhiyun 				case HNBU_ACPA_6G_C0: {
4274*4882a593Smuzhiyun 					const int a = 0;
4275*4882a593Smuzhiyun #ifndef OTP_SKIP_MAXP_PAPARAMS
4276*4882a593Smuzhiyun 					varbuf_append(&b, vstr_subband6gver,
4277*4882a593Smuzhiyun 						(cis[i + 2] << 8) + cis[i + 1]);
4278*4882a593Smuzhiyun 					/* maxp5g */
4279*4882a593Smuzhiyun 					varbuf_append(&b, vstr_maxp6ga, a,
4280*4882a593Smuzhiyun 						cis[i + 3],
4281*4882a593Smuzhiyun 						cis[i + 4],
4282*4882a593Smuzhiyun 						cis[i + 5],
4283*4882a593Smuzhiyun 						cis[i + 6],
4284*4882a593Smuzhiyun 						cis[i + 7],
4285*4882a593Smuzhiyun 						cis[i + 8]);
4286*4882a593Smuzhiyun #endif /* OTP_SKIP_MAXP_PAPARAMS */
4287*4882a593Smuzhiyun 					/* pa5g */
4288*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pa6ga, a,
4289*4882a593Smuzhiyun 						(cis[i + 10] << 8) + cis[i + 9],
4290*4882a593Smuzhiyun 						(cis[i + 12] << 8) + cis[i + 11],
4291*4882a593Smuzhiyun 						(cis[i + 14] << 8) + cis[i + 13],
4292*4882a593Smuzhiyun 						(cis[i + 16] << 8) + cis[i + 15],
4293*4882a593Smuzhiyun 						(cis[i + 18] << 8) + cis[i + 17],
4294*4882a593Smuzhiyun 						(cis[i + 20] << 8) + cis[i + 19],
4295*4882a593Smuzhiyun 						(cis[i + 22] << 8) + cis[i + 21],
4296*4882a593Smuzhiyun 						(cis[i + 24] << 8) + cis[i + 23],
4297*4882a593Smuzhiyun 						(cis[i + 26] << 8) + cis[i + 25],
4298*4882a593Smuzhiyun 						(cis[i + 28] << 8) + cis[i + 27],
4299*4882a593Smuzhiyun 						(cis[i + 30] << 8) + cis[i + 29],
4300*4882a593Smuzhiyun 						(cis[i + 32] << 8) + cis[i + 31],
4301*4882a593Smuzhiyun 						(cis[i + 34] << 8) + cis[i + 33],
4302*4882a593Smuzhiyun 						(cis[i + 36] << 8) + cis[i + 35],
4303*4882a593Smuzhiyun 						(cis[i + 38] << 8) + cis[i + 37],
4304*4882a593Smuzhiyun 						(cis[i + 40] << 8) + cis[i + 39],
4305*4882a593Smuzhiyun 						(cis[i + 42] << 8) + cis[i + 41],
4306*4882a593Smuzhiyun 						(cis[i + 44] << 8) + cis[i + 43]);
4307*4882a593Smuzhiyun 					break;
4308*4882a593Smuzhiyun 				}
4309*4882a593Smuzhiyun 
4310*4882a593Smuzhiyun 				case HNBU_ACPA_6G_C1: {
4311*4882a593Smuzhiyun 					const int a = 1;
4312*4882a593Smuzhiyun #ifndef OTP_SKIP_MAXP_PAPARAMS
4313*4882a593Smuzhiyun 					/* maxp6g */
4314*4882a593Smuzhiyun 					varbuf_append(&b, vstr_maxp6ga, a,
4315*4882a593Smuzhiyun 						cis[i + 1],
4316*4882a593Smuzhiyun 						cis[i + 2],
4317*4882a593Smuzhiyun 						cis[i + 3],
4318*4882a593Smuzhiyun 						cis[i + 4],
4319*4882a593Smuzhiyun 						cis[i + 5],
4320*4882a593Smuzhiyun 						cis[i + 6]);
4321*4882a593Smuzhiyun #endif /* OTP_SKIP_MAXP_PAPARAMS */
4322*4882a593Smuzhiyun 					/* pa6g */
4323*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pa6ga, a,
4324*4882a593Smuzhiyun 						(cis[i + 8] << 8) + cis[i + 7],
4325*4882a593Smuzhiyun 						(cis[i + 10] << 8) + cis[i + 9],
4326*4882a593Smuzhiyun 						(cis[i + 12] << 8) + cis[i + 11],
4327*4882a593Smuzhiyun 						(cis[i + 14] << 8) + cis[i + 13],
4328*4882a593Smuzhiyun 						(cis[i + 16] << 8) + cis[i + 15],
4329*4882a593Smuzhiyun 						(cis[i + 18] << 8) + cis[i + 17],
4330*4882a593Smuzhiyun 						(cis[i + 20] << 8) + cis[i + 19],
4331*4882a593Smuzhiyun 						(cis[i + 22] << 8) + cis[i + 21],
4332*4882a593Smuzhiyun 						(cis[i + 24] << 8) + cis[i + 23],
4333*4882a593Smuzhiyun 						(cis[i + 26] << 8) + cis[i + 25],
4334*4882a593Smuzhiyun 						(cis[i + 28] << 8) + cis[i + 27],
4335*4882a593Smuzhiyun 						(cis[i + 30] << 8) + cis[i + 29],
4336*4882a593Smuzhiyun 						(cis[i + 32] << 8) + cis[i + 31],
4337*4882a593Smuzhiyun 						(cis[i + 34] << 8) + cis[i + 33],
4338*4882a593Smuzhiyun 						(cis[i + 36] << 8) + cis[i + 35],
4339*4882a593Smuzhiyun 						(cis[i + 38] << 8) + cis[i + 37],
4340*4882a593Smuzhiyun 						(cis[i + 40] << 8) + cis[i + 39],
4341*4882a593Smuzhiyun 						(cis[i + 42] << 8) + cis[i + 41]);
4342*4882a593Smuzhiyun 					break;
4343*4882a593Smuzhiyun 				}
4344*4882a593Smuzhiyun 
4345*4882a593Smuzhiyun 				case HNBU_ACPA_6G_C2: {
4346*4882a593Smuzhiyun 					const int a = 2;
4347*4882a593Smuzhiyun #ifndef OTP_SKIP_MAXP_PAPARAMS
4348*4882a593Smuzhiyun 					/* maxp6g */
4349*4882a593Smuzhiyun 					varbuf_append(&b, vstr_maxp6ga, a,
4350*4882a593Smuzhiyun 						cis[i + 1],
4351*4882a593Smuzhiyun 						cis[i + 2],
4352*4882a593Smuzhiyun 						cis[i + 3],
4353*4882a593Smuzhiyun 						cis[i + 4],
4354*4882a593Smuzhiyun 						cis[i + 5],
4355*4882a593Smuzhiyun 						cis[i + 6]);
4356*4882a593Smuzhiyun #endif /* OTP_SKIP_MAXP_PAPARAMS */
4357*4882a593Smuzhiyun 					/* pa6g */
4358*4882a593Smuzhiyun 					varbuf_append(&b, vstr_pa6ga, a,
4359*4882a593Smuzhiyun 						(cis[i + 8] << 8) + cis[i + 7],
4360*4882a593Smuzhiyun 						(cis[i + 10] << 8) + cis[i + 9],
4361*4882a593Smuzhiyun 						(cis[i + 12] << 8) + cis[i + 11],
4362*4882a593Smuzhiyun 						(cis[i + 14] << 8) + cis[i + 13],
4363*4882a593Smuzhiyun 						(cis[i + 16] << 8) + cis[i + 15],
4364*4882a593Smuzhiyun 						(cis[i + 18] << 8) + cis[i + 17],
4365*4882a593Smuzhiyun 						(cis[i + 20] << 8) + cis[i + 19],
4366*4882a593Smuzhiyun 						(cis[i + 22] << 8) + cis[i + 21],
4367*4882a593Smuzhiyun 						(cis[i + 24] << 8) + cis[i + 23],
4368*4882a593Smuzhiyun 						(cis[i + 26] << 8) + cis[i + 25],
4369*4882a593Smuzhiyun 						(cis[i + 28] << 8) + cis[i + 27],
4370*4882a593Smuzhiyun 						(cis[i + 30] << 8) + cis[i + 29],
4371*4882a593Smuzhiyun 						(cis[i + 32] << 8) + cis[i + 31],
4372*4882a593Smuzhiyun 						(cis[i + 34] << 8) + cis[i + 33],
4373*4882a593Smuzhiyun 						(cis[i + 36] << 8) + cis[i + 35],
4374*4882a593Smuzhiyun 						(cis[i + 38] << 8) + cis[i + 37],
4375*4882a593Smuzhiyun 						(cis[i + 40] << 8) + cis[i + 39],
4376*4882a593Smuzhiyun 						(cis[i + 42] << 8) + cis[i + 41]);
4377*4882a593Smuzhiyun 					break;
4378*4882a593Smuzhiyun 				}
4379*4882a593Smuzhiyun 
4380*4882a593Smuzhiyun 				case HNBU_SUBBAND5GVER:
4381*4882a593Smuzhiyun 					varbuf_append(&b, vstr_subband5gver,
4382*4882a593Smuzhiyun 					        (cis[i + 2] << 8) + cis[i + 1]);
4383*4882a593Smuzhiyun 					break;
4384*4882a593Smuzhiyun 
4385*4882a593Smuzhiyun 				case HNBU_PAPARAMBWVER:
4386*4882a593Smuzhiyun 					varbuf_append(&b, vstr_paparambwver, cis[i + 1]);
4387*4882a593Smuzhiyun 					break;
4388*4882a593Smuzhiyun 
4389*4882a593Smuzhiyun 				case HNBU_TXBFRPCALS:
4390*4882a593Smuzhiyun 				/* note: all 5 rpcal parameters are expected to be */
4391*4882a593Smuzhiyun 				/* inside one tuple record, i.e written with one  */
4392*4882a593Smuzhiyun 				/* wl wrvar cmd as follows: */
4393*4882a593Smuzhiyun 				/* wl wrvar rpcal2g=0x1211 ... rpcal5gb3=0x0  */
4394*4882a593Smuzhiyun 					if (tlen != 11 ) { /* sanity check */
4395*4882a593Smuzhiyun 						BS_ERROR(("srom_parsecis:incorrect length:%d for"
4396*4882a593Smuzhiyun 							" HNBU_TXBFRPCALS tuple\n",
4397*4882a593Smuzhiyun 							tlen));
4398*4882a593Smuzhiyun 						break;
4399*4882a593Smuzhiyun 					}
4400*4882a593Smuzhiyun 
4401*4882a593Smuzhiyun 					varbuf_append(&b, vstr_paparamrpcalvars[0],
4402*4882a593Smuzhiyun 						(cis[i + 1] + (cis[i + 2] << 8)));
4403*4882a593Smuzhiyun 					varbuf_append(&b, vstr_paparamrpcalvars[1],
4404*4882a593Smuzhiyun 						(cis[i + 3]  +  (cis[i + 4] << 8)));
4405*4882a593Smuzhiyun 					varbuf_append(&b, vstr_paparamrpcalvars[2],
4406*4882a593Smuzhiyun 						(cis[i + 5]  +  (cis[i + 6] << 8)));
4407*4882a593Smuzhiyun 					varbuf_append(&b, vstr_paparamrpcalvars[3],
4408*4882a593Smuzhiyun 						(cis[i + 7]  +  (cis[i + 8] << 8)));
4409*4882a593Smuzhiyun 					varbuf_append(&b, vstr_paparamrpcalvars[4],
4410*4882a593Smuzhiyun 						(cis[i + 9]  +  (cis[i + 10] << 8)));
4411*4882a593Smuzhiyun 					break;
4412*4882a593Smuzhiyun 
4413*4882a593Smuzhiyun 				case HNBU_GPIO_PULL_DOWN:
4414*4882a593Smuzhiyun 					varbuf_append(&b, vstr_gpdn,
4415*4882a593Smuzhiyun 					              (cis[i + 4] << 24) |
4416*4882a593Smuzhiyun 					              (cis[i + 3] << 16) |
4417*4882a593Smuzhiyun 					              (cis[i + 2] << 8) |
4418*4882a593Smuzhiyun 					              cis[i + 1]);
4419*4882a593Smuzhiyun 					break;
4420*4882a593Smuzhiyun 
4421*4882a593Smuzhiyun 				case HNBU_MACADDR2:
4422*4882a593Smuzhiyun 					if (!(ETHER_ISNULLADDR(&cis[i+1])) &&
4423*4882a593Smuzhiyun 					    !(ETHER_ISMULTI(&cis[i+1]))) {
4424*4882a593Smuzhiyun 						bcm_ether_ntoa((struct ether_addr *)&cis[i + 1],
4425*4882a593Smuzhiyun 						               eabuf2);
4426*4882a593Smuzhiyun 					}
4427*4882a593Smuzhiyun 					break;
4428*4882a593Smuzhiyun 				} /* CISTPL_BRCM_HNBU */
4429*4882a593Smuzhiyun 				break;
4430*4882a593Smuzhiyun 			} /* switch (tup) */
4431*4882a593Smuzhiyun 
4432*4882a593Smuzhiyun 			i += tlen;
4433*4882a593Smuzhiyun 		} while (tup != CISTPL_END);
4434*4882a593Smuzhiyun 	}
4435*4882a593Smuzhiyun 
4436*4882a593Smuzhiyun 	if (boardnum != -1) {
4437*4882a593Smuzhiyun 		varbuf_append(&b, vstr_boardnum, boardnum);
4438*4882a593Smuzhiyun 	}
4439*4882a593Smuzhiyun 
4440*4882a593Smuzhiyun 	if (eabuf[0]) {
4441*4882a593Smuzhiyun 		varbuf_append(&b, vstr_macaddr, eabuf);
4442*4882a593Smuzhiyun 	}
4443*4882a593Smuzhiyun 
4444*4882a593Smuzhiyun 	if (eabuf2[0]) {
4445*4882a593Smuzhiyun 		varbuf_append(&b, vstr_macaddr2, eabuf2);
4446*4882a593Smuzhiyun 	}
4447*4882a593Smuzhiyun 
4448*4882a593Smuzhiyun #ifndef BCM_BOOTLOADER
4449*4882a593Smuzhiyun 	/* if there is no antenna gain field, set default */
4450*4882a593Smuzhiyun 	sromrev = (sromrev == 1u) ? (uint8)getintvar(NULL, rstr_sromrev) : sromrev;
4451*4882a593Smuzhiyun 	if (sromrev <= 10u && getvar(NULL, rstr_ag0) == NULL && ag_init == FALSE) {
4452*4882a593Smuzhiyun 		varbuf_append(&b, vstr_ag, 0, 0xff);
4453*4882a593Smuzhiyun 	}
4454*4882a593Smuzhiyun #endif
4455*4882a593Smuzhiyun 
4456*4882a593Smuzhiyun 	/* final nullbyte terminator */
4457*4882a593Smuzhiyun 	ASSERT(b.size >= 1u);
4458*4882a593Smuzhiyun 	*b.buf++ = '\0';
4459*4882a593Smuzhiyun 
4460*4882a593Smuzhiyun 	ASSERT((uint)(b.buf - base) <= var_cis_size);
4461*4882a593Smuzhiyun 
4462*4882a593Smuzhiyun 	/* initvars_table() MALLOCs, copies and assigns the MALLOCed buffer to '*vars' */
4463*4882a593Smuzhiyun 	err = initvars_table(osh, base /* start */, b.buf /* end */, vars, count);
4464*4882a593Smuzhiyun 
4465*4882a593Smuzhiyun 	MFREE(osh, base, var_cis_size);
4466*4882a593Smuzhiyun 	return err;
4467*4882a593Smuzhiyun }
4468*4882a593Smuzhiyun #endif /* !defined(BCMDONGLEHOST) */
4469*4882a593Smuzhiyun 
4470*4882a593Smuzhiyun /**
4471*4882a593Smuzhiyun  * In chips with chipcommon rev 32 and later, the srom is in chipcommon,
4472*4882a593Smuzhiyun  * not in the bus cores.
4473*4882a593Smuzhiyun  */
4474*4882a593Smuzhiyun static uint16
4475*4882a593Smuzhiyun srom_cc_cmd(si_t *sih, osl_t *osh, volatile void *ccregs, uint32 cmd, uint wordoff, uint16 data)
4476*4882a593Smuzhiyun {
4477*4882a593Smuzhiyun 	chipcregs_t *cc = ccregs;
4478*4882a593Smuzhiyun 	uint wait_cnt = 1000;
4479*4882a593Smuzhiyun 	uint32 byteoff = 0, sprom_size = 0;
4480*4882a593Smuzhiyun 
4481*4882a593Smuzhiyun 	BCM_REFERENCE(sih);
4482*4882a593Smuzhiyun 	byteoff = wordoff * 2;
4483*4882a593Smuzhiyun 
4484*4882a593Smuzhiyun 	sprom_size = R_REG(osh, &cc->sromcontrol);
4485*4882a593Smuzhiyun 	sprom_size = (sprom_size & SROM_SIZE_MASK) >> SROM_SIZE_SHFT_MASK;
4486*4882a593Smuzhiyun 	if (sprom_size == SROM_SIZE_2K)
4487*4882a593Smuzhiyun 		sprom_size = 2048;
4488*4882a593Smuzhiyun 	else if (sprom_size == SROM_SIZE_512)
4489*4882a593Smuzhiyun 		sprom_size = 512;
4490*4882a593Smuzhiyun 	else if (sprom_size == SROM_SIZE_128)
4491*4882a593Smuzhiyun 		sprom_size = 128;
4492*4882a593Smuzhiyun 	if (byteoff >= sprom_size)
4493*4882a593Smuzhiyun 		return 0xffff;
4494*4882a593Smuzhiyun 
4495*4882a593Smuzhiyun 	if ((cmd == SRC_OP_READ) || (cmd == SRC_OP_WRITE)) {
4496*4882a593Smuzhiyun 		if (sih->ccrev >= 59)
4497*4882a593Smuzhiyun 			W_REG(osh, &cc->chipcontrol, (byteoff & SROM16K_BANK_SEL_MASK) >>
4498*4882a593Smuzhiyun 				SROM16K_BANK_SHFT_MASK);
4499*4882a593Smuzhiyun 		W_REG(osh, &cc->sromaddress, (byteoff  & SROM16K_ADDR_SEL_MASK));
4500*4882a593Smuzhiyun 		if (cmd == SRC_OP_WRITE)
4501*4882a593Smuzhiyun 			W_REG(osh, &cc->sromdata, data);
4502*4882a593Smuzhiyun 	}
4503*4882a593Smuzhiyun 
4504*4882a593Smuzhiyun 	W_REG(osh, &cc->sromcontrol, SRC_START | cmd);
4505*4882a593Smuzhiyun 
4506*4882a593Smuzhiyun 	while (wait_cnt--) {
4507*4882a593Smuzhiyun 		if ((R_REG(osh, &cc->sromcontrol) & SRC_BUSY) == 0)
4508*4882a593Smuzhiyun 			break;
4509*4882a593Smuzhiyun 	}
4510*4882a593Smuzhiyun 
4511*4882a593Smuzhiyun 	if (!wait_cnt) {
4512*4882a593Smuzhiyun 		BS_ERROR(("srom_cc_cmd: Command 0x%x timed out\n", cmd));
4513*4882a593Smuzhiyun 		return 0xffff;
4514*4882a593Smuzhiyun 	}
4515*4882a593Smuzhiyun 	if (cmd == SRC_OP_READ)
4516*4882a593Smuzhiyun 		return (uint16)R_REG(osh, &cc->sromdata);
4517*4882a593Smuzhiyun 	else
4518*4882a593Smuzhiyun 		return 0xffff;
4519*4882a593Smuzhiyun }
4520*4882a593Smuzhiyun 
4521*4882a593Smuzhiyun #define CC_SROM_SHADOW_WSIZE	512	/* 0x800 - 0xC00 */
4522*4882a593Smuzhiyun 
4523*4882a593Smuzhiyun /**
4524*4882a593Smuzhiyun  * Read in and validate sprom.
4525*4882a593Smuzhiyun  * Return 0 on success, nonzero on error.
4526*4882a593Smuzhiyun  * Returns success on an SPROM containing only ones, unclear if this is intended.
4527*4882a593Smuzhiyun  */
4528*4882a593Smuzhiyun static int
4529*4882a593Smuzhiyun sprom_read_pci(osl_t *osh, si_t *sih, volatile uint16 *sprom, uint wordoff,
4530*4882a593Smuzhiyun 	uint16 *buf, uint nwords, bool check_crc)
4531*4882a593Smuzhiyun {
4532*4882a593Smuzhiyun 	int err = 0;
4533*4882a593Smuzhiyun 	uint i;
4534*4882a593Smuzhiyun 	volatile void *ccregs = NULL;
4535*4882a593Smuzhiyun 	chipcregs_t *cc = NULL;
4536*4882a593Smuzhiyun 	uint32 ccval = 0, sprom_size = 0;
4537*4882a593Smuzhiyun 	uint32 sprom_num_words;
4538*4882a593Smuzhiyun 
4539*4882a593Smuzhiyun 	if (BCM43602_CHIP(sih->chip) ||
4540*4882a593Smuzhiyun 	    (CHIPID(sih->chip) == BCM4360_CHIP_ID) ||
4541*4882a593Smuzhiyun 	    (CHIPID(sih->chip) == BCM43460_CHIP_ID) ||
4542*4882a593Smuzhiyun 	    (CHIPID(sih->chip) == BCM4352_CHIP_ID)) {
4543*4882a593Smuzhiyun 		/* save current control setting */
4544*4882a593Smuzhiyun 		ccval = si_chipcontrl_read(sih);
4545*4882a593Smuzhiyun 	}
4546*4882a593Smuzhiyun 
4547*4882a593Smuzhiyun 	if (BCM43602_CHIP(sih->chip) ||
4548*4882a593Smuzhiyun 		(((CHIPID(sih->chip) == BCM4360_CHIP_ID) ||
4549*4882a593Smuzhiyun 		(CHIPID(sih->chip) == BCM43460_CHIP_ID) ||
4550*4882a593Smuzhiyun 		(CHIPID(sih->chip) == BCM4352_CHIP_ID)) &&
4551*4882a593Smuzhiyun 		(CHIPREV(sih->chiprev) <= 2))) {
4552*4882a593Smuzhiyun 		si_chipcontrl_srom4360(sih, TRUE);
4553*4882a593Smuzhiyun 	}
4554*4882a593Smuzhiyun 
4555*4882a593Smuzhiyun 	if (FALSE) {
4556*4882a593Smuzhiyun 		si_srom_clk_set(sih); /* corrects srom clock frequency */
4557*4882a593Smuzhiyun 	}
4558*4882a593Smuzhiyun 
4559*4882a593Smuzhiyun 	ccregs = ((volatile uint8 *)sprom - CC_SROM_OTP);
4560*4882a593Smuzhiyun 	cc = ccregs;
4561*4882a593Smuzhiyun 	sprom_size = R_REG(osh, &cc->sromcontrol);
4562*4882a593Smuzhiyun 	sprom_size = (sprom_size & SROM_SIZE_MASK) >> SROM_SIZE_SHFT_MASK;
4563*4882a593Smuzhiyun 	if (sprom_size == SROM_SIZE_2K)
4564*4882a593Smuzhiyun 		sprom_size = 2048;
4565*4882a593Smuzhiyun 	else if (sprom_size == SROM_SIZE_512)
4566*4882a593Smuzhiyun 		sprom_size = 512;
4567*4882a593Smuzhiyun 	else if (sprom_size == SROM_SIZE_128)
4568*4882a593Smuzhiyun 		sprom_size = 128;
4569*4882a593Smuzhiyun 	sprom_num_words = sprom_size/2;
4570*4882a593Smuzhiyun 
4571*4882a593Smuzhiyun 	/* read the sprom */
4572*4882a593Smuzhiyun 	for (i = 0; i < nwords; i++) {
4573*4882a593Smuzhiyun 		if (sih->ccrev > 31 && ISSIM_ENAB(sih)) {
4574*4882a593Smuzhiyun 			/* use indirect since direct is too slow on QT */
4575*4882a593Smuzhiyun 			if ((sih->cccaps & CC_CAP_SROM) == 0) {
4576*4882a593Smuzhiyun 				err = 1;
4577*4882a593Smuzhiyun 				goto error;
4578*4882a593Smuzhiyun 			}
4579*4882a593Smuzhiyun 
4580*4882a593Smuzhiyun 			/* hack to get ccregs */
4581*4882a593Smuzhiyun 			ccregs = (volatile void *)((volatile uint8 *)sprom - CC_SROM_OTP);
4582*4882a593Smuzhiyun 			buf[i] = srom_cc_cmd(sih, osh, ccregs, SRC_OP_READ, wordoff + i, 0);
4583*4882a593Smuzhiyun 
4584*4882a593Smuzhiyun 		} else {
4585*4882a593Smuzhiyun 			/* Because of the slow emulation we need to read twice in QT */
4586*4882a593Smuzhiyun 			if (ISSIM_ENAB(sih)) {
4587*4882a593Smuzhiyun 				buf[i] = R_REG(osh, &sprom[wordoff + i]);
4588*4882a593Smuzhiyun 			}
4589*4882a593Smuzhiyun 
4590*4882a593Smuzhiyun 			if ((wordoff + i) >= sprom_num_words) {
4591*4882a593Smuzhiyun 				buf[i] = 0xffff;
4592*4882a593Smuzhiyun 			} else if ((wordoff + i) >= CC_SROM_SHADOW_WSIZE) {
4593*4882a593Smuzhiyun 				/* Srom shadow region in chipcommon is only 512 words
4594*4882a593Smuzhiyun 				 * use indirect access for Srom beyond 512 words
4595*4882a593Smuzhiyun 				 */
4596*4882a593Smuzhiyun 				buf[i] = srom_cc_cmd(sih, osh, ccregs, SRC_OP_READ, wordoff + i, 0);
4597*4882a593Smuzhiyun 			} else {
4598*4882a593Smuzhiyun 				buf[i] = R_REG(osh, &sprom[wordoff + i]);
4599*4882a593Smuzhiyun 			}
4600*4882a593Smuzhiyun 		}
4601*4882a593Smuzhiyun 		if (i == SROM13_SIGN) {
4602*4882a593Smuzhiyun 			if ((buf[SROM13_SIGN] !=  SROM13_SIGNATURE) && (nwords == SROM13_WORDS)) {
4603*4882a593Smuzhiyun 				err = 1;
4604*4882a593Smuzhiyun 				goto error;
4605*4882a593Smuzhiyun 			}
4606*4882a593Smuzhiyun 		}
4607*4882a593Smuzhiyun 	}
4608*4882a593Smuzhiyun 
4609*4882a593Smuzhiyun 	/* bypass crc checking for simulation to allow srom hack */
4610*4882a593Smuzhiyun 	if (ISSIM_ENAB(sih)) {
4611*4882a593Smuzhiyun 		goto error;
4612*4882a593Smuzhiyun 	}
4613*4882a593Smuzhiyun 
4614*4882a593Smuzhiyun 	if (check_crc) {
4615*4882a593Smuzhiyun 
4616*4882a593Smuzhiyun 		if (buf[0] == 0xffff) {
4617*4882a593Smuzhiyun 			/* The hardware thinks that an srom that starts with 0xffff
4618*4882a593Smuzhiyun 			 * is blank, regardless of the rest of the content, so declare
4619*4882a593Smuzhiyun 			 * it bad.
4620*4882a593Smuzhiyun 			 */
4621*4882a593Smuzhiyun 			BS_ERROR(("sprom_read_pci: buf[0] = 0x%x, returning bad-crc\n", buf[0]));
4622*4882a593Smuzhiyun 			err = 1;
4623*4882a593Smuzhiyun 			goto error;
4624*4882a593Smuzhiyun 		}
4625*4882a593Smuzhiyun 
4626*4882a593Smuzhiyun 		/* fixup the endianness so crc8 will pass */
4627*4882a593Smuzhiyun 		htol16_buf(buf, nwords * 2);
4628*4882a593Smuzhiyun 		if (hndcrc8((uint8 *)buf, nwords * 2, CRC8_INIT_VALUE) != CRC8_GOOD_VALUE) {
4629*4882a593Smuzhiyun 			/* DBG only pci always read srom4 first, then srom8/9 */
4630*4882a593Smuzhiyun 			/* BS_ERROR(("sprom_read_pci: bad crc\n")); */
4631*4882a593Smuzhiyun 			err = 1;
4632*4882a593Smuzhiyun 		}
4633*4882a593Smuzhiyun 		/* now correct the endianness of the byte array */
4634*4882a593Smuzhiyun 		ltoh16_buf(buf, nwords * 2);
4635*4882a593Smuzhiyun 	}
4636*4882a593Smuzhiyun 
4637*4882a593Smuzhiyun error:
4638*4882a593Smuzhiyun 	if ((CHIPID(sih->chip) == BCM4360_CHIP_ID) ||
4639*4882a593Smuzhiyun 	    (CHIPID(sih->chip) == BCM43460_CHIP_ID) ||
4640*4882a593Smuzhiyun 	    (CHIPID(sih->chip) == BCM4352_CHIP_ID) ||
4641*4882a593Smuzhiyun 	    BCM43602_CHIP(sih->chip)) {
4642*4882a593Smuzhiyun 		/* Restore config after reading SROM */
4643*4882a593Smuzhiyun 		si_chipcontrl_restore(sih, ccval);
4644*4882a593Smuzhiyun 	}
4645*4882a593Smuzhiyun 
4646*4882a593Smuzhiyun 	return err;
4647*4882a593Smuzhiyun }
4648*4882a593Smuzhiyun 
4649*4882a593Smuzhiyun #if !defined(BCMDONGLEHOST)
4650*4882a593Smuzhiyun #if defined(BCMNVRAMW) || defined(BCMNVRAMR)
4651*4882a593Smuzhiyun static int
4652*4882a593Smuzhiyun BCMSROMATTACHFN(otp_read_pci)(osl_t *osh, si_t *sih, uint16 *buf, uint bufsz)
4653*4882a593Smuzhiyun {
4654*4882a593Smuzhiyun 	uint8 *otp;
4655*4882a593Smuzhiyun 	uint sz = OTP_SZ_MAX/2; /* size in words */
4656*4882a593Smuzhiyun 	int err = 0;
4657*4882a593Smuzhiyun 
4658*4882a593Smuzhiyun 	if (bufsz > OTP_SZ_MAX) {
4659*4882a593Smuzhiyun 		return BCME_ERROR;
4660*4882a593Smuzhiyun 	}
4661*4882a593Smuzhiyun 
4662*4882a593Smuzhiyun 	/* freed in same function */
4663*4882a593Smuzhiyun 	if ((otp = MALLOC_NOPERSIST(osh, OTP_SZ_MAX)) == NULL) {
4664*4882a593Smuzhiyun 		return BCME_ERROR;
4665*4882a593Smuzhiyun 	}
4666*4882a593Smuzhiyun 
4667*4882a593Smuzhiyun 	bzero(otp, OTP_SZ_MAX);
4668*4882a593Smuzhiyun 
4669*4882a593Smuzhiyun 	err = otp_read_region(sih, OTP_HW_RGN, (uint16 *)otp, &sz);
4670*4882a593Smuzhiyun 
4671*4882a593Smuzhiyun 	if (err) {
4672*4882a593Smuzhiyun 		MFREE(osh, otp, OTP_SZ_MAX);
4673*4882a593Smuzhiyun 		return err;
4674*4882a593Smuzhiyun 	}
4675*4882a593Smuzhiyun 
4676*4882a593Smuzhiyun 	bcopy(otp, buf, bufsz);
4677*4882a593Smuzhiyun 
4678*4882a593Smuzhiyun 	/* Check CRC */
4679*4882a593Smuzhiyun 	if (((uint16 *)otp)[0] == 0xffff) {
4680*4882a593Smuzhiyun 		/* The hardware thinks that an srom that starts with 0xffff
4681*4882a593Smuzhiyun 		 * is blank, regardless of the rest of the content, so declare
4682*4882a593Smuzhiyun 		 * it bad.
4683*4882a593Smuzhiyun 		 */
4684*4882a593Smuzhiyun 		BS_ERROR(("otp_read_pci: otp[0] = 0x%x, returning bad-crc\n",
4685*4882a593Smuzhiyun 		          ((uint16 *)otp)[0]));
4686*4882a593Smuzhiyun 		MFREE(osh, otp, OTP_SZ_MAX);
4687*4882a593Smuzhiyun 		return 1;
4688*4882a593Smuzhiyun 	}
4689*4882a593Smuzhiyun 
4690*4882a593Smuzhiyun 	/* fixup the endianness so crc8 will pass */
4691*4882a593Smuzhiyun 	htol16_buf(otp, OTP_SZ_MAX);
4692*4882a593Smuzhiyun 	if (hndcrc8(otp, SROM4_WORDS * 2, CRC8_INIT_VALUE) != CRC8_GOOD_VALUE &&
4693*4882a593Smuzhiyun 		hndcrc8(otp, SROM10_WORDS * 2, CRC8_INIT_VALUE) != CRC8_GOOD_VALUE &&
4694*4882a593Smuzhiyun 		hndcrc8(otp, SROM11_WORDS * 2, CRC8_INIT_VALUE) != CRC8_GOOD_VALUE &&
4695*4882a593Smuzhiyun 		hndcrc8(otp, SROM12_WORDS * 2, CRC8_INIT_VALUE) != CRC8_GOOD_VALUE &&
4696*4882a593Smuzhiyun 		hndcrc8(otp, SROM13_WORDS * 2, CRC8_INIT_VALUE) != CRC8_GOOD_VALUE) {
4697*4882a593Smuzhiyun 		BS_ERROR(("otp_read_pci: bad crc\n"));
4698*4882a593Smuzhiyun 		err = 1;
4699*4882a593Smuzhiyun 	}
4700*4882a593Smuzhiyun 
4701*4882a593Smuzhiyun 	MFREE(osh, otp, OTP_SZ_MAX);
4702*4882a593Smuzhiyun 
4703*4882a593Smuzhiyun 	return err;
4704*4882a593Smuzhiyun }
4705*4882a593Smuzhiyun #endif /* defined(BCMNVRAMW) || defined(BCMNVRAMR) */
4706*4882a593Smuzhiyun #endif /* !defined(BCMDONGLEHOST) */
4707*4882a593Smuzhiyun 
4708*4882a593Smuzhiyun int
4709*4882a593Smuzhiyun srom_otp_write_region_crc(si_t *sih, uint nbytes, uint16* buf16, bool write)
4710*4882a593Smuzhiyun {
4711*4882a593Smuzhiyun #if defined(WLTEST) || defined(BCMDBG)
4712*4882a593Smuzhiyun 	int err = 0, crc = 0;
4713*4882a593Smuzhiyun #if !defined(BCMDONGLEHOST)
4714*4882a593Smuzhiyun 	uint8 *buf8;
4715*4882a593Smuzhiyun 
4716*4882a593Smuzhiyun 	/* Check nbytes is not odd or too big */
4717*4882a593Smuzhiyun 	if ((nbytes & 1) || (nbytes > SROM_MAX))
4718*4882a593Smuzhiyun 		return 1;
4719*4882a593Smuzhiyun 
4720*4882a593Smuzhiyun 	/* block invalid buffer size */
4721*4882a593Smuzhiyun 	if (nbytes < SROM4_WORDS * 2)
4722*4882a593Smuzhiyun 		return BCME_BUFTOOSHORT;
4723*4882a593Smuzhiyun 	else if (nbytes > SROM13_WORDS * 2)
4724*4882a593Smuzhiyun 		return BCME_BUFTOOLONG;
4725*4882a593Smuzhiyun 
4726*4882a593Smuzhiyun 	/* Verify signatures */
4727*4882a593Smuzhiyun 	if (!((buf16[SROM4_SIGN] == SROM4_SIGNATURE) ||
4728*4882a593Smuzhiyun 		(buf16[SROM8_SIGN] == SROM4_SIGNATURE) ||
4729*4882a593Smuzhiyun 		(buf16[SROM10_SIGN] == SROM4_SIGNATURE) ||
4730*4882a593Smuzhiyun 		(buf16[SROM11_SIGN] == SROM11_SIGNATURE)||
4731*4882a593Smuzhiyun 		(buf16[SROM12_SIGN] == SROM12_SIGNATURE)||
4732*4882a593Smuzhiyun 		(buf16[SROM13_SIGN] == SROM13_SIGNATURE))) {
4733*4882a593Smuzhiyun 		BS_ERROR(("srom_otp_write_region_crc: wrong signature SROM4_SIGN %x SROM8_SIGN %x"
4734*4882a593Smuzhiyun 			" SROM10_SIGN %x\n",
4735*4882a593Smuzhiyun 			buf16[SROM4_SIGN], buf16[SROM8_SIGN], buf16[SROM10_SIGN]));
4736*4882a593Smuzhiyun 		return BCME_ERROR;
4737*4882a593Smuzhiyun 	}
4738*4882a593Smuzhiyun 
4739*4882a593Smuzhiyun 	/* Check CRC */
4740*4882a593Smuzhiyun 	if (buf16[0] == 0xffff) {
4741*4882a593Smuzhiyun 		/* The hardware thinks that an srom that starts with 0xffff
4742*4882a593Smuzhiyun 		 * is blank, regardless of the rest of the content, so declare
4743*4882a593Smuzhiyun 		 * it bad.
4744*4882a593Smuzhiyun 		 */
4745*4882a593Smuzhiyun 		BS_ERROR(("srom_otp_write_region_crc: invalid buf16[0] = 0x%x\n", buf16[0]));
4746*4882a593Smuzhiyun 		goto out;
4747*4882a593Smuzhiyun 	}
4748*4882a593Smuzhiyun 
4749*4882a593Smuzhiyun 	buf8 = (uint8*)buf16;
4750*4882a593Smuzhiyun 	/* fixup the endianness and then calculate crc */
4751*4882a593Smuzhiyun 	htol16_buf(buf8, nbytes);
4752*4882a593Smuzhiyun 	crc = ~hndcrc8(buf8, nbytes - 1, CRC8_INIT_VALUE);
4753*4882a593Smuzhiyun 	/* now correct the endianness of the byte array */
4754*4882a593Smuzhiyun 	ltoh16_buf(buf8, nbytes);
4755*4882a593Smuzhiyun 
4756*4882a593Smuzhiyun 	if (nbytes == SROM11_WORDS * 2)
4757*4882a593Smuzhiyun 		buf16[SROM11_CRCREV] = (crc << 8) | (buf16[SROM11_CRCREV] & 0xff);
4758*4882a593Smuzhiyun 	else if (nbytes == SROM12_WORDS * 2)
4759*4882a593Smuzhiyun 		buf16[SROM12_CRCREV] = (crc << 8) | (buf16[SROM12_CRCREV] & 0xff);
4760*4882a593Smuzhiyun 	else if (nbytes == SROM13_WORDS * 2)
4761*4882a593Smuzhiyun 		buf16[SROM13_CRCREV] = (crc << 8) | (buf16[SROM13_CRCREV] & 0xff);
4762*4882a593Smuzhiyun 	else if (nbytes == SROM10_WORDS * 2)
4763*4882a593Smuzhiyun 		buf16[SROM10_CRCREV] = (crc << 8) | (buf16[SROM10_CRCREV] & 0xff);
4764*4882a593Smuzhiyun 	else
4765*4882a593Smuzhiyun 		buf16[SROM4_CRCREV] = (crc << 8) | (buf16[SROM4_CRCREV] & 0xff);
4766*4882a593Smuzhiyun 
4767*4882a593Smuzhiyun #ifdef BCMNVRAMW
4768*4882a593Smuzhiyun 	/* Write the CRC back */
4769*4882a593Smuzhiyun 	if (write)
4770*4882a593Smuzhiyun 		err = otp_write_region(sih, OTP_HW_RGN, buf16, nbytes/2, 0);
4771*4882a593Smuzhiyun #endif /* BCMNVRAMW */
4772*4882a593Smuzhiyun 
4773*4882a593Smuzhiyun out:
4774*4882a593Smuzhiyun #endif /* !defined(BCMDONGLEHOST) */
4775*4882a593Smuzhiyun 	return write ? err : crc;
4776*4882a593Smuzhiyun #else
4777*4882a593Smuzhiyun 	BCM_REFERENCE(sih);
4778*4882a593Smuzhiyun 	BCM_REFERENCE(nbytes);
4779*4882a593Smuzhiyun 	BCM_REFERENCE(buf16);
4780*4882a593Smuzhiyun 	BCM_REFERENCE(write);
4781*4882a593Smuzhiyun 	return 0;
4782*4882a593Smuzhiyun #endif /* WLTEST || BCMDBG */
4783*4882a593Smuzhiyun 
4784*4882a593Smuzhiyun }
4785*4882a593Smuzhiyun 
4786*4882a593Smuzhiyun #if !defined(BCMDONGLEHOST)
4787*4882a593Smuzhiyun int
4788*4882a593Smuzhiyun BCMATTACHFN(dbushost_initvars_flash)(si_t *sih, osl_t *osh, char **base, uint len)
4789*4882a593Smuzhiyun {
4790*4882a593Smuzhiyun 	return initvars_flash(sih, osh, base, len);
4791*4882a593Smuzhiyun }
4792*4882a593Smuzhiyun 
4793*4882a593Smuzhiyun /**
4794*4882a593Smuzhiyun  * Find variables with <devpath> from flash. 'base' points to the beginning
4795*4882a593Smuzhiyun  * of the table upon enter and to the end of the table upon exit when success.
4796*4882a593Smuzhiyun  * Return 0 on success, nonzero on error.
4797*4882a593Smuzhiyun  */
4798*4882a593Smuzhiyun static int
4799*4882a593Smuzhiyun BCMATTACHFN(initvars_flash)(si_t *sih, osl_t *osh, char **base, uint len)
4800*4882a593Smuzhiyun {
4801*4882a593Smuzhiyun 	char *vp = *base;
4802*4882a593Smuzhiyun 	char *flash;
4803*4882a593Smuzhiyun 	int err;
4804*4882a593Smuzhiyun 	char *s;
4805*4882a593Smuzhiyun 	uint l, dl, copy_len;
4806*4882a593Smuzhiyun 	char devpath[SI_DEVPATH_BUFSZ], devpath_pcie[SI_DEVPATH_BUFSZ];
4807*4882a593Smuzhiyun 	char coded_name[SI_DEVPATH_BUFSZ] = {0};
4808*4882a593Smuzhiyun 	int path_len, coded_len, devid_len, pcie_path_len;
4809*4882a593Smuzhiyun 
4810*4882a593Smuzhiyun 	/* allocate memory and read in flash */
4811*4882a593Smuzhiyun 	/* freed in same function */
4812*4882a593Smuzhiyun 	if (!(flash = MALLOC_NOPERSIST(osh, MAX_NVRAM_SPACE)))
4813*4882a593Smuzhiyun 		return BCME_NOMEM;
4814*4882a593Smuzhiyun 	if ((err = nvram_getall(flash, MAX_NVRAM_SPACE)))
4815*4882a593Smuzhiyun 		goto exit;
4816*4882a593Smuzhiyun 
4817*4882a593Smuzhiyun 	/* create legacy devpath prefix */
4818*4882a593Smuzhiyun 	si_devpath(sih, devpath, sizeof(devpath));
4819*4882a593Smuzhiyun 	path_len = strlen(devpath);
4820*4882a593Smuzhiyun 
4821*4882a593Smuzhiyun 	if (BUSTYPE(sih->bustype) == PCI_BUS) {
4822*4882a593Smuzhiyun 		si_devpath_pcie(sih, devpath_pcie, sizeof(devpath_pcie));
4823*4882a593Smuzhiyun 		pcie_path_len = strlen(devpath_pcie);
4824*4882a593Smuzhiyun 	} else
4825*4882a593Smuzhiyun 		pcie_path_len = 0;
4826*4882a593Smuzhiyun 
4827*4882a593Smuzhiyun 	/* create coded devpath prefix */
4828*4882a593Smuzhiyun 	si_coded_devpathvar(sih, coded_name, sizeof(coded_name), "devid");
4829*4882a593Smuzhiyun 
4830*4882a593Smuzhiyun 	/* coded_name now is 'xx:devid, eat ending 'devid' */
4831*4882a593Smuzhiyun 	/* to be 'xx:' */
4832*4882a593Smuzhiyun 	devid_len = strlen("devid");
4833*4882a593Smuzhiyun 	coded_len = strlen(coded_name);
4834*4882a593Smuzhiyun 	if (coded_len > devid_len) {
4835*4882a593Smuzhiyun 		coded_name[coded_len - devid_len] = '\0';
4836*4882a593Smuzhiyun 		coded_len -= devid_len;
4837*4882a593Smuzhiyun 	}
4838*4882a593Smuzhiyun 	else
4839*4882a593Smuzhiyun 		coded_len = 0;
4840*4882a593Smuzhiyun 
4841*4882a593Smuzhiyun 	/* grab vars with the <devpath> prefix or <coded_name> previx in name */
4842*4882a593Smuzhiyun 	for (s = flash; s && *s; s += l + 1) {
4843*4882a593Smuzhiyun 		l = strlen(s);
4844*4882a593Smuzhiyun 
4845*4882a593Smuzhiyun 		/* skip non-matching variable */
4846*4882a593Smuzhiyun 		if (strncmp(s, devpath, path_len) == 0)
4847*4882a593Smuzhiyun 			dl = path_len;
4848*4882a593Smuzhiyun 		else if (pcie_path_len && strncmp(s, devpath_pcie, pcie_path_len) == 0)
4849*4882a593Smuzhiyun 			dl = pcie_path_len;
4850*4882a593Smuzhiyun 		else if (coded_len && strncmp(s, coded_name, coded_len) == 0)
4851*4882a593Smuzhiyun 			dl = coded_len;
4852*4882a593Smuzhiyun 		else
4853*4882a593Smuzhiyun 			continue;
4854*4882a593Smuzhiyun 
4855*4882a593Smuzhiyun 		/* is there enough room to copy? */
4856*4882a593Smuzhiyun 		copy_len = l - dl + 1;
4857*4882a593Smuzhiyun 		if (len < copy_len) {
4858*4882a593Smuzhiyun 			err = BCME_BUFTOOSHORT;
4859*4882a593Smuzhiyun 			goto exit;
4860*4882a593Smuzhiyun 		}
4861*4882a593Smuzhiyun 
4862*4882a593Smuzhiyun 		/* no prefix, just the name=value */
4863*4882a593Smuzhiyun 		strlcpy(vp, &s[dl], copy_len);
4864*4882a593Smuzhiyun 		vp += copy_len;
4865*4882a593Smuzhiyun 		len -= copy_len;
4866*4882a593Smuzhiyun 	}
4867*4882a593Smuzhiyun 
4868*4882a593Smuzhiyun 	/* add null string as terminator */
4869*4882a593Smuzhiyun 	if (len < 1) {
4870*4882a593Smuzhiyun 		err = BCME_BUFTOOSHORT;
4871*4882a593Smuzhiyun 		goto exit;
4872*4882a593Smuzhiyun 	}
4873*4882a593Smuzhiyun 	*vp++ = '\0';
4874*4882a593Smuzhiyun 
4875*4882a593Smuzhiyun 	*base = vp;
4876*4882a593Smuzhiyun 
4877*4882a593Smuzhiyun exit:
4878*4882a593Smuzhiyun 	MFREE(osh, flash, MAX_NVRAM_SPACE);
4879*4882a593Smuzhiyun 	return err;
4880*4882a593Smuzhiyun }
4881*4882a593Smuzhiyun #endif /* !defined(BCMDONGLEHOST) */
4882*4882a593Smuzhiyun 
4883*4882a593Smuzhiyun #if !defined(BCMUSBDEV_ENABLED) && !defined(BCMSDIODEV_ENABLED) &&	\
4884*4882a593Smuzhiyun 	!defined(BCMPCIEDEV_ENABLED)
4885*4882a593Smuzhiyun #if !defined(BCMDONGLEHOST)
4886*4882a593Smuzhiyun /**
4887*4882a593Smuzhiyun  * Initialize nonvolatile variable table from flash.
4888*4882a593Smuzhiyun  * Return 0 on success, nonzero on error.
4889*4882a593Smuzhiyun  */
4890*4882a593Smuzhiyun /* no needs to load the nvram variables from the flash for dongles.
4891*4882a593Smuzhiyun  * These variables are mainly for supporting SROM-less devices although
4892*4882a593Smuzhiyun  * we can use the same machenism to support configuration of multiple
4893*4882a593Smuzhiyun  * cores of the same type.
4894*4882a593Smuzhiyun  */
4895*4882a593Smuzhiyun static int
4896*4882a593Smuzhiyun BCMATTACHFN(initvars_flash_si)(si_t *sih, char **vars, uint *count)
4897*4882a593Smuzhiyun {
4898*4882a593Smuzhiyun 	osl_t *osh = si_osh(sih);
4899*4882a593Smuzhiyun 	char *vp, *base;
4900*4882a593Smuzhiyun 	int err;
4901*4882a593Smuzhiyun 
4902*4882a593Smuzhiyun 	ASSERT(vars != NULL);
4903*4882a593Smuzhiyun 	ASSERT(count != NULL);
4904*4882a593Smuzhiyun 
4905*4882a593Smuzhiyun 	/* freed in same function */
4906*4882a593Smuzhiyun 	base = vp = MALLOC_NOPERSIST(osh, MAXSZ_NVRAM_VARS);
4907*4882a593Smuzhiyun 	ASSERT(vp != NULL);
4908*4882a593Smuzhiyun 	if (!vp)
4909*4882a593Smuzhiyun 		return BCME_NOMEM;
4910*4882a593Smuzhiyun 
4911*4882a593Smuzhiyun 	if ((err = initvars_flash(sih, osh, &vp, MAXSZ_NVRAM_VARS)) == 0)
4912*4882a593Smuzhiyun 		err = initvars_table(osh, base, vp, vars, count);
4913*4882a593Smuzhiyun 
4914*4882a593Smuzhiyun 	MFREE(osh, base, MAXSZ_NVRAM_VARS);
4915*4882a593Smuzhiyun 
4916*4882a593Smuzhiyun 	return err;
4917*4882a593Smuzhiyun }
4918*4882a593Smuzhiyun #endif /* !defined(BCMDONGLEHOST) */
4919*4882a593Smuzhiyun #endif	/* !BCMUSBDEV && !BCMSDIODEV */
4920*4882a593Smuzhiyun 
4921*4882a593Smuzhiyun #if !defined(BCMDONGLEHOST)
4922*4882a593Smuzhiyun 
4923*4882a593Smuzhiyun /** returns position of rightmost bit that was set in caller supplied mask */
4924*4882a593Smuzhiyun static uint
4925*4882a593Smuzhiyun mask_shift(uint16 mask)
4926*4882a593Smuzhiyun {
4927*4882a593Smuzhiyun 	uint i;
4928*4882a593Smuzhiyun 	for (i = 0; i < (sizeof(mask) << 3); i ++) {
4929*4882a593Smuzhiyun 		if (mask & (1 << i))
4930*4882a593Smuzhiyun 			return i;
4931*4882a593Smuzhiyun 	}
4932*4882a593Smuzhiyun 	ASSERT(mask);
4933*4882a593Smuzhiyun 	return 0;
4934*4882a593Smuzhiyun }
4935*4882a593Smuzhiyun 
4936*4882a593Smuzhiyun static uint
4937*4882a593Smuzhiyun mask_width(uint16 mask)
4938*4882a593Smuzhiyun {
4939*4882a593Smuzhiyun 	int i;
4940*4882a593Smuzhiyun 	for (i = (sizeof(mask) << 3) - 1; i >= 0; i --) {
4941*4882a593Smuzhiyun 		if (mask & (1 << i))
4942*4882a593Smuzhiyun 			return (uint)(i - mask_shift(mask) + 1);
4943*4882a593Smuzhiyun 	}
4944*4882a593Smuzhiyun 	ASSERT(mask);
4945*4882a593Smuzhiyun 	return 0;
4946*4882a593Smuzhiyun }
4947*4882a593Smuzhiyun 
4948*4882a593Smuzhiyun #ifdef BCMASSERT_SUPPORT
4949*4882a593Smuzhiyun static bool
4950*4882a593Smuzhiyun mask_valid(uint16 mask)
4951*4882a593Smuzhiyun {
4952*4882a593Smuzhiyun 	uint shift = mask_shift(mask);
4953*4882a593Smuzhiyun 	uint width = mask_width(mask);
4954*4882a593Smuzhiyun 	return mask == ((~0 << shift) & ~(~0 << (shift + width)));
4955*4882a593Smuzhiyun }
4956*4882a593Smuzhiyun #endif
4957*4882a593Smuzhiyun #ifdef NVSRCX
4958*4882a593Smuzhiyun void
4959*4882a593Smuzhiyun srom_set_sromvars(char *vars)
4960*4882a593Smuzhiyun {
4961*4882a593Smuzhiyun 	if (sromh)
4962*4882a593Smuzhiyun 		sromh->_srom_vars = vars;
4963*4882a593Smuzhiyun }
4964*4882a593Smuzhiyun char *
4965*4882a593Smuzhiyun srom_get_sromvars()
4966*4882a593Smuzhiyun {
4967*4882a593Smuzhiyun 	if (sromh)
4968*4882a593Smuzhiyun 		return sromh->_srom_vars;
4969*4882a593Smuzhiyun 	else
4970*4882a593Smuzhiyun 		return NULL;
4971*4882a593Smuzhiyun }
4972*4882a593Smuzhiyun 
4973*4882a593Smuzhiyun srom_info_t *
4974*4882a593Smuzhiyun srom_info_init(osl_t *osh)
4975*4882a593Smuzhiyun {
4976*4882a593Smuzhiyun 	sromh = (srom_info_t *) MALLOC_NOPERSIST(osh, sizeof(srom_info_t));
4977*4882a593Smuzhiyun 	if (!sromh)
4978*4882a593Smuzhiyun 		return NULL;
4979*4882a593Smuzhiyun 	sromh->_srom_vars = NULL;
4980*4882a593Smuzhiyun 	sromh->is_caldata_prsnt = FALSE;
4981*4882a593Smuzhiyun 	return sromh;
4982*4882a593Smuzhiyun }
4983*4882a593Smuzhiyun #endif /* NVSRCX */
4984*4882a593Smuzhiyun /**
4985*4882a593Smuzhiyun  * Parses caller supplied SROM contents into name=value pairs. Global array pci_sromvars[] contains
4986*4882a593Smuzhiyun  * the link between a word offset in SROM and the corresponding NVRAM variable name.'srom' points to
4987*4882a593Smuzhiyun  * the SROM word array. 'off' specifies the offset of the first word 'srom' points to, which should
4988*4882a593Smuzhiyun  * be either 0 or SROM3_SWRG_OFF (full SROM or software region).
4989*4882a593Smuzhiyun  */
4990*4882a593Smuzhiyun static void
4991*4882a593Smuzhiyun BCMATTACHFN(_initvars_srom_pci)(uint8 sromrev, uint16 *srom, uint off, varbuf_t *b)
4992*4882a593Smuzhiyun {
4993*4882a593Smuzhiyun 	uint16 w;
4994*4882a593Smuzhiyun 	uint32 val;
4995*4882a593Smuzhiyun 	const sromvar_t *srv;
4996*4882a593Smuzhiyun 	uint width;
4997*4882a593Smuzhiyun 	uint flags;
4998*4882a593Smuzhiyun 	uint32 sr = (1 << sromrev);
4999*4882a593Smuzhiyun 	bool in_array = FALSE;
5000*4882a593Smuzhiyun 	static char array_temp[256];
5001*4882a593Smuzhiyun 	uint array_curr = 0;
5002*4882a593Smuzhiyun 	const char* array_name = NULL;
5003*4882a593Smuzhiyun 
5004*4882a593Smuzhiyun 	varbuf_append(b, "sromrev=%d", sromrev);
5005*4882a593Smuzhiyun #if !defined(SROM15_MEMOPT) && !defined(SROM17_MEMOPT)
5006*4882a593Smuzhiyun 	if (sromrev == 15) {
5007*4882a593Smuzhiyun 		srv = pci_srom15vars;
5008*4882a593Smuzhiyun 	} else if (sromrev == 16) {
5009*4882a593Smuzhiyun 		srv = pci_srom16vars;
5010*4882a593Smuzhiyun 	} else if (sromrev == 17) {
5011*4882a593Smuzhiyun 		srv = pci_srom17vars;
5012*4882a593Smuzhiyun 	} else if (sromrev == 18) {
5013*4882a593Smuzhiyun 		srv = pci_srom18vars;
5014*4882a593Smuzhiyun 	} else {
5015*4882a593Smuzhiyun 		srv = pci_sromvars;
5016*4882a593Smuzhiyun 	}
5017*4882a593Smuzhiyun #else
5018*4882a593Smuzhiyun #if defined(SROM15_MEMOPT)
5019*4882a593Smuzhiyun 	srv = pci_srom15vars;
5020*4882a593Smuzhiyun #endif /* defined(SROM15_MEMOPT) */
5021*4882a593Smuzhiyun #if defined(SROM17_MEMOPT)
5022*4882a593Smuzhiyun 	srv = pci_srom17vars;
5023*4882a593Smuzhiyun #endif /* defined(SROM17_MEMOPT) */
5024*4882a593Smuzhiyun #endif /* !defined(SROM15_MEMOPT) && !defined(SROM17_MEMOPT) */
5025*4882a593Smuzhiyun 
5026*4882a593Smuzhiyun 	for (; srv->name != NULL; srv ++) {
5027*4882a593Smuzhiyun 		const char *name;
5028*4882a593Smuzhiyun 		static bool in_array2 = FALSE;
5029*4882a593Smuzhiyun 		static char array_temp2[256];
5030*4882a593Smuzhiyun 		static uint array_curr2 = 0;
5031*4882a593Smuzhiyun 		static const char* array_name2 = NULL;
5032*4882a593Smuzhiyun 
5033*4882a593Smuzhiyun 		if ((srv->revmask & sr) == 0)
5034*4882a593Smuzhiyun 		    continue;
5035*4882a593Smuzhiyun 
5036*4882a593Smuzhiyun 		if (srv->off < off)
5037*4882a593Smuzhiyun 			continue;
5038*4882a593Smuzhiyun 
5039*4882a593Smuzhiyun 		flags = srv->flags;
5040*4882a593Smuzhiyun 		name = srv->name;
5041*4882a593Smuzhiyun 
5042*4882a593Smuzhiyun 		/* This entry is for mfgc only. Don't generate param for it, */
5043*4882a593Smuzhiyun 		if (flags & SRFL_NOVAR)
5044*4882a593Smuzhiyun 			continue;
5045*4882a593Smuzhiyun 
5046*4882a593Smuzhiyun 		if (flags & SRFL_ETHADDR) {
5047*4882a593Smuzhiyun 			char eabuf[ETHER_ADDR_STR_LEN];
5048*4882a593Smuzhiyun 			struct ether_addr ea;
5049*4882a593Smuzhiyun 
5050*4882a593Smuzhiyun 			ea.octet[0] = (srom[srv->off - off] >> 8) & 0xff;
5051*4882a593Smuzhiyun 			ea.octet[1] = srom[srv->off - off] & 0xff;
5052*4882a593Smuzhiyun 			ea.octet[2] = (srom[srv->off + 1 - off] >> 8) & 0xff;
5053*4882a593Smuzhiyun 			ea.octet[3] = srom[srv->off + 1 - off] & 0xff;
5054*4882a593Smuzhiyun 			ea.octet[4] = (srom[srv->off + 2 - off] >> 8) & 0xff;
5055*4882a593Smuzhiyun 			ea.octet[5] = srom[srv->off + 2 - off] & 0xff;
5056*4882a593Smuzhiyun 			bcm_ether_ntoa(&ea, eabuf);
5057*4882a593Smuzhiyun 
5058*4882a593Smuzhiyun 			varbuf_append(b, "%s=%s", name, eabuf);
5059*4882a593Smuzhiyun 		} else {
5060*4882a593Smuzhiyun 			ASSERT(mask_valid(srv->mask));
5061*4882a593Smuzhiyun 			ASSERT(mask_width(srv->mask));
5062*4882a593Smuzhiyun 
5063*4882a593Smuzhiyun 			/* Start of an array */
5064*4882a593Smuzhiyun 			if (sromrev >= 10 && (srv->flags & SRFL_ARRAY) && !in_array2) {
5065*4882a593Smuzhiyun 				array_curr2 = 0;
5066*4882a593Smuzhiyun 				array_name2 = (const char*)srv->name;
5067*4882a593Smuzhiyun 				bzero((void*)array_temp2, sizeof(array_temp2));
5068*4882a593Smuzhiyun 				in_array2 = TRUE;
5069*4882a593Smuzhiyun 			}
5070*4882a593Smuzhiyun 
5071*4882a593Smuzhiyun 			w = srom[srv->off - off];
5072*4882a593Smuzhiyun 			val = (w & srv->mask) >> mask_shift(srv->mask);
5073*4882a593Smuzhiyun 			width = mask_width(srv->mask);
5074*4882a593Smuzhiyun 
5075*4882a593Smuzhiyun 			while (srv->flags & SRFL_MORE) {
5076*4882a593Smuzhiyun 				srv ++;
5077*4882a593Smuzhiyun 				ASSERT(srv->name != NULL);
5078*4882a593Smuzhiyun 
5079*4882a593Smuzhiyun 				if (srv->off == 0 || srv->off < off)
5080*4882a593Smuzhiyun 					continue;
5081*4882a593Smuzhiyun 
5082*4882a593Smuzhiyun 				ASSERT(mask_valid(srv->mask));
5083*4882a593Smuzhiyun 				ASSERT(mask_width(srv->mask));
5084*4882a593Smuzhiyun 
5085*4882a593Smuzhiyun 				w = srom[srv->off - off];
5086*4882a593Smuzhiyun 				val += ((w & srv->mask) >> mask_shift(srv->mask)) << width;
5087*4882a593Smuzhiyun 				width += mask_width(srv->mask);
5088*4882a593Smuzhiyun 			}
5089*4882a593Smuzhiyun 
5090*4882a593Smuzhiyun 			if ((flags & SRFL_NOFFS) && ((int)val == (1 << width) - 1))
5091*4882a593Smuzhiyun 				continue;
5092*4882a593Smuzhiyun 
5093*4882a593Smuzhiyun 			/* Array support starts in sromrev 10. Skip arrays for sromrev <= 9 */
5094*4882a593Smuzhiyun 			if (sromrev <= 9 && srv->flags & SRFL_ARRAY) {
5095*4882a593Smuzhiyun 				while (srv->flags & SRFL_ARRAY)
5096*4882a593Smuzhiyun 					srv ++;
5097*4882a593Smuzhiyun 				srv ++;
5098*4882a593Smuzhiyun 			}
5099*4882a593Smuzhiyun 
5100*4882a593Smuzhiyun 			if (in_array2) {
5101*4882a593Smuzhiyun 				int ret;
5102*4882a593Smuzhiyun 
5103*4882a593Smuzhiyun 				if (flags & SRFL_PRHEX) {
5104*4882a593Smuzhiyun 					ret = snprintf(array_temp2 + array_curr2,
5105*4882a593Smuzhiyun 						sizeof(array_temp2) - array_curr2, "0x%x,", val);
5106*4882a593Smuzhiyun 				} else if ((flags & SRFL_PRSIGN) &&
5107*4882a593Smuzhiyun 					(val & (1 << (width - 1)))) {
5108*4882a593Smuzhiyun 					ret = snprintf(array_temp2 + array_curr2,
5109*4882a593Smuzhiyun 						sizeof(array_temp2) - array_curr2, "%d,",
5110*4882a593Smuzhiyun 						(int)(val | (~0 << width)));
5111*4882a593Smuzhiyun 				} else {
5112*4882a593Smuzhiyun 					ret = snprintf(array_temp2 + array_curr2,
5113*4882a593Smuzhiyun 						sizeof(array_temp2) - array_curr2, "%u,", val);
5114*4882a593Smuzhiyun 				}
5115*4882a593Smuzhiyun 
5116*4882a593Smuzhiyun 				if (ret > 0) {
5117*4882a593Smuzhiyun 					array_curr2 += ret;
5118*4882a593Smuzhiyun 				} else {
5119*4882a593Smuzhiyun 					BS_ERROR(("_initvars_srom_pci: array %s parsing error."
5120*4882a593Smuzhiyun 						" buffer too short.\n",
5121*4882a593Smuzhiyun 						array_name2));
5122*4882a593Smuzhiyun 					ASSERT(0);
5123*4882a593Smuzhiyun 
5124*4882a593Smuzhiyun 					/* buffer too small, skip this param */
5125*4882a593Smuzhiyun 					while (srv->flags & SRFL_ARRAY)
5126*4882a593Smuzhiyun 						srv ++;
5127*4882a593Smuzhiyun 					srv ++;
5128*4882a593Smuzhiyun 					in_array2 = FALSE;
5129*4882a593Smuzhiyun 					continue;
5130*4882a593Smuzhiyun 				}
5131*4882a593Smuzhiyun 
5132*4882a593Smuzhiyun 				if (!(srv->flags & SRFL_ARRAY)) { /* Array ends */
5133*4882a593Smuzhiyun 					/* Remove the last ',' */
5134*4882a593Smuzhiyun 					array_temp2[array_curr2-1] = '\0';
5135*4882a593Smuzhiyun 					in_array2 = FALSE;
5136*4882a593Smuzhiyun 					varbuf_append(b, "%s=%s", array_name2, array_temp2);
5137*4882a593Smuzhiyun 				}
5138*4882a593Smuzhiyun 			} else if (flags & SRFL_CCODE) {
5139*4882a593Smuzhiyun 				if (val == 0)
5140*4882a593Smuzhiyun 					varbuf_append(b, "ccode=");
5141*4882a593Smuzhiyun 				else
5142*4882a593Smuzhiyun 					varbuf_append(b, "ccode=%c%c", (val >> 8), (val & 0xff));
5143*4882a593Smuzhiyun 			} else if (flags & SRFL_PRHEX) {
5144*4882a593Smuzhiyun 				varbuf_append(b, "%s=0x%x", name, val);
5145*4882a593Smuzhiyun 			} else if ((flags & SRFL_PRSIGN) && (val & (1 << (width - 1)))) {
5146*4882a593Smuzhiyun 				varbuf_append(b, "%s=%d", name, (int)(val | (~0 << width)));
5147*4882a593Smuzhiyun 			} else {
5148*4882a593Smuzhiyun 				varbuf_append(b, "%s=%u", name, val);
5149*4882a593Smuzhiyun 			}
5150*4882a593Smuzhiyun 		}
5151*4882a593Smuzhiyun 	}
5152*4882a593Smuzhiyun 
5153*4882a593Smuzhiyun 	if ((sromrev >= 4) && (sromrev != 16) && (sromrev != 18)) {
5154*4882a593Smuzhiyun 		/* Do per-path variables */
5155*4882a593Smuzhiyun 		uint p, pb, psz, path_num;
5156*4882a593Smuzhiyun 
5157*4882a593Smuzhiyun 		if  ((sromrev == 17) || (sromrev == 15)) {
5158*4882a593Smuzhiyun 			pb = psz = 0;
5159*4882a593Smuzhiyun 			path_num = 0;
5160*4882a593Smuzhiyun 			if (sromh)
5161*4882a593Smuzhiyun 				sromh->is_caldata_prsnt = TRUE;
5162*4882a593Smuzhiyun 		} else if  (sromrev >= 13) {
5163*4882a593Smuzhiyun 			pb = SROM13_PATH0;
5164*4882a593Smuzhiyun 			psz = SROM13_PATH1 - SROM13_PATH0;
5165*4882a593Smuzhiyun 			path_num = MAX_PATH_SROM_13;
5166*4882a593Smuzhiyun 		} else if  (sromrev >= 12) {
5167*4882a593Smuzhiyun 			pb = SROM12_PATH0;
5168*4882a593Smuzhiyun 			psz = SROM12_PATH1 - SROM12_PATH0;
5169*4882a593Smuzhiyun 			path_num = MAX_PATH_SROM_12;
5170*4882a593Smuzhiyun 		} else if (sromrev >= 11) {
5171*4882a593Smuzhiyun 			pb = SROM11_PATH0;
5172*4882a593Smuzhiyun 			psz = SROM11_PATH1 - SROM11_PATH0;
5173*4882a593Smuzhiyun 			path_num = MAX_PATH_SROM_11;
5174*4882a593Smuzhiyun 		} else if (sromrev >= 8) {
5175*4882a593Smuzhiyun 			pb = SROM8_PATH0;
5176*4882a593Smuzhiyun 			psz = SROM8_PATH1 - SROM8_PATH0;
5177*4882a593Smuzhiyun 			path_num = MAX_PATH_SROM;
5178*4882a593Smuzhiyun 		} else {
5179*4882a593Smuzhiyun 			pb = SROM4_PATH0;
5180*4882a593Smuzhiyun 			psz = SROM4_PATH1 - SROM4_PATH0;
5181*4882a593Smuzhiyun 			path_num = MAX_PATH_SROM;
5182*4882a593Smuzhiyun 		}
5183*4882a593Smuzhiyun 
5184*4882a593Smuzhiyun 		for (p = 0; p < path_num; p++) {
5185*4882a593Smuzhiyun 			for (srv = perpath_pci_sromvars; srv->name != NULL; srv ++) {
5186*4882a593Smuzhiyun 
5187*4882a593Smuzhiyun 				if ((srv->revmask & sr) == 0)
5188*4882a593Smuzhiyun 					continue;
5189*4882a593Smuzhiyun 
5190*4882a593Smuzhiyun 				if (pb + srv->off < off)
5191*4882a593Smuzhiyun 					continue;
5192*4882a593Smuzhiyun 
5193*4882a593Smuzhiyun 				/* This entry is for mfgc only. Don't generate param for it, */
5194*4882a593Smuzhiyun 				if (srv->flags & SRFL_NOVAR)
5195*4882a593Smuzhiyun 					continue;
5196*4882a593Smuzhiyun 
5197*4882a593Smuzhiyun 				/* Start of an array */
5198*4882a593Smuzhiyun 				if (sromrev >= 10 && (srv->flags & SRFL_ARRAY) && !in_array) {
5199*4882a593Smuzhiyun 					array_curr = 0;
5200*4882a593Smuzhiyun 					array_name = (const char*)srv->name;
5201*4882a593Smuzhiyun 					bzero((void*)array_temp, sizeof(array_temp));
5202*4882a593Smuzhiyun 					in_array = TRUE;
5203*4882a593Smuzhiyun 				}
5204*4882a593Smuzhiyun 
5205*4882a593Smuzhiyun 				w = srom[pb + srv->off - off];
5206*4882a593Smuzhiyun 
5207*4882a593Smuzhiyun 				ASSERT(mask_valid(srv->mask));
5208*4882a593Smuzhiyun 				val = (w & srv->mask) >> mask_shift(srv->mask);
5209*4882a593Smuzhiyun 				width = mask_width(srv->mask);
5210*4882a593Smuzhiyun 
5211*4882a593Smuzhiyun 				flags = srv->flags;
5212*4882a593Smuzhiyun 
5213*4882a593Smuzhiyun 				/* Cheating: no per-path var is more than 1 word */
5214*4882a593Smuzhiyun 
5215*4882a593Smuzhiyun 				if ((srv->flags & SRFL_NOFFS) && ((int)val == (1 << width) - 1))
5216*4882a593Smuzhiyun 					continue;
5217*4882a593Smuzhiyun 
5218*4882a593Smuzhiyun 				if (in_array) {
5219*4882a593Smuzhiyun 					int ret;
5220*4882a593Smuzhiyun 
5221*4882a593Smuzhiyun 					if (flags & SRFL_PRHEX) {
5222*4882a593Smuzhiyun 						ret = snprintf(array_temp + array_curr,
5223*4882a593Smuzhiyun 						  sizeof(array_temp) - array_curr, "0x%x,", val);
5224*4882a593Smuzhiyun 					} else if ((flags & SRFL_PRSIGN) &&
5225*4882a593Smuzhiyun 						(val & (1 << (width - 1)))) {
5226*4882a593Smuzhiyun 						ret = snprintf(array_temp + array_curr,
5227*4882a593Smuzhiyun 							sizeof(array_temp) - array_curr, "%d,",
5228*4882a593Smuzhiyun 							(int)(val | (~0 << width)));
5229*4882a593Smuzhiyun 					} else {
5230*4882a593Smuzhiyun 						ret = snprintf(array_temp + array_curr,
5231*4882a593Smuzhiyun 						  sizeof(array_temp) - array_curr, "%u,", val);
5232*4882a593Smuzhiyun 					}
5233*4882a593Smuzhiyun 
5234*4882a593Smuzhiyun 					if (ret > 0) {
5235*4882a593Smuzhiyun 						array_curr += ret;
5236*4882a593Smuzhiyun 					} else {
5237*4882a593Smuzhiyun 						BS_ERROR(
5238*4882a593Smuzhiyun 						("_initvars_srom_pci: array %s parsing error."
5239*4882a593Smuzhiyun 						" buffer too short.\n",
5240*4882a593Smuzhiyun 						array_name));
5241*4882a593Smuzhiyun 						ASSERT(0);
5242*4882a593Smuzhiyun 
5243*4882a593Smuzhiyun 						/* buffer too small, skip this param */
5244*4882a593Smuzhiyun 						while (srv->flags & SRFL_ARRAY)
5245*4882a593Smuzhiyun 							srv ++;
5246*4882a593Smuzhiyun 						srv ++;
5247*4882a593Smuzhiyun 						in_array = FALSE;
5248*4882a593Smuzhiyun 						continue;
5249*4882a593Smuzhiyun 					}
5250*4882a593Smuzhiyun 
5251*4882a593Smuzhiyun 					if (!(srv->flags & SRFL_ARRAY)) { /* Array ends */
5252*4882a593Smuzhiyun 						/* Remove the last ',' */
5253*4882a593Smuzhiyun 						array_temp[array_curr-1] = '\0';
5254*4882a593Smuzhiyun 						in_array = FALSE;
5255*4882a593Smuzhiyun 						varbuf_append(b, "%s%d=%s",
5256*4882a593Smuzhiyun 							array_name, p, array_temp);
5257*4882a593Smuzhiyun 					}
5258*4882a593Smuzhiyun 				} else if (srv->flags & SRFL_PRHEX)
5259*4882a593Smuzhiyun 					varbuf_append(b, "%s%d=0x%x", srv->name, p, val);
5260*4882a593Smuzhiyun 				else
5261*4882a593Smuzhiyun 					varbuf_append(b, "%s%d=%d", srv->name, p, val);
5262*4882a593Smuzhiyun 			}
5263*4882a593Smuzhiyun 			if (sromrev >= 13 && (p == (MAX_PATH_SROM_13 - 2))) {
5264*4882a593Smuzhiyun 				psz = SROM13_PATH3 - SROM13_PATH2;
5265*4882a593Smuzhiyun 			}
5266*4882a593Smuzhiyun 			pb += psz;
5267*4882a593Smuzhiyun 		}
5268*4882a593Smuzhiyun 	} /* per path variables */
5269*4882a593Smuzhiyun } /* _initvars_srom_pci */
5270*4882a593Smuzhiyun 
5271*4882a593Smuzhiyun int
5272*4882a593Smuzhiyun BCMATTACHFN(get_srom_pci_caldata_size)(uint32 sromrev)
5273*4882a593Smuzhiyun {
5274*4882a593Smuzhiyun 	uint32 caldata_size;
5275*4882a593Smuzhiyun 
5276*4882a593Smuzhiyun 	switch (sromrev) {
5277*4882a593Smuzhiyun 		case 15:
5278*4882a593Smuzhiyun 			caldata_size = (SROM15_CALDATA_WORDS * 2);
5279*4882a593Smuzhiyun 			break;
5280*4882a593Smuzhiyun 		case 17:
5281*4882a593Smuzhiyun 			caldata_size = (SROM17_CALDATA_WORDS * 2);
5282*4882a593Smuzhiyun 			break;
5283*4882a593Smuzhiyun 		default:
5284*4882a593Smuzhiyun 			caldata_size = 0;
5285*4882a593Smuzhiyun 			break;
5286*4882a593Smuzhiyun 	}
5287*4882a593Smuzhiyun 	return caldata_size;
5288*4882a593Smuzhiyun }
5289*4882a593Smuzhiyun 
5290*4882a593Smuzhiyun uint32
5291*4882a593Smuzhiyun BCMATTACHFN(get_srom_size)(uint32 sromrev)
5292*4882a593Smuzhiyun {
5293*4882a593Smuzhiyun 	uint32 size;
5294*4882a593Smuzhiyun 
5295*4882a593Smuzhiyun 	switch (sromrev) {
5296*4882a593Smuzhiyun 		case 15:
5297*4882a593Smuzhiyun 			size = (SROM15_WORDS * 2);
5298*4882a593Smuzhiyun 			break;
5299*4882a593Smuzhiyun 		case 17:
5300*4882a593Smuzhiyun 			size = (SROM17_WORDS * 2);
5301*4882a593Smuzhiyun 			break;
5302*4882a593Smuzhiyun 		default:
5303*4882a593Smuzhiyun 			size = 0;
5304*4882a593Smuzhiyun 			break;
5305*4882a593Smuzhiyun 	}
5306*4882a593Smuzhiyun 	return size;
5307*4882a593Smuzhiyun }
5308*4882a593Smuzhiyun #if defined(BCMPCIEDEV_SROM_FORMAT) && defined(WLC_TXCAL)
5309*4882a593Smuzhiyun 
5310*4882a593Smuzhiyun int
5311*4882a593Smuzhiyun BCMATTACHFN(_initvars_srom_pci_caldata)(si_t *sih, uint16 *srom, uint32 sromrev)
5312*4882a593Smuzhiyun {
5313*4882a593Smuzhiyun 	int err = BCME_ERROR;
5314*4882a593Smuzhiyun 
5315*4882a593Smuzhiyun 	if (sromh && (!sromh->is_caldata_prsnt)) {
5316*4882a593Smuzhiyun 		return err;
5317*4882a593Smuzhiyun 	}
5318*4882a593Smuzhiyun 
5319*4882a593Smuzhiyun 	if (si_is_sprom_available(sih)) {
5320*4882a593Smuzhiyun 		uint32 caldata_size;
5321*4882a593Smuzhiyun 
5322*4882a593Smuzhiyun 		caldata_size = get_srom_pci_caldata_size(sromrev);
5323*4882a593Smuzhiyun 		memcpy(srom, caldata_array, caldata_size);
5324*4882a593Smuzhiyun 		err = BCME_OK;
5325*4882a593Smuzhiyun 	}
5326*4882a593Smuzhiyun 	return err;
5327*4882a593Smuzhiyun }
5328*4882a593Smuzhiyun #endif /* defined(BCMPCIEDEV_SROM_FORMAT) && defined(WLC_TXCAL) */
5329*4882a593Smuzhiyun /**
5330*4882a593Smuzhiyun  * Initialize nonvolatile variable table from sprom, or OTP when SPROM is not available, or
5331*4882a593Smuzhiyun  * optionally a set of 'defaultsromvars' (compiled-in) variables when both OTP and SPROM bear no
5332*4882a593Smuzhiyun  * contents.
5333*4882a593Smuzhiyun  *
5334*4882a593Smuzhiyun  * On success, a buffer containing var/val pairs is allocated and returned in params vars and count.
5335*4882a593Smuzhiyun  *
5336*4882a593Smuzhiyun  * Return 0 on success, nonzero on error.
5337*4882a593Smuzhiyun  */
5338*4882a593Smuzhiyun static int
5339*4882a593Smuzhiyun BCMATTACHFN(initvars_srom_pci)(si_t *sih, volatile void *curmap, char **vars, uint *count)
5340*4882a593Smuzhiyun {
5341*4882a593Smuzhiyun 	uint16 *srom;
5342*4882a593Smuzhiyun 	volatile uint16 *sromwindow;
5343*4882a593Smuzhiyun 	uint8 sromrev = 0;
5344*4882a593Smuzhiyun 	uint32 sr;
5345*4882a593Smuzhiyun 	varbuf_t b;
5346*4882a593Smuzhiyun 	char *vp, *base = NULL;
5347*4882a593Smuzhiyun 	osl_t *osh = si_osh(sih);
5348*4882a593Smuzhiyun 	bool flash = FALSE;
5349*4882a593Smuzhiyun 	int err = 0;
5350*4882a593Smuzhiyun #if defined(BCMPCIEDEV_SROM_FORMAT) && defined(WLC_TXCAL)
5351*4882a593Smuzhiyun 	uint16 cal_wordoffset;
5352*4882a593Smuzhiyun #endif
5353*4882a593Smuzhiyun 
5354*4882a593Smuzhiyun 	/*
5355*4882a593Smuzhiyun 	 * Apply CRC over SROM content regardless SROM is present or not, and use variable
5356*4882a593Smuzhiyun 	 * <devpath>sromrev's existance in flash to decide if we should return an error when CRC
5357*4882a593Smuzhiyun 	 * fails or read SROM variables from flash.
5358*4882a593Smuzhiyun 	 */
5359*4882a593Smuzhiyun 
5360*4882a593Smuzhiyun 	/* freed in same function */
5361*4882a593Smuzhiyun 	srom = MALLOC_NOPERSIST(osh, SROM_MAX);
5362*4882a593Smuzhiyun 	ASSERT(srom != NULL);
5363*4882a593Smuzhiyun 	if (!srom)
5364*4882a593Smuzhiyun 		return -2;
5365*4882a593Smuzhiyun 
5366*4882a593Smuzhiyun 	sromwindow = (volatile uint16 *)srom_offset(sih, curmap);
5367*4882a593Smuzhiyun 	if (si_is_sprom_available(sih)) {
5368*4882a593Smuzhiyun 		err = sprom_read_pci(osh, sih, sromwindow, 0, srom, SROM_SIGN_MINWORDS + 1, FALSE);
5369*4882a593Smuzhiyun 		if (err == 0) {
5370*4882a593Smuzhiyun 			if (srom[SROM18_SIGN] == SROM18_SIGNATURE) {
5371*4882a593Smuzhiyun 				err = sprom_read_pci(osh, sih, sromwindow,
5372*4882a593Smuzhiyun 						0, srom, SROM18_WORDS, TRUE);
5373*4882a593Smuzhiyun 				sromrev = srom[SROM18_CRCREV] & 0xff;
5374*4882a593Smuzhiyun 			} else if (srom[SROM17_SIGN] == SROM17_SIGNATURE) {
5375*4882a593Smuzhiyun 				err = sprom_read_pci(osh, sih, sromwindow,
5376*4882a593Smuzhiyun 						0, srom, SROM17_WORDS, TRUE);
5377*4882a593Smuzhiyun 				sromrev = srom[SROM17_CRCREV] & 0xff;
5378*4882a593Smuzhiyun 			} else if (srom[SROM16_SIGN] == SROM16_SIGNATURE) {
5379*4882a593Smuzhiyun 				err = sprom_read_pci(osh, sih, sromwindow,
5380*4882a593Smuzhiyun 						0, srom, SROM16_WORDS, TRUE);
5381*4882a593Smuzhiyun 				sromrev = srom[SROM16_CRCREV] & 0xff;
5382*4882a593Smuzhiyun 			} else if (srom[SROM15_SIGN] == SROM15_SIGNATURE) { /* srom 15  */
5383*4882a593Smuzhiyun 				err = sprom_read_pci(osh, sih, sromwindow,
5384*4882a593Smuzhiyun 						0, srom, SROM15_WORDS, TRUE);
5385*4882a593Smuzhiyun 				sromrev = srom[SROM15_CRCREV] & 0xff;
5386*4882a593Smuzhiyun 			} else if (srom[SROM11_SIGN] == SROM13_SIGNATURE) {
5387*4882a593Smuzhiyun 				err = sprom_read_pci(osh, sih, sromwindow,
5388*4882a593Smuzhiyun 						0, srom, SROM13_WORDS, TRUE);
5389*4882a593Smuzhiyun 				sromrev = srom[SROM13_CRCREV] & 0xff;
5390*4882a593Smuzhiyun 			} else if (srom[SROM11_SIGN] == SROM12_SIGNATURE) {
5391*4882a593Smuzhiyun 				err = sprom_read_pci(osh, sih, sromwindow,
5392*4882a593Smuzhiyun 						0, srom, SROM12_WORDS, TRUE);
5393*4882a593Smuzhiyun 				sromrev = srom[SROM12_CRCREV] & 0xff;
5394*4882a593Smuzhiyun 			} else if (srom[SROM11_SIGN] == SROM11_SIGNATURE) {
5395*4882a593Smuzhiyun 				err = sprom_read_pci(osh, sih, sromwindow,
5396*4882a593Smuzhiyun 						0, srom, SROM11_WORDS, TRUE);
5397*4882a593Smuzhiyun 				sromrev = srom[SROM11_CRCREV] & 0xff;
5398*4882a593Smuzhiyun 			} else  if ((srom[SROM4_SIGN] == SROM4_SIGNATURE) || /* srom 4  */
5399*4882a593Smuzhiyun 				(srom[SROM8_SIGN] == SROM4_SIGNATURE)) { /* srom 8,9  */
5400*4882a593Smuzhiyun 				err = sprom_read_pci(osh, sih, sromwindow,
5401*4882a593Smuzhiyun 						0, srom, SROM4_WORDS, TRUE);
5402*4882a593Smuzhiyun 				sromrev = srom[SROM4_CRCREV] & 0xff;
5403*4882a593Smuzhiyun 			} else {
5404*4882a593Smuzhiyun 				err = sprom_read_pci(osh, sih, sromwindow, 0,
5405*4882a593Smuzhiyun 						srom, SROM_WORDS, TRUE);
5406*4882a593Smuzhiyun 				if (err == 0) {
5407*4882a593Smuzhiyun 					/* srom is good and is rev < 4 */
5408*4882a593Smuzhiyun 					/* top word of sprom contains version and crc8 */
5409*4882a593Smuzhiyun 					sromrev = srom[SROM_CRCREV] & 0xff;
5410*4882a593Smuzhiyun 					/* bcm4401 sroms misprogrammed */
5411*4882a593Smuzhiyun 					if (sromrev == 0x10)
5412*4882a593Smuzhiyun 						sromrev = 1;
5413*4882a593Smuzhiyun 				}
5414*4882a593Smuzhiyun 			}
5415*4882a593Smuzhiyun 			if (err)
5416*4882a593Smuzhiyun 				BS_ERROR(("srom read failed\n"));
5417*4882a593Smuzhiyun 		}
5418*4882a593Smuzhiyun 		else
5419*4882a593Smuzhiyun 			BS_ERROR(("srom read failed\n"));
5420*4882a593Smuzhiyun 	}
5421*4882a593Smuzhiyun 
5422*4882a593Smuzhiyun #if defined(BCMNVRAMW) || defined(BCMNVRAMR)
5423*4882a593Smuzhiyun 	/* Use OTP if SPROM not available */
5424*4882a593Smuzhiyun 	else if ((err = otp_read_pci(osh, sih, srom, SROM_MAX)) == 0) {
5425*4882a593Smuzhiyun 		/* OTP only contain SROM rev8/rev9/rev10/Rev11 for now */
5426*4882a593Smuzhiyun 
5427*4882a593Smuzhiyun 		if (srom[SROM13_SIGN] == SROM13_SIGNATURE)
5428*4882a593Smuzhiyun 			sromrev = srom[SROM13_CRCREV] & 0xff;
5429*4882a593Smuzhiyun 		else if (srom[SROM12_SIGN] == SROM12_SIGNATURE)
5430*4882a593Smuzhiyun 			sromrev = srom[SROM12_CRCREV] & 0xff;
5431*4882a593Smuzhiyun 		else if (srom[SROM11_SIGN] == SROM11_SIGNATURE)
5432*4882a593Smuzhiyun 			sromrev = srom[SROM11_CRCREV] & 0xff;
5433*4882a593Smuzhiyun 		else if (srom[SROM10_SIGN] == SROM10_SIGNATURE)
5434*4882a593Smuzhiyun 			sromrev = srom[SROM10_CRCREV] & 0xff;
5435*4882a593Smuzhiyun 		else
5436*4882a593Smuzhiyun 			sromrev = srom[SROM4_CRCREV] & 0xff;
5437*4882a593Smuzhiyun 	}
5438*4882a593Smuzhiyun #endif /* defined(BCMNVRAMW) || defined(BCMNVRAMR) */
5439*4882a593Smuzhiyun 	else {
5440*4882a593Smuzhiyun 		err = 1;
5441*4882a593Smuzhiyun 		BS_ERROR(("Neither SPROM nor OTP has valid image\n"));
5442*4882a593Smuzhiyun 	}
5443*4882a593Smuzhiyun 
5444*4882a593Smuzhiyun 	BS_ERROR(("srom rev:%d\n", sromrev));
5445*4882a593Smuzhiyun 
5446*4882a593Smuzhiyun 	/* We want internal/wltest driver to come up with default sromvars so we can
5447*4882a593Smuzhiyun 	 * program a blank SPROM/OTP.
5448*4882a593Smuzhiyun 	 */
5449*4882a593Smuzhiyun 	if (err || sromrev == 0) {
5450*4882a593Smuzhiyun 		char *value;
5451*4882a593Smuzhiyun #if defined(BCMHOSTVARS)
5452*4882a593Smuzhiyun 		uint32 val;
5453*4882a593Smuzhiyun #endif
5454*4882a593Smuzhiyun 
5455*4882a593Smuzhiyun 		if ((value = si_getdevpathvar(sih, "sromrev"))) {
5456*4882a593Smuzhiyun 			sromrev = (uint8)bcm_strtoul(value, NULL, 0);
5457*4882a593Smuzhiyun 			flash = TRUE;
5458*4882a593Smuzhiyun 			goto varscont;
5459*4882a593Smuzhiyun 		}
5460*4882a593Smuzhiyun 
5461*4882a593Smuzhiyun 		BS_ERROR(("initvars_srom_pci, SROM CRC Error\n"));
5462*4882a593Smuzhiyun 
5463*4882a593Smuzhiyun #if !defined(DONGLEBUILD) || defined(BCMPCIEDEV_SROM_FORMAT)
5464*4882a593Smuzhiyun 		/* NIC build or PCIe FD using SROM format shouldn't load driver
5465*4882a593Smuzhiyun 		 * default when external nvram exists.
5466*4882a593Smuzhiyun 		 */
5467*4882a593Smuzhiyun 		if ((value = getvar(NULL, "sromrev"))) {
5468*4882a593Smuzhiyun 			BS_ERROR(("initvars_srom_pci, Using external nvram\n"));
5469*4882a593Smuzhiyun 			err = 0;
5470*4882a593Smuzhiyun 			goto errout;
5471*4882a593Smuzhiyun 		}
5472*4882a593Smuzhiyun #endif /* !DONGLEBUILD || BCMPCIEDEV_SROM_FORMAT */
5473*4882a593Smuzhiyun 
5474*4882a593Smuzhiyun #if defined(BCMHOSTVARS)
5475*4882a593Smuzhiyun 		/*
5476*4882a593Smuzhiyun 		 * CRC failed on srom, so if the device is using OTP
5477*4882a593Smuzhiyun 		 * and if OTP is not programmed use the default variables.
5478*4882a593Smuzhiyun 		 * for 4311 A1 there is no signature to indicate that OTP is
5479*4882a593Smuzhiyun 		 * programmed, so can't really verify the OTP is unprogrammed
5480*4882a593Smuzhiyun 		 * or a bad OTP.
5481*4882a593Smuzhiyun 		*/
5482*4882a593Smuzhiyun 		val = OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32));
5483*4882a593Smuzhiyun 		if ((si_is_sprom_available(sih) && srom[0] == 0xffff) ||
5484*4882a593Smuzhiyun #ifdef BCMQT
5485*4882a593Smuzhiyun 			(si_is_sprom_available(sih) && sromrev == 0) ||
5486*4882a593Smuzhiyun #endif
5487*4882a593Smuzhiyun 			(val & SPROM_OTPIN_USE)) {
5488*4882a593Smuzhiyun 			vp = base = mfgsromvars;
5489*4882a593Smuzhiyun 
5490*4882a593Smuzhiyun 			/* For windows internal/wltest driver, a .nvm file with default
5491*4882a593Smuzhiyun 			 * nvram parameters is downloaded from the file system (in src/wl/sys:
5492*4882a593Smuzhiyun 			 * wl_readconfigdata()).
5493*4882a593Smuzhiyun 			 * Only when we cannot download default vars from the file system, use
5494*4882a593Smuzhiyun 			 * defaultsromvars_wltest as default
5495*4882a593Smuzhiyun 			 */
5496*4882a593Smuzhiyun 			if (defvarslen == 0) {
5497*4882a593Smuzhiyun 				BS_ERROR(("No nvm file, use generic default (for programming"
5498*4882a593Smuzhiyun 					" SPROM/OTP only)\n"));
5499*4882a593Smuzhiyun 
5500*4882a593Smuzhiyun 				if (BCM43602_CHIP(sih->chip)) {
5501*4882a593Smuzhiyun 					defvarslen = srom_vars_len(defaultsromvars_43602);
5502*4882a593Smuzhiyun 					bcopy(defaultsromvars_43602, vp, defvarslen);
5503*4882a593Smuzhiyun 				} else if ((CHIPID(sih->chip) == BCM4360_CHIP_ID) ||
5504*4882a593Smuzhiyun 				           (CHIPID(sih->chip) == BCM4352_CHIP_ID)) {
5505*4882a593Smuzhiyun 					defvarslen = srom_vars_len(defaultsromvars_4360);
5506*4882a593Smuzhiyun 					bcopy(defaultsromvars_4360, vp, defvarslen);
5507*4882a593Smuzhiyun 				} else if (BCM4378_CHIP(sih->chip)) {
5508*4882a593Smuzhiyun 					defvarslen = srom_vars_len(defaultsromvars_4378);
5509*4882a593Smuzhiyun 					bcopy(defaultsromvars_4378, vp, defvarslen);
5510*4882a593Smuzhiyun 				} else if (BCM4387_CHIP(sih->chip)) {
5511*4882a593Smuzhiyun 					defvarslen = srom_vars_len(defaultsromvars_4387);
5512*4882a593Smuzhiyun 					bcopy(defaultsromvars_4387, vp, defvarslen);
5513*4882a593Smuzhiyun 				} else {
5514*4882a593Smuzhiyun 					defvarslen = srom_vars_len(defaultsromvars_wltest);
5515*4882a593Smuzhiyun 					bcopy(defaultsromvars_wltest, vp, defvarslen);
5516*4882a593Smuzhiyun 				}
5517*4882a593Smuzhiyun 			} else {
5518*4882a593Smuzhiyun 				BS_ERROR(("Use nvm file as default\n"));
5519*4882a593Smuzhiyun 			}
5520*4882a593Smuzhiyun 
5521*4882a593Smuzhiyun 			vp += defvarslen;
5522*4882a593Smuzhiyun 			/* add final null terminator */
5523*4882a593Smuzhiyun 			*vp++ = '\0';
5524*4882a593Smuzhiyun 
5525*4882a593Smuzhiyun 			BS_ERROR(("Used %d bytes of defaultsromvars\n", defvarslen));
5526*4882a593Smuzhiyun 			goto varsdone;
5527*4882a593Smuzhiyun 
5528*4882a593Smuzhiyun 		} else if ((CHIPID(sih->chip) == BCM4360_CHIP_ID) ||
5529*4882a593Smuzhiyun 			(CHIPID(sih->chip) == BCM43460_CHIP_ID) ||
5530*4882a593Smuzhiyun 			(CHIPID(sih->chip) == BCM4352_CHIP_ID) ||
5531*4882a593Smuzhiyun 			BCM43602_CHIP(sih->chip)) {
5532*4882a593Smuzhiyun 
5533*4882a593Smuzhiyun 			base = vp = mfgsromvars;
5534*4882a593Smuzhiyun 
5535*4882a593Smuzhiyun 			if ((CHIPID(sih->chip) == BCM4360_CHIP_ID) ||
5536*4882a593Smuzhiyun 			    (CHIPID(sih->chip) == BCM43460_CHIP_ID) ||
5537*4882a593Smuzhiyun 			    (CHIPID(sih->chip) == BCM4352_CHIP_ID) ||
5538*4882a593Smuzhiyun 			    BCM43602_CHIP(sih->chip))
5539*4882a593Smuzhiyun 				BS_ERROR(("4360 BOOT w/o SPROM or OTP\n"));
5540*4882a593Smuzhiyun 			else
5541*4882a593Smuzhiyun 				BS_ERROR(("BOOT w/o SPROM or OTP\n"));
5542*4882a593Smuzhiyun 
5543*4882a593Smuzhiyun 			if (defvarslen == 0) {
5544*4882a593Smuzhiyun 				if (BCM43602_CHIP(sih->chip)) {
5545*4882a593Smuzhiyun 					defvarslen = srom_vars_len(defaultsromvars_43602);
5546*4882a593Smuzhiyun 					bcopy(defaultsromvars_43602, vp, defvarslen);
5547*4882a593Smuzhiyun 				} else if ((sih->chip == BCM4360_CHIP_ID) ||
5548*4882a593Smuzhiyun 						(sih->chip == BCM4352_CHIP_ID)) {
5549*4882a593Smuzhiyun 					defvarslen = srom_vars_len(defaultsromvars_4360);
5550*4882a593Smuzhiyun 					bcopy(defaultsromvars_4360, vp, defvarslen);
5551*4882a593Smuzhiyun 				} else {
5552*4882a593Smuzhiyun 					defvarslen = srom_vars_len(defaultsromvars_4331);
5553*4882a593Smuzhiyun 					bcopy(defaultsromvars_4331, vp, defvarslen);
5554*4882a593Smuzhiyun 				}
5555*4882a593Smuzhiyun 			}
5556*4882a593Smuzhiyun 			vp += defvarslen;
5557*4882a593Smuzhiyun 			*vp++ = '\0';
5558*4882a593Smuzhiyun 			goto varsdone;
5559*4882a593Smuzhiyun 		} else
5560*4882a593Smuzhiyun #endif /* defined(BCMHOSTVARS) */
5561*4882a593Smuzhiyun 		{
5562*4882a593Smuzhiyun 			err = -1;
5563*4882a593Smuzhiyun 			goto errout;
5564*4882a593Smuzhiyun 		}
5565*4882a593Smuzhiyun 	}
5566*4882a593Smuzhiyun #if defined(BCM_ONE_NVRAM_SRC)
5567*4882a593Smuzhiyun 	/* Discard hostvars if SROM parsing is successful, so only one nvram source
5568*4882a593Smuzhiyun 	 * will be used.
5569*4882a593Smuzhiyun 	 * Routers use combined srom/host nvram so shouldn't define BCM_ONE_NVRAM_SRC.
5570*4882a593Smuzhiyun 	 */
5571*4882a593Smuzhiyun 	else {
5572*4882a593Smuzhiyun 		nvram_exit((void *)sih); /* free up global vars */
5573*4882a593Smuzhiyun 	}
5574*4882a593Smuzhiyun #endif /* BCM_ONE_NVRAM_SRC */
5575*4882a593Smuzhiyun 
5576*4882a593Smuzhiyun varscont:
5577*4882a593Smuzhiyun 	/* Bitmask for the sromrev */
5578*4882a593Smuzhiyun 	sr = 1 << sromrev;
5579*4882a593Smuzhiyun 
5580*4882a593Smuzhiyun 	/* srom version check: Current valid versions are:
5581*4882a593Smuzhiyun 	  * 1-5, 8-11, 12, 13, 15, 16, 17, 18 SROM_MAXREV
5582*4882a593Smuzhiyun 	  * This is a bit mask of all valid SROM versions.
5583*4882a593Smuzhiyun 	  */
5584*4882a593Smuzhiyun 	if ((sr & 0x7bf3e) == 0) {
5585*4882a593Smuzhiyun 		BS_ERROR(("Invalid SROM rev %d\n", sromrev));
5586*4882a593Smuzhiyun 		err = -2;
5587*4882a593Smuzhiyun 		goto errout;
5588*4882a593Smuzhiyun 	}
5589*4882a593Smuzhiyun 
5590*4882a593Smuzhiyun 	ASSERT(vars != NULL);
5591*4882a593Smuzhiyun 	ASSERT(count != NULL);
5592*4882a593Smuzhiyun 
5593*4882a593Smuzhiyun #if defined(BCMPCIEDEV_SROM_FORMAT) && defined(WLC_TXCAL)
5594*4882a593Smuzhiyun 	srom_sromrev = sromrev;
5595*4882a593Smuzhiyun #endif /* defined(BCMPCIEDEV_SROM_FORMAT) && defined(WLC_TXCAL) */
5596*4882a593Smuzhiyun 
5597*4882a593Smuzhiyun 	/* freed in same function */
5598*4882a593Smuzhiyun 	base = vp = MALLOC_NOPERSIST(osh, MAXSZ_NVRAM_VARS);
5599*4882a593Smuzhiyun 	ASSERT(vp != NULL);
5600*4882a593Smuzhiyun 	if (!vp) {
5601*4882a593Smuzhiyun 		err = -2;
5602*4882a593Smuzhiyun 		goto errout;
5603*4882a593Smuzhiyun 	}
5604*4882a593Smuzhiyun 
5605*4882a593Smuzhiyun 	/* read variables from flash */
5606*4882a593Smuzhiyun 	if (flash) {
5607*4882a593Smuzhiyun 		if ((err = initvars_flash(sih, osh, &vp, MAXSZ_NVRAM_VARS)))
5608*4882a593Smuzhiyun 			goto errout;
5609*4882a593Smuzhiyun 		goto varsdone;
5610*4882a593Smuzhiyun 	}
5611*4882a593Smuzhiyun 
5612*4882a593Smuzhiyun 	varbuf_init(&b, base, MAXSZ_NVRAM_VARS);
5613*4882a593Smuzhiyun 
5614*4882a593Smuzhiyun 	/* parse SROM into name=value pairs. */
5615*4882a593Smuzhiyun 	_initvars_srom_pci(sromrev, srom, 0, &b);
5616*4882a593Smuzhiyun 
5617*4882a593Smuzhiyun 	/* final nullbyte terminator */
5618*4882a593Smuzhiyun 	ASSERT(b.size >= 1);
5619*4882a593Smuzhiyun 	vp = b.buf;
5620*4882a593Smuzhiyun 	*vp++ = '\0';
5621*4882a593Smuzhiyun 
5622*4882a593Smuzhiyun 	ASSERT((vp - base) <= MAXSZ_NVRAM_VARS);
5623*4882a593Smuzhiyun 
5624*4882a593Smuzhiyun varsdone:
5625*4882a593Smuzhiyun 	err = initvars_table(osh, base, vp, vars, count); /* allocates buffer in 'vars' */
5626*4882a593Smuzhiyun 
5627*4882a593Smuzhiyun #if defined(BCMPCIEDEV_SROM_FORMAT) && defined(WLC_TXCAL)
5628*4882a593Smuzhiyun 	if (sromrev == 18) {
5629*4882a593Smuzhiyun 		int caldata_wordoffset = srom[SROM18_CALDATA_OFFSET_LOC] / 2;
5630*4882a593Smuzhiyun 
5631*4882a593Smuzhiyun 		if ((caldata_wordoffset != 0) &&
5632*4882a593Smuzhiyun 			(caldata_wordoffset + SROM_CALDATA_WORDS < SROM18_WORDS)) {
5633*4882a593Smuzhiyun 			memcpy(caldata_array, srom + caldata_wordoffset, SROM18_CALDATA_WORDS * 2);
5634*4882a593Smuzhiyun 			is_caldata_prsnt = TRUE;
5635*4882a593Smuzhiyun 		}
5636*4882a593Smuzhiyun 	} else if (sromrev == 16) {
5637*4882a593Smuzhiyun 		int caldata_wordoffset = srom[SROM16_CALDATA_OFFSET_LOC] / 2;
5638*4882a593Smuzhiyun 
5639*4882a593Smuzhiyun 		if ((caldata_wordoffset != 0) &&
5640*4882a593Smuzhiyun 			(caldata_wordoffset + SROM_CALDATA_WORDS < SROM16_WORDS)) {
5641*4882a593Smuzhiyun 			memcpy(caldata_array, srom + caldata_wordoffset, SROM_CALDATA_WORDS * 2);
5642*4882a593Smuzhiyun 			is_caldata_prsnt = TRUE;
5643*4882a593Smuzhiyun 		}
5644*4882a593Smuzhiyun 	}
5645*4882a593Smuzhiyun #endif /* defined(BCMPCIEDEV_SROM_FORMAT) && defined(WLC_TXCAL) */
5646*4882a593Smuzhiyun 
5647*4882a593Smuzhiyun #ifdef NVSRCX
5648*4882a593Smuzhiyun 	if (sromrev != 0)
5649*4882a593Smuzhiyun 		nvram_append((void *)sih, *vars, *count, VARBUF_PRIO_SROM);
5650*4882a593Smuzhiyun #endif
5651*4882a593Smuzhiyun #if defined(BCMPCIEDEV_SROM_FORMAT) && defined(WLC_TXCAL)
5652*4882a593Smuzhiyun 	if ((sromrev == 15) || (sromrev == 17)) {
5653*4882a593Smuzhiyun 		uint32 caldata_size = get_srom_pci_caldata_size(sromrev);
5654*4882a593Smuzhiyun 
5655*4882a593Smuzhiyun 		cal_wordoffset = getintvar(NULL, "caldata_offset")/2;
5656*4882a593Smuzhiyun 		memcpy(caldata_array, srom + cal_wordoffset, caldata_size);
5657*4882a593Smuzhiyun 	}
5658*4882a593Smuzhiyun #endif
5659*4882a593Smuzhiyun errout:
5660*4882a593Smuzhiyun #if defined(BCMHOSTVARS)
5661*4882a593Smuzhiyun 	if (base && (base != mfgsromvars))
5662*4882a593Smuzhiyun #else
5663*4882a593Smuzhiyun 	if (base)
5664*4882a593Smuzhiyun #endif /* defined(BCMHOSTVARS) */
5665*4882a593Smuzhiyun 		MFREE(osh, base, MAXSZ_NVRAM_VARS);
5666*4882a593Smuzhiyun 
5667*4882a593Smuzhiyun 	MFREE(osh, srom, SROM_MAX);
5668*4882a593Smuzhiyun 	return err;
5669*4882a593Smuzhiyun }
5670*4882a593Smuzhiyun 
5671*4882a593Smuzhiyun /**
5672*4882a593Smuzhiyun  * initvars_cis_pci() parses OTP CIS. This is specifically for PCIe full dongle that has SROM
5673*4882a593Smuzhiyun  * header plus CIS tuples programmed in OTP.
5674*4882a593Smuzhiyun  * Return error if the content is not in CIS format or OTP is not present.
5675*4882a593Smuzhiyun  */
5676*4882a593Smuzhiyun static int
5677*4882a593Smuzhiyun BCMATTACHFN(initvars_cis_pci)(si_t *sih, osl_t *osh, volatile void *curmap,
5678*4882a593Smuzhiyun 	char **vars, uint *count)
5679*4882a593Smuzhiyun {
5680*4882a593Smuzhiyun 	uint wsz = 0, sz = 0, base_len = 0;
5681*4882a593Smuzhiyun 	void *oh = NULL;
5682*4882a593Smuzhiyun 	int rc = BCME_OK;
5683*4882a593Smuzhiyun 	uint16 *cisbuf = NULL;
5684*4882a593Smuzhiyun 	uint8 *cis = NULL;
5685*4882a593Smuzhiyun #if defined (BCMHOSTVARS)
5686*4882a593Smuzhiyun 	char *vp = NULL;
5687*4882a593Smuzhiyun #endif /* BCMHOSTVARS */
5688*4882a593Smuzhiyun 	char *base = NULL;
5689*4882a593Smuzhiyun 	bool wasup;
5690*4882a593Smuzhiyun 	uint32 min_res_mask = 0;
5691*4882a593Smuzhiyun 	BCM_REFERENCE(curmap);
5692*4882a593Smuzhiyun 
5693*4882a593Smuzhiyun 	/* Bail out if we've dealt with OTP/SPROM before! */
5694*4882a593Smuzhiyun 	if (srvars_inited)
5695*4882a593Smuzhiyun 		goto exit;
5696*4882a593Smuzhiyun 
5697*4882a593Smuzhiyun 	/* Turn on OTP if it's not already on */
5698*4882a593Smuzhiyun 	if (!(wasup = si_is_otp_powered(sih)))
5699*4882a593Smuzhiyun 		si_otp_power(sih, TRUE, &min_res_mask);
5700*4882a593Smuzhiyun 
5701*4882a593Smuzhiyun 	if (si_cis_source(sih) != CIS_OTP)
5702*4882a593Smuzhiyun 		rc = BCME_NOTFOUND;
5703*4882a593Smuzhiyun 	else if ((oh = otp_init(sih)) == NULL)
5704*4882a593Smuzhiyun 		rc = BCME_ERROR;
5705*4882a593Smuzhiyun 	else if (!(((BUSCORETYPE(sih->buscoretype) == PCIE2_CORE_ID) || otp_newcis(oh)) &&
5706*4882a593Smuzhiyun 		(otp_status(oh) & OTPS_GUP_HW))) {
5707*4882a593Smuzhiyun 		/* OTP bit CIS format (507) not used by pcie core - only needed for sdio core */
5708*4882a593Smuzhiyun 		rc = BCME_NOTFOUND;
5709*4882a593Smuzhiyun 	} else if ((sz = otp_size(oh)) != 0) {
5710*4882a593Smuzhiyun 		if ((cisbuf = (uint16*)MALLOC_NOPERSIST(osh, sz))) {
5711*4882a593Smuzhiyun 			/* otp_size() returns bytes, not words. */
5712*4882a593Smuzhiyun 			wsz = sz >> 1;
5713*4882a593Smuzhiyun 			/* for 4389b0 (CCREV-70) sw region is before the hw region */
5714*4882a593Smuzhiyun 			if (CCREV(sih->ccrev) == 70) {
5715*4882a593Smuzhiyun 				rc = otp_read_region(sih, OTP_SW_RGN, cisbuf, &wsz);
5716*4882a593Smuzhiyun 				cis = (uint8*)cisbuf;
5717*4882a593Smuzhiyun 			} else {
5718*4882a593Smuzhiyun 				rc = otp_read_region(sih, OTP_HW_RGN, cisbuf, &wsz);
5719*4882a593Smuzhiyun 				/* Bypass the HW header and signature */
5720*4882a593Smuzhiyun 				cis = (uint8*)(cisbuf + (otp_pcie_hwhdr_sz(sih) / 2));
5721*4882a593Smuzhiyun 			}
5722*4882a593Smuzhiyun 			BS_ERROR(("initvars_cis_pci: Parsing CIS in OTP.\n"));
5723*4882a593Smuzhiyun 		} else
5724*4882a593Smuzhiyun 			rc = BCME_NOMEM;
5725*4882a593Smuzhiyun 	}
5726*4882a593Smuzhiyun 
5727*4882a593Smuzhiyun 	/* Restore original OTP state */
5728*4882a593Smuzhiyun 	if (!wasup)
5729*4882a593Smuzhiyun 		si_otp_power(sih, FALSE, &min_res_mask);
5730*4882a593Smuzhiyun 
5731*4882a593Smuzhiyun 	if (rc != BCME_OK) {
5732*4882a593Smuzhiyun 		BS_ERROR(("initvars_cis_pci: Not CIS format\n"));
5733*4882a593Smuzhiyun 		goto exit;
5734*4882a593Smuzhiyun 	}
5735*4882a593Smuzhiyun 
5736*4882a593Smuzhiyun #if defined (BCMHOSTVARS)
5737*4882a593Smuzhiyun 	if (defvarslen) {
5738*4882a593Smuzhiyun 		vp = mfgsromvars;
5739*4882a593Smuzhiyun 		vp += defvarslen;
5740*4882a593Smuzhiyun 
5741*4882a593Smuzhiyun 		/* allocates buffer in 'vars' */
5742*4882a593Smuzhiyun 		rc = initvars_table(osh, mfgsromvars, vp, &base, &base_len);
5743*4882a593Smuzhiyun 		if (rc)
5744*4882a593Smuzhiyun 			goto exit;
5745*4882a593Smuzhiyun 
5746*4882a593Smuzhiyun 		*vars = base;
5747*4882a593Smuzhiyun 		*count = base_len;
5748*4882a593Smuzhiyun 
5749*4882a593Smuzhiyun 		BS_ERROR(("initvars_cis_pci external nvram %d bytes\n", defvarslen));
5750*4882a593Smuzhiyun 	}
5751*4882a593Smuzhiyun 
5752*4882a593Smuzhiyun #endif /* BCMHOSTVARS */
5753*4882a593Smuzhiyun 
5754*4882a593Smuzhiyun 	/* Parse the CIS and allocate a(nother) buffer in 'vars' */
5755*4882a593Smuzhiyun 	rc = srom_parsecis(sih, osh, &cis, SROM_CIS_SINGLE, vars, count);
5756*4882a593Smuzhiyun 
5757*4882a593Smuzhiyun 	srvars_inited = TRUE;
5758*4882a593Smuzhiyun exit:
5759*4882a593Smuzhiyun 	/* Clean up */
5760*4882a593Smuzhiyun 	if (base)
5761*4882a593Smuzhiyun 		MFREE(osh, base, base_len);
5762*4882a593Smuzhiyun 	if (cisbuf)
5763*4882a593Smuzhiyun 		MFREE(osh, cisbuf, sz);
5764*4882a593Smuzhiyun 
5765*4882a593Smuzhiyun 	/* return OK so the driver will load & use defaults if bad srom/otp */
5766*4882a593Smuzhiyun 	return rc;
5767*4882a593Smuzhiyun }
5768*4882a593Smuzhiyun #endif /* !defined(BCMDONGLEHOST) */
5769*4882a593Smuzhiyun 
5770*4882a593Smuzhiyun #ifdef BCMSDIO
5771*4882a593Smuzhiyun #if !defined(BCMDONGLEHOST)
5772*4882a593Smuzhiyun /**
5773*4882a593Smuzhiyun  * Read the SDIO cis and call parsecis to allocate and initialize the NVRAM vars buffer.
5774*4882a593Smuzhiyun  * Return 0 on success, nonzero on error.
5775*4882a593Smuzhiyun  */
5776*4882a593Smuzhiyun static int
5777*4882a593Smuzhiyun BCMATTACHFN(initvars_cis_sdio)(si_t *sih, osl_t *osh, char **vars, uint *count)
5778*4882a593Smuzhiyun {
5779*4882a593Smuzhiyun 	uint8 *cis[SBSDIO_NUM_FUNCTION + 1];
5780*4882a593Smuzhiyun 	uint fn, numfn;
5781*4882a593Smuzhiyun 	int rc = 0;
5782*4882a593Smuzhiyun 
5783*4882a593Smuzhiyun 	/* Using MALLOC here causes the Windows driver to crash Needs Investigating */
5784*4882a593Smuzhiyun #ifdef NDIS
5785*4882a593Smuzhiyun 	uint8 cisd[SBSDIO_NUM_FUNCTION + 1][SBSDIO_CIS_SIZE_LIMIT];
5786*4882a593Smuzhiyun #endif
5787*4882a593Smuzhiyun 
5788*4882a593Smuzhiyun 	numfn = bcmsdh_query_iofnum(NULL);
5789*4882a593Smuzhiyun 	ASSERT(numfn <= SDIOD_MAX_IOFUNCS);
5790*4882a593Smuzhiyun 
5791*4882a593Smuzhiyun 	for (fn = 0; fn <= numfn; fn++) {
5792*4882a593Smuzhiyun #ifdef NDIS
5793*4882a593Smuzhiyun 		cis[fn] = (uint8*)cisd[fn];
5794*4882a593Smuzhiyun #else
5795*4882a593Smuzhiyun 		/* freed in same function */
5796*4882a593Smuzhiyun 		if ((cis[fn] = MALLOC_NOPERSIST(osh, SBSDIO_CIS_SIZE_LIMIT)) == NULL) {
5797*4882a593Smuzhiyun 			rc = -1;
5798*4882a593Smuzhiyun 			break;
5799*4882a593Smuzhiyun 		}
5800*4882a593Smuzhiyun #endif /* NDIS */
5801*4882a593Smuzhiyun 
5802*4882a593Smuzhiyun 		bzero(cis[fn], SBSDIO_CIS_SIZE_LIMIT);
5803*4882a593Smuzhiyun 
5804*4882a593Smuzhiyun 		if (bcmsdh_cis_read(NULL, fn, cis[fn], SBSDIO_CIS_SIZE_LIMIT) != 0) {
5805*4882a593Smuzhiyun #ifdef NDIS
5806*4882a593Smuzhiyun 			/* nothing to do */
5807*4882a593Smuzhiyun #else
5808*4882a593Smuzhiyun 			MFREE(osh, cis[fn], SBSDIO_CIS_SIZE_LIMIT);
5809*4882a593Smuzhiyun #endif
5810*4882a593Smuzhiyun 			rc = -2;
5811*4882a593Smuzhiyun 			break;
5812*4882a593Smuzhiyun 		}
5813*4882a593Smuzhiyun 	}
5814*4882a593Smuzhiyun 
5815*4882a593Smuzhiyun 	if (!rc)
5816*4882a593Smuzhiyun 		rc = srom_parsecis(sih, osh, cis, fn, vars, count);
5817*4882a593Smuzhiyun 
5818*4882a593Smuzhiyun #ifdef NDIS
5819*4882a593Smuzhiyun 	/* nothing to do here */
5820*4882a593Smuzhiyun #else
5821*4882a593Smuzhiyun 	while (fn-- > 0)
5822*4882a593Smuzhiyun 		MFREE(osh, cis[fn], SBSDIO_CIS_SIZE_LIMIT);
5823*4882a593Smuzhiyun #endif
5824*4882a593Smuzhiyun 
5825*4882a593Smuzhiyun 	return (rc);
5826*4882a593Smuzhiyun }
5827*4882a593Smuzhiyun #endif /* !defined(BCMDONGLEHOST) */
5828*4882a593Smuzhiyun 
5829*4882a593Smuzhiyun /** set SDIO sprom command register */
5830*4882a593Smuzhiyun static int
5831*4882a593Smuzhiyun BCMATTACHFN(sprom_cmd_sdio)(osl_t *osh, uint8 cmd)
5832*4882a593Smuzhiyun {
5833*4882a593Smuzhiyun 	uint8 status = 0;
5834*4882a593Smuzhiyun 	uint wait_cnt = 1000;
5835*4882a593Smuzhiyun 
5836*4882a593Smuzhiyun 	/* write sprom command register */
5837*4882a593Smuzhiyun 	bcmsdh_cfg_write(NULL, SDIO_FUNC_1, SBSDIO_SPROM_CS, cmd, NULL);
5838*4882a593Smuzhiyun 
5839*4882a593Smuzhiyun 	/* wait status */
5840*4882a593Smuzhiyun 	while (wait_cnt--) {
5841*4882a593Smuzhiyun 		status = bcmsdh_cfg_read(NULL, SDIO_FUNC_1, SBSDIO_SPROM_CS, NULL);
5842*4882a593Smuzhiyun 		if (status & SBSDIO_SPROM_DONE)
5843*4882a593Smuzhiyun 			return 0;
5844*4882a593Smuzhiyun 	}
5845*4882a593Smuzhiyun 
5846*4882a593Smuzhiyun 	return 1;
5847*4882a593Smuzhiyun }
5848*4882a593Smuzhiyun 
5849*4882a593Smuzhiyun /** read a word from the SDIO srom */
5850*4882a593Smuzhiyun static int
5851*4882a593Smuzhiyun sprom_read_sdio(osl_t *osh, uint16 addr, uint16 *data)
5852*4882a593Smuzhiyun {
5853*4882a593Smuzhiyun 	uint8 addr_l, addr_h, data_l, data_h;
5854*4882a593Smuzhiyun 
5855*4882a593Smuzhiyun 	addr_l = (uint8)((addr * 2) & 0xff);
5856*4882a593Smuzhiyun 	addr_h = (uint8)(((addr * 2) >> 8) & 0xff);
5857*4882a593Smuzhiyun 
5858*4882a593Smuzhiyun 	/* set address */
5859*4882a593Smuzhiyun 	bcmsdh_cfg_write(NULL, SDIO_FUNC_1, SBSDIO_SPROM_ADDR_HIGH, addr_h, NULL);
5860*4882a593Smuzhiyun 	bcmsdh_cfg_write(NULL, SDIO_FUNC_1, SBSDIO_SPROM_ADDR_LOW, addr_l, NULL);
5861*4882a593Smuzhiyun 
5862*4882a593Smuzhiyun 	/* do read */
5863*4882a593Smuzhiyun 	if (sprom_cmd_sdio(osh, SBSDIO_SPROM_READ))
5864*4882a593Smuzhiyun 		return 1;
5865*4882a593Smuzhiyun 
5866*4882a593Smuzhiyun 	/* read data */
5867*4882a593Smuzhiyun 	data_h = bcmsdh_cfg_read(NULL, SDIO_FUNC_1, SBSDIO_SPROM_DATA_HIGH, NULL);
5868*4882a593Smuzhiyun 	data_l = bcmsdh_cfg_read(NULL, SDIO_FUNC_1, SBSDIO_SPROM_DATA_LOW, NULL);
5869*4882a593Smuzhiyun 
5870*4882a593Smuzhiyun 	*data = (data_h << 8) | data_l;
5871*4882a593Smuzhiyun 	return 0;
5872*4882a593Smuzhiyun }
5873*4882a593Smuzhiyun 
5874*4882a593Smuzhiyun #if defined(WLTEST) || defined (DHD_SPROM) || defined (BCMDBG)
5875*4882a593Smuzhiyun /** write a word to the SDIO srom */
5876*4882a593Smuzhiyun static int
5877*4882a593Smuzhiyun sprom_write_sdio(osl_t *osh, uint16 addr, uint16 data)
5878*4882a593Smuzhiyun {
5879*4882a593Smuzhiyun 	uint8 addr_l, addr_h, data_l, data_h;
5880*4882a593Smuzhiyun 
5881*4882a593Smuzhiyun 	addr_l = (uint8)((addr * 2) & 0xff);
5882*4882a593Smuzhiyun 	addr_h = (uint8)(((addr * 2) >> 8) & 0xff);
5883*4882a593Smuzhiyun 	data_l = (uint8)(data & 0xff);
5884*4882a593Smuzhiyun 	data_h = (uint8)((data >> 8) & 0xff);
5885*4882a593Smuzhiyun 
5886*4882a593Smuzhiyun 	/* set address */
5887*4882a593Smuzhiyun 	bcmsdh_cfg_write(NULL, SDIO_FUNC_1, SBSDIO_SPROM_ADDR_HIGH, addr_h, NULL);
5888*4882a593Smuzhiyun 	bcmsdh_cfg_write(NULL, SDIO_FUNC_1, SBSDIO_SPROM_ADDR_LOW, addr_l, NULL);
5889*4882a593Smuzhiyun 
5890*4882a593Smuzhiyun 	/* write data */
5891*4882a593Smuzhiyun 	bcmsdh_cfg_write(NULL, SDIO_FUNC_1, SBSDIO_SPROM_DATA_HIGH, data_h, NULL);
5892*4882a593Smuzhiyun 	bcmsdh_cfg_write(NULL, SDIO_FUNC_1, SBSDIO_SPROM_DATA_LOW, data_l, NULL);
5893*4882a593Smuzhiyun 
5894*4882a593Smuzhiyun 	/* do write */
5895*4882a593Smuzhiyun 	return sprom_cmd_sdio(osh, SBSDIO_SPROM_WRITE);
5896*4882a593Smuzhiyun }
5897*4882a593Smuzhiyun #endif /* defined(WLTEST) || defined (DHD_SPROM) || defined (BCMDBG) */
5898*4882a593Smuzhiyun #endif /* BCMSDIO */
5899*4882a593Smuzhiyun 
5900*4882a593Smuzhiyun #if !defined(BCMDONGLEHOST)
5901*4882a593Smuzhiyun #ifdef BCMSPI
5902*4882a593Smuzhiyun /**
5903*4882a593Smuzhiyun  * Read the SPI cis and call parsecis to allocate and initialize the NVRAM vars buffer.
5904*4882a593Smuzhiyun  * Return 0 on success, nonzero on error.
5905*4882a593Smuzhiyun  */
5906*4882a593Smuzhiyun static int
5907*4882a593Smuzhiyun BCMATTACHFN(initvars_cis_spi)(si_t *sih, osl_t *osh, char **vars, uint *count)
5908*4882a593Smuzhiyun {
5909*4882a593Smuzhiyun 	uint8 *cis;
5910*4882a593Smuzhiyun 	int rc;
5911*4882a593Smuzhiyun 
5912*4882a593Smuzhiyun 	/* Using MALLOC here causes the Windows driver to crash Needs Investigating */
5913*4882a593Smuzhiyun #ifdef NDIS
5914*4882a593Smuzhiyun 	uint8 cisd[SBSDIO_CIS_SIZE_LIMIT];
5915*4882a593Smuzhiyun 	cis = (uint8*)cisd;
5916*4882a593Smuzhiyun #else
5917*4882a593Smuzhiyun 	/* freed in same function */
5918*4882a593Smuzhiyun 	if ((cis = MALLOC_NOPERSIST(osh, SBSDIO_CIS_SIZE_LIMIT)) == NULL) {
5919*4882a593Smuzhiyun 		return -1;
5920*4882a593Smuzhiyun 	}
5921*4882a593Smuzhiyun #endif /* NDIS */
5922*4882a593Smuzhiyun 
5923*4882a593Smuzhiyun 	bzero(cis, SBSDIO_CIS_SIZE_LIMIT);
5924*4882a593Smuzhiyun 
5925*4882a593Smuzhiyun 	if (bcmsdh_cis_read(NULL, SDIO_FUNC_1, cis, SBSDIO_CIS_SIZE_LIMIT) != 0) {
5926*4882a593Smuzhiyun #ifdef NDIS
5927*4882a593Smuzhiyun 		/* nothing to do */
5928*4882a593Smuzhiyun #else
5929*4882a593Smuzhiyun 		MFREE(osh, cis, SBSDIO_CIS_SIZE_LIMIT);
5930*4882a593Smuzhiyun #endif /* NDIS */
5931*4882a593Smuzhiyun 		return -2;
5932*4882a593Smuzhiyun 	}
5933*4882a593Smuzhiyun 
5934*4882a593Smuzhiyun 	rc = srom_parsecis(sih, osh, &cis, SDIO_FUNC_1, vars, count);
5935*4882a593Smuzhiyun 
5936*4882a593Smuzhiyun #ifdef NDIS
5937*4882a593Smuzhiyun 	/* nothing to do here */
5938*4882a593Smuzhiyun #else
5939*4882a593Smuzhiyun 	MFREE(osh, cis, SBSDIO_CIS_SIZE_LIMIT);
5940*4882a593Smuzhiyun #endif
5941*4882a593Smuzhiyun 
5942*4882a593Smuzhiyun 	return (rc);
5943*4882a593Smuzhiyun }
5944*4882a593Smuzhiyun #endif /* BCMSPI */
5945*4882a593Smuzhiyun #endif /* !defined(BCMDONGLEHOST) */
5946*4882a593Smuzhiyun 
5947*4882a593Smuzhiyun /** Return sprom size in 16-bit words */
5948*4882a593Smuzhiyun uint
5949*4882a593Smuzhiyun srom_size(si_t *sih, osl_t *osh)
5950*4882a593Smuzhiyun {
5951*4882a593Smuzhiyun 	uint size = (SROM16_SIGN + 1) * 2;	/* must big enough for SROM16 */
5952*4882a593Smuzhiyun 	return size;
5953*4882a593Smuzhiyun }
5954*4882a593Smuzhiyun 
5955*4882a593Smuzhiyun /**
5956*4882a593Smuzhiyun  * initvars are different for BCMUSBDEV and BCMSDIODEV.  This is OK when supporting both at
5957*4882a593Smuzhiyun  * the same time, but only because all of the code is in attach functions and not in ROM.
5958*4882a593Smuzhiyun  */
5959*4882a593Smuzhiyun 
5960*4882a593Smuzhiyun #if defined(BCMUSBDEV_ENABLED)
5961*4882a593Smuzhiyun #ifdef BCM_DONGLEVARS
5962*4882a593Smuzhiyun /*** reads a CIS structure (so not an SROM-MAP structure) from either OTP or SROM */
5963*4882a593Smuzhiyun static int
5964*4882a593Smuzhiyun BCMATTACHFN(initvars_srom_si_bl)(si_t *sih, osl_t *osh, volatile void *curmap,
5965*4882a593Smuzhiyun 	char **vars, uint *varsz)
5966*4882a593Smuzhiyun {
5967*4882a593Smuzhiyun 	int sel = 0;		/* where to read srom/cis: 0 - none, 1 - otp, 2 - sprom */
5968*4882a593Smuzhiyun 	uint sz = 0;		/* srom size in bytes */
5969*4882a593Smuzhiyun 	void *oh = NULL;
5970*4882a593Smuzhiyun 	int rc = BCME_OK;
5971*4882a593Smuzhiyun 	uint16 prio = VARBUF_PRIO_INVALID;
5972*4882a593Smuzhiyun 
5973*4882a593Smuzhiyun 	if ((oh = otp_init(sih)) != NULL && (otp_status(oh) & OTPS_GUP_SW)) {
5974*4882a593Smuzhiyun 		/* Access OTP if it is present, powered on, and programmed */
5975*4882a593Smuzhiyun 		sz = otp_size(oh);
5976*4882a593Smuzhiyun 		sel = 1;
5977*4882a593Smuzhiyun 	} else if ((sz = srom_size(sih, osh)) != 0) {
5978*4882a593Smuzhiyun 		/* Access the SPROM if it is present */
5979*4882a593Smuzhiyun 		sz <<= 1;
5980*4882a593Smuzhiyun 		sel = 2;
5981*4882a593Smuzhiyun 	}
5982*4882a593Smuzhiyun 
5983*4882a593Smuzhiyun 	/* Read CIS in OTP/SPROM */
5984*4882a593Smuzhiyun 	if (sel != 0) {
5985*4882a593Smuzhiyun 		uint16 *srom;
5986*4882a593Smuzhiyun 		uint8 *body = NULL;
5987*4882a593Smuzhiyun 		uint otpsz = sz;
5988*4882a593Smuzhiyun 
5989*4882a593Smuzhiyun 		ASSERT(sz);
5990*4882a593Smuzhiyun 
5991*4882a593Smuzhiyun 		/* Allocate memory */
5992*4882a593Smuzhiyun 		if ((srom = (uint16 *)MALLOC(osh, sz)) == NULL)
5993*4882a593Smuzhiyun 			return BCME_NOMEM;
5994*4882a593Smuzhiyun 
5995*4882a593Smuzhiyun 		/* Read CIS */
5996*4882a593Smuzhiyun 		switch (sel) {
5997*4882a593Smuzhiyun 		case 1:
5998*4882a593Smuzhiyun 			rc = otp_read_region(sih, OTP_SW_RGN, srom, &otpsz);
5999*4882a593Smuzhiyun 			sz = otpsz;
6000*4882a593Smuzhiyun 			body = (uint8 *)srom;
6001*4882a593Smuzhiyun 			prio = VARBUF_PRIO_OTP;
6002*4882a593Smuzhiyun 			break;
6003*4882a593Smuzhiyun 		case 2:
6004*4882a593Smuzhiyun 			rc = srom_read(sih, SI_BUS, curmap, osh, 0, sz, srom, TRUE);
6005*4882a593Smuzhiyun 			/* sprom has 8 byte h/w header */
6006*4882a593Smuzhiyun 			body = (uint8 *)srom + SBSDIO_SPROM_CIS_OFFSET;
6007*4882a593Smuzhiyun 			prio = VARBUF_PRIO_SROM;
6008*4882a593Smuzhiyun 			break;
6009*4882a593Smuzhiyun 		default:
6010*4882a593Smuzhiyun 			/* impossible to come here */
6011*4882a593Smuzhiyun 			ASSERT(0);
6012*4882a593Smuzhiyun 			break;
6013*4882a593Smuzhiyun 		}
6014*4882a593Smuzhiyun 
6015*4882a593Smuzhiyun 		/* Parse CIS */
6016*4882a593Smuzhiyun 		if (rc == BCME_OK) {
6017*4882a593Smuzhiyun 			/* each word is in host endian */
6018*4882a593Smuzhiyun 			htol16_buf((uint8 *)srom, sz);
6019*4882a593Smuzhiyun 			ASSERT(body);
6020*4882a593Smuzhiyun 			rc = srom_parsecis(sih, osh, &body, SROM_CIS_SINGLE, vars, varsz);
6021*4882a593Smuzhiyun 		}
6022*4882a593Smuzhiyun 
6023*4882a593Smuzhiyun 		MFREE(osh, srom, sz);	/* Clean up */
6024*4882a593Smuzhiyun 
6025*4882a593Smuzhiyun 		/* Make SROM variables global */
6026*4882a593Smuzhiyun 		if (rc == BCME_OK) {
6027*4882a593Smuzhiyun 			nvram_append((void *)sih, *vars, *varsz, prio);
6028*4882a593Smuzhiyun 			DONGLE_STORE_VARS_OTP_PTR(*vars);
6029*4882a593Smuzhiyun 		}
6030*4882a593Smuzhiyun 	}
6031*4882a593Smuzhiyun 
6032*4882a593Smuzhiyun 	return BCME_OK;
6033*4882a593Smuzhiyun }
6034*4882a593Smuzhiyun #endif	/* #ifdef BCM_DONGLEVARS */
6035*4882a593Smuzhiyun 
6036*4882a593Smuzhiyun /**
6037*4882a593Smuzhiyun  * initvars_srom_si() is defined multiple times in this file. This is the 1st variant for chips with
6038*4882a593Smuzhiyun  * an active USB interface. It is called only for bus types SI_BUS, and only for CIS
6039*4882a593Smuzhiyun  * format in SPROM and/or OTP. Reads OTP or SPROM (bootloader only) and appends parsed contents to
6040*4882a593Smuzhiyun  * caller supplied var/value pairs.
6041*4882a593Smuzhiyun  */
6042*4882a593Smuzhiyun static int
6043*4882a593Smuzhiyun BCMATTACHFN(initvars_srom_si)(si_t *sih, osl_t *osh, volatile void *curmap,
6044*4882a593Smuzhiyun 	char **vars, uint *varsz)
6045*4882a593Smuzhiyun {
6046*4882a593Smuzhiyun 
6047*4882a593Smuzhiyun #if defined(BCM_DONGLEVARS)
6048*4882a593Smuzhiyun 	BCM_REFERENCE(osh);
6049*4882a593Smuzhiyun 	BCM_REFERENCE(sih);
6050*4882a593Smuzhiyun 	BCM_REFERENCE(curmap);
6051*4882a593Smuzhiyun #endif
6052*4882a593Smuzhiyun 
6053*4882a593Smuzhiyun 	/* Bail out if we've dealt with OTP/SPROM before! */
6054*4882a593Smuzhiyun 	if (srvars_inited)
6055*4882a593Smuzhiyun 		goto exit;
6056*4882a593Smuzhiyun 
6057*4882a593Smuzhiyun #ifdef BCM_DONGLEVARS	/* this flag should be defined for usb bootloader, to read OTP or SROM */
6058*4882a593Smuzhiyun 	if (BCME_OK != initvars_srom_si_bl(sih, osh, curmap, vars, varsz)) /* CIS format only */
6059*4882a593Smuzhiyun 		return BCME_ERROR;
6060*4882a593Smuzhiyun #endif
6061*4882a593Smuzhiyun 
6062*4882a593Smuzhiyun 	/* update static local var to skip for next call */
6063*4882a593Smuzhiyun 	srvars_inited = TRUE;
6064*4882a593Smuzhiyun 
6065*4882a593Smuzhiyun exit:
6066*4882a593Smuzhiyun 	/* Tell the caller there is no individual SROM variables */
6067*4882a593Smuzhiyun 	*vars = NULL;
6068*4882a593Smuzhiyun 	*varsz = 0;
6069*4882a593Smuzhiyun 
6070*4882a593Smuzhiyun 	/* return OK so the driver will load & use defaults if bad srom/otp */
6071*4882a593Smuzhiyun 	return BCME_OK;
6072*4882a593Smuzhiyun }
6073*4882a593Smuzhiyun 
6074*4882a593Smuzhiyun #elif defined(BCMSDIODEV_ENABLED)
6075*4882a593Smuzhiyun 
6076*4882a593Smuzhiyun #ifdef BCM_DONGLEVARS
6077*4882a593Smuzhiyun static uint8 BCMATTACHDATA(defcis4369)[] = { 0x20, 0x4, 0xd0, 0x2, 0x64, 0x43, 0xff, 0xff };
6078*4882a593Smuzhiyun static uint8 BCMATTACHDATA(defcis43012)[] = { 0x20, 0x4, 0xd0, 0x2, 0x04, 0xA8, 0xff, 0xff };
6079*4882a593Smuzhiyun static uint8 BCMATTACHDATA(defcis43013)[] = { 0x20, 0x4, 0xd0, 0x2, 0x05, 0xA8, 0xff, 0xff };
6080*4882a593Smuzhiyun static uint8 BCMATTACHDATA(defcis43014)[] = { 0x20, 0x4, 0xd0, 0x2, 0x06, 0xA8, 0xff, 0xff };
6081*4882a593Smuzhiyun static uint8 BCMATTACHDATA(defcis4362)[] = { 0x20, 0x4, 0xd0, 0x2, 0x62, 0x43, 0xff, 0xff };
6082*4882a593Smuzhiyun static uint8 BCMATTACHDATA(defcis4378)[] = { 0x20, 0x4, 0xd0, 0x2, 0x78, 0x43, 0xff, 0xff };
6083*4882a593Smuzhiyun static uint8 BCMATTACHDATA(defcis4385)[] = { 0x20, 0x4, 0xd0, 0x2, 0x85, 0x43, 0xff, 0xff };
6084*4882a593Smuzhiyun static uint8 BCMATTACHDATA(defcis4387)[] = { 0x20, 0x4, 0xd0, 0x2, 0x78, 0x43, 0xff, 0xff };
6085*4882a593Smuzhiyun static uint8 BCMATTACHDATA(defcis4388)[] = { 0x20, 0x4, 0xd0, 0x2, 0x88, 0x43, 0xff, 0xff };
6086*4882a593Smuzhiyun static uint8 BCMATTACHDATA(defcis4389)[] = { 0x20, 0x4, 0xd0, 0x2, 0x89, 0x43, 0xff, 0xff };
6087*4882a593Smuzhiyun static uint8 BCMATTACHDATA(defcis4397)[] = { 0x20, 0x4, 0xd0, 0x2, 0x97, 0x43, 0xff, 0xff };
6088*4882a593Smuzhiyun 
6089*4882a593Smuzhiyun /**
6090*4882a593Smuzhiyun  * initvars_srom_si() is defined multiple times in this file. This is the 2nd variant for chips with
6091*4882a593Smuzhiyun  * an active SDIOd interface using DONGLEVARS
6092*4882a593Smuzhiyun  */
6093*4882a593Smuzhiyun static int
6094*4882a593Smuzhiyun BCMATTACHFN(initvars_srom_si)(si_t *sih, osl_t *osh, volatile void *curmap,
6095*4882a593Smuzhiyun 	char **vars, uint *varsz)
6096*4882a593Smuzhiyun {
6097*4882a593Smuzhiyun 	int cis_src;
6098*4882a593Smuzhiyun 	uint msz = 0;
6099*4882a593Smuzhiyun 	uint sz = 0;
6100*4882a593Smuzhiyun 	void *oh = NULL;
6101*4882a593Smuzhiyun 	int rc = BCME_OK;
6102*4882a593Smuzhiyun 	bool	new_cisformat = FALSE;
6103*4882a593Smuzhiyun 
6104*4882a593Smuzhiyun 	uint16 *cisbuf = NULL;
6105*4882a593Smuzhiyun 
6106*4882a593Smuzhiyun 	/* # sdiod fns + common + extra */
6107*4882a593Smuzhiyun 	uint8 *cis[SBSDIO_NUM_FUNCTION + 2] = { 0 };
6108*4882a593Smuzhiyun 
6109*4882a593Smuzhiyun 	uint ciss = 0;
6110*4882a593Smuzhiyun 	uint8 *defcis;
6111*4882a593Smuzhiyun 	uint hdrsz;
6112*4882a593Smuzhiyun 	uint16 prio = VARBUF_PRIO_INVALID;
6113*4882a593Smuzhiyun 
6114*4882a593Smuzhiyun #if defined(BCMSDIODEV_ENABLED) && defined(ATE_BUILD)
6115*4882a593Smuzhiyun 	if (si_chipcap_sdio_ate_only(sih)) {
6116*4882a593Smuzhiyun 		BS_ERROR(("ATE BUILD: skip cis based var init\n"));
6117*4882a593Smuzhiyun 		goto exit;
6118*4882a593Smuzhiyun 	}
6119*4882a593Smuzhiyun #endif /* BCMSDIODEV_ENABLED && ATE_BUILD */
6120*4882a593Smuzhiyun 
6121*4882a593Smuzhiyun 	/* Bail out if we've dealt with OTP/SPROM before! */
6122*4882a593Smuzhiyun 	if (srvars_inited)
6123*4882a593Smuzhiyun 		goto exit;
6124*4882a593Smuzhiyun 
6125*4882a593Smuzhiyun 	/* Initialize default and cis format count */
6126*4882a593Smuzhiyun 	switch (CHIPID(sih->chip)) {
6127*4882a593Smuzhiyun 	case BCM4369_CHIP_GRPID: ciss = 1; defcis = defcis4369; hdrsz = 4; break;
6128*4882a593Smuzhiyun 	case BCM4378_CHIP_GRPID: ciss = 1; defcis = defcis4378; hdrsz = 4; break;
6129*4882a593Smuzhiyun 	case BCM4385_CHIP_GRPID: ciss = 1; defcis = defcis4385; hdrsz = 4; break;
6130*4882a593Smuzhiyun 	case BCM4387_CHIP_GRPID: ciss = 1; defcis = defcis4387; hdrsz = 4; break;
6131*4882a593Smuzhiyun 	case BCM4388_CHIP_GRPID: ciss = 1; defcis = defcis4388; hdrsz = 4; break;
6132*4882a593Smuzhiyun 	case BCM4389_CHIP_GRPID: ciss = 1; defcis = defcis4389; hdrsz = 4; break;
6133*4882a593Smuzhiyun 	case BCM4397_CHIP_GRPID: ciss = 1; defcis = defcis4397; hdrsz = 4; break;
6134*4882a593Smuzhiyun 	case BCM43012_CHIP_ID: ciss = 1; defcis = defcis43012; hdrsz = 4; break;
6135*4882a593Smuzhiyun 	case BCM43013_CHIP_ID: ciss = 1; defcis = defcis43013; hdrsz = 4; break;
6136*4882a593Smuzhiyun 	case BCM43014_CHIP_ID: ciss = 1; defcis = defcis43014; hdrsz = 4; break;
6137*4882a593Smuzhiyun 	case BCM4362_CHIP_GRPID: ciss = 1; defcis = defcis4362; hdrsz = 4; break;
6138*4882a593Smuzhiyun 	default:
6139*4882a593Smuzhiyun 		BS_ERROR(("initvars_srom_si: Unknown chip 0x%04x\n", CHIPID(sih->chip)));
6140*4882a593Smuzhiyun 		return BCME_ERROR;
6141*4882a593Smuzhiyun 	}
6142*4882a593Smuzhiyun 	if (sih->ccrev >= 36) {
6143*4882a593Smuzhiyun 		uint32 otplayout;
6144*4882a593Smuzhiyun 		if (AOB_ENAB(sih)) {
6145*4882a593Smuzhiyun 			otplayout = si_corereg(sih, si_findcoreidx(sih, GCI_CORE_ID, 0),
6146*4882a593Smuzhiyun 			 OFFSETOF(gciregs_t, otplayout), 0, 0);
6147*4882a593Smuzhiyun 		} else {
6148*4882a593Smuzhiyun 			otplayout = si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, otplayout),
6149*4882a593Smuzhiyun 			 0, 0);
6150*4882a593Smuzhiyun 		}
6151*4882a593Smuzhiyun 		if (otplayout & OTP_CISFORMAT_NEW) {
6152*4882a593Smuzhiyun 			ciss = 1;
6153*4882a593Smuzhiyun 			hdrsz = 2;
6154*4882a593Smuzhiyun 			new_cisformat = TRUE;
6155*4882a593Smuzhiyun 		}
6156*4882a593Smuzhiyun 		else {
6157*4882a593Smuzhiyun 			ciss = 3;
6158*4882a593Smuzhiyun 			hdrsz = 12;
6159*4882a593Smuzhiyun 		}
6160*4882a593Smuzhiyun 	}
6161*4882a593Smuzhiyun 
6162*4882a593Smuzhiyun 	cis_src = si_cis_source(sih);
6163*4882a593Smuzhiyun 	switch (cis_src) {
6164*4882a593Smuzhiyun 	case CIS_SROM:
6165*4882a593Smuzhiyun 		sz = srom_size(sih, osh) << 1;
6166*4882a593Smuzhiyun 		prio = VARBUF_PRIO_SROM;
6167*4882a593Smuzhiyun 		break;
6168*4882a593Smuzhiyun 	case CIS_OTP:
6169*4882a593Smuzhiyun 		/* Note that for *this* type of OTP -- which otp_read_region()
6170*4882a593Smuzhiyun 		 * can operate on -- otp_size() returns bytes, not words.
6171*4882a593Smuzhiyun 		 */
6172*4882a593Smuzhiyun 		if (((oh = otp_init(sih)) != NULL) && (otp_status(oh) & OTPS_GUP_HW))
6173*4882a593Smuzhiyun 			sz = otp_size(oh);
6174*4882a593Smuzhiyun 		prio = VARBUF_PRIO_OTP;
6175*4882a593Smuzhiyun 		break;
6176*4882a593Smuzhiyun 	}
6177*4882a593Smuzhiyun 
6178*4882a593Smuzhiyun 	if (sz != 0) {
6179*4882a593Smuzhiyun 		/* freed in same function */
6180*4882a593Smuzhiyun 		if ((cisbuf = (uint16*)MALLOC_NOPERSIST(osh, sz)) == NULL)
6181*4882a593Smuzhiyun 			return BCME_NOMEM;
6182*4882a593Smuzhiyun 		msz = sz;
6183*4882a593Smuzhiyun 
6184*4882a593Smuzhiyun 		switch (cis_src) {
6185*4882a593Smuzhiyun 		case CIS_SROM:
6186*4882a593Smuzhiyun 			rc = srom_read(sih, SI_BUS, curmap, osh, 0, sz, cisbuf, FALSE);
6187*4882a593Smuzhiyun 			break;
6188*4882a593Smuzhiyun 		case CIS_OTP:
6189*4882a593Smuzhiyun 			sz >>= 1;
6190*4882a593Smuzhiyun 			rc = otp_read_region(sih, OTP_HW_RGN, cisbuf, &sz);
6191*4882a593Smuzhiyun 			sz <<= 1;
6192*4882a593Smuzhiyun 			break;
6193*4882a593Smuzhiyun 		}
6194*4882a593Smuzhiyun 
6195*4882a593Smuzhiyun 		ASSERT(sz > hdrsz);
6196*4882a593Smuzhiyun 		if (rc == BCME_OK) {
6197*4882a593Smuzhiyun 			if ((cisbuf[0] == 0xffff) || (cisbuf[0] == 0)) {
6198*4882a593Smuzhiyun 				MFREE(osh, cisbuf, msz);
6199*4882a593Smuzhiyun 			} else if (new_cisformat) {
6200*4882a593Smuzhiyun 				cis[0] = (uint8*)(cisbuf + hdrsz);
6201*4882a593Smuzhiyun 			} else {
6202*4882a593Smuzhiyun 				cis[0] = (uint8*)cisbuf + hdrsz;
6203*4882a593Smuzhiyun 				cis[1] = (uint8*)cisbuf + hdrsz +
6204*4882a593Smuzhiyun 				        (cisbuf[1] >> 8) + ((cisbuf[2] & 0x00ff) << 8) -
6205*4882a593Smuzhiyun 				        SBSDIO_CIS_BASE_COMMON;
6206*4882a593Smuzhiyun 				cis[2] = (uint8*)cisbuf + hdrsz +
6207*4882a593Smuzhiyun 				        cisbuf[3] - SBSDIO_CIS_BASE_COMMON;
6208*4882a593Smuzhiyun 				cis[3] = (uint8*)cisbuf + hdrsz +
6209*4882a593Smuzhiyun 				        cisbuf[4] - SBSDIO_CIS_BASE_COMMON;
6210*4882a593Smuzhiyun 				ASSERT((cis[1] >= cis[0]) && (cis[1] < (uint8*)cisbuf + sz));
6211*4882a593Smuzhiyun 				ASSERT((cis[2] >= cis[0]) && (cis[2] < (uint8*)cisbuf + sz));
6212*4882a593Smuzhiyun 				ASSERT(((cis[3] >= cis[0]) && (cis[3] < (uint8*)cisbuf + sz)) ||
6213*4882a593Smuzhiyun 				        (ciss <= 3));
6214*4882a593Smuzhiyun 			}
6215*4882a593Smuzhiyun 		}
6216*4882a593Smuzhiyun 	}
6217*4882a593Smuzhiyun 
6218*4882a593Smuzhiyun 	/* Use default if strapped to, or strapped source empty */
6219*4882a593Smuzhiyun 	if (cisbuf == NULL) {
6220*4882a593Smuzhiyun 		ciss = 1;
6221*4882a593Smuzhiyun 		cis[0] = defcis;
6222*4882a593Smuzhiyun 	}
6223*4882a593Smuzhiyun 
6224*4882a593Smuzhiyun 	/* Parse the CIS */
6225*4882a593Smuzhiyun 	if (rc == BCME_OK) {
6226*4882a593Smuzhiyun 		if ((rc = srom_parsecis(sih, osh, cis, ciss, vars, varsz)) == BCME_OK) {
6227*4882a593Smuzhiyun 			nvram_append((void *)sih, *vars, *varsz, prio);
6228*4882a593Smuzhiyun 			DONGLE_STORE_VARS_OTP_PTR(*vars);
6229*4882a593Smuzhiyun 		}
6230*4882a593Smuzhiyun 	}
6231*4882a593Smuzhiyun 
6232*4882a593Smuzhiyun 	/* Clean up */
6233*4882a593Smuzhiyun 	if (cisbuf != NULL)
6234*4882a593Smuzhiyun 		MFREE(osh, cisbuf, msz);
6235*4882a593Smuzhiyun 
6236*4882a593Smuzhiyun 	srvars_inited = TRUE;
6237*4882a593Smuzhiyun exit:
6238*4882a593Smuzhiyun 	/* Tell the caller there is no individual SROM variables */
6239*4882a593Smuzhiyun 	*vars = NULL;
6240*4882a593Smuzhiyun 	*varsz = 0;
6241*4882a593Smuzhiyun 
6242*4882a593Smuzhiyun 	/* return OK so the driver will load & use defaults if bad srom/otp */
6243*4882a593Smuzhiyun 	return BCME_OK;
6244*4882a593Smuzhiyun } /* initvars_srom_si */
6245*4882a593Smuzhiyun #else /* BCM_DONGLEVARS */
6246*4882a593Smuzhiyun 
6247*4882a593Smuzhiyun /**
6248*4882a593Smuzhiyun  * initvars_srom_si() is defined multiple times in this file. This is the variant for chips with an
6249*4882a593Smuzhiyun  * active SDIOd interface but without BCM_DONGLEVARS
6250*4882a593Smuzhiyun  */
6251*4882a593Smuzhiyun static int
6252*4882a593Smuzhiyun BCMATTACHFN(initvars_srom_si)(si_t *sih, osl_t *osh, volatile void *curmap,
6253*4882a593Smuzhiyun 	char **vars, uint *varsz)
6254*4882a593Smuzhiyun {
6255*4882a593Smuzhiyun 	*vars = NULL;
6256*4882a593Smuzhiyun 	*varsz = 0;
6257*4882a593Smuzhiyun 	return BCME_OK;
6258*4882a593Smuzhiyun }
6259*4882a593Smuzhiyun #endif /* BCM_DONGLEVARS */
6260*4882a593Smuzhiyun 
6261*4882a593Smuzhiyun #elif defined(BCMPCIEDEV_ENABLED)
6262*4882a593Smuzhiyun 
6263*4882a593Smuzhiyun /**
6264*4882a593Smuzhiyun  * initvars_srom_si() is defined multiple times in this file. This is the variant for chips with an
6265*4882a593Smuzhiyun  * active PCIe interface *and* that use OTP for NVRAM storage.
6266*4882a593Smuzhiyun  *
6267*4882a593Smuzhiyun  * On success, a buffer containing var/val values has been allocated in parameter 'vars'.
6268*4882a593Smuzhiyun  * put an ifdef where if the host wants the dongle wants to parse sprom or not
6269*4882a593Smuzhiyun  */
6270*4882a593Smuzhiyun static int
6271*4882a593Smuzhiyun BCMATTACHFN(initvars_srom_si)(si_t *sih, osl_t *osh, volatile void *curmap,
6272*4882a593Smuzhiyun 	char **vars, uint *varsz)
6273*4882a593Smuzhiyun {
6274*4882a593Smuzhiyun #ifdef BCM_DONGLEVARS
6275*4882a593Smuzhiyun 	void *oh = NULL;
6276*4882a593Smuzhiyun 	uint8 *cis;
6277*4882a593Smuzhiyun 	uint sz = 0;
6278*4882a593Smuzhiyun 	int rc;
6279*4882a593Smuzhiyun 
6280*4882a593Smuzhiyun 	if (si_cis_source(sih) !=  CIS_OTP)
6281*4882a593Smuzhiyun 		return BCME_OK;
6282*4882a593Smuzhiyun 
6283*4882a593Smuzhiyun 	if (((oh = otp_init(sih)) != NULL) && (otp_status(oh) & OTPS_GUP_HW))
6284*4882a593Smuzhiyun 		sz = otp_size(oh);
6285*4882a593Smuzhiyun 	if (sz == 0)
6286*4882a593Smuzhiyun 		return BCME_OK;
6287*4882a593Smuzhiyun 
6288*4882a593Smuzhiyun 	if ((cis = MALLOC(osh, sz)) == NULL)
6289*4882a593Smuzhiyun 		return BCME_NOMEM;
6290*4882a593Smuzhiyun 	sz >>= 1;
6291*4882a593Smuzhiyun 	rc = otp_read_region(sih, OTP_HW_RGN, (uint16 *)cis, &sz);
6292*4882a593Smuzhiyun 	sz <<= 1;
6293*4882a593Smuzhiyun 
6294*4882a593Smuzhiyun 	/* account for the Hardware header */
6295*4882a593Smuzhiyun 	if (sz == 128)
6296*4882a593Smuzhiyun 		return BCME_OK;
6297*4882a593Smuzhiyun 
6298*4882a593Smuzhiyun 	cis += 128;
6299*4882a593Smuzhiyun 
6300*4882a593Smuzhiyun 	/* need to find a better way to identify sprom format content and ignore parse */
6301*4882a593Smuzhiyun 	if (*(uint16 *)cis == SROM11_SIGNATURE) {
6302*4882a593Smuzhiyun 		return BCME_OK;
6303*4882a593Smuzhiyun 	}
6304*4882a593Smuzhiyun 
6305*4882a593Smuzhiyun 	if ((rc = srom_parsecis(sih, osh, &cis, SROM_CIS_SINGLE, vars, varsz)) == BCME_OK)
6306*4882a593Smuzhiyun 		nvram_append((void *)sih, *vars, *varsz, VARBUF_PRIO_OTP);
6307*4882a593Smuzhiyun 
6308*4882a593Smuzhiyun 	return rc;
6309*4882a593Smuzhiyun #else /* BCM_DONGLEVARS */
6310*4882a593Smuzhiyun 	*vars = NULL;
6311*4882a593Smuzhiyun 	*varsz = 0;
6312*4882a593Smuzhiyun 	return BCME_OK;
6313*4882a593Smuzhiyun #endif /* BCM_DONGLEVARS */
6314*4882a593Smuzhiyun }
6315*4882a593Smuzhiyun #else /* !BCMUSBDEV && !BCMSDIODEV  && !BCMPCIEDEV */
6316*4882a593Smuzhiyun 
6317*4882a593Smuzhiyun #ifndef BCMDONGLEHOST
6318*4882a593Smuzhiyun 
6319*4882a593Smuzhiyun /**
6320*4882a593Smuzhiyun  * initvars_srom_si() is defined multiple times in this file. This is the variant for:
6321*4882a593Smuzhiyun  * !BCMDONGLEHOST && !BCMUSBDEV && !BCMSDIODEV && !BCMPCIEDEV
6322*4882a593Smuzhiyun  * So this function is defined for PCI (not PCIe) builds that are also non DHD builds.
6323*4882a593Smuzhiyun  * On success, a buffer containing var/val values has been allocated in parameter 'vars'.
6324*4882a593Smuzhiyun  */
6325*4882a593Smuzhiyun static int
6326*4882a593Smuzhiyun BCMATTACHFN(initvars_srom_si)(si_t *sih, osl_t *osh, volatile void *curmap,
6327*4882a593Smuzhiyun 	char **vars, uint *varsz)
6328*4882a593Smuzhiyun {
6329*4882a593Smuzhiyun 	/* Search flash nvram section for srom variables */
6330*4882a593Smuzhiyun 	BCM_REFERENCE(osh);
6331*4882a593Smuzhiyun 	BCM_REFERENCE(curmap);
6332*4882a593Smuzhiyun 	return initvars_flash_si(sih, vars, varsz);
6333*4882a593Smuzhiyun } /* initvars_srom_si */
6334*4882a593Smuzhiyun #endif /* !BCMDONGLEHOST */
6335*4882a593Smuzhiyun #endif	/* !BCMUSBDEV && !BCMSDIODEV  && !BCMPCIEDEV */
6336*4882a593Smuzhiyun 
6337*4882a593Smuzhiyun void
6338*4882a593Smuzhiyun BCMATTACHFN(srom_var_deinit)(si_t *sih)
6339*4882a593Smuzhiyun {
6340*4882a593Smuzhiyun 	BCM_REFERENCE(sih);
6341*4882a593Smuzhiyun 
6342*4882a593Smuzhiyun 	srvars_inited = FALSE;
6343*4882a593Smuzhiyun }
6344*4882a593Smuzhiyun 
6345*4882a593Smuzhiyun #if defined(BCMPCIEDEV_SROM_FORMAT) && defined(WLC_TXCAL)
6346*4882a593Smuzhiyun bool
6347*4882a593Smuzhiyun BCMATTACHFN(srom_caldata_prsnt)(si_t *sih)
6348*4882a593Smuzhiyun {
6349*4882a593Smuzhiyun 	return is_caldata_prsnt;
6350*4882a593Smuzhiyun }
6351*4882a593Smuzhiyun 
6352*4882a593Smuzhiyun int
6353*4882a593Smuzhiyun BCMATTACHFN(srom_get_caldata)(si_t *sih, uint16 *srom)
6354*4882a593Smuzhiyun {
6355*4882a593Smuzhiyun 	if (!is_caldata_prsnt) {
6356*4882a593Smuzhiyun 		return BCME_ERROR;
6357*4882a593Smuzhiyun 	}
6358*4882a593Smuzhiyun 	if (srom_sromrev == 18) {
6359*4882a593Smuzhiyun 		memcpy(srom, caldata_array, SROM18_CALDATA_WORDS * 2);
6360*4882a593Smuzhiyun 	} else {
6361*4882a593Smuzhiyun 		memcpy(srom, caldata_array, SROM_CALDATA_WORDS * 2);
6362*4882a593Smuzhiyun 	}
6363*4882a593Smuzhiyun 	return BCME_OK;
6364*4882a593Smuzhiyun }
6365*4882a593Smuzhiyun #endif /* defined(BCMPCIEDEV_SROM_FORMAT) && defined(WLC_TXCAL) */
6366