2 * Routines to access SPROM and to parse SROM/CIS variables.
4 * Copyright (C) 2012, Broadcom Corporation. All Rights Reserved.
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 * $Id: bcmsrom.c 364585 2012-10-24 18:17:16Z $
25 #if defined(__FreeBSD__) || defined(__NetBSD__)
26 #if __NetBSD_Version__ >= 500000003
27 #include <sys/stdarg.h>
29 #include <machine/stdarg.h>
38 #include <bcmendian.h>
43 #include <bcmsrom_tbl.h>
51 #if defined(BCMUSBDEV)
54 #include <sbsdpcmdev.h>
57 #if defined(WLTEST) || defined(DHD_SPROM) || defined(BCMDBG)
60 #include <proto/ethernet.h> /* for sprom content groking */
63 #if defined(BCMDBG_ERR) || defined(WLTEST)
64 #define BS_ERROR(args) printf args
66 #define BS_ERROR(args)
69 #define SROM_OFFSET(sih) ((sih->ccrev > 31) ? \
70 (((sih->cccaps & CC_CAP_SROM) == 0) ? NULL : \
71 ((uint8 *)curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP)) : \
72 ((uint8 *)curmap + PCI_BAR0_SPROM_OFFSET))
74 #if defined(WLTEST) || defined(DHD_SPROM) || defined(BCMDBG)
75 #define WRITE_ENABLE_DELAY 500 /* 500 ms after write enable/disable toggle */
76 #define WRITE_WORD_DELAY 20 /* 20 ms between each word write */
79 typedef struct varbuf
{
80 char *base
; /* pointer to buffer base */
81 char *buf
; /* pointer to current position */
82 unsigned int size
; /* current (residual) size in bytes */
87 #define SROM_CIS_SINGLE 1
90 static int initvars_srom_si(si_t
*sih
, osl_t
*osh
, void *curmap
, char **vars
, uint
*count
);
91 static void _initvars_srom_pci(uint8 sromrev
, uint16
*srom
, uint off
, varbuf_t
*b
);
92 static int initvars_srom_pci(si_t
*sih
, void *curmap
, char **vars
, uint
*count
);
93 static int initvars_cis_pcmcia(si_t
*sih
, osl_t
*osh
, char **vars
, uint
*count
);
94 #if !defined(BCMUSBDEV_ENABLED) && !defined(BCMSDIODEV_ENABLED)
95 static int initvars_flash_si(si_t
*sih
, char **vars
, uint
*count
);
98 static int initvars_cis_spi(osl_t
*osh
, char **vars
, uint
*count
);
100 static int sprom_cmd_pcmcia(osl_t
*osh
, uint8 cmd
);
101 static int sprom_read_pcmcia(osl_t
*osh
, uint16 addr
, uint16
*data
);
102 #if defined(WLTEST) || defined(DHD_SPROM) || defined(BCMDBG)
103 static int sprom_write_pcmcia(osl_t
*osh
, uint16 addr
, uint16 data
);
105 static int sprom_read_pci(osl_t
*osh
, si_t
*sih
, uint16
*sprom
, uint wordoff
, uint16
*buf
,
106 uint nwords
, bool check_crc
);
107 #if defined(BCMNVRAMW) || defined(BCMNVRAMR)
108 static int otp_read_pci(osl_t
*osh
, si_t
*sih
, uint16
*buf
, uint bufsz
);
109 #endif /* defined(BCMNVRAMW) || defined(BCMNVRAMR) */
110 static uint16
srom_cc_cmd(si_t
*sih
, osl_t
*osh
, void *ccregs
, uint32 cmd
, uint wordoff
,
113 static int initvars_table(osl_t
*osh
, char *start
, char *end
, char **vars
, uint
*count
);
114 static int initvars_flash(si_t
*sih
, osl_t
*osh
, char **vp
, uint len
);
116 #if defined(BCMUSBDEV)
117 static int get_si_pcmcia_srom(si_t
*sih
, osl_t
*osh
, uint8
*pcmregs
,
118 uint boff
, uint16
*srom
, uint bsz
, bool check_crc
);
119 #if defined(WLTEST) || defined(DHD_SPROM) || defined(BCMDBG)
120 static int set_si_pcmcia_srom(si_t
*sih
, osl_t
*osh
, uint8
*pcmregs
,
121 uint boff
, uint16
*srom
, uint bsz
);
125 #if defined(BCMUSBDEV)
126 #if defined(BCMUSBDEV_BMAC) || defined(BCM_BMAC_VARS_APPEND)
127 /* default to bcm94323 P200, other boards should have OTP programmed */
128 static char BCMATTACHDATA(defaultsromvars_4322usb
)[] =
132 "macaddr=00:90:4c:d3:04:73\0"
137 "boardflags2=0x602\0"
204 static char BCMATTACHDATA(defaultsromvars_43234usb
)[] =
208 "macaddr=00:90:4c:03:21:23\0"
230 "boardflags2=0x2000\0"
304 static char BCMATTACHDATA(defaultsromvars_43235usb
)[] =
308 "macaddr=00:90:4c:05:30:01\0"
357 "temp_hysteresis=5\0"
360 static char BCMATTACHDATA(defaultsromvars_4350usb
)[] =
371 "macaddr=00:90:4c:0c:e0:42\0"
400 "rawtempsense=0x1ff\0"
402 "tempsense_slope=0xff\0"
404 "tempsense_option=0x3\0"
405 "phycal_tempdelta=255\0"
407 "temps_hysteresis=15\0"
428 "rxgainerr2g=0xffff\0"
429 "rxgainerr5g=0xffff,0xffff,0xffff,0xffff\0"
431 "pa2ga0=0xfe72,0x14c0,0xfac7\0"
432 "rxgains2gelnagaina0=4\0"
433 "rxgains2gtrisoa0=10\0"
434 "rxgains2gtrelnabypa0=1\0"
435 "rxgains5gelnagaina0=3\0"
436 "rxgains5gtrisoa0=10\0"
437 "rxgains5gtrelnabypa0=1\0"
438 "maxp5ga0=17,34,51,68\0"
439 "pa5ga0=0xfe75,0x14b5,0xfad4,0xfe97,0x121a,0xfb6e,0xfe7f,0x149d,0xfad0,0xfe7c,0x1431,0xfae6\0"
441 "pa2ga1=0xfe80,0x1472,0xfabc\0"
442 "rxgains2gelnagaina1=4\0"
443 "rxgains2gtrisoa1=10\0"
444 "rxgains2gtrelnabypa1=1\0"
445 "rxgains5gelnagaina1=3\0"
446 "rxgains5gtrisoa1=10\0"
447 "rxgains5gtrelnabypa1=1\0"
448 "maxp5ga1=72,72,76,76\0"
449 "pa5ga1=0xfe72,0x155e,0xfa96,0xfea1,0x125d,0xfb55,0xfe77,0x1596,0xfa8e,0xfe78,0x15e1,0xfa7a\0"
451 "pa2ga2=0xfe82,0x14bf,0xfad9\0"
452 "rxgains2gelnagaina2=4\0"
453 "rxgains2gtrisoa2=10\0"
454 "rxgains2gtrelnabypa2=1\0"
455 "rxgains5gelnagaina2=3\0"
456 "rxgains5gtrisoa2=10\0"
457 "rxgains5gtrelnabypa2=1\0"
458 "maxp5ga2=72,72,76,76\0"
459 "pa5ga2=0xfe7d,0x14d8,0xfacd,0xfea6,0x1218,0xfb79,0xfe7c,0x1452,0xfade,0xfe82,0x1406,0xfaf6\0"
462 static char BCMATTACHDATA(defaultsromvars_43242usb
)[] =
468 "macaddr=00:90:4c:c5:12:38\0"
533 "cckbw20ul2gpo=0x0\0"
534 "legofdmbw202gpo=0x88888888\0"
535 "legofdmbw20ul2gpo=0x88888888\0"
536 "mcsbw202gpo=0x88888888\0"
537 "mcsbw20ul2gpo=0x88888888\0"
538 "mcsbw402gpo=0x88888888\0"
541 "legofdmbw205glpo=0x22220000\0"
542 "legofdmbw20ul5glpo=0x44442222\0"
543 "legofdmbw205gmpo=0x22220000\0"
544 "legofdmbw20ul5gmpo=0x44442222\0"
545 "legofdmbw205ghpo=0x22220000\0"
546 "legofdmbw20ul5ghpo=0x44442222\0"
547 "mcsbw205glpo=0x44422222\0"
548 "mcsbw20ul5glpo=0x66644444\0"
549 "mcsbw405glpo=0x66644444\0"
550 "mcsbw205gmpo=0x44422222\0"
551 "mcsbw20ul5gmpo=0x66644444\0"
552 "mcsbw405gmpo=0x66644444\0"
553 "mcsbw205ghpo=0x44422222\0"
554 "mcsbw20ul5ghpo=0x66644444\0"
555 "mcsbw405ghpo=0x66644444\0"
561 "noisecaloffset=10\0"
562 "noisecaloffset5g=12\0"
565 static char BCMATTACHDATA(defaultsromvars_43143usb
)[] =
575 "boardflags2=0x000\0"
576 "macaddr=00:90:4c:0e:81:23\0"
602 "cckbw202gpo=0x0000\0"
603 "legofdmbw202gpo=0x43333333\0"
604 "mcsbw202gpo=0x63333333\0"
605 "mcsbw402gpo=0x66666666\0"
606 "swctrlmap_2g=0x00000000,0x00000000,0x00000000,0x00000000,0x000\0"
611 "temp_hysteresis=5\0"
617 static char BCMATTACHDATA(defaultsromvars_43236usb
)[] =
621 "macaddr=00:90:4c:03:21:23\0"
643 "boardflags2=0x2000\0"
655 "ofdm2gpo=0x33333333\0"
717 "temp_hysteresis=5\0"
720 static char BCMATTACHDATA(defaultsromvars_4319usb
)[] =
745 "ofdmpo=0x44441111\0"
749 "macaddr=00:90:4c:16:${maclo}\0"
753 static char BCMATTACHDATA(defaultsromvars_4360usb
)[] =
757 "boardvendor=0x14e4\0"
760 "boardflags=0x10001000\0"
763 "macaddr=00:90:4c:0e:60:11\0"
796 "rawtempsense=0x1ff\0"
798 "tempsense_slope=0xff\0"
800 "tempsense_option=0x3\0"
801 "phycal_tempdelta=255\0"
803 "temps_hysteresis=15\0"
808 "pcieingress_war=15\0"
813 "noiselvl5ga0=31,31,31,31\0"
814 "noiselvl5ga1=31,31,31,31\0"
817 "rxgainerr5ga0=31,31,31,31\0"
818 "rxgainerr5ga1=31,31,31,31\0"
820 "pa2ga0=0xff34,0x19d6,0xfccf\0"
821 "rxgains2gelnagaina0=4\0"
822 "rxgains2gtrisoa0=9\0"
823 "rxgains2gtrelnabypa0=1\0"
824 "rxgains5gelnagaina0=3\0"
825 "rxgains5gtrisoa0=9\0"
826 "rxgains5gtrelnabypa0=1\0"
827 "maxp5ga0=72,72,76,76\0"
828 "pa5ga0=0xff2b,0x1652,0xfd2b,0xff2f,0x167a,0xfd29,0xff29,0x1615,0xfd2e,0xff2b,0x15c9,0xfd3a\0"
830 "pa2ga1=0xff27,0x1895,0xfced\0"
831 "rxgains2gelnagaina1=4\0"
832 "rxgains2gtrisoa1=9\0"
833 "rxgains2gtrelnabypa1=1\0"
834 "rxgains5gelnagaina1=3\0"
835 "rxgains5gtrisoa1=9\0"
836 "rxgains5gtrelnabypa1=1\0"
837 "maxp5ga1=72,72,72,72\0"
838 "pa5ga1=0xff27,0x171b,0xfd14,0xff2d,0x1741,0xfd0f,0xff33,0x1705,0xfd1a,0xff32,0x1666,0xfd2c\0"
841 #endif /* BCMUSBDEV_BMAC || BCM_BMAC_VARS_APPEND */
842 #endif /* BCMUSBDEV */
845 /* BCMHOSTVARS is enabled only if WLTEST is enabled or BCMEXTNVM is enabled */
846 #if defined(BCMHOSTVARS)
847 /* Also used by wl_readconfigdata for vars download */
848 char BCMATTACHDATA(mfgsromvars
)[VARS_MAX
];
849 int BCMATTACHDATA(defvarslen
) = 0;
852 /* BCMHOSTVARS is enabled only if WLTEST is enabled or BCMEXTNVM is enabled */
853 #if defined(BCMHOSTVARS)
854 static char BCMATTACHDATA(defaultsromvars_4331
)[] =
860 "boardvendor=0x14e4\0"
862 "macaddr=00:90:4c:1a:20:64\0"
925 "cckbw20ul2gpo=0x0\0"
926 "legofdmbw202gpo=0x0\0"
927 "legofdmbw20ul2gpo=0x0\0"
928 "legofdmbw205glpo=0x0\0"
929 "legofdmbw20ul5glpo=0x0\0"
930 "legofdmbw205gmpo=0x0\0"
931 "legofdmbw20ul5gmpo=0x0\0"
932 "legofdmbw205ghpo=0x0\0"
933 "legofdmbw20ul5ghpo=0x0\0"
935 "mcsbw20ul2gpo=0x0\0"
938 "mcsbw20ul5glpo=0x0\0"
941 "mcsbw20ul5gmpo=0x0\0"
944 "mcsbw20ul5ghpo=0x0\0"
947 "legofdm40duppo=0x0\0"
986 static char BCMATTACHDATA(defaultsromvars_4360
)[] =
989 "boardflags=0x10401001\0"
995 "macaddr=00:90:4c:0d:f4:3e\0"
1007 "tssiposslope2g=1\0"
1010 "tworangetssi2g=0\0"
1013 "tssiposslope5g=1\0"
1016 "tworangetssi5g=0\0"
1021 "rawtempsense=0x1ff\0"
1023 "tempsense_slope=0xff\0"
1025 "tempsense_option=0x3\0"
1027 "phycal_tempdelta=255\0"
1029 "temps_hysteresis=15\0"
1032 "pdoffset2g40ma0=15\0"
1033 "pdoffset2g40ma1=15\0"
1034 "pdoffset2g40ma2=15\0"
1035 "pdoffset2g40mvalid=1\0"
1036 "pdoffset40ma0=9010\0"
1037 "pdoffset40ma1=12834\0"
1038 "pdoffset40ma2=8994\0"
1039 "pdoffset80ma0=16\0"
1040 "pdoffset80ma1=4096\0"
1042 "subband5gver=0x4\0"
1045 "mcsbw202gpo=2571386880\0"
1046 "mcsbw402gpo=2571386880\0"
1047 "dot11agofdmhrbw202gpo=17408\0"
1048 "ofdmlrbw202gpo=0\0"
1049 "mcsbw205glpo=4001923072\0"
1050 "mcsbw405glpo=4001923072\0"
1051 "mcsbw805glpo=4001923072\0"
1053 "mcsbw205gmpo=3431497728\0"
1054 "mcsbw405gmpo=3431497728\0"
1055 "mcsbw805gmpo=3431497728\0"
1057 "mcsbw205ghpo=3431497728\0"
1058 "mcsbw405ghpo=3431497728\0"
1059 "mcsbw805ghpo=3431497728\0"
1065 "sb20in80and160hr5glpo=0\0"
1066 "sb40and80hr5glpo=0\0"
1067 "sb20in80and160hr5gmpo=0\0"
1068 "sb40and80hr5gmpo=0\0"
1069 "sb20in80and160hr5ghpo=0\0"
1070 "sb40and80hr5ghpo=0\0"
1072 "sb20in80and160lr5glpo=0\0"
1073 "sb40and80lr5glpo=0\0"
1074 "sb20in80and160lr5gmpo=0\0"
1075 "sb40and80lr5gmpo=0\0"
1076 "sb20in80and160lr5ghpo=0\0"
1077 "sb40and80lr5ghpo=0\0"
1078 "dot11agduphrpo=0\0"
1079 "dot11agduplrpo=0\0"
1080 "pcieingress_war=15\0"
1086 "noiselvl5ga0=31,31,31,31\0"
1087 "noiselvl5ga1=31,31,31,31\0"
1088 "noiselvl5ga2=31,31,31,31\0"
1089 "rxgainerr2ga0=63\0"
1090 "rxgainerr2ga1=31\0"
1091 "rxgainerr2ga2=31\0"
1092 "rxgainerr5ga0=63,63,63,63\0"
1093 "rxgainerr5ga1=31,31,31,31\0"
1094 "rxgainerr5ga2=31,31,31,31\0"
1096 "pa2ga0=0xff3c,0x172c,0xfd20\0"
1097 "rxgains5gmelnagaina0=7\0"
1098 "rxgains5gmtrisoa0=15\0"
1099 "rxgains5gmtrelnabypa0=1\0"
1100 "rxgains5ghelnagaina0=7\0"
1101 "rxgains5ghtrisoa0=15\0"
1102 "rxgains5ghtrelnabypa0=1\0"
1103 "rxgains2gelnagaina0=4\0"
1104 "rxgains2gtrisoa0=7\0"
1105 "rxgains2gtrelnabypa0=1\0"
1106 "rxgains5gelnagaina0=3\0"
1107 "rxgains5gtrisoa0=7\0"
1108 "rxgains5gtrelnabypa0=1\0"
1109 "maxp5ga0=76,76,76,76\0"
1110 "pa5ga0=0xff3a,0x14d4,0xfd5f,0xff36,0x1626,0xfd2e,0xff42,0x15bd,0xfd47,0xff39,0x15a3,0xfd3d\0"
1112 "pa2ga1=0xff2a,0x16b2,0xfd28\0"
1113 "rxgains5gmelnagaina1=7\0"
1114 "rxgains5gmtrisoa1=15\0"
1115 "rxgains5gmtrelnabypa1=1\0"
1116 "rxgains5ghelnagaina1=7\0"
1117 "rxgains5ghtrisoa1=15\0"
1118 "rxgains5ghtrelnabypa1=1\0"
1119 "rxgains2gelnagaina1=3\0"
1120 "rxgains2gtrisoa1=6\0"
1121 "rxgains2gtrelnabypa1=1\0"
1122 "rxgains5gelnagaina1=3\0"
1123 "rxgains5gtrisoa1=6\0"
1124 "rxgains5gtrelnabypa1=1\0"
1125 "maxp5ga1=76,76,76,76\0"
1126 "pa5ga1=0xff4e,0x1530,0xfd53,0xff58,0x15b4,0xfd4d,0xff58,0x1671,0xfd2f,0xff55,0x15e2,0xfd46\0"
1128 "pa2ga2=0xff3c,0x1736,0xfd1f\0"
1129 "rxgains5gmelnagaina2=7\0"
1130 "rxgains5gmtrisoa2=15\0"
1131 "rxgains5gmtrelnabypa2=1\0"
1132 "rxgains5ghelnagaina2=7\0"
1133 "rxgains5ghtrisoa2=15\0"
1134 "rxgains5ghtrelnabypa2=1\0"
1135 "rxgains2gelnagaina2=4\0"
1136 "rxgains2gtrisoa2=7\0"
1137 "rxgains2gtrelnabypa2=1\0"
1138 "rxgains5gelnagaina2=3\0"
1139 "rxgains5gtrisoa2=7\0"
1140 "rxgains5gtrelnabypa2=1\0"
1141 "maxp5ga2=76,76,76,76\0"
1142 "pa5ga2=0xff2d,0x144a,0xfd63,0xff35,0x15d7,0xfd3b,0xff35,0x1668,0xfd2f,0xff31,0x1664,0xfd27\0"
1145 static char BCMATTACHDATA(defaultsromvars_4335
)[] =
1148 "boardtype=0x0647\0"
1149 "boardflags=0x10401001\0"
1152 "macaddr=00:90:4c:c5:43:55\0"
1158 "tworangetssi2g=0\0"
1159 "tworangetssi5g=0\0"
1161 "pcieingress_war=15\0"
1172 "rxgains2gelnagaina0=3\0"
1173 "rxgains2gtrisoa0=3\0"
1174 "rxgains2gtrelnabypa0=1\0"
1175 "rxgains5gelnagaina0=3\0"
1176 "rxgains5gtrisoa0=4\0"
1177 "rxgains5gtrelnabypa0=1\0"
1186 "pa2ga0=0x0,0x0,0x0\0"
1187 "pa5ga0=-217,5493,-673\0"
1188 "tssifloor2g=0x3ff\0"
1189 "tssifloor5g=0x3ff,0x3ff,0x3ff,0x3ff\0"
1195 /* BCMHOSTVARS is enabled only if WLTEST is enabled or BCMEXTNVM is enabled */
1196 #if defined(BCMHOSTVARS)
1197 static char BCMATTACHDATA(defaultsromvars_wltest
)[] =
1198 "macaddr=00:90:4c:f8:00:01\0"
1199 "et0macaddr=00:11:22:33:44:52\0"
1202 "gpio2=robo_reset\0"
1203 "boardvendor=0x14e4\0"
1204 "boardflags=0x210\0"
1206 "boardtype=0x04c3\0"
1263 static bool srvars_inited
= FALSE
; /* Use OTP/SROM as global variables */
1265 /* BCMHOSTVARS is enabled only if WLTEST is enabled or BCMEXTNVM is enabled */
1266 #if defined(BCMHOSTVARS) || (defined(BCMUSBDEV_BMAC) || defined(BCM_BMAC_VARS_APPEND))
1267 /* It must end with pattern of "END" */
1269 BCMATTACHFN(srom_vars_len
)(char *vars
)
1275 for (s
= vars
; s
&& *s
;) {
1277 if (strcmp(s
, "END") == 0)
1283 /* BS_ERROR(("len %d vars[pos] %s\n", pos, s)); */
1289 return pos
+ 4; /* include the "END\0" */
1293 /* Initialization of varbuf structure */
1295 BCMATTACHFN(varbuf_init
)(varbuf_t
*b
, char *buf
, uint size
)
1298 b
->base
= b
->buf
= buf
;
1301 /* append a null terminated var=value string */
1303 BCMATTACHFN(varbuf_append
)(varbuf_t
*b
, const char *fmt
, ...)
1314 r
= vsnprintf(b
->buf
, b
->size
, fmt
, ap
);
1317 /* C99 snprintf behavior returns r >= size on overflow,
1318 * others return -1 on overflow.
1319 * All return -1 on format error.
1320 * We need to leave room for 2 null terminations, one for the current var
1321 * string, and one for final null of the var table. So check that the
1322 * strlen written, r, leaves room for 2 chars.
1324 if ((r
== -1) || (r
> (int)(b
->size
- 2))) {
1329 /* Remove any earlier occurrence of the same variable */
1330 if ((s
= strchr(b
->buf
, '=')) != NULL
) {
1331 len
= (size_t)(s
- b
->buf
);
1332 for (s
= b
->base
; s
< b
->buf
;) {
1333 if ((bcmp(s
, b
->buf
, len
) == 0) && s
[len
] == '=') {
1334 len
= strlen(s
) + 1;
1335 memmove(s
, (s
+ len
), ((b
->buf
+ r
+ 1) - (s
+ len
)));
1337 b
->size
+= (unsigned int)len
;
1346 /* skip over this string's null termination */
1355 * Initialize local vars from the right source for this platform.
1356 * Return 0 on success, nonzero on error.
1359 BCMATTACHFN(srom_var_init
)(si_t
*sih
, uint bustype
, void *curmap
, osl_t
*osh
,
1360 char **vars
, uint
*count
)
1362 ASSERT(bustype
== BUSTYPE(bustype
));
1363 if (vars
== NULL
|| count
== NULL
)
1369 switch (BUSTYPE(bustype
)) {
1372 return initvars_srom_si(sih
, osh
, curmap
, vars
, count
);
1375 ASSERT(curmap
!= NULL
);
1379 return initvars_srom_pci(sih
, curmap
, vars
, count
);
1382 return initvars_cis_pcmcia(sih
, osh
, vars
, count
);
1387 return initvars_cis_spi(osh
, vars
, count
);
1396 /* support only 16-bit word read from srom */
1398 srom_read(si_t
*sih
, uint bustype
, void *curmap
, osl_t
*osh
,
1399 uint byteoff
, uint nbytes
, uint16
*buf
, bool check_crc
)
1403 ASSERT(bustype
== BUSTYPE(bustype
));
1405 /* check input - 16-bit access only */
1406 if (byteoff
& 1 || nbytes
& 1 || (byteoff
+ nbytes
) > SROM_MAX
)
1412 if (BUSTYPE(bustype
) == PCI_BUS
) {
1416 if (si_is_sprom_available(sih
)) {
1419 srom
= (uint16
*)SROM_OFFSET(sih
);
1423 if (sprom_read_pci(osh
, sih
, srom
, off
, buf
, nw
, check_crc
))
1426 #if defined(BCMNVRAMW) || defined(BCMNVRAMR)
1428 if (otp_read_pci(osh
, sih
, buf
, nbytes
))
1432 } else if (BUSTYPE(bustype
) == PCMCIA_BUS
) {
1433 for (i
= 0; i
< nw
; i
++) {
1434 if (sprom_read_pcmcia(osh
, (uint16
)(off
+ i
), (uint16
*)(buf
+ i
)))
1438 } else if (BUSTYPE(bustype
) == SPI_BUS
) {
1439 if (bcmsdh_cis_read(NULL
, SDIO_FUNC_1
, (uint8
*)buf
, byteoff
+ nbytes
) != 0)
1442 } else if (BUSTYPE(bustype
) == SI_BUS
) {
1443 #if defined(BCMUSBDEV)
1444 if (SPROMBUS
== PCMCIA_BUS
) {
1450 /* Don't bother if we can't talk to SPROM */
1451 if (!si_is_sprom_available(sih
))
1454 origidx
= si_coreidx(sih
);
1455 regs
= si_setcore(sih
, PCMCIA_CORE_ID
, 0);
1457 regs
= si_setcore(sih
, SDIOD_CORE_ID
, 0);
1458 ASSERT(regs
!= NULL
);
1460 if (!(wasup
= si_iscoreup(sih
)))
1461 si_core_reset(sih
, 0, 0);
1463 rc
= get_si_pcmcia_srom(sih
, osh
, regs
, byteoff
, buf
, nbytes
, check_crc
);
1466 si_core_disable(sih
, 0);
1468 si_setcoreidx(sih
, origidx
);
1481 #if defined(WLTEST) || defined(DHD_SPROM) || defined(BCMDBG)
1482 /* support only 16-bit word write into srom */
1484 srom_write(si_t
*sih
, uint bustype
, void *curmap
, osl_t
*osh
,
1485 uint byteoff
, uint nbytes
, uint16
*buf
)
1487 uint i
, nw
, crc_range
;
1490 volatile uint32 val32
;
1493 ASSERT(bustype
== BUSTYPE(bustype
));
1495 old
= MALLOC(osh
, SROM_MAXW
* sizeof(uint16
));
1496 new = MALLOC(osh
, SROM_MAXW
* sizeof(uint16
));
1498 if (old
== NULL
|| new == NULL
)
1501 /* check input - 16-bit access only. use byteoff 0x55aa to indicate
1504 if ((byteoff
!= 0x55aa) && ((byteoff
& 1) || (nbytes
& 1)))
1507 if ((byteoff
!= 0x55aa) && ((byteoff
+ nbytes
) > SROM_MAX
))
1510 if (BUSTYPE(bustype
) == PCMCIA_BUS
) {
1511 crc_range
= SROM_MAX
;
1513 #if defined(BCMUSBDEV)
1515 crc_range
= srom_size(sih
, osh
);
1519 crc_range
= (SROM8_SIGN
+ 1) * 2; /* must big enough for SROM8 */
1524 /* read first small number words from srom, then adjust the length, read all */
1525 if (srom_read(sih
, bustype
, curmap
, osh
, 0, crc_range
, old
, FALSE
))
1528 BS_ERROR(("%s: old[SROM4_SIGN] 0x%x, old[SROM8_SIGN] 0x%x\n",
1529 __FUNCTION__
, old
[SROM4_SIGN
], old
[SROM8_SIGN
]));
1530 /* Deal with blank srom */
1531 if (old
[0] == 0xffff) {
1532 /* see if the input buffer is valid SROM image or not */
1533 if (buf
[SROM11_SIGN
] == SROM11_SIGNATURE
) {
1534 BS_ERROR(("%s: buf[SROM11_SIGN] 0x%x\n",
1535 __FUNCTION__
, buf
[SROM11_SIGN
]));
1537 /* block invalid buffer size */
1538 if (nbytes
< SROM11_WORDS
* 2) {
1539 rc
= BCME_BUFTOOSHORT
;
1541 } else if (nbytes
> SROM11_WORDS
* 2) {
1542 rc
= BCME_BUFTOOLONG
;
1547 } else if ((buf
[SROM4_SIGN
] == SROM4_SIGNATURE
) ||
1548 (buf
[SROM8_SIGN
] == SROM4_SIGNATURE
)) {
1549 BS_ERROR(("%s: buf[SROM4_SIGN] 0x%x, buf[SROM8_SIGN] 0x%x\n",
1550 __FUNCTION__
, buf
[SROM4_SIGN
], buf
[SROM8_SIGN
]));
1552 /* block invalid buffer size */
1553 if (nbytes
< SROM4_WORDS
* 2) {
1554 rc
= BCME_BUFTOOSHORT
;
1556 } else if (nbytes
> SROM4_WORDS
* 2) {
1557 rc
= BCME_BUFTOOLONG
;
1562 } else if (nbytes
== SROM_WORDS
* 2){ /* the other possible SROM format */
1563 BS_ERROR(("%s: Not SROM4 or SROM8.\n", __FUNCTION__
));
1567 BS_ERROR(("%s: Invalid input file signature\n", __FUNCTION__
));
1572 if (srom_read(sih
, bustype
, curmap
, osh
, 0, crc_range
, old
, FALSE
))
1574 } else if (old
[SROM11_SIGN
] == SROM11_SIGNATURE
) {
1577 if (srom_read(sih
, bustype
, curmap
, osh
, 0, crc_range
, old
, FALSE
))
1579 } else if ((old
[SROM4_SIGN
] == SROM4_SIGNATURE
) ||
1580 (old
[SROM8_SIGN
] == SROM4_SIGNATURE
)) {
1583 if (srom_read(sih
, bustype
, curmap
, osh
, 0, crc_range
, old
, FALSE
))
1586 /* Assert that we have already read enough for sromrev 2 */
1587 ASSERT(crc_range
>= SROM_WORDS
* 2);
1592 if (byteoff
== 0x55aa) {
1595 memset((void *)new, 0xff, nw
* 2);
1597 /* Copy old contents */
1598 bcopy((void *)old
, (void *)new, nw
* 2);
1600 bcopy((void *)buf
, (void *)&new[byteoff
/ 2], nbytes
);
1605 htol16_buf(new, crc_range
);
1606 crc
= ~hndcrc8((uint8
*)new, crc_range
- 1, CRC8_INIT_VALUE
);
1607 ltoh16_buf(new, crc_range
);
1608 new[nw
- 1] = (crc
<< 8) | (new[nw
- 1] & 0xff);
1611 if (BUSTYPE(bustype
) == PCI_BUS
) {
1612 uint16
*srom
= NULL
;
1613 void *ccregs
= NULL
;
1616 if ((CHIPID(sih
->chip
) == BCM4331_CHIP_ID
) ||
1617 (CHIPID(sih
->chip
) == BCM43431_CHIP_ID
) ||
1618 (CHIPID(sih
->chip
) == BCM4360_CHIP_ID
) ||
1619 (CHIPID(sih
->chip
) == BCM43460_CHIP_ID
) ||
1620 (CHIPID(sih
->chip
) == BCM43526_CHIP_ID
) ||
1621 (CHIPID(sih
->chip
) == BCM4352_CHIP_ID
)) {
1622 /* save current control setting */
1623 ccval
= si_chipcontrl_read(sih
);
1626 if ((CHIPID(sih
->chip
) == BCM4331_CHIP_ID
) ||
1627 (CHIPID(sih
->chip
) == BCM43431_CHIP_ID
)) {
1628 /* Disable Ext PA lines to allow reading from SROM */
1629 si_chipcontrl_epa4331(sih
, FALSE
);
1630 } else if (((CHIPID(sih
->chip
) == BCM4360_CHIP_ID
) ||
1631 (CHIPID(sih
->chip
) == BCM43460_CHIP_ID
) ||
1632 (CHIPID(sih
->chip
) == BCM4352_CHIP_ID
)) &&
1633 (CHIPREV(sih
->chiprev
) <= 2)) {
1634 si_chipcontrl_srom4360(sih
, TRUE
);
1637 /* enable writes to the SPROM */
1638 if (sih
->ccrev
> 31) {
1639 ccregs
= (void *)((uint8
*)curmap
+ PCI_16KB0_CCREGS_OFFSET
);
1640 srom
= (uint16
*)((uint8
*)ccregs
+ CC_SROM_OTP
);
1641 (void)srom_cc_cmd(sih
, osh
, ccregs
, SRC_OP_WREN
, 0, 0);
1643 srom
= (uint16
*)((uint8
*)curmap
+ PCI_BAR0_SPROM_OFFSET
);
1644 val32
= OSL_PCI_READ_CONFIG(osh
, PCI_SPROM_CONTROL
, sizeof(uint32
));
1645 val32
|= SPROM_WRITEEN
;
1646 OSL_PCI_WRITE_CONFIG(osh
, PCI_SPROM_CONTROL
, sizeof(uint32
), val32
);
1648 bcm_mdelay(WRITE_ENABLE_DELAY
);
1650 for (i
= 0; i
< nw
; i
++) {
1651 if (old
[i
] != new[i
]) {
1652 if (sih
->ccrev
> 31) {
1653 if ((sih
->cccaps
& CC_CAP_SROM
) == 0) {
1654 /* No srom support in this chip */
1655 BS_ERROR(("srom_write, invalid srom, skip\n"));
1657 (void)srom_cc_cmd(sih
, osh
, ccregs
, SRC_OP_WRITE
,
1660 W_REG(osh
, &srom
[i
], new[i
]);
1662 bcm_mdelay(WRITE_WORD_DELAY
);
1665 /* disable writes to the SPROM */
1666 if (sih
->ccrev
> 31) {
1667 (void)srom_cc_cmd(sih
, osh
, ccregs
, SRC_OP_WRDIS
, 0, 0);
1669 OSL_PCI_WRITE_CONFIG(osh
, PCI_SPROM_CONTROL
, sizeof(uint32
), val32
&
1673 if ((CHIPID(sih
->chip
) == BCM4331_CHIP_ID
) ||
1674 (CHIPID(sih
->chip
) == BCM43431_CHIP_ID
) ||
1675 (CHIPID(sih
->chip
) == BCM4360_CHIP_ID
) ||
1676 (CHIPID(sih
->chip
) == BCM43460_CHIP_ID
) ||
1677 (CHIPID(sih
->chip
) == BCM4352_CHIP_ID
)) {
1678 /* Restore config after reading SROM */
1679 si_chipcontrl_restore(sih
, ccval
);
1682 } else if (BUSTYPE(bustype
) == PCMCIA_BUS
) {
1683 /* enable writes to the SPROM */
1684 if (sprom_cmd_pcmcia(osh
, SROM_WEN
))
1686 bcm_mdelay(WRITE_ENABLE_DELAY
);
1688 for (i
= 0; i
< nw
; i
++) {
1689 if (old
[i
] != new[i
]) {
1690 sprom_write_pcmcia(osh
, (uint16
)(i
), new[i
]);
1691 bcm_mdelay(WRITE_WORD_DELAY
);
1694 /* disable writes to the SPROM */
1695 if (sprom_cmd_pcmcia(osh
, SROM_WDS
))
1697 } else if (BUSTYPE(bustype
) == SI_BUS
) {
1698 #if defined(BCMUSBDEV)
1699 if (SPROMBUS
== PCMCIA_BUS
) {
1704 origidx
= si_coreidx(sih
);
1705 regs
= si_setcore(sih
, PCMCIA_CORE_ID
, 0);
1707 regs
= si_setcore(sih
, SDIOD_CORE_ID
, 0);
1708 ASSERT(regs
!= NULL
);
1710 if (!(wasup
= si_iscoreup(sih
)))
1711 si_core_reset(sih
, 0, 0);
1713 rc
= set_si_pcmcia_srom(sih
, osh
, regs
, byteoff
, buf
, nbytes
);
1716 si_core_disable(sih
, 0);
1718 si_setcoreidx(sih
, origidx
);
1727 bcm_mdelay(WRITE_ENABLE_DELAY
);
1732 MFREE(osh
, old
, SROM_MAXW
* sizeof(uint16
));
1734 MFREE(osh
, new, SROM_MAXW
* sizeof(uint16
));
1740 #if defined(BCMUSBDEV)
1741 #define SI_PCMCIA_READ(osh, regs, fcr) \
1742 R_REG(osh, (volatile uint8 *)(regs) + 0x600 + (fcr) - 0x700 / 2)
1743 #define SI_PCMCIA_WRITE(osh, regs, fcr, v) \
1744 W_REG(osh, (volatile uint8 *)(regs) + 0x600 + (fcr) - 0x700 / 2, v)
1746 /* set PCMCIA srom command register */
1748 srom_cmd_si_pcmcia(osl_t
*osh
, uint8
*pcmregs
, uint8 cmd
)
1753 /* write srom command register */
1754 SI_PCMCIA_WRITE(osh
, pcmregs
, SROM_CS
, cmd
);
1757 while (++wait_cnt
< 1000000) {
1758 status
= SI_PCMCIA_READ(osh
, pcmregs
, SROM_CS
);
1759 if (status
& SROM_DONE
)
1764 BS_ERROR(("sr_cmd: Give up after %d tries, stat = 0x%x\n", wait_cnt
, status
));
1768 /* read a word from the PCMCIA srom over SI */
1770 srom_read_si_pcmcia(osl_t
*osh
, uint8
*pcmregs
, uint16 addr
, uint16
*data
)
1772 uint8 addr_l
, addr_h
, data_l
, data_h
;
1774 addr_l
= (uint8
)((addr
* 2) & 0xff);
1775 addr_h
= (uint8
)(((addr
* 2) >> 8) & 0xff);
1778 SI_PCMCIA_WRITE(osh
, pcmregs
, SROM_ADDRH
, addr_h
);
1779 SI_PCMCIA_WRITE(osh
, pcmregs
, SROM_ADDRL
, addr_l
);
1782 if (srom_cmd_si_pcmcia(osh
, pcmregs
, SROM_READ
))
1786 data_h
= SI_PCMCIA_READ(osh
, pcmregs
, SROM_DATAH
);
1787 data_l
= SI_PCMCIA_READ(osh
, pcmregs
, SROM_DATAL
);
1788 *data
= ((uint16
)data_h
<< 8) | data_l
;
1793 #if defined(WLTEST) || defined(DHD_SPROM) || defined(BCMDBG)
1794 /* write a word to the PCMCIA srom over SI */
1796 srom_write_si_pcmcia(osl_t
*osh
, uint8
*pcmregs
, uint16 addr
, uint16 data
)
1798 uint8 addr_l
, addr_h
, data_l
, data_h
;
1801 addr_l
= (uint8
)((addr
* 2) & 0xff);
1802 addr_h
= (uint8
)(((addr
* 2) >> 8) & 0xff);
1805 SI_PCMCIA_WRITE(osh
, pcmregs
, SROM_ADDRH
, addr_h
);
1806 SI_PCMCIA_WRITE(osh
, pcmregs
, SROM_ADDRL
, addr_l
);
1808 data_l
= (uint8
)(data
& 0xff);
1809 data_h
= (uint8
)((data
>> 8) & 0xff);
1812 SI_PCMCIA_WRITE(osh
, pcmregs
, SROM_DATAH
, data_h
);
1813 SI_PCMCIA_WRITE(osh
, pcmregs
, SROM_DATAL
, data_l
);
1816 rc
= srom_cmd_si_pcmcia(osh
, pcmregs
, SROM_WRITE
);
1823 * Read the srom for the pcmcia-srom over si case.
1824 * Return 0 on success, nonzero on error.
1827 get_si_pcmcia_srom(si_t
*sih
, osl_t
*osh
, uint8
*pcmregs
,
1828 uint boff
, uint16
*srom
, uint bsz
, bool check_crc
)
1830 uint i
, nw
, woff
, wsz
;
1833 /* read must be at word boundary */
1834 ASSERT((boff
& 1) == 0 && (bsz
& 1) == 0);
1836 /* read sprom size and validate the parms */
1837 if ((nw
= srom_size(sih
, osh
)) == 0) {
1838 BS_ERROR(("get_si_pcmcia_srom: sprom size unknown\n"));
1842 if (boff
+ bsz
> 2 * nw
) {
1843 BS_ERROR(("get_si_pcmcia_srom: sprom size exceeded\n"));
1848 /* read in sprom contents */
1849 for (woff
= boff
/ 2, wsz
= bsz
/ 2, i
= 0;
1850 woff
< nw
&& i
< wsz
; woff
++, i
++) {
1851 if (srom_read_si_pcmcia(osh
, pcmregs
, (uint16
)woff
, &srom
[i
])) {
1852 BS_ERROR(("get_si_pcmcia_srom: sprom read failed\n"));
1859 if (srom
[0] == 0xffff) {
1860 /* The hardware thinks that an srom that starts with 0xffff
1861 * is blank, regardless of the rest of the content, so declare
1864 BS_ERROR(("%s: srom[0] == 0xffff, assuming unprogrammed srom\n",
1870 /* fixup the endianness so crc8 will pass */
1871 htol16_buf(srom
, nw
* 2);
1872 if (hndcrc8((uint8
*)srom
, nw
* 2, CRC8_INIT_VALUE
) != CRC8_GOOD_VALUE
) {
1873 BS_ERROR(("%s: bad crc\n", __FUNCTION__
));
1876 /* now correct the endianness of the byte array */
1877 ltoh16_buf(srom
, nw
* 2);
1884 #if defined(WLTEST) || defined(DHD_SPROM) || defined(BCMDBG)
1886 * Write the srom for the pcmcia-srom over si case.
1887 * Return 0 on success, nonzero on error.
1890 set_si_pcmcia_srom(si_t
*sih
, osl_t
*osh
, uint8
*pcmregs
,
1891 uint boff
, uint16
*srom
, uint bsz
)
1893 uint i
, nw
, woff
, wsz
;
1898 /* write must be at word boundary */
1899 ASSERT((boff
& 1) == 0 && (bsz
& 1) == 0);
1901 /* read sprom size and validate the parms */
1902 if ((nw
= srom_size(sih
, osh
)) == 0) {
1903 BS_ERROR(("set_si_pcmcia_srom: sprom size unknown\n"));
1907 if (boff
+ bsz
> 2 * nw
) {
1908 BS_ERROR(("set_si_pcmcia_srom: sprom size exceeded\n"));
1914 if (srom_cmd_si_pcmcia(osh
, pcmregs
, SROM_WEN
)) {
1915 BS_ERROR(("set_si_pcmcia_srom: sprom wen failed\n"));
1920 /* write buffer to sprom */
1921 for (woff
= boff
/ 2, wsz
= bsz
/ 2, i
= 0;
1922 woff
< nw
&& i
< wsz
; woff
++, i
++) {
1923 if (srom_write_si_pcmcia(osh
, pcmregs
, (uint16
)woff
, srom
[i
])) {
1924 BS_ERROR(("set_si_pcmcia_srom: sprom write failed\n"));
1931 crc
= CRC8_INIT_VALUE
;
1932 for (woff
= 0; woff
< nw
; woff
++) {
1933 if (srom_read_si_pcmcia(osh
, pcmregs
, (uint16
)woff
, &word
)) {
1934 BS_ERROR(("set_si_pcmcia_srom: sprom fix crc read failed\n"));
1938 word
= htol16(word
);
1939 crc
= hndcrc8((uint8
*)&word
, woff
!= nw
- 1 ? 2 : 1, crc
);
1941 word
= (~crc
<< 8) + (ltoh16(word
) & 0xff);
1942 if (srom_write_si_pcmcia(osh
, pcmregs
, (uint16
)(woff
- 1), word
)) {
1943 BS_ERROR(("set_si_pcmcia_srom: sprom fix crc write failed\n"));
1949 if (srom_cmd_si_pcmcia(osh
, pcmregs
, SROM_WDS
)) {
1950 BS_ERROR(("set_si_pcmcia_srom: sprom wds failed\n"));
1961 static const char BCMATTACHDATA(vstr_manf
)[] = "manf=%s";
1962 static const char BCMATTACHDATA(vstr_productname
)[] = "productname=%s";
1963 static const char BCMATTACHDATA(vstr_manfid
)[] = "manfid=0x%x";
1964 static const char BCMATTACHDATA(vstr_prodid
)[] = "prodid=0x%x";
1965 static const char BCMATTACHDATA(vstr_regwindowsz
)[] = "regwindowsz=%d";
1966 static const char BCMATTACHDATA(vstr_sromrev
)[] = "sromrev=%d";
1967 static const char BCMATTACHDATA(vstr_chiprev
)[] = "chiprev=%d";
1968 static const char BCMATTACHDATA(vstr_subvendid
)[] = "subvendid=0x%x";
1969 static const char BCMATTACHDATA(vstr_subdevid
)[] = "subdevid=0x%x";
1970 static const char BCMATTACHDATA(vstr_boardrev
)[] = "boardrev=0x%x";
1971 static const char BCMATTACHDATA(vstr_aa2g
)[] = "aa2g=0x%x";
1972 static const char BCMATTACHDATA(vstr_aa5g
)[] = "aa5g=0x%x";
1973 static const char BCMATTACHDATA(vstr_ag
)[] = "ag%d=0x%x";
1974 static const char BCMATTACHDATA(vstr_cc
)[] = "cc=%d";
1975 static const char BCMATTACHDATA(vstr_opo
)[] = "opo=%d";
1976 static const char BCMATTACHDATA(vstr_pa0b
)[][9] = { "pa0b0=%d", "pa0b1=%d", "pa0b2=%d" };
1977 static const char BCMATTACHDATA(vstr_pa0itssit
)[] = "pa0itssit=%d";
1978 static const char BCMATTACHDATA(vstr_pa0maxpwr
)[] = "pa0maxpwr=%d";
1979 static const char BCMATTACHDATA(vstr_pa1b
)[][9] = { "pa1b0=%d", "pa1b1=%d", "pa1b2=%d" };
1980 static const char BCMATTACHDATA(vstr_pa1lob
)[][11] =
1981 { "pa1lob0=%d", "pa1lob1=%d", "pa1lob2=%d" };
1982 static const char BCMATTACHDATA(vstr_pa1hib
)[][11] =
1983 { "pa1hib0=%d", "pa1hib1=%d", "pa1hib2=%d" };
1984 static const char BCMATTACHDATA(vstr_pa1itssit
)[] = "pa1itssit=%d";
1985 static const char BCMATTACHDATA(vstr_pa1maxpwr
)[] = "pa1maxpwr=%d";
1986 static const char BCMATTACHDATA(vstr_pa1lomaxpwr
)[] = "pa1lomaxpwr=%d";
1987 static const char BCMATTACHDATA(vstr_pa1himaxpwr
)[] = "pa1himaxpwr=%d";
1988 static const char BCMATTACHDATA(vstr_oem
)[] = "oem=%02x%02x%02x%02x%02x%02x%02x%02x";
1989 static const char BCMATTACHDATA(vstr_boardflags
)[] = "boardflags=0x%x";
1990 static const char BCMATTACHDATA(vstr_boardflags2
)[] = "boardflags2=0x%x";
1991 static const char BCMATTACHDATA(vstr_boardflags3
)[] = "boardflags3=0x%x";
1992 static const char BCMATTACHDATA(vstr_ledbh
)[] = "ledbh%d=0x%x";
1993 static const char BCMATTACHDATA(vstr_noccode
)[] = "ccode=0x0";
1994 static const char BCMATTACHDATA(vstr_ccode
)[] = "ccode=%c%c";
1995 static const char BCMATTACHDATA(vstr_cctl
)[] = "cctl=0x%x";
1996 static const char BCMATTACHDATA(vstr_cckpo
)[] = "cckpo=0x%x";
1997 static const char BCMATTACHDATA(vstr_ofdmpo
)[] = "ofdmpo=0x%x";
1998 static const char BCMATTACHDATA(vstr_rdlid
)[] = "rdlid=0x%x";
1999 static const char BCMATTACHDATA(vstr_rdlrndis
)[] = "rdlrndis=%d";
2000 static const char BCMATTACHDATA(vstr_rdlrwu
)[] = "rdlrwu=%d";
2001 static const char BCMATTACHDATA(vstr_usbfs
)[] = "usbfs=%d";
2002 static const char BCMATTACHDATA(vstr_wpsgpio
)[] = "wpsgpio=%d";
2003 static const char BCMATTACHDATA(vstr_wpsled
)[] = "wpsled=%d";
2004 static const char BCMATTACHDATA(vstr_rdlsn
)[] = "rdlsn=%d";
2005 static const char BCMATTACHDATA(vstr_rssismf2g
)[] = "rssismf2g=%d";
2006 static const char BCMATTACHDATA(vstr_rssismc2g
)[] = "rssismc2g=%d";
2007 static const char BCMATTACHDATA(vstr_rssisav2g
)[] = "rssisav2g=%d";
2008 static const char BCMATTACHDATA(vstr_bxa2g
)[] = "bxa2g=%d";
2009 static const char BCMATTACHDATA(vstr_rssismf5g
)[] = "rssismf5g=%d";
2010 static const char BCMATTACHDATA(vstr_rssismc5g
)[] = "rssismc5g=%d";
2011 static const char BCMATTACHDATA(vstr_rssisav5g
)[] = "rssisav5g=%d";
2012 static const char BCMATTACHDATA(vstr_bxa5g
)[] = "bxa5g=%d";
2013 static const char BCMATTACHDATA(vstr_tri2g
)[] = "tri2g=%d";
2014 static const char BCMATTACHDATA(vstr_tri5gl
)[] = "tri5gl=%d";
2015 static const char BCMATTACHDATA(vstr_tri5g
)[] = "tri5g=%d";
2016 static const char BCMATTACHDATA(vstr_tri5gh
)[] = "tri5gh=%d";
2017 static const char BCMATTACHDATA(vstr_rxpo2g
)[] = "rxpo2g=%d";
2018 static const char BCMATTACHDATA(vstr_rxpo5g
)[] = "rxpo5g=%d";
2019 static const char BCMATTACHDATA(vstr_boardtype
)[] = "boardtype=0x%x";
2020 static const char BCMATTACHDATA(vstr_leddc
)[] = "leddc=0x%04x";
2021 static const char BCMATTACHDATA(vstr_vendid
)[] = "vendid=0x%x";
2022 static const char BCMATTACHDATA(vstr_devid
)[] = "devid=0x%x";
2023 static const char BCMATTACHDATA(vstr_xtalfreq
)[] = "xtalfreq=%d";
2024 static const char BCMATTACHDATA(vstr_txchain
)[] = "txchain=0x%x";
2025 static const char BCMATTACHDATA(vstr_rxchain
)[] = "rxchain=0x%x";
2026 static const char BCMNMIATTACHDATA(vstr_elna2g
)[] = "elna2g=0x%x";
2027 static const char BCMNMIATTACHDATA(vstr_elna5g
)[] = "elna5g=0x%x";
2028 static const char BCMATTACHDATA(vstr_antswitch
)[] = "antswitch=0x%x";
2029 static const char BCMATTACHDATA(vstr_regrev
)[] = "regrev=0x%x";
2030 static const char BCMATTACHDATA(vstr_antswctl2g
)[] = "antswctl2g=0x%x";
2031 static const char BCMATTACHDATA(vstr_triso2g
)[] = "triso2g=0x%x";
2032 static const char BCMATTACHDATA(vstr_pdetrange2g
)[] = "pdetrange2g=0x%x";
2033 static const char BCMATTACHDATA(vstr_extpagain2g
)[] = "extpagain2g=0x%x";
2034 static const char BCMATTACHDATA(vstr_tssipos2g
)[] = "tssipos2g=0x%x";
2035 static const char BCMATTACHDATA(vstr_antswctl5g
)[] = "antswctl5g=0x%x";
2036 static const char BCMATTACHDATA(vstr_triso5g
)[] = "triso5g=0x%x";
2037 static const char BCMATTACHDATA(vstr_pdetrange5g
)[] = "pdetrange5g=0x%x";
2038 static const char BCMATTACHDATA(vstr_extpagain5g
)[] = "extpagain5g=0x%x";
2039 static const char BCMATTACHDATA(vstr_tssipos5g
)[] = "tssipos5g=0x%x";
2040 static const char BCMATTACHDATA(vstr_maxp2ga
)[] = "maxp2ga%d=0x%x";
2041 static const char BCMATTACHDATA(vstr_itt2ga0
)[] = "itt2ga0=0x%x";
2042 static const char BCMATTACHDATA(vstr_pa
)[] = "pa%dgw%da%d=0x%x";
2043 static const char BCMATTACHDATA(vstr_pahl
)[] = "pa%dg%cw%da%d=0x%x";
2044 static const char BCMATTACHDATA(vstr_maxp5ga0
)[] = "maxp5ga0=0x%x";
2045 static const char BCMATTACHDATA(vstr_itt5ga0
)[] = "itt5ga0=0x%x";
2046 static const char BCMATTACHDATA(vstr_maxp5gha0
)[] = "maxp5gha0=0x%x";
2047 static const char BCMATTACHDATA(vstr_maxp5gla0
)[] = "maxp5gla0=0x%x";
2048 static const char BCMATTACHDATA(vstr_itt2ga1
)[] = "itt2ga1=0x%x";
2049 static const char BCMATTACHDATA(vstr_maxp5ga1
)[] = "maxp5ga1=0x%x";
2050 static const char BCMATTACHDATA(vstr_itt5ga1
)[] = "itt5ga1=0x%x";
2051 static const char BCMATTACHDATA(vstr_maxp5gha1
)[] = "maxp5gha1=0x%x";
2052 static const char BCMATTACHDATA(vstr_maxp5gla1
)[] = "maxp5gla1=0x%x";
2053 static const char BCMATTACHDATA(vstr_cck2gpo
)[] = "cck2gpo=0x%x";
2054 static const char BCMATTACHDATA(vstr_ofdm2gpo
)[] = "ofdm2gpo=0x%x";
2055 static const char BCMATTACHDATA(vstr_ofdm5gpo
)[] = "ofdm5gpo=0x%x";
2056 static const char BCMATTACHDATA(vstr_ofdm5glpo
)[] = "ofdm5glpo=0x%x";
2057 static const char BCMATTACHDATA(vstr_ofdm5ghpo
)[] = "ofdm5ghpo=0x%x";
2058 static const char BCMATTACHDATA(vstr_cddpo
)[] = "cddpo=0x%x";
2059 static const char BCMATTACHDATA(vstr_stbcpo
)[] = "stbcpo=0x%x";
2060 static const char BCMATTACHDATA(vstr_bw40po
)[] = "bw40po=0x%x";
2061 static const char BCMATTACHDATA(vstr_bwduppo
)[] = "bwduppo=0x%x";
2062 static const char BCMATTACHDATA(vstr_mcspo
)[] = "mcs%dgpo%d=0x%x";
2063 static const char BCMATTACHDATA(vstr_mcspohl
)[] = "mcs%dg%cpo%d=0x%x";
2064 static const char BCMATTACHDATA(vstr_custom
)[] = "customvar%d=0x%x";
2065 static const char BCMATTACHDATA(vstr_cckdigfilttype
)[] = "cckdigfilttype=%d";
2066 static const char BCMATTACHDATA(vstr_usbflags
)[] = "usbflags=0x%x";
2067 #ifdef BCM_BOOTLOADER
2068 static const char BCMATTACHDATA(vstr_mdio
)[] = "mdio%d=0x%%x";
2069 static const char BCMATTACHDATA(vstr_mdioex
)[] = "mdioex%d=0x%%x";
2070 static const char BCMATTACHDATA(vstr_brmin
)[] = "brmin=0x%x";
2071 static const char BCMATTACHDATA(vstr_brmax
)[] = "brmax=0x%x";
2072 static const char BCMATTACHDATA(vstr_pllreg
)[] = "pll%d=0x%x";
2073 static const char BCMATTACHDATA(vstr_ccreg
)[] = "chipc%d=0x%x";
2074 static const char BCMATTACHDATA(vstr_regctrl
)[] = "reg%d=0x%x";
2075 static const char BCMATTACHDATA(vstr_time
)[] = "r%dt=0x%x";
2076 static const char BCMATTACHDATA(vstr_depreg
)[] = "r%dd=0x%x";
2077 static const char BCMATTACHDATA(vstr_usbpredly
)[] = "usbpredly=0x%x";
2078 static const char BCMATTACHDATA(vstr_usbpostdly
)[] = "usbpostdly=0x%x";
2079 static const char BCMATTACHDATA(vstr_usbrdy
)[] = "usbrdy=0x%x";
2080 static const char BCMATTACHDATA(vstr_hsicphyctrl1
)[] = "hsicphyctrl1=0x%x";
2081 static const char BCMATTACHDATA(vstr_hsicphyctrl2
)[] = "hsicphyctrl2=0x%x";
2082 static const char BCMATTACHDATA(vstr_usbdevctrl
)[] = "usbdevctrl=0x%x";
2083 static const char BCMATTACHDATA(vstr_bldr_reset_timeout
)[] = "bldr_to=0x%x";
2084 static const char BCMATTACHDATA(vstr_muxenab
)[] = "muxenab=0x%x";
2085 static const char BCMATTACHDATA(vstr_pubkey
)[] = "pubkey=%s";
2086 #endif /* BCM_BOOTLOADER */
2087 static const char BCMATTACHDATA(vstr_boardnum
)[] = "boardnum=%d";
2088 static const char BCMATTACHDATA(vstr_macaddr
)[] = "macaddr=%s";
2089 static const char BCMATTACHDATA(vstr_usbepnum
)[] = "usbepnum=0x%x";
2090 #ifdef BCMUSBDEV_COMPOSITE
2091 static const char BCMATTACHDATA(vstr_usbdesc_composite
)[] = "usbdesc_composite=0x%x";
2092 #endif /* BCMUSBDEV_COMPOSITE */
2093 static const char BCMATTACHDATA(vstr_usbutmi_ctl
)[] = "usbutmi_ctl=0x%x";
2094 static const char BCMATTACHDATA(vstr_usbssphy_utmi_ctl0
)[] = "usbssphy_utmi_ctl0=0x%x";
2095 static const char BCMATTACHDATA(vstr_usbssphy_utmi_ctl1
)[] = "usbssphy_utmi_ctl1=0x%x";
2096 static const char BCMATTACHDATA(vstr_usbssphy_utmi_ctl2
)[] = "usbssphy_utmi_ctl2=0x%x";
2097 static const char BCMATTACHDATA(vstr_usbssphy_sleep0
)[] = "usbssphy_sleep0=0x%x";
2098 static const char BCMATTACHDATA(vstr_usbssphy_sleep1
)[] = "usbssphy_sleep1=0x%x";
2099 static const char BCMATTACHDATA(vstr_usbssphy_sleep2
)[] = "usbssphy_sleep2=0x%x";
2100 static const char BCMATTACHDATA(vstr_usbssphy_sleep3
)[] = "usbssphy_sleep3=0x%x";
2102 /* Power per rate for SROM V9 */
2103 static const char BCMATTACHDATA(vstr_cckbw202gpo
)[][19] =
2104 { "cckbw202gpo=0x%x", "cckbw20ul2gpo=0x%x" };
2105 static const char BCMATTACHDATA(vstr_legofdmbw202gpo
)[][22] =
2106 { "legofdmbw202gpo=0x%x", "legofdmbw20ul2gpo=0x%x" };
2107 static const char BCMATTACHDATA(vstr_legofdmbw205gpo
)[][24] =
2108 { "legofdmbw205glpo=0x%x", "legofdmbw20ul5glpo=0x%x",
2109 "legofdmbw205gmpo=0x%x", "legofdmbw20ul5gmpo=0x%x",
2110 "legofdmbw205ghpo=0x%x", "legofdmbw20ul5ghpo=0x%x" };
2112 static const char BCMATTACHDATA(vstr_mcs2gpo
)[][19] =
2113 { "mcsbw202gpo=0x%x", "mcsbw20ul2gpo=0x%x", "mcsbw402gpo=0x%x"};
2115 static const char BCMATTACHDATA(vstr_mcs5glpo
)[][20] =
2116 { "mcsbw205glpo=0x%x", "mcsbw20ul5glpo=0x%x", "mcsbw405glpo=0x%x"};
2118 static const char BCMATTACHDATA(vstr_mcs5gmpo
)[][20] =
2119 { "mcsbw205gmpo=0x%x", "mcsbw20ul5gmpo=0x%x", "mcsbw405gmpo=0x%x"};
2121 static const char BCMATTACHDATA(vstr_mcs5ghpo
)[][20] =
2122 { "mcsbw205ghpo=0x%x", "mcsbw20ul5ghpo=0x%x", "mcsbw405ghpo=0x%x"};
2124 static const char BCMATTACHDATA(vstr_mcs32po
)[] = "mcs32po=0x%x";
2125 static const char BCMATTACHDATA(vstr_legofdm40duppo
)[] = "legofdm40duppo=0x%x";
2128 static const char BCMATTACHDATA(vstr_tempthresh
)[] = "tempthresh=%d"; /* HNBU_TEMPTHRESH */
2129 static const char BCMATTACHDATA(vstr_temps_period
)[] = "temps_period=%d";
2130 static const char BCMATTACHDATA(vstr_temps_hysteresis
)[] = "temps_hysteresis=%d";
2131 static const char BCMATTACHDATA(vstr_tempoffset
)[] = "tempoffset=%d";
2132 static const char BCMATTACHDATA(vstr_tempsense_slope
)[] = "tempsense_slope=%d";
2133 static const char BCMATTACHDATA(vstr_temp_corrx
)[] = "tempcorrx=%d";
2134 static const char BCMATTACHDATA(vstr_tempsense_option
)[] = "tempsense_option=%d";
2135 static const char BCMATTACHDATA(vstr_phycal_tempdelta
)[] = "phycal_tempdelta=%d";
2136 static const char BCMATTACHDATA(vstr_tssiposslopeg
)[] = "tssiposslope%dg=%d"; /* HNBU_FEM_CFG */
2137 static const char BCMATTACHDATA(vstr_epagaing
)[] = "epagain%dg=%d";
2138 static const char BCMATTACHDATA(vstr_pdgaing
)[] = "pdgain%dg=%d";
2139 static const char BCMATTACHDATA(vstr_tworangetssi
)[] = "tworangetssi%dg=%d";
2140 static const char BCMATTACHDATA(vstr_papdcap
)[] = "papdcap%dg=%d";
2141 static const char BCMATTACHDATA(vstr_femctrl
)[] = "femctrl=%d";
2142 static const char BCMATTACHDATA(vstr_gainctrlsph
)[] = "gainctrlsph=%d";
2143 static const char BCMATTACHDATA(vstr_subband5gver
)[] = "subband5gver=%d"; /* HNBU_ACPA_CX */
2144 static const char BCMATTACHDATA(vstr_pa2ga
)[] = "pa2ga%d=0x%x,0x%x,0x%x";
2145 static const char BCMATTACHDATA(vstr_maxp5ga
)[] = "maxp5ga%d=0x%x,0x%x,0x%x,0x%x";
2146 static const char BCMATTACHDATA(vstr_pa5ga
)[] = "pa5ga%d=0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,"
2147 "0x%x,0x%x,0x%x,0x%x,0x%x,0x%x";
2148 static const char BCMATTACHDATA(vstr_rxgainsgelnagaina
)[] = "rxgains%dgelnagaina=%d";
2149 static const char BCMATTACHDATA(vstr_rxgainsgtrisoa
)[] = "rxgains%dgtrisoa%d=%d";
2150 static const char BCMATTACHDATA(vstr_rxgainsgtrelnabypa
)[] = "rxgains%dgtrelnabypa%d=%d";
2151 static const char BCMATTACHDATA(vstr_rxgainsgxelnagaina
)[] = "rxgains%dg%celnagaina%d=%d";
2152 static const char BCMATTACHDATA(vstr_rxgainsgxtrisoa
)[] = "rxgains%dg%ctrisoa%d=%d";
2153 static const char BCMATTACHDATA(vstr_rxgainsgxtrelnabypa
)[] = "rxgains%dg%ctrelnabypa%d=%d";
2154 static const char BCMATTACHDATA(vstr_measpower
)[] = "measpower=0x%x"; /* HNBU_MEAS_PWR */
2155 static const char BCMATTACHDATA(vstr_measpowerX
)[] = "measpower%d=0x%x";
2156 static const char BCMATTACHDATA(vstr_pdoffsetma
)[] = "pdoffset%dma%d=0x%x"; /* HNBU_PDOFF */
2157 static const char BCMATTACHDATA(vstr_pdoffset2gma
)[] = "pdoffset2g%dma%d=0x%x"; /* HNBU_PDOFF_2G */
2158 static const char BCMATTACHDATA(vstr_pdoffset2gmvalid
)[] = "pdoffset2g%dmvalid=0x%x";
2159 static const char BCMATTACHDATA(vstr_rawtempsense
)[] = "rawtempsense=0x%x";
2160 /* HNBU_ACPPR_2GPO */
2161 static const char BCMATTACHDATA(vstr_dot11agofdmhrbw202gpo
)[] = "dot11agofdmhrbw202gpo=0x%x";
2162 static const char BCMATTACHDATA(vstr_ofdmlrbw202gpo
)[] = "ofdmlrbw202gpo=0x%x";
2163 static const char BCMATTACHDATA(vstr_mcsbw805gpo
)[] = "mcsbw805g%cpo=0x%x"; /* HNBU_ACPPR_5GPO */
2164 static const char BCMATTACHDATA(vstr_mcsbw1605gpo
)[] = "mcsbw1605g%cpo=0x%x";
2165 static const char BCMATTACHDATA(vstr_mcslr5gpo
)[] = "mcslr5g%cpo=0x%x";
2166 static const char BCMATTACHDATA(vstr_sb20in40rpo
)[] = "sb20in40%crpo=0x%x"; /* HNBU_ACPPR_SBPO */
2167 static const char BCMATTACHDATA(vstr_sb20in80and160r5gpo
)[] = "sb20in80and160%cr5g%cpo=0x%x";
2168 static const char BCMATTACHDATA(vstr_sb40and80r5gpo
)[] = "sb40and80%cr5g%cpo=0x%x";
2169 static const char BCMATTACHDATA(vstr_dot11agduprpo
)[] = "dot11agdup%crpo=0x%x";
2170 static const char BCMATTACHDATA(vstr_noiselvl2ga
)[] = "noiselvl2ga%d=%d"; /* HNBU_NOISELVL */
2171 static const char BCMATTACHDATA(vstr_noiselvl5ga
)[] = "noiselvl5ga%d=%d,%d,%d,%d";
2172 static const char BCMATTACHDATA(vstr_rxgainerr2ga
)[] = "rxgainerr2ga%d=0x%x"; /* HNBU_RXGAIN_ERR */
2173 static const char BCMATTACHDATA(vstr_rxgainerr5ga
)[] = "rxgainerr5ga%d=0x%x,0x%x,0x%x,0x%x";
2174 static const char BCMATTACHDATA(vstr_agbg
)[] = "agbg%d=0x%x"; /* HNBU_AGBGA */
2175 static const char BCMATTACHDATA(vstr_aga
)[] = "aga%d=0x%x";
2176 static const char BCMATTACHDATA(vstr_txduty_ofdm
)[] = "tx_duty_cycle_ofdm_%d_5g=%d";
2177 static const char BCMATTACHDATA(vstr_txduty_thresh
)[] = "tx_duty_cycle_thresh_%d_5g=%d";
2179 static const char BCMATTACHDATA(vstr_uuid
)[] = "uuid=%s";
2181 static const char BCMATTACHDATA(vstr_end
)[] = "END\0";
2183 uint8 patch_pair
= 0;
2185 /* For dongle HW, accept partial calibration parameters */
2186 #if defined(BCMUSBDEV)
2187 #define BCMDONGLECASE(n) case n:
2189 #define BCMDONGLECASE(n)
2192 #ifdef BCM_BOOTLOADER
2193 /* The format of the PMUREGS OTP Tuple ->
2194 * 1 byte -> Lower 5 bits has the address of the register
2195 * Higher 3 bits has the mode of the register like
2196 * PLL, ChipCtrl, RegCtrl, UpDwn or Dependency mask
2197 * 4 bytes -> Value of the register to be updated.
2199 #define PMUREGS_MODE_MASK 0xE0
2200 #define PMUREGS_MODE_SHIFT 5
2201 #define PMUREGS_ADDR_MASK 0x1F
2202 #define PMUREGS_TPL_SIZE 5
2212 #define USBREGS_TPL_SIZE 5
2219 #define USBRDY_DLY_TYPE 0x8000 /* Bit indicating if the byte is pre or post delay value */
2220 #define USBRDY_DLY_MASK 0x7FFF /* Bits indicating the amount of delay */
2221 #define USBRDY_MAXOTP_SIZE 5 /* Max size of the OTP parameter */
2223 #endif /* BCM_BOOTLOADER */
2225 #ifdef BCM_BMAC_VARS_APPEND
2227 BCMATTACHFN(srom_probe_boardtype
)(uint8
*pcis
[], uint ciscnt
)
2231 uint8
*cis
, tup
, tlen
;
2233 for (cisnum
= 0; cisnum
< ciscnt
; cisnum
++) {
2238 if (tup
== CISTPL_NULL
|| tup
== CISTPL_END
)
2243 if ((i
+ tlen
) >= CIS_SIZE
)
2246 if ((tup
== CISTPL_BRCM_HNBU
) && (cis
[i
] == HNBU_BOARDTYPE
)) {
2247 return (int)((cis
[i
+ 2] << 8) + cis
[i
+ 1]);
2252 } while (tup
!= CISTPL_END
);
2257 #endif /* BCM_BMAC_VARS_APPEND */
2260 BCMATTACHFN(srom_parsecis
)(osl_t
*osh
, uint8
*pcis
[], uint ciscnt
, char **vars
, uint
*count
)
2265 uint8
*cis
, tup
, tlen
, sromrev
= 1;
2267 #ifndef BCM_BOOTLOADER
2268 bool ag_init
= FALSE
;
2277 ASSERT(vars
!= NULL
);
2278 ASSERT(count
!= NULL
);
2282 base
= MALLOC(osh
, MAXSZ_NVRAM_VARS
);
2283 ASSERT(base
!= NULL
);
2287 varbuf_init(&b
, base
, MAXSZ_NVRAM_VARS
);
2288 bzero(base
, MAXSZ_NVRAM_VARS
);
2289 #ifdef BCM_BMAC_VARS_APPEND
2290 /* 43236 use defaultsromvars_43236usb as the base,
2291 * then append and update it with the content from OTP.
2292 * Only revision/board specfic content or updates used to override
2293 * the driver default will be stored in OTP
2295 *count
-= (strlen(vstr_end
) + 1 + 1); /* back off the termnating END\0\0 from fakenvram */
2296 bcopy(*vars
, base
, *count
);
2298 #endif /* BCM_BMAC_VARS_APPEND */
2300 for (cisnum
= 0; cisnum
< ciscnt
; cisnum
++) {
2304 standard_cis
= TRUE
;
2308 if (tup
== CISTPL_NULL
|| tup
== CISTPL_END
)
2313 if (cis
[i
] == CISTPL_NULL
|| cis
[i
] == CISTPL_END
) {
2318 tup
= CISTPL_BRCM_HNBU
;
2322 if ((i
+ tlen
) >= CIS_SIZE
)
2327 /* assume the strings are good if the version field checks out */
2328 if (((cis
[i
+ 1] << 8) + cis
[i
]) >= 0x0008) {
2329 varbuf_append(&b
, vstr_manf
, &cis
[i
+ 2]);
2330 varbuf_append(&b
, vstr_productname
,
2331 &cis
[i
+ 3 + strlen((char *)&cis
[i
+ 2])]);
2336 varbuf_append(&b
, vstr_manfid
, (cis
[i
+ 1] << 8) + cis
[i
]);
2337 varbuf_append(&b
, vstr_prodid
, (cis
[i
+ 3] << 8) + cis
[i
+ 2]);
2346 case CISTPL_FID_SDIO
:
2350 /* set macaddr if HNBU_MACADDR not seen yet */
2351 if (eabuf
[0] == '\0' && cis
[i
] == LAN_NID
&&
2352 !(ETHER_ISNULLADDR(&cis
[i
+ 2])) &&
2353 !(ETHER_ISMULTI(&cis
[i
+ 2]))) {
2354 ASSERT(cis
[i
+ 1] == ETHER_ADDR_LEN
);
2355 bcm_ether_ntoa((struct ether_addr
*)&cis
[i
+ 2],
2358 /* set boardnum if HNBU_BOARDNUM not seen yet */
2360 boardnum
= (cis
[i
+ 6] << 8) + cis
[i
+ 7];
2366 case CISTPL_CFTABLE
:
2367 varbuf_append(&b
, vstr_regwindowsz
, (cis
[i
+ 7] << 8) | cis
[i
+ 6]);
2370 case CISTPL_BRCM_HNBU
:
2373 sromrev
= cis
[i
+ 1];
2374 varbuf_append(&b
, vstr_sromrev
, sromrev
);
2378 varbuf_append(&b
, vstr_xtalfreq
,
2379 (cis
[i
+ 4] << 24) |
2380 (cis
[i
+ 3] << 16) |
2386 varbuf_append(&b
, vstr_vendid
, (cis
[i
+ 2] << 8) +
2388 varbuf_append(&b
, vstr_devid
, (cis
[i
+ 4] << 8) +
2391 varbuf_append(&b
, vstr_chiprev
,
2392 (cis
[i
+ 6] << 8) + cis
[i
+ 5]);
2395 varbuf_append(&b
, vstr_subvendid
,
2396 (cis
[i
+ 8] << 8) + cis
[i
+ 7]);
2399 varbuf_append(&b
, vstr_subdevid
,
2400 (cis
[i
+ 10] << 8) + cis
[i
+ 9]);
2401 /* subdevid doubles for boardtype */
2402 varbuf_append(&b
, vstr_boardtype
,
2403 (cis
[i
+ 10] << 8) + cis
[i
+ 9]);
2408 boardnum
= (cis
[i
+ 2] << 8) + cis
[i
+ 1];
2413 char vstr_paddr
[16];
2414 char vstr_pdata
[16];
2416 /* retrieve the patch pairs
2417 * from tlen/6; where 6 is
2418 * sizeof(patch addr(2)) +
2419 * sizeof(patch data(4)).
2421 patch_pair
= tlen
/6;
2423 for (j
= 0; j
< patch_pair
; j
++) {
2424 snprintf(vstr_paddr
, sizeof(vstr_paddr
),
2426 snprintf(vstr_pdata
, sizeof(vstr_pdata
),
2429 varbuf_append(&b
, vstr_paddr
,
2430 (cis
[i
+ (j
*6) + 2] << 8) |
2431 cis
[i
+ (j
*6) + 1]);
2433 varbuf_append(&b
, vstr_pdata
,
2434 (cis
[i
+ (j
*6) + 6] << 24) |
2435 (cis
[i
+ (j
*6) + 5] << 16) |
2436 (cis
[i
+ (j
*6) + 4] << 8) |
2437 cis
[i
+ (j
*6) + 3]);
2444 varbuf_append(&b
, vstr_boardrev
, cis
[i
+ 1]);
2446 varbuf_append(&b
, vstr_boardrev
,
2447 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
2450 case HNBU_BOARDFLAGS
:
2451 w32
= (cis
[i
+ 2] << 8) + cis
[i
+ 1];
2453 w32
|= ((cis
[i
+ 4] << 24) + (cis
[i
+ 3] << 16));
2454 varbuf_append(&b
, vstr_boardflags
, w32
);
2457 w32
= (cis
[i
+ 6] << 8) + cis
[i
+ 5];
2459 w32
|= ((cis
[i
+ 8] << 24) +
2460 (cis
[i
+ 7] << 16));
2461 varbuf_append(&b
, vstr_boardflags2
, w32
);
2464 w32
= (cis
[i
+ 10] << 8) + cis
[i
+ 9];
2466 w32
|= ((cis
[i
+ 12] << 24) +
2467 (cis
[i
+ 11] << 16));
2468 varbuf_append(&b
, vstr_boardflags3
, w32
);
2473 varbuf_append(&b
, vstr_usbfs
, cis
[i
+ 1]);
2476 case HNBU_BOARDTYPE
:
2477 varbuf_append(&b
, vstr_boardtype
,
2478 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
2483 * what follows is a nonstandard HNBU CIS
2484 * that lacks CISTPL_BRCM_HNBU tags
2486 * skip 0xff (end of standard CIS)
2490 standard_cis
= FALSE
;
2494 varbuf_append(&b
, vstr_usbepnum
,
2495 (cis
[i
+ 2] << 8) | cis
[i
+ 1]);
2498 case HNBU_PATCH_AUTOINC
: {
2499 char vstr_paddr
[16];
2500 char vstr_pdata
[16];
2504 addr_inc
= (cis
[i
+ 4] << 24) |
2505 (cis
[i
+ 3] << 16) |
2509 pcnt
= (tlen
- 5)/4;
2510 for (j
= 0; j
< pcnt
; j
++) {
2511 snprintf(vstr_paddr
, sizeof(vstr_paddr
),
2512 "pa%d=0x%%x", j
+ patch_pair
);
2513 snprintf(vstr_pdata
, sizeof(vstr_pdata
),
2514 "pd%d=0x%%x", j
+ patch_pair
);
2516 varbuf_append(&b
, vstr_paddr
, addr_inc
);
2517 varbuf_append(&b
, vstr_pdata
,
2518 (cis
[i
+ (j
*4) + 8] << 24) |
2519 (cis
[i
+ (j
*4) + 7] << 16) |
2520 (cis
[i
+ (j
*4) + 6] << 8) |
2521 cis
[i
+ (j
*4) + 5]);
2529 char vstr_paddr
[16];
2530 char vstr_pdata
[16];
2532 /* retrieve the patch pairs
2533 * from tlen/8; where 8 is
2534 * sizeof(patch addr(4)) +
2535 * sizeof(patch data(4)).
2537 patch_pair
= tlen
/8;
2539 for (j
= 0; j
< patch_pair
; j
++) {
2540 snprintf(vstr_paddr
, sizeof(vstr_paddr
),
2542 snprintf(vstr_pdata
, sizeof(vstr_pdata
),
2545 varbuf_append(&b
, vstr_paddr
,
2546 (cis
[i
+ (j
*8) + 4] << 24) |
2547 (cis
[i
+ (j
*8) + 3] << 16) |
2548 (cis
[i
+ (j
*8) + 2] << 8) |
2549 cis
[i
+ (j
*8) + 1]);
2551 varbuf_append(&b
, vstr_pdata
,
2552 (cis
[i
+ (j
*8) + 8] << 24) |
2553 (cis
[i
+ (j
*8) + 7] << 16) |
2554 (cis
[i
+ (j
*8) + 6] << 8) |
2555 cis
[i
+ (j
*8) + 5]);
2560 varbuf_append(&b
, vstr_usbflags
,
2561 (cis
[i
+ 4] << 24) |
2562 (cis
[i
+ 3] << 16) |
2566 #ifdef BCM_BOOTLOADER
2567 case HNBU_MDIOEX_REGLIST
:
2568 case HNBU_MDIO_REGLIST
: {
2569 /* Format: addr (8 bits) | val (16 bits) */
2570 const uint8 msize
= 3;
2572 const char *mdiodesc
;
2575 mdiodesc
= (cis
[i
] == HNBU_MDIO_REGLIST
) ?
2576 vstr_mdio
: vstr_mdioex
;
2578 ASSERT(((tlen
- 1) % msize
) == 0);
2580 st
= &cis
[i
+ 1]; /* start of reg list */
2581 for (j
= 0; j
< (tlen
- 1); j
+= msize
, st
+= msize
) {
2582 snprintf(mdiostr
, sizeof(mdiostr
),
2584 varbuf_append(&b
, mdiostr
, (st
[2] << 8) | st
[1]);
2589 varbuf_append(&b
, vstr_brmin
,
2590 (cis
[i
+ 4] << 24) |
2591 (cis
[i
+ 3] << 16) |
2597 varbuf_append(&b
, vstr_brmax
,
2598 (cis
[i
+ 4] << 24) |
2599 (cis
[i
+ 3] << 16) |
2603 #endif /* BCM_BOOTLOADER */
2606 varbuf_append(&b
, vstr_rdlid
,
2607 (cis
[i
+ 2] << 8) | cis
[i
+ 1]);
2614 * |len| <== variable, multiple of 5
2615 * |tup| <== tupletype
2616 * |ccreg_ix0|<== ix of ccreg [1byte]
2617 * |ccreg_val0|<= corr value [4bytes]
2619 * Multiple registers are possible. for eg: we
2620 * can specify reg_ix3val3 and reg_ix5val5, etc
2622 char vstr_gci_ccreg_entry
[16];
2623 int num_entries
= 0;
2625 /* retrieve the index-value pairs
2626 * from tlen/5; where 5 is
2627 * sizeof(ccreg_ix(1)) +
2628 * sizeof(ccreg_val(4)).
2630 num_entries
= tlen
/5;
2632 for (j
= 0; j
< num_entries
; j
++) {
2633 snprintf(vstr_gci_ccreg_entry
,
2634 sizeof(vstr_gci_ccreg_entry
),
2635 "gcr%d=0x%%x", cis
[i
+ (j
*5) + 1]);
2637 varbuf_append(&b
, vstr_gci_ccreg_entry
,
2638 (cis
[i
+ (j
*5) + 5] << 24) |
2639 (cis
[i
+ (j
*5) + 4] << 16) |
2640 (cis
[i
+ (j
*5) + 3] << 8) |
2641 cis
[i
+ (j
*5) + 2]);
2646 #ifdef BCM_BOOTLOADER
2648 varbuf_append(&b
, vstr_rdlrndis
, cis
[i
+ 1]);
2652 varbuf_append(&b
, vstr_rdlrwu
, cis
[i
+ 1]);
2657 varbuf_append(&b
, vstr_rdlsn
,
2658 (cis
[i
+ 4] << 24) |
2659 (cis
[i
+ 3] << 16) |
2663 varbuf_append(&b
, vstr_rdlsn
,
2670 uint8 offset
= 1, mode_addr
, mode
, addr
;
2674 mode_addr
= cis
[i
+offset
];
2676 mode
= (mode_addr
& PMUREGS_MODE_MASK
)
2677 >> PMUREGS_MODE_SHIFT
;
2678 addr
= mode_addr
& PMUREGS_ADDR_MASK
;
2681 case PMU_PLLREG_MODE
:
2684 case PMU_CCREG_MODE
:
2687 case PMU_VOLTREG_MODE
:
2690 case PMU_RES_TIME_MODE
:
2693 case PMU_RESDEPEND_MODE
:
2702 varbuf_append(&b
, fmt
, addr
,
2703 (cis
[i
+ offset
+ 4] << 24) |
2704 (cis
[i
+ offset
+ 3] << 16) |
2705 (cis
[i
+ offset
+ 2] << 8) |
2706 cis
[i
+ offset
+ 1]);
2709 offset
+= PMUREGS_TPL_SIZE
;
2710 } while (offset
< tlen
);
2716 uint8 offset
= 1, usb_reg
;
2720 usb_reg
= cis
[i
+offset
];
2723 case USB_DEV_CTRL_REG
:
2724 fmt
= vstr_usbdevctrl
;
2726 case HSIC_PHY_CTRL1_REG
:
2727 fmt
= vstr_hsicphyctrl1
;
2729 case HSIC_PHY_CTRL2_REG
:
2730 fmt
= vstr_hsicphyctrl2
;
2738 varbuf_append(&b
, fmt
,
2739 (cis
[i
+ offset
+ 4] << 24) |
2740 (cis
[i
+ offset
+ 3] << 16) |
2741 (cis
[i
+ offset
+ 2] << 8) |
2742 cis
[i
+ offset
+ 1]);
2745 offset
+= USBREGS_TPL_SIZE
;
2746 } while (offset
< tlen
);
2751 /* The first byte of this tuple indicate if the host
2752 * needs to be informed about the readiness of
2753 * the HSIC/USB for enumeration on which GPIO should
2754 * the device assert this event.
2756 varbuf_append(&b
, vstr_usbrdy
, cis
[i
+ 1]);
2758 /* The following fields in this OTP are optional.
2759 * The remaining bytes will indicate the delay required
2760 * before and/or after the ch_init(). The delay is defined
2761 * using 16-bits of this the MSB(bit15 of 15:0) will be
2762 * used indicate if the parameter is for Pre or Post delay.
2764 for (j
= 2; j
< USBRDY_MAXOTP_SIZE
&& j
< tlen
;
2768 usb_delay
= cis
[i
+ j
] | (cis
[i
+ j
+ 1] << 8);
2770 /* The bit-15 of the delay field will indicate the
2771 * type of delay (pre or post).
2773 if (usb_delay
& USBRDY_DLY_TYPE
) {
2774 varbuf_append(&b
, vstr_usbpostdly
,
2775 (usb_delay
& USBRDY_DLY_MASK
));
2777 varbuf_append(&b
, vstr_usbpredly
,
2778 (usb_delay
& USBRDY_DLY_MASK
));
2783 case HNBU_BLDR_TIMEOUT
:
2784 /* The Delay after USBConnect for timeout till dongle
2785 * receives get_descriptor request.
2787 varbuf_append(&b
, vstr_bldr_reset_timeout
,
2788 (cis
[i
+ 1] | (cis
[i
+ 2] << 8)));
2791 varbuf_append(&b
, vstr_muxenab
, cis
[i
+ 1]);
2794 /* The public key is in binary format in OTP,
2795 * convert to string format before appending
2797 * public key(12 bytes) + crc (1byte) = 129
2800 unsigned char a
[300];
2803 for (k
= 1, j
= 0; k
< 129; k
++)
2804 j
+= sprintf((char *)(a
+ j
), "%02x",
2809 varbuf_append(&b
, vstr_pubkey
, a
);
2814 varbuf_append(&b
, vstr_aa2g
, cis
[i
+ 1]);
2816 varbuf_append(&b
, vstr_aa5g
, cis
[i
+ 2]);
2820 varbuf_append(&b
, vstr_ag
, 0, cis
[i
+ 1]);
2822 varbuf_append(&b
, vstr_ag
, 1, cis
[i
+ 2]);
2824 varbuf_append(&b
, vstr_ag
, 2, cis
[i
+ 3]);
2826 varbuf_append(&b
, vstr_ag
, 3, cis
[i
+ 4]);
2831 varbuf_append(&b
, vstr_aa5g
, cis
[i
+ 1]);
2832 varbuf_append(&b
, vstr_ag
, 1, cis
[i
+ 2]);
2836 ASSERT(sromrev
== 1);
2837 varbuf_append(&b
, vstr_cc
, cis
[i
+ 1]);
2843 ASSERT(sromrev
== 1);
2844 varbuf_append(&b
, vstr_pa0maxpwr
, cis
[i
+ 1]);
2847 ASSERT(sromrev
>= 2);
2848 varbuf_append(&b
, vstr_opo
, cis
[i
+ 9]);
2851 varbuf_append(&b
, vstr_pa0maxpwr
, cis
[i
+ 8]);
2854 varbuf_append(&b
, vstr_pa0itssit
, cis
[i
+ 7]);
2857 for (j
= 0; j
< 3; j
++) {
2858 varbuf_append(&b
, vstr_pa0b
[j
],
2859 (cis
[i
+ (j
* 2) + 2] << 8) +
2860 cis
[i
+ (j
* 2) + 1]);
2864 ASSERT((tlen
== 2) || (tlen
== 9) || (tlen
== 10));
2869 case HNBU_PAPARMS5G
:
2870 ASSERT((sromrev
== 2) || (sromrev
== 3));
2873 varbuf_append(&b
, vstr_pa1himaxpwr
, cis
[i
+ 22]);
2874 varbuf_append(&b
, vstr_pa1lomaxpwr
, cis
[i
+ 21]);
2875 varbuf_append(&b
, vstr_pa1maxpwr
, cis
[i
+ 20]);
2878 varbuf_append(&b
, vstr_pa1itssit
, cis
[i
+ 19]);
2881 for (j
= 0; j
< 3; j
++) {
2882 varbuf_append(&b
, vstr_pa1b
[j
],
2883 (cis
[i
+ (j
* 2) + 2] << 8) +
2884 cis
[i
+ (j
* 2) + 1]);
2886 for (j
= 3; j
< 6; j
++) {
2887 varbuf_append(&b
, vstr_pa1lob
[j
- 3],
2888 (cis
[i
+ (j
* 2) + 2] << 8) +
2889 cis
[i
+ (j
* 2) + 1]);
2891 for (j
= 6; j
< 9; j
++) {
2892 varbuf_append(&b
, vstr_pa1hib
[j
- 6],
2893 (cis
[i
+ (j
* 2) + 2] << 8) +
2894 cis
[i
+ (j
* 2) + 1]);
2898 ASSERT((tlen
== 19) ||
2899 (tlen
== 20) || (tlen
== 23));
2905 ASSERT(sromrev
== 1);
2906 varbuf_append(&b
, vstr_oem
,
2907 cis
[i
+ 1], cis
[i
+ 2],
2908 cis
[i
+ 3], cis
[i
+ 4],
2909 cis
[i
+ 5], cis
[i
+ 6],
2910 cis
[i
+ 7], cis
[i
+ 8]);
2914 for (j
= 1; j
<= 4; j
++) {
2915 if (cis
[i
+ j
] != 0xff) {
2916 varbuf_append(&b
, vstr_ledbh
, j
-1,
2920 if (tlen
< 13) break;
2922 for (j
= 5; j
<= 12; j
++) {
2923 if (cis
[i
+ j
] != 0xff) {
2924 varbuf_append(&b
, vstr_ledbh
, j
-1,
2931 ASSERT(sromrev
> 1);
2932 if ((cis
[i
+ 1] == 0) || (cis
[i
+ 2] == 0))
2933 varbuf_append(&b
, vstr_noccode
);
2935 varbuf_append(&b
, vstr_ccode
,
2936 cis
[i
+ 1], cis
[i
+ 2]);
2937 varbuf_append(&b
, vstr_cctl
, cis
[i
+ 3]);
2941 ASSERT(sromrev
> 2);
2942 varbuf_append(&b
, vstr_cckpo
,
2943 (cis
[i
+ 2] << 8) | cis
[i
+ 1]);
2947 ASSERT(sromrev
> 2);
2948 varbuf_append(&b
, vstr_ofdmpo
,
2949 (cis
[i
+ 4] << 24) |
2950 (cis
[i
+ 3] << 16) |
2956 varbuf_append(&b
, vstr_wpsgpio
, cis
[i
+ 1]);
2958 varbuf_append(&b
, vstr_wpsled
, cis
[i
+ 2]);
2961 case HNBU_RSSISMBXA2G
:
2962 ASSERT(sromrev
== 3);
2963 varbuf_append(&b
, vstr_rssismf2g
, cis
[i
+ 1] & 0xf);
2964 varbuf_append(&b
, vstr_rssismc2g
, (cis
[i
+ 1] >> 4) & 0xf);
2965 varbuf_append(&b
, vstr_rssisav2g
, cis
[i
+ 2] & 0x7);
2966 varbuf_append(&b
, vstr_bxa2g
, (cis
[i
+ 2] >> 3) & 0x3);
2969 case HNBU_RSSISMBXA5G
:
2970 ASSERT(sromrev
== 3);
2971 varbuf_append(&b
, vstr_rssismf5g
, cis
[i
+ 1] & 0xf);
2972 varbuf_append(&b
, vstr_rssismc5g
, (cis
[i
+ 1] >> 4) & 0xf);
2973 varbuf_append(&b
, vstr_rssisav5g
, cis
[i
+ 2] & 0x7);
2974 varbuf_append(&b
, vstr_bxa5g
, (cis
[i
+ 2] >> 3) & 0x3);
2978 ASSERT(sromrev
== 3);
2979 varbuf_append(&b
, vstr_tri2g
, cis
[i
+ 1]);
2983 ASSERT(sromrev
== 3);
2984 varbuf_append(&b
, vstr_tri5gl
, cis
[i
+ 1]);
2985 varbuf_append(&b
, vstr_tri5g
, cis
[i
+ 2]);
2986 varbuf_append(&b
, vstr_tri5gh
, cis
[i
+ 3]);
2990 ASSERT(sromrev
== 3);
2991 varbuf_append(&b
, vstr_rxpo2g
, cis
[i
+ 1]);
2995 ASSERT(sromrev
== 3);
2996 varbuf_append(&b
, vstr_rxpo5g
, cis
[i
+ 1]);
3000 if (!(ETHER_ISNULLADDR(&cis
[i
+1])) &&
3001 !(ETHER_ISMULTI(&cis
[i
+1]))) {
3002 bcm_ether_ntoa((struct ether_addr
*)&cis
[i
+ 1],
3005 /* set boardnum if HNBU_BOARDNUM not seen yet */
3007 boardnum
= (cis
[i
+ 5] << 8) + cis
[i
+ 6];
3012 /* CIS leddc only has 16bits, convert it to 32bits */
3013 w32
= ((cis
[i
+ 2] << 24) | /* oncount */
3014 (cis
[i
+ 1] << 8)); /* offcount */
3015 varbuf_append(&b
, vstr_leddc
, w32
);
3018 case HNBU_CHAINSWITCH
:
3019 varbuf_append(&b
, vstr_txchain
, cis
[i
+ 1]);
3020 varbuf_append(&b
, vstr_rxchain
, cis
[i
+ 2]);
3021 varbuf_append(&b
, vstr_antswitch
,
3022 (cis
[i
+ 4] << 8) + cis
[i
+ 3]);
3026 varbuf_append(&b
, vstr_elna2g
, cis
[i
+ 1]);
3030 varbuf_append(&b
, vstr_elna5g
, cis
[i
+ 1]);
3034 varbuf_append(&b
, vstr_regrev
, cis
[i
+ 1]);
3038 uint16 fem
= (cis
[i
+ 2] << 8) + cis
[i
+ 1];
3039 varbuf_append(&b
, vstr_antswctl2g
, (fem
&
3040 SROM8_FEM_ANTSWLUT_MASK
) >>
3041 SROM8_FEM_ANTSWLUT_SHIFT
);
3042 varbuf_append(&b
, vstr_triso2g
, (fem
&
3043 SROM8_FEM_TR_ISO_MASK
) >>
3044 SROM8_FEM_TR_ISO_SHIFT
);
3045 varbuf_append(&b
, vstr_pdetrange2g
, (fem
&
3046 SROM8_FEM_PDET_RANGE_MASK
) >>
3047 SROM8_FEM_PDET_RANGE_SHIFT
);
3048 varbuf_append(&b
, vstr_extpagain2g
, (fem
&
3049 SROM8_FEM_EXTPA_GAIN_MASK
) >>
3050 SROM8_FEM_EXTPA_GAIN_SHIFT
);
3051 varbuf_append(&b
, vstr_tssipos2g
, (fem
&
3052 SROM8_FEM_TSSIPOS_MASK
) >>
3053 SROM8_FEM_TSSIPOS_SHIFT
);
3054 if (tlen
< 5) break;
3056 fem
= (cis
[i
+ 4] << 8) + cis
[i
+ 3];
3057 varbuf_append(&b
, vstr_antswctl5g
, (fem
&
3058 SROM8_FEM_ANTSWLUT_MASK
) >>
3059 SROM8_FEM_ANTSWLUT_SHIFT
);
3060 varbuf_append(&b
, vstr_triso5g
, (fem
&
3061 SROM8_FEM_TR_ISO_MASK
) >>
3062 SROM8_FEM_TR_ISO_SHIFT
);
3063 varbuf_append(&b
, vstr_pdetrange5g
, (fem
&
3064 SROM8_FEM_PDET_RANGE_MASK
) >>
3065 SROM8_FEM_PDET_RANGE_SHIFT
);
3066 varbuf_append(&b
, vstr_extpagain5g
, (fem
&
3067 SROM8_FEM_EXTPA_GAIN_MASK
) >>
3068 SROM8_FEM_EXTPA_GAIN_SHIFT
);
3069 varbuf_append(&b
, vstr_tssipos5g
, (fem
&
3070 SROM8_FEM_TSSIPOS_MASK
) >>
3071 SROM8_FEM_TSSIPOS_SHIFT
);
3075 case HNBU_PAPARMS_C0
:
3076 varbuf_append(&b
, vstr_maxp2ga
, 0, cis
[i
+ 1]);
3077 varbuf_append(&b
, vstr_itt2ga0
, cis
[i
+ 2]);
3078 varbuf_append(&b
, vstr_pa
, 2, 0, 0,
3079 (cis
[i
+ 4] << 8) + cis
[i
+ 3]);
3080 varbuf_append(&b
, vstr_pa
, 2, 1, 0,
3081 (cis
[i
+ 6] << 8) + cis
[i
+ 5]);
3082 varbuf_append(&b
, vstr_pa
, 2, 2, 0,
3083 (cis
[i
+ 8] << 8) + cis
[i
+ 7]);
3084 if (tlen
< 31) break;
3086 varbuf_append(&b
, vstr_maxp5ga0
, cis
[i
+ 9]);
3087 varbuf_append(&b
, vstr_itt5ga0
, cis
[i
+ 10]);
3088 varbuf_append(&b
, vstr_maxp5gha0
, cis
[i
+ 11]);
3089 varbuf_append(&b
, vstr_maxp5gla0
, cis
[i
+ 12]);
3090 varbuf_append(&b
, vstr_pa
, 5, 0, 0,
3091 (cis
[i
+ 14] << 8) + cis
[i
+ 13]);
3092 varbuf_append(&b
, vstr_pa
, 5, 1, 0,
3093 (cis
[i
+ 16] << 8) + cis
[i
+ 15]);
3094 varbuf_append(&b
, vstr_pa
, 5, 2, 0,
3095 (cis
[i
+ 18] << 8) + cis
[i
+ 17]);
3096 varbuf_append(&b
, vstr_pahl
, 5, 'l', 0, 0,
3097 (cis
[i
+ 20] << 8) + cis
[i
+ 19]);
3098 varbuf_append(&b
, vstr_pahl
, 5, 'l', 1, 0,
3099 (cis
[i
+ 22] << 8) + cis
[i
+ 21]);
3100 varbuf_append(&b
, vstr_pahl
, 5, 'l', 2, 0,
3101 (cis
[i
+ 24] << 8) + cis
[i
+ 23]);
3102 varbuf_append(&b
, vstr_pahl
, 5, 'h', 0, 0,
3103 (cis
[i
+ 26] << 8) + cis
[i
+ 25]);
3104 varbuf_append(&b
, vstr_pahl
, 5, 'h', 1, 0,
3105 (cis
[i
+ 28] << 8) + cis
[i
+ 27]);
3106 varbuf_append(&b
, vstr_pahl
, 5, 'h', 2, 0,
3107 (cis
[i
+ 30] << 8) + cis
[i
+ 29]);
3110 case HNBU_PAPARMS_C1
:
3111 varbuf_append(&b
, vstr_maxp2ga
, 1, cis
[i
+ 1]);
3112 varbuf_append(&b
, vstr_itt2ga1
, cis
[i
+ 2]);
3113 varbuf_append(&b
, vstr_pa
, 2, 0, 1,
3114 (cis
[i
+ 4] << 8) + cis
[i
+ 3]);
3115 varbuf_append(&b
, vstr_pa
, 2, 1, 1,
3116 (cis
[i
+ 6] << 8) + cis
[i
+ 5]);
3117 varbuf_append(&b
, vstr_pa
, 2, 2, 1,
3118 (cis
[i
+ 8] << 8) + cis
[i
+ 7]);
3119 if (tlen
< 31) break;
3121 varbuf_append(&b
, vstr_maxp5ga1
, cis
[i
+ 9]);
3122 varbuf_append(&b
, vstr_itt5ga1
, cis
[i
+ 10]);
3123 varbuf_append(&b
, vstr_maxp5gha1
, cis
[i
+ 11]);
3124 varbuf_append(&b
, vstr_maxp5gla1
, cis
[i
+ 12]);
3125 varbuf_append(&b
, vstr_pa
, 5, 0, 1,
3126 (cis
[i
+ 14] << 8) + cis
[i
+ 13]);
3127 varbuf_append(&b
, vstr_pa
, 5, 1, 1,
3128 (cis
[i
+ 16] << 8) + cis
[i
+ 15]);
3129 varbuf_append(&b
, vstr_pa
, 5, 2, 1,
3130 (cis
[i
+ 18] << 8) + cis
[i
+ 17]);
3131 varbuf_append(&b
, vstr_pahl
, 5, 'l', 0, 1,
3132 (cis
[i
+ 20] << 8) + cis
[i
+ 19]);
3133 varbuf_append(&b
, vstr_pahl
, 5, 'l', 1, 1,
3134 (cis
[i
+ 22] << 8) + cis
[i
+ 21]);
3135 varbuf_append(&b
, vstr_pahl
, 5, 'l', 2, 1,
3136 (cis
[i
+ 24] << 8) + cis
[i
+ 23]);
3137 varbuf_append(&b
, vstr_pahl
, 5, 'h', 0, 1,
3138 (cis
[i
+ 26] << 8) + cis
[i
+ 25]);
3139 varbuf_append(&b
, vstr_pahl
, 5, 'h', 1, 1,
3140 (cis
[i
+ 28] << 8) + cis
[i
+ 27]);
3141 varbuf_append(&b
, vstr_pahl
, 5, 'h', 2, 1,
3142 (cis
[i
+ 30] << 8) + cis
[i
+ 29]);
3145 case HNBU_PO_CCKOFDM
:
3146 varbuf_append(&b
, vstr_cck2gpo
,
3147 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
3148 varbuf_append(&b
, vstr_ofdm2gpo
,
3149 (cis
[i
+ 6] << 24) + (cis
[i
+ 5] << 16) +
3150 (cis
[i
+ 4] << 8) + cis
[i
+ 3]);
3151 if (tlen
< 19) break;
3153 varbuf_append(&b
, vstr_ofdm5gpo
,
3154 (cis
[i
+ 10] << 24) + (cis
[i
+ 9] << 16) +
3155 (cis
[i
+ 8] << 8) + cis
[i
+ 7]);
3156 varbuf_append(&b
, vstr_ofdm5glpo
,
3157 (cis
[i
+ 14] << 24) + (cis
[i
+ 13] << 16) +
3158 (cis
[i
+ 12] << 8) + cis
[i
+ 11]);
3159 varbuf_append(&b
, vstr_ofdm5ghpo
,
3160 (cis
[i
+ 18] << 24) + (cis
[i
+ 17] << 16) +
3161 (cis
[i
+ 16] << 8) + cis
[i
+ 15]);
3165 for (j
= 0; j
<= (tlen
/2); j
++) {
3166 varbuf_append(&b
, vstr_mcspo
, 2, j
,
3167 (cis
[i
+ 2 + 2*j
] << 8) + cis
[i
+ 1 + 2*j
]);
3171 case HNBU_PO_MCS5GM
:
3172 for (j
= 0; j
<= (tlen
/2); j
++) {
3173 varbuf_append(&b
, vstr_mcspo
, 5, j
,
3174 (cis
[i
+ 2 + 2*j
] << 8) + cis
[i
+ 1 + 2*j
]);
3178 case HNBU_PO_MCS5GLH
:
3179 for (j
= 0; j
<= (tlen
/4); j
++) {
3180 varbuf_append(&b
, vstr_mcspohl
, 5, 'l', j
,
3181 (cis
[i
+ 2 + 2*j
] << 8) + cis
[i
+ 1 + 2*j
]);
3184 for (j
= 0; j
<= (tlen
/4); j
++) {
3185 varbuf_append(&b
, vstr_mcspohl
, 5, 'h', j
,
3186 (cis
[i
+ ((tlen
/2)+2) + 2*j
] << 8) +
3187 cis
[i
+ ((tlen
/2)+1) + 2*j
]);
3193 varbuf_append(&b
, vstr_cddpo
,
3194 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
3198 varbuf_append(&b
, vstr_stbcpo
,
3199 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
3203 varbuf_append(&b
, vstr_bw40po
,
3204 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
3207 case HNBU_PO_40MDUP
:
3208 varbuf_append(&b
, vstr_bwduppo
,
3209 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
3213 varbuf_append(&b
, vstr_ofdm5gpo
,
3214 (cis
[i
+ 4] << 24) + (cis
[i
+ 3] << 16) +
3215 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
3216 varbuf_append(&b
, vstr_ofdm5glpo
,
3217 (cis
[i
+ 8] << 24) + (cis
[i
+ 7] << 16) +
3218 (cis
[i
+ 6] << 8) + cis
[i
+ 5]);
3219 varbuf_append(&b
, vstr_ofdm5ghpo
,
3220 (cis
[i
+ 12] << 24) + (cis
[i
+ 11] << 16) +
3221 (cis
[i
+ 10] << 8) + cis
[i
+ 9]);
3223 /* Power per rate for SROM V9 */
3224 case HNBU_CCKBW202GPO
:
3225 varbuf_append(&b
, vstr_cckbw202gpo
[0],
3226 ((cis
[i
+ 2] << 8) + cis
[i
+ 1]));
3228 varbuf_append(&b
, vstr_cckbw202gpo
[1],
3229 ((cis
[i
+ 4] << 8) + cis
[i
+ 3]));
3232 case HNBU_LEGOFDMBW202GPO
:
3233 varbuf_append(&b
, vstr_legofdmbw202gpo
[0],
3234 ((cis
[i
+ 4] << 24) + (cis
[i
+ 3] << 16) +
3235 (cis
[i
+ 2] << 8) + cis
[i
+ 1]));
3237 varbuf_append(&b
, vstr_legofdmbw202gpo
[1],
3238 ((cis
[i
+ 8] << 24) + (cis
[i
+ 7] << 16) +
3239 (cis
[i
+ 6] << 8) + cis
[i
+ 5]));
3243 case HNBU_LEGOFDMBW205GPO
:
3244 for (j
= 0; j
< 6; j
++) {
3245 if (tlen
< (2 + 4 * j
))
3247 varbuf_append(&b
, vstr_legofdmbw205gpo
[j
],
3248 ((cis
[4 * j
+ i
+ 4] << 24)
3249 + (cis
[4 * j
+ i
+ 3] << 16)
3250 + (cis
[4 * j
+ i
+ 2] << 8)
3251 + cis
[4 * j
+ i
+ 1]));
3256 for (j
= 0; j
< 3; j
++) {
3257 if (tlen
< (2 + 4 * j
))
3259 varbuf_append(&b
, vstr_mcs2gpo
[j
],
3260 ((cis
[4 * j
+ i
+ 4] << 24)
3261 + (cis
[4 * j
+ i
+ 3] << 16)
3262 + (cis
[4 * j
+ i
+ 2] << 8)
3263 + cis
[4 * j
+ i
+ 1]));
3268 for (j
= 0; j
< 3; j
++) {
3269 if (tlen
< (2 + 4 * j
))
3271 varbuf_append(&b
, vstr_mcs5glpo
[j
],
3272 ((cis
[4 * j
+ i
+ 4] << 24)
3273 + (cis
[4 * j
+ i
+ 3] << 16)
3274 + (cis
[4 * j
+ i
+ 2] << 8)
3275 + cis
[4 * j
+ i
+ 1]));
3280 for (j
= 0; j
< 3; j
++) {
3281 if (tlen
< (2 + 4 * j
))
3283 varbuf_append(&b
, vstr_mcs5gmpo
[j
],
3284 ((cis
[4 * j
+ i
+ 4] << 24)
3285 + (cis
[4 * j
+ i
+ 3] << 16)
3286 + (cis
[4 * j
+ i
+ 2] << 8)
3287 + cis
[4 * j
+ i
+ 1]));
3292 for (j
= 0; j
< 3; j
++) {
3293 if (tlen
< (2 + 4 * j
))
3295 varbuf_append(&b
, vstr_mcs5ghpo
[j
],
3296 ((cis
[4 * j
+ i
+ 4] << 24)
3297 + (cis
[4 * j
+ i
+ 3] << 16)
3298 + (cis
[4 * j
+ i
+ 2] << 8)
3299 + cis
[4 * j
+ i
+ 1]));
3304 varbuf_append(&b
, vstr_mcs32po
,
3305 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
3308 case HNBU_LEG40DUPPO
:
3309 varbuf_append(&b
, vstr_legofdm40duppo
,
3310 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
3314 varbuf_append(&b
, vstr_custom
, 1, ((cis
[i
+ 4] << 24) +
3315 (cis
[i
+ 3] << 16) + (cis
[i
+ 2] << 8) +
3319 #if defined(BCMCCISSR3)
3320 case HNBU_SROM3SWRGN
:
3323 uint8 srev
= cis
[i
+ 1 + 70];
3325 /* make tuple value 16-bit aligned and parse it */
3326 bcopy(&cis
[i
+ 1], srom
, sizeof(srom
));
3327 _initvars_srom_pci(srev
, srom
, SROM3_SWRGN_OFF
, &b
);
3328 /* 2.4G antenna gain is included in SROM */
3330 /* Ethernet MAC address is included in SROM */
3334 /* create extra variables */
3336 varbuf_append(&b
, vstr_vendid
,
3337 (cis
[i
+ 1 + 73] << 8) +
3340 varbuf_append(&b
, vstr_devid
,
3341 (cis
[i
+ 1 + 75] << 8) +
3344 varbuf_append(&b
, vstr_xtalfreq
,
3345 (cis
[i
+ 1 + 77] << 8) +
3350 case HNBU_CCKFILTTYPE
:
3351 varbuf_append(&b
, vstr_cckdigfilttype
,
3355 case HNBU_TEMPTHRESH
:
3356 varbuf_append(&b
, vstr_tempthresh
,
3358 /* period in msb nibble */
3359 varbuf_append(&b
, vstr_temps_period
,
3360 (cis
[i
+ 2] & SROM11_TEMPS_PERIOD_MASK
) >>
3361 SROM11_TEMPS_PERIOD_SHIFT
);
3362 /* hysterisis in lsb nibble */
3363 varbuf_append(&b
, vstr_temps_hysteresis
,
3364 (cis
[i
+ 2] & SROM11_TEMPS_HYSTERESIS_MASK
) >>
3365 SROM11_TEMPS_HYSTERESIS_SHIFT
);
3367 varbuf_append(&b
, vstr_tempoffset
,
3369 varbuf_append(&b
, vstr_tempsense_slope
,
3371 varbuf_append(&b
, vstr_temp_corrx
,
3372 (cis
[i
+ 5] & SROM11_TEMPCORRX_MASK
) >>
3373 SROM11_TEMPCORRX_SHIFT
);
3374 varbuf_append(&b
, vstr_tempsense_option
,
3375 (cis
[i
+ 5] & SROM11_TEMPSENSE_OPTION_MASK
) >>
3376 SROM11_TEMPSENSE_OPTION_SHIFT
);
3377 varbuf_append(&b
, vstr_phycal_tempdelta
,
3382 case HNBU_FEM_CFG
: {
3384 uint16 fem_cfg
= (cis
[i
+ 2] << 8) + cis
[i
+ 1];
3385 varbuf_append(&b
, vstr_femctrl
,
3386 (fem_cfg
& SROM11_FEMCTRL_MASK
) >>
3387 SROM11_FEMCTRL_SHIFT
);
3388 varbuf_append(&b
, vstr_papdcap
, 2,
3389 (fem_cfg
& SROM11_PAPDCAP_MASK
) >>
3390 SROM11_PAPDCAP_SHIFT
);
3391 varbuf_append(&b
, vstr_tworangetssi
, 2,
3392 (fem_cfg
& SROM11_TWORANGETSSI_MASK
) >>
3393 SROM11_TWORANGETSSI_SHIFT
);
3394 varbuf_append(&b
, vstr_pdgaing
, 2,
3395 (fem_cfg
& SROM11_PDGAIN_MASK
) >>
3396 SROM11_PDGAIN_SHIFT
);
3397 varbuf_append(&b
, vstr_epagaing
, 2,
3398 (fem_cfg
& SROM11_EPAGAIN_MASK
) >>
3399 SROM11_EPAGAIN_SHIFT
);
3400 varbuf_append(&b
, vstr_tssiposslopeg
, 2,
3401 (fem_cfg
& SROM11_TSSIPOSSLOPE_MASK
) >>
3402 SROM11_TSSIPOSSLOPE_SHIFT
);
3404 fem_cfg
= (cis
[i
+ 4] << 8) + cis
[i
+ 3];
3405 varbuf_append(&b
, vstr_gainctrlsph
,
3406 (fem_cfg
& SROM11_GAINCTRLSPH_MASK
) >>
3407 SROM11_GAINCTRLSPH_SHIFT
);
3408 varbuf_append(&b
, vstr_papdcap
, 5,
3409 (fem_cfg
& SROM11_PAPDCAP_MASK
) >>
3410 SROM11_PAPDCAP_SHIFT
);
3411 varbuf_append(&b
, vstr_tworangetssi
, 5,
3412 (fem_cfg
& SROM11_TWORANGETSSI_MASK
) >>
3413 SROM11_TWORANGETSSI_SHIFT
);
3414 varbuf_append(&b
, vstr_pdgaing
, 5,
3415 (fem_cfg
& SROM11_PDGAIN_MASK
) >>
3416 SROM11_PDGAIN_SHIFT
);
3417 varbuf_append(&b
, vstr_epagaing
, 5,
3418 (fem_cfg
& SROM11_EPAGAIN_MASK
) >>
3419 SROM11_EPAGAIN_SHIFT
);
3420 varbuf_append(&b
, vstr_tssiposslopeg
, 5,
3421 (fem_cfg
& SROM11_TSSIPOSSLOPE_MASK
) >>
3422 SROM11_TSSIPOSSLOPE_SHIFT
);
3430 varbuf_append(&b
, vstr_subband5gver
,
3431 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
3432 varbuf_append(&b
, vstr_maxp2ga
, a
,
3433 (cis
[i
+ 4] << 8) + cis
[i
+ 3]);
3435 varbuf_append(&b
, vstr_pa2ga
, a
,
3436 (cis
[i
+ 6] << 8) + cis
[i
+ 5],
3437 (cis
[i
+ 8] << 8) + cis
[i
+ 7],
3438 (cis
[i
+ 10] << 8) + cis
[i
+ 9]);
3440 varbuf_append(&b
, vstr_maxp5ga
, a
,
3446 varbuf_append(&b
, vstr_pa5ga
, a
,
3447 (cis
[i
+ 16] << 8) + cis
[i
+ 15],
3448 (cis
[i
+ 18] << 8) + cis
[i
+ 17],
3449 (cis
[i
+ 20] << 8) + cis
[i
+ 19],
3450 (cis
[i
+ 22] << 8) + cis
[i
+ 21],
3451 (cis
[i
+ 24] << 8) + cis
[i
+ 23],
3452 (cis
[i
+ 26] << 8) + cis
[i
+ 25],
3453 (cis
[i
+ 28] << 8) + cis
[i
+ 27],
3454 (cis
[i
+ 30] << 8) + cis
[i
+ 29],
3455 (cis
[i
+ 32] << 8) + cis
[i
+ 31],
3456 (cis
[i
+ 34] << 8) + cis
[i
+ 33],
3457 (cis
[i
+ 36] << 8) + cis
[i
+ 35],
3458 (cis
[i
+ 38] << 8) + cis
[i
+ 37]);
3466 varbuf_append(&b
, vstr_maxp2ga
, a
,
3467 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
3469 varbuf_append(&b
, vstr_pa2ga
, a
,
3470 (cis
[i
+ 4] << 8) + cis
[i
+ 3],
3471 (cis
[i
+ 6] << 8) + cis
[i
+ 5],
3472 (cis
[i
+ 8] << 8) + cis
[i
+ 7]);
3474 varbuf_append(&b
, vstr_maxp5ga
, a
,
3480 varbuf_append(&b
, vstr_pa5ga
, a
,
3481 (cis
[i
+ 14] << 8) + cis
[i
+ 13],
3482 (cis
[i
+ 16] << 8) + cis
[i
+ 15],
3483 (cis
[i
+ 18] << 8) + cis
[i
+ 17],
3484 (cis
[i
+ 20] << 8) + cis
[i
+ 19],
3485 (cis
[i
+ 22] << 8) + cis
[i
+ 21],
3486 (cis
[i
+ 24] << 8) + cis
[i
+ 23],
3487 (cis
[i
+ 26] << 8) + cis
[i
+ 25],
3488 (cis
[i
+ 28] << 8) + cis
[i
+ 27],
3489 (cis
[i
+ 30] << 8) + cis
[i
+ 29],
3490 (cis
[i
+ 32] << 8) + cis
[i
+ 31],
3491 (cis
[i
+ 34] << 8) + cis
[i
+ 33],
3492 (cis
[i
+ 36] << 8) + cis
[i
+ 35]);
3500 varbuf_append(&b
, vstr_maxp2ga
, a
,
3501 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
3503 varbuf_append(&b
, vstr_pa2ga
, a
,
3504 (cis
[i
+ 4] << 8) + cis
[i
+ 3],
3505 (cis
[i
+ 6] << 8) + cis
[i
+ 5],
3506 (cis
[i
+ 8] << 8) + cis
[i
+ 7]);
3508 varbuf_append(&b
, vstr_maxp5ga
, a
,
3514 varbuf_append(&b
, vstr_pa5ga
, a
,
3515 (cis
[i
+ 14] << 8) + cis
[i
+ 13],
3516 (cis
[i
+ 16] << 8) + cis
[i
+ 15],
3517 (cis
[i
+ 18] << 8) + cis
[i
+ 17],
3518 (cis
[i
+ 20] << 8) + cis
[i
+ 19],
3519 (cis
[i
+ 22] << 8) + cis
[i
+ 21],
3520 (cis
[i
+ 24] << 8) + cis
[i
+ 23],
3521 (cis
[i
+ 26] << 8) + cis
[i
+ 25],
3522 (cis
[i
+ 28] << 8) + cis
[i
+ 27],
3523 (cis
[i
+ 30] << 8) + cis
[i
+ 29],
3524 (cis
[i
+ 32] << 8) + cis
[i
+ 31],
3525 (cis
[i
+ 34] << 8) + cis
[i
+ 33],
3526 (cis
[i
+ 36] << 8) + cis
[i
+ 35]);
3531 varbuf_append(&b
, vstr_measpower
, cis
[i
+ 1]);
3532 varbuf_append(&b
, vstr_measpowerX
, 1, (cis
[i
+ 2]));
3533 varbuf_append(&b
, vstr_measpowerX
, 2, (cis
[i
+ 3]));
3534 varbuf_append(&b
, vstr_rawtempsense
,
3535 ((cis
[i
+ 5] & 0x1) << 8) + cis
[i
+ 4]);
3539 varbuf_append(&b
, vstr_pdoffsetma
, 40, 0,
3540 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
3541 varbuf_append(&b
, vstr_pdoffsetma
, 40, 1,
3542 (cis
[i
+ 4] << 8) + cis
[i
+ 3]);
3543 varbuf_append(&b
, vstr_pdoffsetma
, 40, 2,
3544 (cis
[i
+ 6] << 8) + cis
[i
+ 5]);
3545 varbuf_append(&b
, vstr_pdoffsetma
, 80, 0,
3546 (cis
[i
+ 8] << 8) + cis
[i
+ 7]);
3547 varbuf_append(&b
, vstr_pdoffsetma
, 80, 1,
3548 (cis
[i
+ 10] << 8) + cis
[i
+ 9]);
3549 varbuf_append(&b
, vstr_pdoffsetma
, 80, 2,
3550 (cis
[i
+ 12] << 8) + cis
[i
+ 11]);
3553 case HNBU_ACPPR_2GPO
:
3554 varbuf_append(&b
, vstr_dot11agofdmhrbw202gpo
,
3555 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
3556 varbuf_append(&b
, vstr_ofdmlrbw202gpo
,
3557 (cis
[i
+ 4] << 8) + cis
[i
+ 3]);
3560 case HNBU_ACPPR_5GPO
:
3561 varbuf_append(&b
, vstr_mcsbw805gpo
, 'l',
3562 (cis
[i
+ 4] << 24) + (cis
[i
+ 3] << 16) +
3563 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
3564 varbuf_append(&b
, vstr_mcsbw1605gpo
, 'l',
3565 (cis
[i
+ 8] << 24) + (cis
[i
+ 7] << 16) +
3566 (cis
[i
+ 6] << 8) + cis
[i
+ 5]);
3567 varbuf_append(&b
, vstr_mcsbw805gpo
, 'm',
3568 (cis
[i
+ 12] << 24) + (cis
[i
+ 11] << 16) +
3569 (cis
[i
+ 10] << 8) + cis
[i
+ 9]);
3570 varbuf_append(&b
, vstr_mcsbw1605gpo
, 'm',
3571 (cis
[i
+ 16] << 24) + (cis
[i
+ 15] << 16) +
3572 (cis
[i
+ 14] << 8) + cis
[i
+ 13]);
3573 varbuf_append(&b
, vstr_mcsbw805gpo
, 'h',
3574 (cis
[i
+ 20] << 24) + (cis
[i
+ 19] << 16) +
3575 (cis
[i
+ 18] << 8) + cis
[i
+ 17]);
3576 varbuf_append(&b
, vstr_mcsbw1605gpo
, 'h',
3577 (cis
[i
+ 24] << 24) + (cis
[i
+ 23] << 16) +
3578 (cis
[i
+ 22] << 8) + cis
[i
+ 21]);
3579 varbuf_append(&b
, vstr_mcslr5gpo
, 'l',
3580 (cis
[i
+ 26] << 8) + cis
[i
+ 25]);
3581 varbuf_append(&b
, vstr_mcslr5gpo
, 'm',
3582 (cis
[i
+ 28] << 8) + cis
[i
+ 27]);
3583 varbuf_append(&b
, vstr_mcslr5gpo
, 'h',
3584 (cis
[i
+ 30] << 8) + cis
[i
+ 29]);
3587 case HNBU_ACPPR_SBPO
:
3588 varbuf_append(&b
, vstr_sb20in40rpo
, 'h',
3589 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
3590 varbuf_append(&b
, vstr_sb20in80and160r5gpo
, 'h', 'l',
3591 (cis
[i
+ 4] << 8) + cis
[i
+ 3]);
3592 varbuf_append(&b
, vstr_sb40and80r5gpo
, 'h', 'l',
3593 (cis
[i
+ 6] << 8) + cis
[i
+ 5]);
3594 varbuf_append(&b
, vstr_sb20in80and160r5gpo
, 'h', 'm',
3595 (cis
[i
+ 8] << 8) + cis
[i
+ 7]);
3596 varbuf_append(&b
, vstr_sb40and80r5gpo
, 'h', 'm',
3597 (cis
[i
+ 10] << 8) + cis
[i
+ 9]);
3598 varbuf_append(&b
, vstr_sb20in80and160r5gpo
, 'h', 'h',
3599 (cis
[i
+ 12] << 8) + cis
[i
+ 11]);
3600 varbuf_append(&b
, vstr_sb40and80r5gpo
, 'h', 'h',
3601 (cis
[i
+ 14] << 8) + cis
[i
+ 13]);
3602 varbuf_append(&b
, vstr_sb20in40rpo
, 'l',
3603 (cis
[i
+ 16] << 8) + cis
[i
+ 15]);
3604 varbuf_append(&b
, vstr_sb20in80and160r5gpo
, 'l', 'l',
3605 (cis
[i
+ 18] << 8) + cis
[i
+ 17]);
3606 varbuf_append(&b
, vstr_sb40and80r5gpo
, 'l', 'l',
3607 (cis
[i
+ 20] << 8) + cis
[i
+ 19]);
3608 varbuf_append(&b
, vstr_sb20in80and160r5gpo
, 'l', 'm',
3609 (cis
[i
+ 22] << 8) + cis
[i
+ 21]);
3610 varbuf_append(&b
, vstr_sb40and80r5gpo
, 'l', 'm',
3611 (cis
[i
+ 24] << 8) + cis
[i
+ 23]);
3612 varbuf_append(&b
, vstr_sb20in80and160r5gpo
, 'l', 'h',
3613 (cis
[i
+ 26] << 8) + cis
[i
+ 25]);
3614 varbuf_append(&b
, vstr_sb40and80r5gpo
, 'l', 'h',
3615 (cis
[i
+ 28] << 8) + cis
[i
+ 27]);
3616 varbuf_append(&b
, vstr_dot11agduprpo
, 'h',
3617 (cis
[i
+ 30] << 8) + cis
[i
+ 24]);
3618 varbuf_append(&b
, vstr_dot11agduprpo
, 'l',
3619 (cis
[i
+ 32] << 8) + cis
[i
+ 26]);
3624 varbuf_append(&b
, vstr_noiselvl2ga
, 0,
3625 (cis
[i
+ 1] & 0x1f));
3626 varbuf_append(&b
, vstr_noiselvl2ga
, 1,
3627 (cis
[i
+ 2] & 0x1f));
3628 varbuf_append(&b
, vstr_noiselvl2ga
, 2,
3629 (cis
[i
+ 3] & 0x1f));
3631 varbuf_append(&b
, vstr_noiselvl5ga
, 0,
3632 (cis
[i
+ 4] & 0x1f),
3633 (cis
[i
+ 5] & 0x1f),
3634 (cis
[i
+ 6] & 0x1f),
3635 (cis
[i
+ 7] & 0x1f));
3636 varbuf_append(&b
, vstr_noiselvl5ga
, 1,
3637 (cis
[i
+ 8] & 0x1f),
3638 (cis
[i
+ 9] & 0x1f),
3639 (cis
[i
+ 10] & 0x1f),
3640 (cis
[i
+ 11] & 0x1f));
3641 varbuf_append(&b
, vstr_noiselvl5ga
, 2,
3642 (cis
[i
+ 12] & 0x1f),
3643 (cis
[i
+ 13] & 0x1f),
3644 (cis
[i
+ 14] & 0x1f),
3645 (cis
[i
+ 15] & 0x1f));
3648 case HNBU_RXGAIN_ERR
:
3649 varbuf_append(&b
, vstr_rxgainerr2ga
, 0,
3650 (cis
[i
+ 1] & 0x3f));
3651 varbuf_append(&b
, vstr_rxgainerr2ga
, 1,
3652 (cis
[i
+ 2] & 0x1f));
3653 varbuf_append(&b
, vstr_rxgainerr2ga
, 2,
3654 (cis
[i
+ 3] & 0x1f));
3655 varbuf_append(&b
, vstr_rxgainerr5ga
, 0,
3656 (cis
[i
+ 4] & 0x3f),
3657 (cis
[i
+ 5] & 0x3f),
3658 (cis
[i
+ 6] & 0x3f),
3659 (cis
[i
+ 7] & 0x3f));
3660 varbuf_append(&b
, vstr_rxgainerr5ga
, 1,
3661 (cis
[i
+ 8] & 0x1f),
3662 (cis
[i
+ 9] & 0x1f),
3663 (cis
[i
+ 10] & 0x1f),
3664 (cis
[i
+ 11] & 0x1f));
3665 varbuf_append(&b
, vstr_rxgainerr5ga
, 2,
3666 (cis
[i
+ 12] & 0x1f),
3667 (cis
[i
+ 13] & 0x1f),
3668 (cis
[i
+ 14] & 0x1f),
3669 (cis
[i
+ 15] & 0x1f));
3673 varbuf_append(&b
, vstr_agbg
, 0, cis
[i
+ 1]);
3674 varbuf_append(&b
, vstr_agbg
, 1, cis
[i
+ 2]);
3675 varbuf_append(&b
, vstr_agbg
, 2, cis
[i
+ 3]);
3676 varbuf_append(&b
, vstr_aga
, 0, cis
[i
+ 4]);
3677 varbuf_append(&b
, vstr_aga
, 1, cis
[i
+ 5]);
3678 varbuf_append(&b
, vstr_aga
, 2, cis
[i
+ 6]);
3681 case HNBU_ACRXGAINS_C0
: {
3685 uint16 rxgains
= (cis
[i
+ 2] << 8) + cis
[i
+ 1];
3686 varbuf_append(&b
, vstr_rxgainsgtrelnabypa
, 5, a
,
3687 (rxgains
& SROM11_RXGAINS5GTRELNABYPA_MASK
) >>
3688 SROM11_RXGAINS5GTRELNABYPA_SHIFT
);
3689 varbuf_append(&b
, vstr_rxgainsgtrisoa
, 5, a
,
3690 (rxgains
& SROM11_RXGAINS5GTRISOA_MASK
) >>
3691 SROM11_RXGAINS5GTRISOA_SHIFT
);
3692 varbuf_append(&b
, vstr_rxgainsgelnagaina
, 5, a
,
3693 (rxgains
& SROM11_RXGAINS5GELNAGAINA_MASK
) >>
3694 SROM11_RXGAINS5GELNAGAINA_SHIFT
);
3695 varbuf_append(&b
, vstr_rxgainsgtrelnabypa
, 2, a
,
3696 (rxgains
& SROM11_RXGAINS2GTRELNABYPA_MASK
) >>
3697 SROM11_RXGAINS2GTRELNABYPA_SHIFT
);
3698 varbuf_append(&b
, vstr_rxgainsgtrisoa
, 2, a
,
3699 (rxgains
& SROM11_RXGAINS2GTRISOA_MASK
) >>
3700 SROM11_RXGAINS2GTRISOA_SHIFT
);
3701 varbuf_append(&b
, vstr_rxgainsgelnagaina
, 2, a
,
3702 (rxgains
& SROM11_RXGAINS2GELNAGAINA_MASK
) >>
3703 SROM11_RXGAINS2GELNAGAINA_SHIFT
);
3705 rxgains
= (cis
[i
+ 4] << 8) + cis
[i
+ 3];
3706 varbuf_append(&b
, vstr_rxgainsgxtrelnabypa
, 5, 'h', a
,
3707 (rxgains
& SROM11_RXGAINS5GTRELNABYPA_MASK
) >>
3708 SROM11_RXGAINS5GTRELNABYPA_SHIFT
);
3709 varbuf_append(&b
, vstr_rxgainsgxtrisoa
, 5, 'h', a
,
3710 (rxgains
& SROM11_RXGAINS5GTRISOA_MASK
) >>
3711 SROM11_RXGAINS5GTRISOA_SHIFT
);
3712 varbuf_append(&b
, vstr_rxgainsgxelnagaina
, 5, 'h', a
,
3713 (rxgains
& SROM11_RXGAINS5GELNAGAINA_MASK
) >>
3714 SROM11_RXGAINS5GELNAGAINA_SHIFT
);
3715 varbuf_append(&b
, vstr_rxgainsgxtrelnabypa
, 5, 'm', a
,
3716 (rxgains
& SROM11_RXGAINS5GTRELNABYPA_MASK
) >>
3717 SROM11_RXGAINS5GTRELNABYPA_SHIFT
);
3718 varbuf_append(&b
, vstr_rxgainsgxtrisoa
, 5, 'm', a
,
3719 (rxgains
& SROM11_RXGAINS5GTRISOA_MASK
) >>
3720 SROM11_RXGAINS5GTRISOA_SHIFT
);
3721 varbuf_append(&b
, vstr_rxgainsgxelnagaina
, 5, 'm', a
,
3722 (rxgains
& SROM11_RXGAINS5GELNAGAINA_MASK
) >>
3723 SROM11_RXGAINS5GELNAGAINA_SHIFT
);
3727 case HNBU_ACRXGAINS_C1
: {
3731 uint16 rxgains
= (cis
[i
+ 2] << 8) + cis
[i
+ 1];
3732 varbuf_append(&b
, vstr_rxgainsgtrelnabypa
, 5, a
,
3733 (rxgains
& SROM11_RXGAINS5GTRELNABYPA_MASK
) >>
3734 SROM11_RXGAINS5GTRELNABYPA_SHIFT
);
3735 varbuf_append(&b
, vstr_rxgainsgtrisoa
, 5, a
,
3736 (rxgains
& SROM11_RXGAINS5GTRISOA_MASK
) >>
3737 SROM11_RXGAINS5GTRISOA_SHIFT
);
3738 varbuf_append(&b
, vstr_rxgainsgelnagaina
, 5, a
,
3739 (rxgains
& SROM11_RXGAINS5GELNAGAINA_MASK
) >>
3740 SROM11_RXGAINS5GELNAGAINA_SHIFT
);
3741 varbuf_append(&b
, vstr_rxgainsgtrelnabypa
, 2, a
,
3742 (rxgains
& SROM11_RXGAINS2GTRELNABYPA_MASK
) >>
3743 SROM11_RXGAINS2GTRELNABYPA_SHIFT
);
3744 varbuf_append(&b
, vstr_rxgainsgtrisoa
, 2, a
,
3745 (rxgains
& SROM11_RXGAINS2GTRISOA_MASK
) >>
3746 SROM11_RXGAINS2GTRISOA_SHIFT
);
3747 varbuf_append(&b
, vstr_rxgainsgelnagaina
, 2, a
,
3748 (rxgains
& SROM11_RXGAINS2GELNAGAINA_MASK
) >>
3749 SROM11_RXGAINS2GELNAGAINA_SHIFT
);
3751 rxgains
= (cis
[i
+ 4] << 8) + cis
[i
+ 3];
3752 varbuf_append(&b
, vstr_rxgainsgxtrelnabypa
, 5, 'h', a
,
3753 (rxgains
& SROM11_RXGAINS5GTRELNABYPA_MASK
) >>
3754 SROM11_RXGAINS5GTRELNABYPA_SHIFT
);
3755 varbuf_append(&b
, vstr_rxgainsgxtrisoa
, 5, 'h', a
,
3756 (rxgains
& SROM11_RXGAINS5GTRISOA_MASK
) >>
3757 SROM11_RXGAINS5GTRISOA_SHIFT
);
3758 varbuf_append(&b
, vstr_rxgainsgxelnagaina
, 5, 'h', a
,
3759 (rxgains
& SROM11_RXGAINS5GELNAGAINA_MASK
) >>
3760 SROM11_RXGAINS5GELNAGAINA_SHIFT
);
3761 varbuf_append(&b
, vstr_rxgainsgxtrelnabypa
, 5, 'm', a
,
3762 (rxgains
& SROM11_RXGAINS5GTRELNABYPA_MASK
) >>
3763 SROM11_RXGAINS5GTRELNABYPA_SHIFT
);
3764 varbuf_append(&b
, vstr_rxgainsgxtrisoa
, 5, 'm', a
,
3765 (rxgains
& SROM11_RXGAINS5GTRISOA_MASK
) >>
3766 SROM11_RXGAINS5GTRISOA_SHIFT
);
3767 varbuf_append(&b
, vstr_rxgainsgxelnagaina
, 5, 'm', a
,
3768 (rxgains
& SROM11_RXGAINS5GELNAGAINA_MASK
) >>
3769 SROM11_RXGAINS5GELNAGAINA_SHIFT
);
3773 case HNBU_ACRXGAINS_C2
: {
3777 uint16 rxgains
= (cis
[i
+ 2] << 8) + cis
[i
+ 1];
3778 varbuf_append(&b
, vstr_rxgainsgtrelnabypa
, 5, a
,
3779 (rxgains
& SROM11_RXGAINS5GTRELNABYPA_MASK
) >>
3780 SROM11_RXGAINS5GTRELNABYPA_SHIFT
);
3781 varbuf_append(&b
, vstr_rxgainsgtrisoa
, 5, a
,
3782 (rxgains
& SROM11_RXGAINS5GTRISOA_MASK
) >>
3783 SROM11_RXGAINS5GTRISOA_SHIFT
);
3784 varbuf_append(&b
, vstr_rxgainsgelnagaina
, 5, a
,
3785 (rxgains
& SROM11_RXGAINS5GELNAGAINA_MASK
) >>
3786 SROM11_RXGAINS5GELNAGAINA_SHIFT
);
3787 varbuf_append(&b
, vstr_rxgainsgtrelnabypa
, 2, a
,
3788 (rxgains
& SROM11_RXGAINS2GTRELNABYPA_MASK
) >>
3789 SROM11_RXGAINS2GTRELNABYPA_SHIFT
);
3790 varbuf_append(&b
, vstr_rxgainsgtrisoa
, 2, a
,
3791 (rxgains
& SROM11_RXGAINS2GTRISOA_MASK
) >>
3792 SROM11_RXGAINS2GTRISOA_SHIFT
);
3793 varbuf_append(&b
, vstr_rxgainsgelnagaina
, 2, a
,
3794 (rxgains
& SROM11_RXGAINS2GELNAGAINA_MASK
) >>
3795 SROM11_RXGAINS2GELNAGAINA_SHIFT
);
3797 rxgains
= (cis
[i
+ 4] << 8) + cis
[i
+ 3];
3798 varbuf_append(&b
, vstr_rxgainsgxtrelnabypa
, 5, 'h', a
,
3799 (rxgains
& SROM11_RXGAINS5GTRELNABYPA_MASK
) >>
3800 SROM11_RXGAINS5GTRELNABYPA_SHIFT
);
3801 varbuf_append(&b
, vstr_rxgainsgxtrisoa
, 5, 'h', a
,
3802 (rxgains
& SROM11_RXGAINS5GTRISOA_MASK
) >>
3803 SROM11_RXGAINS5GTRISOA_SHIFT
);
3804 varbuf_append(&b
, vstr_rxgainsgxelnagaina
, 5, 'h', a
,
3805 (rxgains
& SROM11_RXGAINS5GELNAGAINA_MASK
) >>
3806 SROM11_RXGAINS5GELNAGAINA_SHIFT
);
3807 varbuf_append(&b
, vstr_rxgainsgxtrelnabypa
, 5, 'm', a
,
3808 (rxgains
& SROM11_RXGAINS5GTRELNABYPA_MASK
) >>
3809 SROM11_RXGAINS5GTRELNABYPA_SHIFT
);
3810 varbuf_append(&b
, vstr_rxgainsgxtrisoa
, 5, 'm', a
,
3811 (rxgains
& SROM11_RXGAINS5GTRISOA_MASK
) >>
3812 SROM11_RXGAINS5GTRISOA_SHIFT
);
3813 varbuf_append(&b
, vstr_rxgainsgxelnagaina
, 5, 'm', a
,
3814 (rxgains
& SROM11_RXGAINS5GELNAGAINA_MASK
) >>
3815 SROM11_RXGAINS5GELNAGAINA_SHIFT
);
3820 varbuf_append(&b
, vstr_txduty_ofdm
, 40,
3821 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
3822 varbuf_append(&b
, vstr_txduty_thresh
, 40,
3823 (cis
[i
+ 4] << 8) + cis
[i
+ 3]);
3824 varbuf_append(&b
, vstr_txduty_ofdm
, 80,
3825 (cis
[i
+ 6] << 8) + cis
[i
+ 5]);
3826 varbuf_append(&b
, vstr_txduty_thresh
, 80,
3827 (cis
[i
+ 8] << 8) + cis
[i
+ 7]);
3833 /* uuid format 12345678-1234-5678-1234-567812345678 */
3835 char uuidstr
[37]; /* 32 ids, 4 '-', 1 Null */
3837 snprintf(uuidstr
, sizeof(uuidstr
),
3838 "%02X%02X%02X%02X-%02X%02X-%02X%02X-"
3839 "%02X%02X-%02X%02X%02X%02X%02X%02X",
3840 cis
[i
+ 1], cis
[i
+ 2], cis
[i
+ 3], cis
[i
+ 4],
3841 cis
[i
+ 5], cis
[i
+ 6], cis
[i
+ 7], cis
[i
+ 8],
3842 cis
[i
+ 9], cis
[i
+ 10], cis
[i
+ 11], cis
[i
+ 12],
3843 cis
[i
+ 13], cis
[i
+ 14], cis
[i
+ 15], cis
[i
+ 16]);
3845 varbuf_append(&b
, vstr_uuid
, uuidstr
);
3849 #endif /* !BCM_BOOTLOADER */
3850 #ifdef BCMUSBDEV_COMPOSITE
3851 case HNBU_USBDESC_COMPOSITE
:
3852 varbuf_append(&b
, vstr_usbdesc_composite
,
3853 (cis
[i
+ 2] << 8) | cis
[i
+ 1]);
3855 #endif /* BCMUSBDEV_COMPOSITE */
3856 case HNBU_USBUTMI_CTL
:
3857 varbuf_append(&b
, vstr_usbutmi_ctl
,
3858 (cis
[i
+ 2] << 8) | cis
[i
+ 1]);
3861 case HNBU_USBSSPHY_UTMI_CTL0
:
3862 varbuf_append(&b
, vstr_usbssphy_utmi_ctl0
,
3863 (cis
[i
+ 4] << 24) | (cis
[i
+ 3] << 16) |
3864 (cis
[i
+ 2] << 8) | cis
[i
+ 1]);
3867 case HNBU_USBSSPHY_UTMI_CTL1
:
3868 varbuf_append(&b
, vstr_usbssphy_utmi_ctl1
,
3869 (cis
[i
+ 4] << 24) | (cis
[i
+ 3] << 16) |
3870 (cis
[i
+ 2] << 8) | cis
[i
+ 1]);
3873 case HNBU_USBSSPHY_UTMI_CTL2
:
3874 varbuf_append(&b
, vstr_usbssphy_utmi_ctl2
,
3875 (cis
[i
+ 4] << 24) | (cis
[i
+ 3] << 16) |
3876 (cis
[i
+ 2] << 8) | cis
[i
+ 1]);
3879 case HNBU_USBSSPHY_SLEEP0
:
3880 varbuf_append(&b
, vstr_usbssphy_sleep0
,
3881 (cis
[i
+ 2] << 8) | cis
[i
+ 1]);
3884 case HNBU_USBSSPHY_SLEEP1
:
3885 varbuf_append(&b
, vstr_usbssphy_sleep1
,
3886 (cis
[i
+ 2] << 8) | cis
[i
+ 1]);
3889 case HNBU_USBSSPHY_SLEEP2
:
3890 varbuf_append(&b
, vstr_usbssphy_sleep2
,
3891 (cis
[i
+ 2] << 8) | cis
[i
+ 1]);
3894 case HNBU_USBSSPHY_SLEEP3
:
3895 varbuf_append(&b
, vstr_usbssphy_sleep3
,
3896 (cis
[i
+ 2] << 8) | cis
[i
+ 1]);
3901 uint16 pdoff_2g
= (cis
[i
+ 2] << 8) + cis
[i
+ 1];
3902 varbuf_append(&b
, vstr_pdoffset2gma
, 40, 0,
3903 (pdoff_2g
& SROM11_PDOFF_2G_40M_A0_MASK
) >>
3904 SROM11_PDOFF_2G_40M_A0_SHIFT
);
3905 varbuf_append(&b
, vstr_pdoffset2gma
, 40, 1,
3906 (pdoff_2g
& SROM11_PDOFF_2G_40M_A1_MASK
) >>
3907 SROM11_PDOFF_2G_40M_A1_SHIFT
);
3908 varbuf_append(&b
, vstr_pdoffset2gma
, 40, 2,
3909 (pdoff_2g
& SROM11_PDOFF_2G_40M_A2_MASK
) >>
3910 SROM11_PDOFF_2G_40M_A2_SHIFT
);
3911 varbuf_append(&b
, vstr_pdoffset2gmvalid
, 40,
3912 (pdoff_2g
& SROM11_PDOFF_2G_40M_VALID_MASK
) >>
3913 SROM11_PDOFF_2G_40M_VALID_SHIFT
);
3921 } while (tup
!= CISTPL_END
);
3924 if (boardnum
!= -1) {
3925 varbuf_append(&b
, vstr_boardnum
, boardnum
);
3929 varbuf_append(&b
, vstr_macaddr
, eabuf
);
3932 #ifndef BCM_BOOTLOADER
3933 /* if there is no antenna gain field, set default */
3934 if (sromrev
<= 10 && getvar(NULL
, "ag0") == NULL
&& ag_init
== FALSE
) {
3935 varbuf_append(&b
, vstr_ag
, 0, 0xff);
3939 #if defined(BCMUSBDEV_BMAC) || defined(BCM_BMAC_VARS_APPEND)
3940 varbuf_append(&b
, vstr_end
, NULL
);
3941 #endif /* BCMUSBDEV_BMAC */
3943 /* final nullbyte terminator */
3944 ASSERT(b
.size
>= 1);
3947 ASSERT(b
.buf
- base
<= MAXSZ_NVRAM_VARS
);
3948 err
= initvars_table(osh
, base
, b
.buf
, vars
, count
);
3950 MFREE(osh
, base
, MAXSZ_NVRAM_VARS
);
3954 /* set PCMCIA sprom command register */
3956 sprom_cmd_pcmcia(osl_t
*osh
, uint8 cmd
)
3959 uint wait_cnt
= 1000;
3961 /* write sprom command register */
3962 OSL_PCMCIA_WRITE_ATTR(osh
, SROM_CS
, &cmd
, 1);
3965 while (wait_cnt
--) {
3966 OSL_PCMCIA_READ_ATTR(osh
, SROM_CS
, &status
, 1);
3967 if (status
& SROM_DONE
)
3974 /* read a word from the PCMCIA srom */
3976 sprom_read_pcmcia(osl_t
*osh
, uint16 addr
, uint16
*data
)
3978 uint8 addr_l
, addr_h
, data_l
, data_h
;
3980 addr_l
= (uint8
)((addr
* 2) & 0xff);
3981 addr_h
= (uint8
)(((addr
* 2) >> 8) & 0xff);
3984 OSL_PCMCIA_WRITE_ATTR(osh
, SROM_ADDRH
, &addr_h
, 1);
3985 OSL_PCMCIA_WRITE_ATTR(osh
, SROM_ADDRL
, &addr_l
, 1);
3988 if (sprom_cmd_pcmcia(osh
, SROM_READ
))
3992 data_h
= data_l
= 0;
3993 OSL_PCMCIA_READ_ATTR(osh
, SROM_DATAH
, &data_h
, 1);
3994 OSL_PCMCIA_READ_ATTR(osh
, SROM_DATAL
, &data_l
, 1);
3996 *data
= (data_h
<< 8) | data_l
;
4000 #if defined(WLTEST) || defined(DHD_SPROM) || defined(BCMDBG)
4001 /* write a word to the PCMCIA srom */
4003 sprom_write_pcmcia(osl_t
*osh
, uint16 addr
, uint16 data
)
4005 uint8 addr_l
, addr_h
, data_l
, data_h
;
4007 addr_l
= (uint8
)((addr
* 2) & 0xff);
4008 addr_h
= (uint8
)(((addr
* 2) >> 8) & 0xff);
4009 data_l
= (uint8
)(data
& 0xff);
4010 data_h
= (uint8
)((data
>> 8) & 0xff);
4013 OSL_PCMCIA_WRITE_ATTR(osh
, SROM_ADDRH
, &addr_h
, 1);
4014 OSL_PCMCIA_WRITE_ATTR(osh
, SROM_ADDRL
, &addr_l
, 1);
4017 OSL_PCMCIA_WRITE_ATTR(osh
, SROM_DATAH
, &data_h
, 1);
4018 OSL_PCMCIA_WRITE_ATTR(osh
, SROM_DATAL
, &data_l
, 1);
4021 return sprom_cmd_pcmcia(osh
, SROM_WRITE
);
4025 /* In chips with chipcommon rev 32 and later, the srom is in chipcommon,
4026 * not in the bus cores.
4029 srom_cc_cmd(si_t
*sih
, osl_t
*osh
, void *ccregs
, uint32 cmd
, uint wordoff
, uint16 data
)
4031 chipcregs_t
*cc
= (chipcregs_t
*)ccregs
;
4032 uint wait_cnt
= 1000;
4034 if ((cmd
== SRC_OP_READ
) || (cmd
== SRC_OP_WRITE
)) {
4035 W_REG(osh
, &cc
->sromaddress
, wordoff
* 2);
4036 if (cmd
== SRC_OP_WRITE
)
4037 W_REG(osh
, &cc
->sromdata
, data
);
4040 W_REG(osh
, &cc
->sromcontrol
, SRC_START
| cmd
);
4042 while (wait_cnt
--) {
4043 if ((R_REG(osh
, &cc
->sromcontrol
) & SRC_BUSY
) == 0)
4048 BS_ERROR(("%s: Command 0x%x timed out\n", __FUNCTION__
, cmd
));
4051 if (cmd
== SRC_OP_READ
)
4052 return (uint16
)R_REG(osh
, &cc
->sromdata
);
4058 * Read in and validate sprom.
4059 * Return 0 on success, nonzero on error.
4062 sprom_read_pci(osl_t
*osh
, si_t
*sih
, uint16
*sprom
, uint wordoff
, uint16
*buf
, uint nwords
,
4067 void *ccregs
= NULL
;
4070 if ((CHIPID(sih
->chip
) == BCM4331_CHIP_ID
) ||
4071 (CHIPID(sih
->chip
) == BCM43431_CHIP_ID
) ||
4072 (CHIPID(sih
->chip
) == BCM4360_CHIP_ID
) ||
4073 (CHIPID(sih
->chip
) == BCM43460_CHIP_ID
) ||
4074 (CHIPID(sih
->chip
) == BCM4352_CHIP_ID
)) {
4075 /* save current control setting */
4076 ccval
= si_chipcontrl_read(sih
);
4079 if ((CHIPID(sih
->chip
) == BCM4331_CHIP_ID
) ||
4080 (CHIPID(sih
->chip
) == BCM43431_CHIP_ID
)) {
4081 /* Disable Ext PA lines to allow reading from SROM */
4082 si_chipcontrl_epa4331(sih
, FALSE
);
4083 } else if (((CHIPID(sih
->chip
) == BCM4360_CHIP_ID
) ||
4084 (CHIPID(sih
->chip
) == BCM43460_CHIP_ID
) ||
4085 (CHIPID(sih
->chip
) == BCM4352_CHIP_ID
)) &&
4086 (CHIPREV(sih
->chiprev
) <= 2)) {
4087 si_chipcontrl_srom4360(sih
, TRUE
);
4090 /* read the sprom */
4091 for (i
= 0; i
< nwords
; i
++) {
4093 if (sih
->ccrev
> 31 && ISSIM_ENAB(sih
)) {
4094 /* use indirect since direct is too slow on QT */
4095 if ((sih
->cccaps
& CC_CAP_SROM
) == 0) {
4100 ccregs
= (void *)((uint8
*)sprom
- CC_SROM_OTP
);
4101 buf
[i
] = srom_cc_cmd(sih
, osh
, ccregs
, SRC_OP_READ
, wordoff
+ i
, 0);
4104 if (ISSIM_ENAB(sih
))
4105 buf
[i
] = R_REG(osh
, &sprom
[wordoff
+ i
]);
4107 buf
[i
] = R_REG(osh
, &sprom
[wordoff
+ i
]);
4112 /* bypass crc checking for simulation to allow srom hack */
4113 if (ISSIM_ENAB(sih
)) {
4119 if (buf
[0] == 0xffff) {
4120 /* The hardware thinks that an srom that starts with 0xffff
4121 * is blank, regardless of the rest of the content, so declare
4124 BS_ERROR(("%s: buf[0] = 0x%x, returning bad-crc\n", __FUNCTION__
, buf
[0]));
4129 /* fixup the endianness so crc8 will pass */
4130 htol16_buf(buf
, nwords
* 2);
4131 if (hndcrc8((uint8
*)buf
, nwords
* 2, CRC8_INIT_VALUE
) != CRC8_GOOD_VALUE
) {
4132 /* DBG only pci always read srom4 first, then srom8/9 */
4133 /* BS_ERROR(("%s: bad crc\n", __FUNCTION__)); */
4136 /* now correct the endianness of the byte array */
4137 ltoh16_buf(buf
, nwords
* 2);
4141 if ((CHIPID(sih
->chip
) == BCM4331_CHIP_ID
) ||
4142 (CHIPID(sih
->chip
) == BCM43431_CHIP_ID
) ||
4143 (CHIPID(sih
->chip
) == BCM4360_CHIP_ID
) ||
4144 (CHIPID(sih
->chip
) == BCM43460_CHIP_ID
) ||
4145 (CHIPID(sih
->chip
) == BCM4352_CHIP_ID
)) {
4147 /* Restore config after reading SROM */
4148 si_chipcontrl_restore(sih
, ccval
);
4154 #if defined(BCMNVRAMW) || defined(BCMNVRAMR)
4156 otp_read_pci(osl_t
*osh
, si_t
*sih
, uint16
*buf
, uint bufsz
)
4159 uint sz
= OTP_SZ_MAX
/2; /* size in words */
4162 ASSERT(bufsz
<= OTP_SZ_MAX
);
4164 if ((otp
= MALLOC(osh
, OTP_SZ_MAX
)) == NULL
) {
4168 bzero(otp
, OTP_SZ_MAX
);
4170 err
= otp_read_region(sih
, OTP_HW_RGN
, (uint16
*)otp
, &sz
);
4173 MFREE(osh
, otp
, OTP_SZ_MAX
);
4177 bcopy(otp
, buf
, bufsz
);
4180 if (((uint16
*)otp
)[0] == 0xffff) {
4181 /* The hardware thinks that an srom that starts with 0xffff
4182 * is blank, regardless of the rest of the content, so declare
4185 BS_ERROR(("%s: otp[0] = 0x%x, returning bad-crc\n",
4186 __FUNCTION__
, ((uint16
*)otp
)[0]));
4187 MFREE(osh
, otp
, OTP_SZ_MAX
);
4191 /* fixup the endianness so crc8 will pass */
4192 htol16_buf((uint16
*)otp
, OTP_SZ_MAX
);
4193 if (hndcrc8(otp
, SROM4_WORDS
* 2, CRC8_INIT_VALUE
) != CRC8_GOOD_VALUE
&&
4194 hndcrc8(otp
, SROM10_WORDS
* 2, CRC8_INIT_VALUE
) != CRC8_GOOD_VALUE
&&
4195 hndcrc8(otp
, SROM11_WORDS
* 2, CRC8_INIT_VALUE
) != CRC8_GOOD_VALUE
) {
4196 BS_ERROR(("%s: bad crc\n", __FUNCTION__
));
4200 MFREE(osh
, otp
, OTP_SZ_MAX
);
4204 #endif /* defined(BCMNVRAMW) || defined(BCMNVRAMR) */
4207 srom_otp_write_region_crc(si_t
*sih
, uint nbytes
, uint16
* buf16
, bool write
)
4209 #if defined(WLTEST) || defined(BCMDBG)
4210 int err
= 0, crc
= 0;
4213 /* Check nbytes is not odd or too big */
4214 if ((nbytes
& 1) || (nbytes
> SROM_MAX
))
4217 /* block invalid buffer size */
4218 if (nbytes
< SROM4_WORDS
* 2)
4219 return BCME_BUFTOOSHORT
;
4220 else if (nbytes
> SROM11_WORDS
* 2)
4221 return BCME_BUFTOOLONG
;
4223 /* Verify signatures */
4224 if (!((buf16
[SROM4_SIGN
] == SROM4_SIGNATURE
) ||
4225 (buf16
[SROM8_SIGN
] == SROM4_SIGNATURE
) ||
4226 (buf16
[SROM10_SIGN
] == SROM4_SIGNATURE
) ||
4227 (buf16
[SROM11_SIGN
] == SROM11_SIGNATURE
))) {
4228 BS_ERROR(("%s: wrong signature SROM4_SIGN %x SROM8_SIGN %x SROM10_SIGN %x\n",
4229 __FUNCTION__
, buf16
[SROM4_SIGN
], buf16
[SROM8_SIGN
], buf16
[SROM10_SIGN
]));
4234 if (buf16
[0] == 0xffff) {
4235 /* The hardware thinks that an srom that starts with 0xffff
4236 * is blank, regardless of the rest of the content, so declare
4239 BS_ERROR(("%s: invalid buf16[0] = 0x%x\n", __FUNCTION__
, buf16
[0]));
4243 buf8
= (uint8
*)buf16
;
4244 /* fixup the endianness and then calculate crc */
4245 htol16_buf(buf8
, nbytes
);
4246 crc
= ~hndcrc8(buf8
, nbytes
- 1, CRC8_INIT_VALUE
);
4247 /* now correct the endianness of the byte array */
4248 ltoh16_buf(buf8
, nbytes
);
4249 if (nbytes
== SROM11_WORDS
* 2)
4250 buf16
[SROM11_CRCREV
] = (crc
<< 8) | (buf16
[SROM11_CRCREV
] & 0xff);
4251 else if (nbytes
== SROM10_WORDS
* 2)
4252 buf16
[SROM10_CRCREV
] = (crc
<< 8) | (buf16
[SROM10_CRCREV
] & 0xff);
4254 buf16
[SROM4_CRCREV
] = (crc
<< 8) | (buf16
[SROM4_CRCREV
] & 0xff);
4257 /* Write the CRC back */
4259 err
= otp_write_region(sih
, OTP_HW_RGN
, buf16
, nbytes
/2);
4260 #endif /* BCMNVRAMW */
4263 return write
? err
: crc
;
4270 * Create variable table from memory.
4271 * Return 0 on success, nonzero on error.
4274 BCMATTACHFN(initvars_table
)(osl_t
*osh
, char *start
, char *end
, char **vars
, uint
*count
)
4276 int c
= (int)(end
- start
);
4278 /* do it only when there is more than just the null string */
4280 char *vp
= MALLOC(osh
, c
);
4284 bcopy(start
, vp
, c
);
4297 * Find variables with <devpath> from flash. 'base' points to the beginning
4298 * of the table upon enter and to the end of the table upon exit when success.
4299 * Return 0 on success, nonzero on error.
4302 BCMATTACHFN(initvars_flash
)(si_t
*sih
, osl_t
*osh
, char **base
, uint len
)
4308 uint l
, dl
, copy_len
;
4309 char devpath
[SI_DEVPATH_BUFSZ
];
4310 char coded_name
[SI_DEVPATH_BUFSZ
] = {0};
4311 int path_len
, coded_len
, devid_len
;
4313 /* allocate memory and read in flash */
4314 if (!(flash
= MALLOC(osh
, MAX_NVRAM_SPACE
)))
4316 if ((err
= nvram_getall(flash
, MAX_NVRAM_SPACE
)))
4319 /* create legacy devpath prefix */
4320 si_devpath(sih
, devpath
, sizeof(devpath
));
4321 path_len
= strlen(devpath
);
4323 /* create coded devpath prefix */
4324 si_coded_devpathvar(sih
, coded_name
, sizeof(coded_name
), "devid");
4326 /* coded_name now is 'xx:devid, eat ending 'devid' */
4328 devid_len
= strlen("devid");
4329 coded_len
= strlen(coded_name
);
4330 if (coded_len
> devid_len
) {
4331 coded_name
[coded_len
- devid_len
] = '\0';
4332 coded_len
-= devid_len
;
4337 /* grab vars with the <devpath> prefix or <coded_name> previx in name */
4338 for (s
= flash
; s
&& *s
; s
+= l
+ 1) {
4341 /* skip non-matching variable */
4342 if (strncmp(s
, devpath
, path_len
) == 0)
4344 else if (coded_len
&& strncmp(s
, coded_name
, coded_len
) == 0)
4349 /* is there enough room to copy? */
4350 copy_len
= l
- dl
+ 1;
4351 if (len
< copy_len
) {
4352 err
= BCME_BUFTOOSHORT
;
4356 /* no prefix, just the name=value */
4357 strncpy(vp
, &s
[dl
], copy_len
);
4362 /* add null string as terminator */
4364 err
= BCME_BUFTOOSHORT
;
4371 exit
: MFREE(osh
, flash
, MAX_NVRAM_SPACE
);
4375 #if !defined(BCMUSBDEV_ENABLED) && !defined(BCMSDIODEV_ENABLED)
4377 * Initialize nonvolatile variable table from flash.
4378 * Return 0 on success, nonzero on error.
4381 BCMATTACHFN(initvars_flash_si
)(si_t
*sih
, char **vars
, uint
*count
)
4383 osl_t
*osh
= si_osh(sih
);
4387 ASSERT(vars
!= NULL
);
4388 ASSERT(count
!= NULL
);
4390 base
= vp
= MALLOC(osh
, MAXSZ_NVRAM_VARS
);
4395 if ((err
= initvars_flash(sih
, osh
, &vp
, MAXSZ_NVRAM_VARS
)) == 0)
4396 err
= initvars_table(osh
, base
, vp
, vars
, count
);
4398 MFREE(osh
, base
, MAXSZ_NVRAM_VARS
);
4404 /* Parse SROM and create name=value pairs. 'srom' points to
4405 * the SROM word array. 'off' specifies the offset of the
4406 * first word 'srom' points to, which should be either 0 or
4407 * SROM3_SWRG_OFF (full SROM or software region).
4411 mask_shift(uint16 mask
)
4414 for (i
= 0; i
< (sizeof(mask
) << 3); i
++) {
4415 if (mask
& (1 << i
))
4423 mask_width(uint16 mask
)
4426 for (i
= (sizeof(mask
) << 3) - 1; i
>= 0; i
--) {
4427 if (mask
& (1 << i
))
4428 return (uint
)(i
- mask_shift(mask
) + 1);
4434 #ifdef BCMASSERT_SUPPORT
4436 mask_valid(uint16 mask
)
4438 uint shift
= mask_shift(mask
);
4439 uint width
= mask_width(mask
);
4440 return mask
== ((~0 << shift
) & ~(~0 << (shift
+ width
)));
4445 BCMATTACHFN(_initvars_srom_pci
)(uint8 sromrev
, uint16
*srom
, uint off
, varbuf_t
*b
)
4449 const sromvar_t
*srv
;
4452 uint32 sr
= (1 << sromrev
);
4453 bool in_array
= FALSE
;
4454 static char array_temp
[256];
4455 uint array_curr
= 0;
4456 const char* array_name
= NULL
;
4458 varbuf_append(b
, "sromrev=%d", sromrev
);
4460 for (srv
= pci_sromvars
; srv
->name
!= NULL
; srv
++) {
4462 static bool in_array2
= FALSE
;
4463 static char array_temp2
[256];
4464 static uint array_curr2
= 0;
4465 static const char* array_name2
= NULL
;
4467 if ((srv
->revmask
& sr
) == 0)
4476 /* This entry is for mfgc only. Don't generate param for it, */
4477 if (flags
& SRFL_NOVAR
)
4480 if (flags
& SRFL_ETHADDR
) {
4481 char eabuf
[ETHER_ADDR_STR_LEN
];
4482 struct ether_addr ea
;
4484 ea
.octet
[0] = (srom
[srv
->off
- off
] >> 8) & 0xff;
4485 ea
.octet
[1] = srom
[srv
->off
- off
] & 0xff;
4486 ea
.octet
[2] = (srom
[srv
->off
+ 1 - off
] >> 8) & 0xff;
4487 ea
.octet
[3] = srom
[srv
->off
+ 1 - off
] & 0xff;
4488 ea
.octet
[4] = (srom
[srv
->off
+ 2 - off
] >> 8) & 0xff;
4489 ea
.octet
[5] = srom
[srv
->off
+ 2 - off
] & 0xff;
4490 bcm_ether_ntoa(&ea
, eabuf
);
4492 varbuf_append(b
, "%s=%s", name
, eabuf
);
4495 ASSERT(mask_valid(srv
->mask
));
4496 ASSERT(mask_width(srv
->mask
));
4498 /* Start of an array */
4499 if (sromrev
>= 10 && (srv
->flags
& SRFL_ARRAY
) && !in_array2
) {
4501 array_name2
= (const char*)srv
->name
;
4502 memset((void*)array_temp2
, 0, sizeof(array_temp2
));
4506 w
= srom
[srv
->off
- off
];
4507 val
= (w
& srv
->mask
) >> mask_shift(srv
->mask
);
4508 width
= mask_width(srv
->mask
);
4510 while (srv
->flags
& SRFL_MORE
) {
4512 ASSERT(srv
->name
!= NULL
);
4514 if (srv
->off
== 0 || srv
->off
< off
)
4517 ASSERT(mask_valid(srv
->mask
));
4518 ASSERT(mask_width(srv
->mask
));
4520 w
= srom
[srv
->off
- off
];
4521 val
+= ((w
& srv
->mask
) >> mask_shift(srv
->mask
)) << width
;
4522 width
+= mask_width(srv
->mask
);
4525 if ((flags
& SRFL_NOFFS
) && ((int)val
== (1 << width
) - 1))
4528 /* Array support starts in sromrev 10. Skip arrays for sromrev <= 9 */
4529 if (sromrev
<= 9 && srv
->flags
& SRFL_ARRAY
) {
4530 while (srv
->flags
& SRFL_ARRAY
)
4538 if (flags
& SRFL_PRHEX
) {
4539 ret
= snprintf(array_temp2
+ array_curr2
,
4540 sizeof(array_temp2
) - array_curr2
, "0x%x,", val
);
4541 } else if ((flags
& SRFL_PRSIGN
) &&
4542 (val
& (1 << (width
- 1)))) {
4543 ret
= snprintf(array_temp2
+ array_curr2
,
4544 sizeof(array_temp2
) - array_curr2
, "%d,",
4545 (int)(val
| (~0 << width
)));
4547 ret
= snprintf(array_temp2
+ array_curr2
,
4548 sizeof(array_temp2
) - array_curr2
, "%u,", val
);
4554 BS_ERROR(("%s: array %s parsing error. buffer too short.\n",
4555 __FUNCTION__
, array_name2
));
4558 /* buffer too small, skip this param */
4559 while (srv
->flags
& SRFL_ARRAY
)
4566 if (!(srv
->flags
& SRFL_ARRAY
)) { /* Array ends */
4567 /* Remove the last ',' */
4568 array_temp2
[array_curr2
-1] = '\0';
4570 varbuf_append(b
, "%s=%s", array_name2
, array_temp2
);
4572 } else if (flags
& SRFL_CCODE
) {
4574 varbuf_append(b
, "ccode=");
4576 varbuf_append(b
, "ccode=%c%c", (val
>> 8), (val
& 0xff));
4578 /* LED Powersave duty cycle has to be scaled:
4579 *(oncount >> 24) (offcount >> 8)
4581 else if (flags
& SRFL_LEDDC
) {
4582 uint32 w32
= (((val
>> 8) & 0xff) << 24) | /* oncount */
4583 (((val
& 0xff)) << 8); /* offcount */
4584 varbuf_append(b
, "leddc=%d", w32
);
4586 else if (flags
& SRFL_PRHEX
)
4587 varbuf_append(b
, "%s=0x%x", name
, val
);
4588 else if ((flags
& SRFL_PRSIGN
) && (val
& (1 << (width
- 1))))
4589 varbuf_append(b
, "%s=%d", name
, (int)(val
| (~0 << width
)));
4591 varbuf_append(b
, "%s=%u", name
, val
);
4596 /* Do per-path variables */
4597 uint p
, pb
, psz
, path_num
;
4599 if (sromrev
>= 11) {
4601 psz
= SROM11_PATH1
- SROM11_PATH0
;
4602 path_num
= MAX_PATH_SROM_11
;
4603 } else if (sromrev
>= 8) {
4605 psz
= SROM8_PATH1
- SROM8_PATH0
;
4606 path_num
= MAX_PATH_SROM
;
4609 psz
= SROM4_PATH1
- SROM4_PATH0
;
4610 path_num
= MAX_PATH_SROM
;
4613 for (p
= 0; p
< path_num
; p
++) {
4614 for (srv
= perpath_pci_sromvars
; srv
->name
!= NULL
; srv
++) {
4615 if ((srv
->revmask
& sr
) == 0)
4618 if (pb
+ srv
->off
< off
)
4621 /* This entry is for mfgc only. Don't generate param for it, */
4622 if (srv
->flags
& SRFL_NOVAR
)
4625 /* Start of an array */
4626 if (sromrev
>= 10 && (srv
->flags
& SRFL_ARRAY
) && !in_array
) {
4628 array_name
= (const char*)srv
->name
;
4629 memset((void*)array_temp
, 0, sizeof(array_temp
));
4633 w
= srom
[pb
+ srv
->off
- off
];
4635 ASSERT(mask_valid(srv
->mask
));
4636 val
= (w
& srv
->mask
) >> mask_shift(srv
->mask
);
4637 width
= mask_width(srv
->mask
);
4641 /* Cheating: no per-path var is more than 1 word */
4643 if ((srv
->flags
& SRFL_NOFFS
) && ((int)val
== (1 << width
) - 1))
4649 if (flags
& SRFL_PRHEX
) {
4650 ret
= snprintf(array_temp
+ array_curr
,
4651 sizeof(array_temp
) - array_curr
, "0x%x,", val
);
4652 } else if ((flags
& SRFL_PRSIGN
) &&
4653 (val
& (1 << (width
- 1)))) {
4654 ret
= snprintf(array_temp
+ array_curr
,
4655 sizeof(array_temp
) - array_curr
, "%d,",
4656 (int)(val
| (~0 << width
)));
4658 ret
= snprintf(array_temp
+ array_curr
,
4659 sizeof(array_temp
) - array_curr
, "%u,", val
);
4666 ("%s: array %s parsing error. buffer too short.\n",
4667 __FUNCTION__
, array_name
));
4670 /* buffer too small, skip this param */
4671 while (srv
->flags
& SRFL_ARRAY
)
4678 if (!(srv
->flags
& SRFL_ARRAY
)) { /* Array ends */
4679 /* Remove the last ',' */
4680 array_temp
[array_curr
-1] = '\0';
4682 varbuf_append(b
, "%s%d=%s",
4683 array_name
, p
, array_temp
);
4685 } else if (srv
->flags
& SRFL_PRHEX
)
4686 varbuf_append(b
, "%s%d=0x%x", srv
->name
, p
, val
);
4688 varbuf_append(b
, "%s%d=%d", srv
->name
, p
, val
);
4696 * Initialize nonvolatile variable table from sprom.
4697 * Return 0 on success, nonzero on error.
4700 BCMATTACHFN(initvars_srom_pci
)(si_t
*sih
, void *curmap
, char **vars
, uint
*count
)
4702 uint16
*srom
, *sromwindow
;
4706 char *vp
, *base
= NULL
;
4707 osl_t
*osh
= si_osh(sih
);
4712 * Apply CRC over SROM content regardless SROM is present or not,
4713 * and use variable <devpath>sromrev's existance in flash to decide
4714 * if we should return an error when CRC fails or read SROM variables
4717 srom
= MALLOC(osh
, SROM_MAX
);
4718 ASSERT(srom
!= NULL
);
4722 sromwindow
= (uint16
*)SROM_OFFSET(sih
);
4723 if (si_is_sprom_available(sih
)) {
4724 err
= sprom_read_pci(osh
, sih
, sromwindow
, 0, srom
, SROM11_WORDS
, TRUE
);
4727 if (srom
[SROM11_SIGN
] == SROM11_SIGNATURE
) /* srom 11 */
4728 sromrev
= srom
[SROM11_CRCREV
] & 0xff;
4730 err
= sprom_read_pci(osh
, sih
, sromwindow
, 0, srom
, SROM4_WORDS
, TRUE
);
4733 if ((srom
[SROM4_SIGN
] == SROM4_SIGNATURE
) || /* srom 4 */
4734 (srom
[SROM8_SIGN
] == SROM4_SIGNATURE
) ) { /* srom 8, 9 */
4735 sromrev
= srom
[SROM4_CRCREV
] & 0xff;
4738 err
= sprom_read_pci(osh
, sih
, sromwindow
, 0,
4739 srom
, SROM_WORDS
, TRUE
);
4742 /* srom is good and is rev < 4 */
4743 /* top word of sprom contains version and crc8 */
4744 sromrev
= srom
[SROM_CRCREV
] & 0xff;
4745 /* bcm4401 sroms misprogrammed */
4746 if (sromrev
== 0x10)
4753 #if defined(BCMNVRAMW) || defined(BCMNVRAMR)
4754 /* Use OTP if SPROM not available */
4755 else if ((err
= otp_read_pci(osh
, sih
, srom
, SROM_MAX
)) == 0) {
4756 /* OTP only contain SROM rev8/rev9/rev10/Rev11 for now */
4757 if (srom
[SROM11_SIGN
] == SROM11_SIGNATURE
)
4758 sromrev
= srom
[SROM11_CRCREV
] & 0xff;
4759 else if (srom
[SROM10_SIGN
] == SROM10_SIGNATURE
)
4760 sromrev
= srom
[SROM10_CRCREV
] & 0xff;
4762 sromrev
= srom
[SROM4_CRCREV
] & 0xff;
4764 #endif /* defined(BCMNVRAMW) || defined(BCMNVRAMR) */
4767 BS_ERROR(("Neither SPROM nor OTP has valid image\n"));
4770 BS_ERROR(("srom rev:%d\n", sromrev
));
4773 /* We want internal/wltest driver to come up with default sromvars so we can
4774 * program a blank SPROM/OTP.
4782 if ((value
= si_getdevpathvar(sih
, "sromrev"))) {
4783 sromrev
= (uint8
)bcm_strtoul(value
, NULL
, 0);
4788 BS_ERROR(("%s, SROM CRC Error\n", __FUNCTION__
));
4791 if ((value
= si_getnvramflvar(sih
, "sromrev"))) {
4796 /* BCMHOSTVARS is enabled only if WLTEST is enabled or BCMEXTNVM is enabled */
4797 #if defined(BCMHOSTVARS)
4798 val
= OSL_PCI_READ_CONFIG(osh
, PCI_SPROM_CONTROL
, sizeof(uint32
));
4799 if ((si_is_sprom_available(sih
) && srom
[0] == 0xffff) ||
4800 (val
& SPROM_OTPIN_USE
)) {
4801 vp
= base
= mfgsromvars
;
4803 if (defvarslen
== 0) {
4804 BS_ERROR(("No nvm file, use generic default (for programming"
4805 " SPROM/OTP only)\n"));
4807 if (((sih
->chip
== BCM4331_CHIP_ID
) ||
4808 (sih
->chip
== BCM43431_CHIP_ID
)) &&
4809 (sih
->chiprev
< 3)) {
4811 defvarslen
= srom_vars_len(defaultsromvars_4331
);
4812 bcopy(defaultsromvars_4331
, vp
, defvarslen
);
4814 } else if ((sih
->chip
== BCM4360_CHIP_ID
) ||
4815 (sih
->chip
== BCM4352_CHIP_ID
)) {
4816 defvarslen
= srom_vars_len(defaultsromvars_4360
);
4817 bcopy(defaultsromvars_4360
, vp
, defvarslen
);
4818 } else if (sih
->chip
== BCM4335_CHIP_ID
||
4820 defvarslen
= srom_vars_len(defaultsromvars_4335
);
4821 bcopy(defaultsromvars_4335
, vp
, defvarslen
);
4823 /* For 4311 A1 there is no signature to indicate that OTP is
4824 * programmed, so can't really verify the OTP is
4825 * unprogrammed or a bad OTP.
4827 if (sih
->chip
== BCM4311_CHIP_ID
) {
4828 const char *devid
= "devid=0x4311";
4829 const size_t devid_strlen
= strlen(devid
);
4830 BS_ERROR(("setting the devid to be 4311\n"));
4831 bcopy(devid
, vp
, devid_strlen
+ 1);
4832 vp
+= devid_strlen
+ 1;
4834 defvarslen
= srom_vars_len(defaultsromvars_wltest
);
4835 bcopy(defaultsromvars_wltest
, vp
, defvarslen
);
4838 BS_ERROR(("Use nvm file as default\n"));
4842 /* add final null terminator */
4845 BS_ERROR(("Used %d bytes of defaultsromvars\n", defvarslen
));
4848 } else if ((((sih
->chip
== BCM4331_CHIP_ID
) ||
4849 (sih
->chip
== BCM43431_CHIP_ID
)) &&
4850 (sih
->chiprev
< 3)) || (sih
->chip
== BCM4360_CHIP_ID
) ||
4851 (sih
->chip
== BCM43460_CHIP_ID
) ||
4852 (sih
->chip
== BCM4352_CHIP_ID
)) {
4853 base
= vp
= mfgsromvars
;
4855 if ((sih
->chip
== BCM4360_CHIP_ID
) ||
4856 (sih
->chip
== BCM43460_CHIP_ID
) ||
4857 (sih
->chip
== BCM4352_CHIP_ID
))
4858 BS_ERROR(("4360 BOOT w/o SPROM or OTP\n"));
4860 BS_ERROR(("4331 BOOT w/o SPROM or OTP\n"));
4862 if (defvarslen
== 0) {
4863 if ((sih
->chip
== BCM4360_CHIP_ID
) ||
4864 (sih
->chip
== BCM4352_CHIP_ID
)) {
4865 defvarslen
= srom_vars_len(defaultsromvars_4360
);
4866 bcopy(defaultsromvars_4360
, vp
, defvarslen
);
4868 defvarslen
= srom_vars_len(defaultsromvars_4331
);
4869 bcopy(defaultsromvars_4331
, vp
, defvarslen
);
4875 } else if (sih
->chip
== BCM4335_CHIP_ID
||
4877 base
= vp
= mfgsromvars
;
4879 defvarslen
= srom_vars_len(defaultsromvars_4335
);
4880 bcopy(defaultsromvars_4335
, vp
, defvarslen
);
4894 /* Bitmask for the sromrev */
4897 /* srom version check: Current valid versions: 1-5, 8-11, SROM_MAXREV */
4898 if ((sr
& 0xf3e) == 0) {
4899 BS_ERROR(("Invalid SROM rev %d\n", sromrev
));
4904 ASSERT(vars
!= NULL
);
4905 ASSERT(count
!= NULL
);
4907 base
= vp
= MALLOC(osh
, MAXSZ_NVRAM_VARS
);
4914 /* read variables from flash */
4916 if ((err
= initvars_flash(sih
, osh
, &vp
, MAXSZ_NVRAM_VARS
)))
4921 varbuf_init(&b
, base
, MAXSZ_NVRAM_VARS
);
4923 /* parse SROM into name=value pairs. */
4924 _initvars_srom_pci(sromrev
, srom
, 0, &b
);
4927 /* final nullbyte terminator */
4928 ASSERT(b
.size
>= 1);
4932 ASSERT((vp
- base
) <= MAXSZ_NVRAM_VARS
);
4935 err
= initvars_table(osh
, base
, vp
, vars
, count
);
4938 /* BCMHOSTVARS are enabled only if WLTEST is enabled or BCMEXTNVM is enabled */
4939 #if defined(BCMHOSTVARS)
4940 if (base
&& (base
!= mfgsromvars
))
4944 MFREE(osh
, base
, MAXSZ_NVRAM_VARS
);
4946 MFREE(osh
, srom
, SROM_MAX
);
4951 * Read the cis and call parsecis to initialize the vars.
4952 * Return 0 on success, nonzero on error.
4955 BCMATTACHFN(initvars_cis_pcmcia
)(si_t
*sih
, osl_t
*osh
, char **vars
, uint
*count
)
4961 data_sz
= (sih
->buscorerev
== 1) ? SROM_MAX
: CIS_SIZE
;
4963 if ((cis
= MALLOC(osh
, data_sz
)) == NULL
)
4966 if (sih
->buscorerev
== 1) {
4967 if (srom_read(sih
, PCMCIA_BUS
, (void *)NULL
, osh
, 0, data_sz
, (uint16
*)cis
,
4969 MFREE(osh
, cis
, data_sz
);
4972 /* fix up endianess for 16-bit data vs 8-bit parsing */
4973 htol16_buf((uint16
*)cis
, data_sz
);
4975 OSL_PCMCIA_READ_ATTR(osh
, 0, cis
, data_sz
);
4977 rc
= srom_parsecis(osh
, &cis
, SROM_CIS_SINGLE
, vars
, count
);
4979 MFREE(osh
, cis
, data_sz
);
4987 * Read the SPI cis and call parsecis to initialize the vars.
4988 * Return 0 on success, nonzero on error.
4991 BCMATTACHFN(initvars_cis_spi
)(osl_t
*osh
, char **vars
, uint
*count
)
4996 #if defined(NDIS) && !defined(UNDER_CE)
4997 uint8 cisd
[SBSDIO_CIS_SIZE_LIMIT
];
5000 if ((cis
= MALLOC(osh
, SBSDIO_CIS_SIZE_LIMIT
)) == NULL
) {
5003 #endif /* defined(NDIS) && (!defined(UNDER_CE)) */
5005 bzero(cis
, SBSDIO_CIS_SIZE_LIMIT
);
5007 if (bcmsdh_cis_read(NULL
, SDIO_FUNC_1
, cis
, SBSDIO_CIS_SIZE_LIMIT
) != 0) {
5008 #if defined(NDIS) && !defined(UNDER_CE)
5011 MFREE(osh
, cis
, SBSDIO_CIS_SIZE_LIMIT
);
5012 #endif /* defined(NDIS) && (!defined(UNDER_CE)) */
5016 rc
= srom_parsecis(osh
, &cis
, SDIO_FUNC_1
, vars
, count
);
5018 #if defined(NDIS) && !defined(UNDER_CE)
5019 /* nothing to do here */
5021 MFREE(osh
, cis
, SBSDIO_CIS_SIZE_LIMIT
);
5028 #if defined(BCMUSBDEV)
5029 /* Return sprom size in 16-bit words */
5031 srom_size(si_t
*sih
, osl_t
*osh
)
5034 if (SPROMBUS
== PCMCIA_BUS
) {
5036 sdpcmd_regs_t
*pcmregs
;
5039 origidx
= si_coreidx(sih
);
5040 pcmregs
= si_setcore(sih
, PCMCIA_CORE_ID
, 0);
5042 pcmregs
= si_setcore(sih
, SDIOD_CORE_ID
, 0);
5045 if (!(wasup
= si_iscoreup(sih
)))
5046 si_core_reset(sih
, 0, 0);
5048 /* not worry about earlier core revs */
5049 /* valid for only pcmcia core */
5050 if (si_coreid(sih
) == PCMCIA_CORE_ID
)
5051 if (si_corerev(sih
) < 8)
5055 switch (SI_PCMCIA_READ(osh
, pcmregs
, SROM_INFO
) & SRI_SZ_MASK
) {
5057 size
= 256; /* SROM_INFO == 1 means 4kbit */
5060 size
= 1024; /* SROM_INFO == 2 means 16kbit */
5068 si_core_disable(sih
, 0);
5070 si_setcoreidx(sih
, origidx
);
5077 * initvars are different for BCMUSBDEV and BCMSDIODEV. This is OK when supporting both at
5078 * the same time, but only because all of the code is in attach functions and not in ROM.
5081 #if defined(BCMUSBDEV_ENABLED)
5082 #if defined(BCMUSBDEV_BMAC) || defined(BCM_BMAC_VARS_APPEND)
5084 * Read the USB cis and call parsecis to initialize the vars.
5085 * Return 0 on success, nonzero on error.
5088 BCMATTACHFN(initvars_cis_usbdriver
)(si_t
*sih
, osl_t
*osh
, char **vars
, uint
*count
)
5091 uint sz
= OTP_SZ_MAX
/2; /* size in words */
5094 if ((cis
= MALLOC(osh
, OTP_SZ_MAX
)) == NULL
) {
5098 bzero(cis
, OTP_SZ_MAX
);
5100 if (otp_read_region(sih
, OTP_SW_RGN
, (uint16
*)cis
, &sz
)) {
5101 BS_ERROR(("%s: OTP read SW region failure.\n*", __FUNCTION__
));
5104 BS_ERROR(("%s: OTP programmed. use OTP for srom vars\n*", __FUNCTION__
));
5105 rc
= srom_parsecis(osh
, &cis
, SROM_CIS_SINGLE
, vars
, count
);
5108 MFREE(osh
, cis
, OTP_SZ_MAX
);
5113 /* For driver(not bootloader), if nvram is not downloadable or missing, use default */
5115 BCMATTACHFN(initvars_srom_si_usbdriver
)(si_t
*sih
, osl_t
*osh
, char **vars
, uint
*varsz
)
5122 base
= fakevars
= NULL
;
5124 switch (CHIPID(sih
->chip
)) {
5125 case BCM4322_CHIP_ID
: case BCM43221_CHIP_ID
: case BCM43231_CHIP_ID
:
5126 fakevars
= defaultsromvars_4322usb
;
5128 case BCM43236_CHIP_ID
: case BCM43235_CHIP_ID
: case BCM43238_CHIP_ID
:
5129 case BCM43234_CHIP_ID
:
5130 /* check against real chipid instead of compile time flag */
5131 if (sih
->chip
== BCM43234_CHIP_ID
) {
5132 fakevars
= defaultsromvars_43234usb
;
5133 } else if (sih
->chip
== BCM43235_CHIP_ID
) {
5134 fakevars
= defaultsromvars_43235usb
;
5136 fakevars
= defaultsromvars_43236usb
;
5139 case BCM4319_CHIP_ID
:
5140 fakevars
= defaultsromvars_4319usb
;
5142 case BCM43242_CHIP_ID
:
5143 case BCM43243_CHIP_ID
:
5144 fakevars
= defaultsromvars_43242usb
;
5147 case BCM4350_CHIP_ID
:
5148 fakevars
= defaultsromvars_4350usb
;
5151 case BCM4360_CHIP_ID
:
5152 case BCM4352_CHIP_ID
:
5153 case BCM43460_CHIP_ID
:
5154 case BCM43526_CHIP_ID
:
5155 fakevars
= defaultsromvars_4360usb
;
5157 case BCM43143_CHIP_ID
:
5158 fakevars
= defaultsromvars_43143usb
;
5165 #ifndef BCM_BMAC_VARS_APPEND
5166 if (BCME_OK
== initvars_cis_usbdriver(sih
, osh
, vars
, varsz
)) {
5167 /* Make OTP/SROM variables global */
5168 if (srvars_inited
== FALSE
)
5169 nvram_append((void *)sih
, *vars
, *varsz
);
5172 #endif /* BCM_BMAC_VARS_APPEND */
5174 /* NO OTP, if nvram downloaded, use it */
5175 if ((_varsz
!= 0) && (_vars
!= NULL
)) {
5176 len
= _varsz
+ (strlen(vstr_end
));
5177 base
= MALLOC(osh
, len
+ 2); /* plus 2 terminating \0 */
5179 BS_ERROR(("initvars_srom_si: MALLOC failed.\n"));
5182 bzero(base
, len
+ 2);
5184 /* make a copy of the _vars, _vars is at the top of the memory, cannot append
5185 * END\0\0 to it. copy the download vars to base, back of the terminating \0,
5186 * then append END\0\0
5188 bcopy((void *)_vars
, base
, _varsz
);
5189 /* backoff all the terminating \0s except the one the for the last string */
5191 while (!base
[len
- 1])
5193 len
++; /* \0 for the last string */
5194 /* append END\0\0 to the end */
5195 bcopy((void *)vstr_end
, (base
+ len
), strlen(vstr_end
));
5196 len
+= (strlen(vstr_end
) + 2);
5200 BS_ERROR(("%s USB nvram downloaded %d bytes\n", __FUNCTION__
, _varsz
));
5202 /* Fall back to fake srom vars if OTP not programmed */
5203 len
= srom_vars_len(fakevars
);
5204 base
= MALLOC(osh
, (len
+ 1));
5206 BS_ERROR(("initvars_srom_si: MALLOC failed.\n"));
5209 bzero(base
, (len
+ 1));
5210 bcopy(fakevars
, base
, len
);
5211 *(base
+ len
) = '\0'; /* add final nullbyte terminator */
5214 BS_ERROR(("initvars_srom_usbdriver: faked nvram %d bytes\n", len
));
5217 #ifdef BCM_BMAC_VARS_APPEND
5218 if (BCME_OK
== initvars_cis_usbdriver(sih
, osh
, vars
, varsz
)) {
5220 MFREE(osh
, base
, (len
+ 1));
5222 #endif /* BCM_BMAC_VARS_APPEND */
5223 /* Make OTP/SROM variables global */
5224 if (srvars_inited
== FALSE
) {
5225 nvram_append((void *)sih
, *vars
, *varsz
);
5226 srvars_inited
= TRUE
;
5231 #endif /* BCMUSBDEV_BMAC || BCM_BMAC_VARS_APPEND */
5233 #ifdef BCM_DONGLEVARS
5235 BCMATTACHFN(initvars_srom_si_bl
)(si_t
*sih
, osl_t
*osh
, void *curmap
, char **vars
, uint
*varsz
)
5237 int sel
= 0; /* where to read srom/cis: 0 - none, 1 - otp, 2 - sprom */
5238 uint sz
= 0; /* srom size in bytes */
5242 if ((oh
= otp_init(sih
)) != NULL
&& (otp_status(oh
) & OTPS_GUP_SW
)) {
5243 /* Access OTP if it is present, powered on, and programmed */
5246 } else if ((sz
= srom_size(sih
, osh
)) != 0) {
5247 /* Access the SPROM if it is present */
5252 /* Read CIS in OTP/SPROM */
5260 /* Allocate memory */
5261 if ((srom
= (uint16
*)MALLOC(osh
, sz
)) == NULL
)
5267 rc
= otp_read_region(sih
, OTP_SW_RGN
, srom
, &otpsz
);
5269 body
= (uint8
*)srom
;
5272 rc
= srom_read(sih
, SI_BUS
, curmap
, osh
, 0, sz
, srom
, TRUE
);
5273 /* sprom has 8 byte h/w header */
5274 body
= (uint8
*)srom
+ SBSDIO_SPROM_CIS_OFFSET
;
5277 /* impossible to come here */
5283 if (rc
== BCME_OK
) {
5284 /* each word is in host endian */
5285 htol16_buf((uint8
*)srom
, sz
);
5287 rc
= srom_parsecis(osh
, &body
, SROM_CIS_SINGLE
, vars
, varsz
);
5290 MFREE(osh
, srom
, sz
); /* Clean up */
5292 /* Make SROM variables global */
5294 nvram_append((void *)sih
, *vars
, *varsz
);
5299 #endif /* #ifdef BCM_DONGLEVARS */
5302 BCMATTACHFN(initvars_srom_si
)(si_t
*sih
, osl_t
*osh
, void *curmap
, char **vars
, uint
*varsz
)
5305 /* Bail out if we've dealt with OTP/SPROM before! */
5309 #if defined(BCMUSBDEV_BMAC) || defined(BCM_BMAC_VARS_APPEND)
5310 /* read OTP or use faked var array */
5311 switch (CHIPID(sih
->chip
)) {
5312 case BCM4322_CHIP_ID
: case BCM43221_CHIP_ID
: case BCM43231_CHIP_ID
:
5313 case BCM43236_CHIP_ID
: case BCM43235_CHIP_ID
: case BCM43238_CHIP_ID
:
5314 case BCM43234_CHIP_ID
:
5315 case BCM4319_CHIP_ID
:
5316 case BCM43242_CHIP_ID
:
5317 case BCM43243_CHIP_ID
:
5318 case BCM4360_CHIP_ID
:
5319 case BCM43460_CHIP_ID
:
5320 case BCM4352_CHIP_ID
:
5321 case BCM43526_CHIP_ID
:
5322 case BCM4350_CHIP_ID
:
5323 case BCM43143_CHIP_ID
:
5324 if (BCME_OK
!= initvars_srom_si_usbdriver(sih
, osh
, vars
, varsz
))
5328 UNUSED_PARAMETER(defaultsromvars_4322usb
);
5329 UNUSED_PARAMETER(defaultsromvars_43234usb
);
5330 UNUSED_PARAMETER(defaultsromvars_43235usb
);
5331 UNUSED_PARAMETER(defaultsromvars_43236usb
);
5332 UNUSED_PARAMETER(defaultsromvars_4319usb
);
5333 UNUSED_PARAMETER(defaultsromvars_43242usb
);
5334 UNUSED_PARAMETER(defaultsromvars_43143usb
);
5336 #endif /* BCMUSBDEV_BMAC || BCM_BMAC_VARS_APPEND */
5338 #ifdef BCM_DONGLEVARS /* this flag should be defined for usb bootloader, to read \
5340 if (BCME_OK
!= initvars_srom_si_bl(sih
, osh
, curmap
, vars
, varsz
))
5344 /* update static local var to skip for next call */
5345 srvars_inited
= TRUE
;
5348 /* Tell the caller there is no individual SROM variables */
5352 /* return OK so the driver will load & use defaults if bad srom/otp */
5356 #elif defined(BCMSDIODEV_ENABLED)
5358 #ifdef BCM_DONGLEVARS
5359 static uint8
BCMATTACHDATA(defcis4325
)[] = { 0x20, 0x4, 0xd0, 0x2, 0x25, 0x43, 0xff, 0xff };
5360 static uint8
BCMATTACHDATA(defcis4315
)[] = { 0x20, 0x4, 0xd0, 0x2, 0x15, 0x43, 0xff, 0xff };
5361 static uint8
BCMATTACHDATA(defcis4329
)[] = { 0x20, 0x4, 0xd0, 0x2, 0x29, 0x43, 0xff, 0xff };
5362 static uint8
BCMATTACHDATA(defcis4319
)[] = { 0x20, 0x4, 0xd0, 0x2, 0x19, 0x43, 0xff, 0xff };
5363 static uint8
BCMATTACHDATA(defcis4336
)[] = { 0x20, 0x4, 0xd0, 0x2, 0x36, 0x43, 0xff, 0xff };
5364 static uint8
BCMATTACHDATA(defcis4330
)[] = { 0x20, 0x4, 0xd0, 0x2, 0x30, 0x43, 0xff, 0xff };
5365 static uint8
BCMATTACHDATA(defcis43237
)[] = { 0x20, 0x4, 0xd0, 0x2, 0xe5, 0xa8, 0xff, 0xff };
5366 static uint8
BCMATTACHDATA(defcis4324
)[] = { 0x20, 0x4, 0xd0, 0x2, 0x24, 0x43, 0xff, 0xff };
5367 static uint8
BCMATTACHDATA(defcis4335
)[] = { 0x20, 0x4, 0xd0, 0x2, 0x24, 0x43, 0xff, 0xff };
5368 static uint8
BCMATTACHDATA(defcis4350
)[] = { 0x20, 0x4, 0xd0, 0x2, 0x50, 0x43, 0xff, 0xff };
5369 static uint8
BCMATTACHDATA(defcis43143
)[] = { 0x20, 0x4, 0xd0, 0x2, 0x87, 0xa8, 0xff, 0xff };
5371 #ifdef BCM_BMAC_VARS_APPEND
5373 static char BCMATTACHDATA(defaultsromvars_4319sdio
)[] =
5377 "boardtype=0x05a1\0"
5379 "boardflags=0x400201\0"
5380 "boardflags2=0x80\0"
5395 "cckdigfilttype=6\0"
5398 "ofdmpo=0x55553333\0"
5405 "macaddr=00:90:4c:06:c0:19\0"
5408 static char BCMATTACHDATA(defaultsromvars_4319sdio_hmb
)[] =
5412 "boardtype=0x058c\0"
5414 "boardflags=0x400201\0"
5415 "boardflags2=0x80\0"
5430 "cckdigfilttype=6\0"
5433 "ofdmpo=0x55553333\0"
5440 "macaddr=00:90:4c:06:c0:19\0"
5443 static char BCMATTACHDATA(defaultsromvars_4319sdio_usbsd
)[] =
5447 "boardtype=0x05a2\0"
5449 "boardflags=0x400201\0"
5450 "boardflags2=0x80\0"
5465 "cckdigfilttype=6\0"
5468 "ofdmpo=0x55553333\0"
5475 "macaddr=00:90:4c:08:90:00\0"
5478 static char BCMATTACHDATA(defaultsromvars_43237
)[] =
5481 "boardtype=0x0583\0"
5484 "boardflags=0x200\0"
5487 "macaddr=00:90:4c:51:a8:e4\0"
5518 "pa1lomaxpwr=0x3a\0"
5519 "pa1himaxpwr=0x3c\0"
5597 "pa5glw0a0=0xfeaa\0"
5598 "pa5glw1a0=0x14b9\0"
5599 "pa5glw2a0=0xfaf0\0"
5600 "pa5ghw0a0=0xfec5\0"
5601 "pa5ghw1a0=0x1439\0"
5602 "pa5ghw2a0=0xfb18\0"
5617 "pa5glw0a1=0xfece\0"
5618 "pa5glw1a1=0x1361\0"
5619 "pa5glw2a1=0xfb5f\0"
5620 "pa5ghw0a1=0xfe9e\0"
5621 "pa5ghw1a1=0x12ca\0"
5622 "pa5ghw2a1=0xfb41\0"
5625 static char BCMATTACHDATA(defaultsromvars_43143sdio
)[] =
5627 "subvendid=0x0a5c\0"
5629 "macaddr=00:90:4c:0e:81:23\0"
5647 "boardflags=0x200\0"
5648 "boardflags2=0x2000\0"
5649 "boardtype=0x0628\0"
5661 "temp_hysteresis=5\0"
5667 "swctrlmap_2g=0x06020602,0x0c080c08,0x04000400,0x00080808,0x6ff\0"
5668 "otpimagesize=154\0"
5672 srom_load_nvram(si_t
*sih
, osl_t
*osh
, uint8
*pcis
[], uint ciscnt
, char **vars
, uint
*varsz
)
5674 uint len
= 0, base_len
;
5678 base
= fakevars
= NULL
;
5679 switch (CHIPID(sih
->chip
)) {
5680 case BCM4319_CHIP_ID
:
5681 printf("load driver default for chip %x\n", CHIPID(sih
->chip
));
5682 fakevars
= defaultsromvars_4319sdio
;
5683 if (si_cis_source(sih
) == CIS_OTP
) {
5684 switch (srom_probe_boardtype(pcis
, ciscnt
)) {
5685 case BCM94319SDHMB_SSID
:
5686 fakevars
= defaultsromvars_4319sdio_hmb
;
5688 case BCM94319USBSDB_SSID
:
5689 fakevars
= defaultsromvars_4319sdio_usbsd
;
5692 fakevars
= defaultsromvars_4319sdio
;
5697 case BCM43237_CHIP_ID
:
5698 printf("load driver default for chip %x\n", CHIPID(sih
->chip
));
5699 fakevars
= defaultsromvars_43237
;
5701 case BCM43143_CHIP_ID
:
5702 printf("load driver default for chip %x\n", CHIPID(sih
->chip
));
5703 fakevars
= defaultsromvars_43143sdio
;
5706 printf("unknown chip %x\n", CHIPID(sih
->chip
));
5707 return BCME_ERROR
; /* fakevars == NULL for switch default */
5711 /* NO OTP, if nvram downloaded, use it */
5712 if ((_varsz
!= 0) && (_vars
!= NULL
)) {
5713 len
= _varsz
+ (strlen(vstr_end
));
5714 base_len
= len
+ 2; /* plus 2 terminating \0 */
5715 base
= MALLOC(osh
, base_len
);
5717 BS_ERROR(("initvars_srom_si: MALLOC failed.\n"));
5720 bzero(base
, base_len
);
5722 /* make a copy of the _vars, _vars is at the top of the memory, cannot append
5723 * END\0\0 to it. copy the download vars to base, back of the terminating \0,
5724 * then append END\0\0
5726 bcopy((void *)_vars
, base
, _varsz
);
5727 /* backoff all the terminating \0s except the one the for the last string */
5729 while (!base
[len
- 1])
5731 len
++; /* \0 for the last string */
5732 /* append END\0\0 to the end */
5733 bcopy((void *)vstr_end
, (base
+ len
), strlen(vstr_end
));
5734 len
+= (strlen(vstr_end
) + 2);
5738 BS_ERROR(("%s nvram downloaded %d bytes\n", __FUNCTION__
, _varsz
));
5740 /* Fall back to fake srom vars if OTP not programmed */
5741 len
= srom_vars_len(fakevars
);
5742 base
= MALLOC(osh
, (len
+ 1));
5745 BS_ERROR(("initvars_srom_si: MALLOC failed.\n"));
5748 bzero(base
, base_len
);
5749 bcopy(fakevars
, base
, len
);
5750 *(base
+ len
) = '\0'; /* add final nullbyte terminator */
5753 BS_ERROR(("srom_load_driver)default: faked nvram %d bytes\n", len
));
5756 if ((srom_parsecis(osh
, pcis
, ciscnt
, vars
, varsz
)) == BCME_OK
)
5757 nvram_append((void *)sih
, *vars
, *varsz
);
5758 MFREE(osh
, base
, base_len
);
5762 #endif /* BCM_BMAC_VARS_APPEND */
5765 BCMATTACHFN(initvars_srom_si
)(si_t
*sih
, osl_t
*osh
, void *curmap
, char **vars
, uint
*varsz
)
5772 bool new_cisformat
= FALSE
;
5774 uint16
*cisbuf
= NULL
;
5776 /* # sdiod fns + common + extra */
5777 uint8
*cis
[SBSDIO_NUM_FUNCTION
+ 2] = { 0 };
5783 /* Bail out if we've dealt with OTP/SPROM before! */
5787 /* Initialize default and cis format count */
5788 switch (CHIPID(sih
->chip
)) {
5789 case BCM4325_CHIP_ID
: ciss
= 3; defcis
= defcis4325
; hdrsz
= 8; break;
5790 case BCM4315_CHIP_ID
: ciss
= 3; defcis
= defcis4315
; hdrsz
= 8; break;
5791 case BCM4329_CHIP_ID
: ciss
= 4; defcis
= defcis4329
; hdrsz
= 12; break;
5792 case BCM4319_CHIP_ID
: ciss
= 3; defcis
= defcis4319
; hdrsz
= 12; break;
5793 case BCM4336_CHIP_ID
: ciss
= 1; defcis
= defcis4336
; hdrsz
= 4; break;
5794 case BCM43362_CHIP_ID
: ciss
= 1; defcis
= defcis4336
; hdrsz
= 4; break;
5795 case BCM4330_CHIP_ID
: ciss
= 1; defcis
= defcis4330
; hdrsz
= 4; break;
5796 case BCM43237_CHIP_ID
: ciss
= 1; defcis
= defcis43237
; hdrsz
= 4; break;
5797 case BCM4324_CHIP_ID
: ciss
= 1; defcis
= defcis4324
; hdrsz
= 4; break;
5798 case BCM4314_CHIP_ID
: ciss
= 1; defcis
= defcis4330
; hdrsz
= 4; break;
5799 case BCM4334_CHIP_ID
: ciss
= 1; defcis
= defcis4330
; hdrsz
= 4; break;
5800 case BCM4335_CHIP_ID
: ciss
= 1; defcis
= defcis4335
; hdrsz
= 4; break;
5801 case BCM43143_CHIP_ID
: ciss
= 1; defcis
= defcis43143
; hdrsz
= 4; break;
5803 BS_ERROR(("%s: Unknown chip 0x%04x\n", __FUNCTION__
, sih
->chip
));
5806 if (sih
->ccrev
>= 36) {
5808 otplayout
= si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, otplayout
), 0, 0);
5809 if (otplayout
& OTP_CISFORMAT_NEW
) {
5812 new_cisformat
= TRUE
;
5820 cis_src
= si_cis_source(sih
);
5823 sz
= srom_size(sih
, osh
) << 1;
5826 if (((oh
= otp_init(sih
)) != NULL
) && (otp_status(oh
) & OTPS_GUP_HW
))
5832 if ((cisbuf
= (uint16
*)MALLOC(osh
, sz
)) == NULL
)
5838 rc
= srom_read(sih
, SI_BUS
, curmap
, osh
, 0, sz
, cisbuf
, FALSE
);
5842 rc
= otp_read_region(sih
, OTP_HW_RGN
, cisbuf
, &sz
);
5848 if (rc
== BCME_OK
) {
5849 if ((cisbuf
[0] == 0xffff) || (cisbuf
[0] == 0)) {
5850 MFREE(osh
, cisbuf
, msz
);
5852 } else if (new_cisformat
) {
5853 cis
[0] = (uint8
*)(cisbuf
+ hdrsz
);
5855 cis
[0] = (uint8
*)cisbuf
+ hdrsz
;
5856 cis
[1] = (uint8
*)cisbuf
+ hdrsz
+
5857 (cisbuf
[1] >> 8) + ((cisbuf
[2] & 0x00ff) << 8) -
5858 SBSDIO_CIS_BASE_COMMON
;
5859 cis
[2] = (uint8
*)cisbuf
+ hdrsz
+
5860 cisbuf
[3] - SBSDIO_CIS_BASE_COMMON
;
5861 cis
[3] = (uint8
*)cisbuf
+ hdrsz
+
5862 cisbuf
[4] - SBSDIO_CIS_BASE_COMMON
;
5863 ASSERT((cis
[1] >= cis
[0]) && (cis
[1] < (uint8
*)cisbuf
+ sz
));
5864 ASSERT((cis
[2] >= cis
[0]) && (cis
[2] < (uint8
*)cisbuf
+ sz
));
5865 ASSERT(((cis
[3] >= cis
[0]) && (cis
[3] < (uint8
*)cisbuf
+ sz
)) ||
5871 /* Use default if strapped to, or strapped source empty */
5872 if (cisbuf
== NULL
) {
5877 #ifdef BCM_BMAC_VARS_APPEND
5878 srom_load_nvram(sih
, osh
, cis
, ciss
, vars
, varsz
);
5881 if (rc
== BCME_OK
) {
5882 if ((rc
= srom_parsecis(osh
, cis
, ciss
, vars
, varsz
)) == BCME_OK
)
5883 nvram_append((void *)sih
, *vars
, *varsz
);
5885 #endif /* BCM_BMAC_VARS_APPEND */
5888 MFREE(osh
, cisbuf
, msz
);
5890 srvars_inited
= TRUE
;
5892 /* Tell the caller there is no individual SROM variables */
5896 /* return OK so the driver will load & use defaults if bad srom/otp */
5899 #else /* BCM_DONGLEVARS */
5901 BCMATTACHFN(initvars_srom_si
)(si_t
*sih
, osl_t
*osh
, void *curmap
, char **vars
, uint
*varsz
)
5907 #endif /* BCM_DONGLEVARS */
5909 #else /* !BCMUSBDEV && !BCMSDIODEV */
5912 BCMATTACHFN(initvars_srom_si
)(si_t
*sih
, osl_t
*osh
, void *curmap
, char **vars
, uint
*varsz
)
5914 /* Search flash nvram section for srom variables */
5915 return initvars_flash_si(sih
, vars
, varsz
);
5920 srom_var_deinit(si_t
*sih
)
5922 srvars_inited
= FALSE
;
5925 extern void _make_gcc_happy_about_unused_variabe_(void);
5927 _make_gcc_happy_about_unused_variabe_(void)
5929 #if defined(BCMUSBDEV)
5930 #if defined(BCMUSBDEV_BMAC) || defined(BCM_BMAC_VARS_APPEND)
5931 UNUSED_PARAMETER(defaultsromvars_4322usb
);
5932 UNUSED_PARAMETER(defaultsromvars_43234usb
);
5933 UNUSED_PARAMETER(defaultsromvars_43235usb
);
5934 UNUSED_PARAMETER(defaultsromvars_43236usb
);
5935 UNUSED_PARAMETER(defaultsromvars_4319usb
);
5936 #endif /* BCMUSBDEV_BMAC || BCM_BMAC_VARS_APPEND */
5937 #endif /* BCMUSBDEV */