2 * Routines to access SPROM and to parse SROM/CIS variables.
4 * Copyright (C) 2011, 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 323253 2012-03-23 17:21:10Z $
25 #if defined(__FreeBSD__) || defined(__NetBSD__)
26 #include <machine/stdarg.h>
34 #include <bcmendian.h>
39 #include <bcmsrom_tbl.h>
47 #if defined(BCMUSBDEV)
50 #include <sbsdpcmdev.h>
53 #if defined(WLTEST) || defined(DHD_SPROM) || defined(BCMDBG)
56 #include <proto/ethernet.h> /* for sprom content groking */
59 #if defined(BCMDBG_ERR) || defined(WLTEST)
60 #define BS_ERROR(args) printf args
62 #define BS_ERROR(args)
65 #define SROM_OFFSET(sih) ((sih->ccrev > 31) ? \
66 (((sih->cccaps & CC_CAP_SROM) == 0) ? NULL : \
67 ((uint8 *)curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP)) : \
68 ((uint8 *)curmap + PCI_BAR0_SPROM_OFFSET))
70 #if defined(WLTEST) || defined(DHD_SPROM) || defined(BCMDBG)
71 #define WRITE_ENABLE_DELAY 500 /* 500 ms after write enable/disable toggle */
72 #define WRITE_WORD_DELAY 20 /* 20 ms between each word write */
75 typedef struct varbuf
{
76 char *base
; /* pointer to buffer base */
77 char *buf
; /* pointer to current position */
78 unsigned int size
; /* current (residual) size in bytes */
83 #define SROM_CIS_SINGLE 1
86 static int initvars_srom_si(si_t
*sih
, osl_t
*osh
, void *curmap
, char **vars
, uint
*count
);
87 static void _initvars_srom_pci(uint8 sromrev
, uint16
*srom
, uint off
, varbuf_t
*b
);
88 static int initvars_srom_pci(si_t
*sih
, void *curmap
, char **vars
, uint
*count
);
89 static int initvars_cis_pcmcia(si_t
*sih
, osl_t
*osh
, char **vars
, uint
*count
);
90 #if !defined(BCMUSBDEV_ENABLED) && !defined(BCMSDIODEV_ENABLED)
91 static int initvars_flash_si(si_t
*sih
, char **vars
, uint
*count
);
94 static int initvars_cis_spi(osl_t
*osh
, char **vars
, uint
*count
);
96 static int sprom_cmd_pcmcia(osl_t
*osh
, uint8 cmd
);
97 static int sprom_read_pcmcia(osl_t
*osh
, uint16 addr
, uint16
*data
);
98 #if defined(WLTEST) || defined(DHD_SPROM) || defined(BCMDBG)
99 static int sprom_write_pcmcia(osl_t
*osh
, uint16 addr
, uint16 data
);
101 static int sprom_read_pci(osl_t
*osh
, si_t
*sih
, uint16
*sprom
, uint wordoff
, uint16
*buf
,
102 uint nwords
, bool check_crc
);
103 #if defined(BCMNVRAMW) || defined(BCMNVRAMR)
104 static int otp_read_pci(osl_t
*osh
, si_t
*sih
, uint16
*buf
, uint bufsz
);
105 #endif /* defined(BCMNVRAMW) || defined(BCMNVRAMR) */
106 static uint16
srom_cc_cmd(si_t
*sih
, osl_t
*osh
, void *ccregs
, uint32 cmd
, uint wordoff
,
109 static int initvars_table(osl_t
*osh
, char *start
, char *end
, char **vars
, uint
*count
);
110 static int initvars_flash(si_t
*sih
, osl_t
*osh
, char **vp
, uint len
);
112 #if defined(BCMUSBDEV)
113 static int get_si_pcmcia_srom(si_t
*sih
, osl_t
*osh
, uint8
*pcmregs
,
114 uint boff
, uint16
*srom
, uint bsz
, bool check_crc
);
115 #if defined(WLTEST) || defined(DHD_SPROM) || defined(BCMDBG)
116 static int set_si_pcmcia_srom(si_t
*sih
, osl_t
*osh
, uint8
*pcmregs
,
117 uint boff
, uint16
*srom
, uint bsz
);
121 #if defined(BCMUSBDEV)
122 #if defined(BCMUSBDEV_BMAC) || defined(BCM_BMAC_VARS_APPEND)
123 /* default to bcm94323 P200, other boards should have OTP programmed */
124 static char BCMATTACHDATA(defaultsromvars_4322usb
)[] =
128 "macaddr=00:90:4c:d3:04:73\0"
133 "boardflags2=0x602\0"
200 static char BCMATTACHDATA(defaultsromvars_43234usb
)[] =
204 "macaddr=00:90:4c:03:21:23\0"
226 "boardflags2=0x2000\0"
300 static char BCMATTACHDATA(defaultsromvars_43235usb
)[] =
304 "macaddr=00:90:4c:05:30:01\0"
353 "temp_hysteresis=5\0"
356 static char BCMATTACHDATA(defaultsromvars_43236usb
)[] =
360 "macaddr=00:90:4c:03:21:23\0"
382 "boardflags2=0x2000\0"
394 "ofdm2gpo=0x33333333\0"
456 "temp_hysteresis=5\0"
459 static char BCMATTACHDATA(defaultsromvars_4319usb
)[] =
484 "ofdmpo=0x44441111\0"
488 "macaddr=00:90:4c:16:${maclo}\0"
492 static char BCMATTACHDATA(defaultsromvars_4360usb
)[] =
496 "boardvendor=0x14e4\0"
499 "boardflags=0x10001000\0"
502 "macaddr=00:90:4c:0e:60:01\0"
530 "rawtempsense=0x1ff\0"
532 "tempsense_slope=0xff\0"
534 "tempsense_option=0x3\0"
535 "phycal_tempdelta=255\0"
537 "temps_hysteresis=15\0"
540 "pcieingress_war=15\0"
558 "rxgainerr2g=0xffff\0"
559 "rxgainerr5g=0xffff,0xffff,0xffff,0xffff\0"
561 "pa2ga0=0xfe72,0x14c0,0xfac7\0"
562 "rxgains2gelnagaina0=4\0"
563 "rxgains2gtrisoa0=10\0"
564 "rxgains2gtrelnabypa0=1\0"
565 "rxgains5gelnagaina0=4\0"
566 "rxgains5gtrisoa0=11\0"
567 "rxgains5gtrelnabypa0=1\0"
568 "maxp5ga0=72,72,76,76\0"
569 "pa5ga0=0xfe75,0x14b5,0xfad4,0xfe97,0x121a,0xfb6e,0xfe7f,0x149d,0xfad0,0xfe7c,0x1431,0xfae6\0"
571 "pa2ga1=0xfe80,0x1472,0xfabc\0"
572 "rxgains2gelnagaina1=4\0"
573 "rxgains2gtrisoa1=10\0"
574 "rxgains2gtrelnabypa1=1\0"
575 "rxgains5gelnagaina1=4\0"
576 "rxgains5gtrisoa1=11\0"
577 "rxgains5gtrelnabypa1=1\0"
578 "maxp5ga1=72,72,76,76\0"
579 "pa5ga1=0xfe72,0x155e,0xfa96,0xfea1,0x125d,0xfb55,0xfe77,0x1596,0xfa8e,0xfe78,0x15e1,0xfa7a\0"
582 #endif /* BCMUSBDEV_BMAC || BCM_BMAC_VARS_APPEND */
583 #endif /* BCMUSBDEV */
586 /* BCMHOSTVARS is enabled only if WLTEST is enabled or BCMEXTNVM is enabled */
587 #if defined(BCMHOSTVARS)
588 /* Also used by wl_readconfigdata for vars download */
589 char BCMATTACHDATA(mfgsromvars
)[VARS_MAX
];
590 int BCMATTACHDATA(defvarslen
) = 0;
593 /* BCMHOSTVARS is enabled only if WLTEST is enabled or BCMEXTNVM is enabled */
594 #if defined(BCMHOSTVARS)
595 static char BCMATTACHDATA(defaultsromvars_4331
)[] =
601 "boardvendor=0x14e4\0"
603 "macaddr=00:90:4c:1a:20:64\0"
666 "cckbw20ul2gpo=0x0\0"
667 "legofdmbw202gpo=0x0\0"
668 "legofdmbw20ul2gpo=0x0\0"
669 "legofdmbw205glpo=0x0\0"
670 "legofdmbw20ul5glpo=0x0\0"
671 "legofdmbw205gmpo=0x0\0"
672 "legofdmbw20ul5gmpo=0x0\0"
673 "legofdmbw205ghpo=0x0\0"
674 "legofdmbw20ul5ghpo=0x0\0"
676 "mcsbw20ul2gpo=0x0\0"
679 "mcsbw20ul5glpo=0x0\0"
682 "mcsbw20ul5gmpo=0x0\0"
685 "mcsbw20ul5ghpo=0x0\0"
688 "legofdm40duppo=0x0\0"
728 /* BCMHOSTVARS is enabled only if WLTEST is enabled or BCMEXTNVM is enabled */
729 #if defined(BCMHOSTVARS)
730 static char BCMATTACHDATA(defaultsromvars_wltest
)[] =
731 "macaddr=00:90:4c:f8:00:01\0"
732 "et0macaddr=00:11:22:33:44:52\0"
736 "boardvendor=0x14e4\0"
796 static bool srvars_inited
= FALSE
; /* Use OTP/SROM as global variables */
798 /* BCMHOSTVARS is enabled only if WLTEST is enabled or BCMEXTNVM is enabled */
799 #if defined(BCMHOSTVARS) || (defined(BCMUSBDEV_BMAC) || defined(BCM_BMAC_VARS_APPEND))
800 /* It must end with pattern of "END" */
802 BCMATTACHFN(srom_vars_len
)(char *vars
)
808 for (s
= vars
; s
&& *s
;) {
810 if (strcmp(s
, "END") == 0)
816 /* BS_ERROR(("len %d vars[pos] %s\n", pos, s)); */
822 return pos
+ 4; /* include the "END\0" */
826 /* Initialization of varbuf structure */
828 BCMATTACHFN(varbuf_init
)(varbuf_t
*b
, char *buf
, uint size
)
831 b
->base
= b
->buf
= buf
;
834 /* append a null terminated var=value string */
836 BCMATTACHFN(varbuf_append
)(varbuf_t
*b
, const char *fmt
, ...)
847 r
= vsnprintf(b
->buf
, b
->size
, fmt
, ap
);
850 /* C99 snprintf behavior returns r >= size on overflow,
851 * others return -1 on overflow.
852 * All return -1 on format error.
853 * We need to leave room for 2 null terminations, one for the current var
854 * string, and one for final null of the var table. So check that the
855 * strlen written, r, leaves room for 2 chars.
857 if ((r
== -1) || (r
> (int)(b
->size
- 2))) {
862 /* Remove any earlier occurrence of the same variable */
863 if ((s
= strchr(b
->buf
, '=')) != NULL
) {
864 len
= (size_t)(s
- b
->buf
);
865 for (s
= b
->base
; s
< b
->buf
;) {
866 if ((bcmp(s
, b
->buf
, len
) == 0) && s
[len
] == '=') {
868 memmove(s
, (s
+ len
), ((b
->buf
+ r
+ 1) - (s
+ len
)));
870 b
->size
+= (unsigned int)len
;
879 /* skip over this string's null termination */
888 * Initialize local vars from the right source for this platform.
889 * Return 0 on success, nonzero on error.
892 BCMATTACHFN(srom_var_init
)(si_t
*sih
, uint bustype
, void *curmap
, osl_t
*osh
,
893 char **vars
, uint
*count
)
895 ASSERT(bustype
== BUSTYPE(bustype
));
896 if (vars
== NULL
|| count
== NULL
)
902 switch (BUSTYPE(bustype
)) {
905 return initvars_srom_si(sih
, osh
, curmap
, vars
, count
);
908 ASSERT(curmap
!= NULL
);
912 return initvars_srom_pci(sih
, curmap
, vars
, count
);
915 return initvars_cis_pcmcia(sih
, osh
, vars
, count
);
920 return initvars_cis_spi(osh
, vars
, count
);
929 /* support only 16-bit word read from srom */
931 srom_read(si_t
*sih
, uint bustype
, void *curmap
, osl_t
*osh
,
932 uint byteoff
, uint nbytes
, uint16
*buf
, bool check_crc
)
936 ASSERT(bustype
== BUSTYPE(bustype
));
938 /* check input - 16-bit access only */
939 if (byteoff
& 1 || nbytes
& 1 || (byteoff
+ nbytes
) > SROM_MAX
)
945 if (BUSTYPE(bustype
) == PCI_BUS
) {
949 if (si_is_sprom_available(sih
)) {
952 srom
= (uint16
*)SROM_OFFSET(sih
);
956 if (sprom_read_pci(osh
, sih
, srom
, off
, buf
, nw
, check_crc
))
959 #if defined(BCMNVRAMW) || defined(BCMNVRAMR)
961 if (otp_read_pci(osh
, sih
, buf
, SROM_MAX
))
965 } else if (BUSTYPE(bustype
) == PCMCIA_BUS
) {
966 for (i
= 0; i
< nw
; i
++) {
967 if (sprom_read_pcmcia(osh
, (uint16
)(off
+ i
), (uint16
*)(buf
+ i
)))
971 } else if (BUSTYPE(bustype
) == SPI_BUS
) {
972 if (bcmsdh_cis_read(NULL
, SDIO_FUNC_1
, (uint8
*)buf
, byteoff
+ nbytes
) != 0)
975 } else if (BUSTYPE(bustype
) == SI_BUS
) {
976 #if defined(BCMUSBDEV)
977 if (SPROMBUS
== PCMCIA_BUS
) {
983 /* Don't bother if we can't talk to SPROM */
984 if (!si_is_sprom_available(sih
))
987 origidx
= si_coreidx(sih
);
988 regs
= si_setcore(sih
, PCMCIA_CORE_ID
, 0);
990 regs
= si_setcore(sih
, SDIOD_CORE_ID
, 0);
991 ASSERT(regs
!= NULL
);
993 if (!(wasup
= si_iscoreup(sih
)))
994 si_core_reset(sih
, 0, 0);
996 rc
= get_si_pcmcia_srom(sih
, osh
, regs
, byteoff
, buf
, nbytes
, check_crc
);
999 si_core_disable(sih
, 0);
1001 si_setcoreidx(sih
, origidx
);
1014 #if defined(WLTEST) || defined(DHD_SPROM) || defined(BCMDBG)
1015 /* support only 16-bit word write into srom */
1017 srom_write(si_t
*sih
, uint bustype
, void *curmap
, osl_t
*osh
,
1018 uint byteoff
, uint nbytes
, uint16
*buf
)
1020 uint i
, nw
, crc_range
;
1023 volatile uint32 val32
;
1026 ASSERT(bustype
== BUSTYPE(bustype
));
1028 old
= MALLOC(osh
, SROM_MAXW
* sizeof(uint16
));
1029 new = MALLOC(osh
, SROM_MAXW
* sizeof(uint16
));
1031 if (old
== NULL
|| new == NULL
)
1034 /* check input - 16-bit access only. use byteoff 0x55aa to indicate
1037 if ((byteoff
!= 0x55aa) && ((byteoff
& 1) || (nbytes
& 1)))
1040 if ((byteoff
!= 0x55aa) && ((byteoff
+ nbytes
) > SROM_MAX
))
1043 if (BUSTYPE(bustype
) == PCMCIA_BUS
) {
1044 crc_range
= SROM_MAX
;
1046 #if defined(BCMUSBDEV)
1048 crc_range
= srom_size(sih
, osh
);
1052 crc_range
= (SROM8_SIGN
+ 1) * 2; /* must big enough for SROM8 */
1057 /* read first small number words from srom, then adjust the length, read all */
1058 if (srom_read(sih
, bustype
, curmap
, osh
, 0, crc_range
, old
, FALSE
))
1061 BS_ERROR(("%s: old[SROM4_SIGN] 0x%x, old[SROM8_SIGN] 0x%x\n",
1062 __FUNCTION__
, old
[SROM4_SIGN
], old
[SROM8_SIGN
]));
1063 /* Deal with blank srom */
1064 if (old
[0] == 0xffff) {
1065 /* see if the input buffer is valid SROM image or not */
1066 if (buf
[SROM11_SIGN
] == SROM11_SIGNATURE
) {
1067 BS_ERROR(("%s: buf[SROM11_SIGN] 0x%x\n",
1068 __FUNCTION__
, buf
[SROM11_SIGN
]));
1070 /* block invalid buffer size */
1071 if (nbytes
< SROM11_WORDS
* 2) {
1072 rc
= BCME_BUFTOOSHORT
;
1074 } else if (nbytes
> SROM11_WORDS
* 2) {
1075 rc
= BCME_BUFTOOLONG
;
1080 } else if ((buf
[SROM4_SIGN
] == SROM4_SIGNATURE
) ||
1081 (buf
[SROM8_SIGN
] == SROM4_SIGNATURE
)) {
1082 BS_ERROR(("%s: buf[SROM4_SIGN] 0x%x, buf[SROM8_SIGN] 0x%x\n",
1083 __FUNCTION__
, buf
[SROM4_SIGN
], buf
[SROM8_SIGN
]));
1085 /* block invalid buffer size */
1086 if (nbytes
< SROM4_WORDS
* 2) {
1087 rc
= BCME_BUFTOOSHORT
;
1089 } else if (nbytes
> SROM4_WORDS
* 2) {
1090 rc
= BCME_BUFTOOLONG
;
1095 } else if (nbytes
== SROM_WORDS
* 2){ /* the other possible SROM format */
1096 BS_ERROR(("%s: Not SROM4 or SROM8.\n", __FUNCTION__
));
1100 BS_ERROR(("%s: Invalid input file signature\n", __FUNCTION__
));
1105 if (srom_read(sih
, bustype
, curmap
, osh
, 0, crc_range
, old
, FALSE
))
1107 } else if (old
[SROM11_SIGN
] == SROM11_SIGNATURE
) {
1110 if (srom_read(sih
, bustype
, curmap
, osh
, 0, crc_range
, old
, FALSE
))
1112 } else if ((old
[SROM4_SIGN
] == SROM4_SIGNATURE
) ||
1113 (old
[SROM8_SIGN
] == SROM4_SIGNATURE
)) {
1116 if (srom_read(sih
, bustype
, curmap
, osh
, 0, crc_range
, old
, FALSE
))
1119 /* Assert that we have already read enough for sromrev 2 */
1120 ASSERT(crc_range
>= SROM_WORDS
* 2);
1125 if (byteoff
== 0x55aa) {
1128 memset((void *)new, 0xff, nw
* 2);
1130 /* Copy old contents */
1131 bcopy((void *)old
, (void *)new, nw
* 2);
1133 bcopy((void *)buf
, (void *)&new[byteoff
/ 2], nbytes
);
1138 htol16_buf(new, crc_range
);
1139 crc
= ~hndcrc8((uint8
*)new, crc_range
- 1, CRC8_INIT_VALUE
);
1140 ltoh16_buf(new, crc_range
);
1141 new[nw
- 1] = (crc
<< 8) | (new[nw
- 1] & 0xff);
1144 if (BUSTYPE(bustype
) == PCI_BUS
) {
1145 uint16
*srom
= NULL
;
1146 void *ccregs
= NULL
;
1149 if ((CHIPID(sih
->chip
) == BCM4331_CHIP_ID
) ||
1150 (CHIPID(sih
->chip
) == BCM43431_CHIP_ID
) ||
1151 (CHIPID(sih
->chip
) == BCM4360_CHIP_ID
) ||
1152 (CHIPID(sih
->chip
) == BCM43460_CHIP_ID
) ||
1153 (CHIPID(sih
->chip
) == BCM4352_CHIP_ID
)) {
1154 /* save current control setting */
1155 ccval
= si_chipcontrl_read(sih
);
1158 if ((CHIPID(sih
->chip
) == BCM4331_CHIP_ID
) ||
1159 (CHIPID(sih
->chip
) == BCM43431_CHIP_ID
)) {
1160 /* Disable Ext PA lines to allow reading from SROM */
1161 si_chipcontrl_epa4331(sih
, FALSE
);
1162 } else if ((CHIPID(sih
->chip
) == BCM4360_CHIP_ID
) ||
1163 (CHIPID(sih
->chip
) == BCM43460_CHIP_ID
) ||
1164 (CHIPID(sih
->chip
) == BCM4352_CHIP_ID
)) {
1165 si_chipcontrl_srom4360(sih
, TRUE
);
1168 /* enable writes to the SPROM */
1169 if (sih
->ccrev
> 31) {
1170 ccregs
= (void *)((uint8
*)curmap
+ PCI_16KB0_CCREGS_OFFSET
);
1171 srom
= (uint16
*)((uint8
*)ccregs
+ CC_SROM_OTP
);
1172 (void)srom_cc_cmd(sih
, osh
, ccregs
, SRC_OP_WREN
, 0, 0);
1174 srom
= (uint16
*)((uint8
*)curmap
+ PCI_BAR0_SPROM_OFFSET
);
1175 val32
= OSL_PCI_READ_CONFIG(osh
, PCI_SPROM_CONTROL
, sizeof(uint32
));
1176 val32
|= SPROM_WRITEEN
;
1177 OSL_PCI_WRITE_CONFIG(osh
, PCI_SPROM_CONTROL
, sizeof(uint32
), val32
);
1179 bcm_mdelay(WRITE_ENABLE_DELAY
);
1181 for (i
= 0; i
< nw
; i
++) {
1182 if (old
[i
] != new[i
]) {
1183 if (sih
->ccrev
> 31) {
1184 if ((sih
->cccaps
& CC_CAP_SROM
) == 0) {
1185 /* No srom support in this chip */
1186 BS_ERROR(("srom_write, invalid srom, skip\n"));
1188 (void)srom_cc_cmd(sih
, osh
, ccregs
, SRC_OP_WRITE
,
1191 W_REG(osh
, &srom
[i
], new[i
]);
1193 bcm_mdelay(WRITE_WORD_DELAY
);
1196 /* disable writes to the SPROM */
1197 if (sih
->ccrev
> 31) {
1198 (void)srom_cc_cmd(sih
, osh
, ccregs
, SRC_OP_WRDIS
, 0, 0);
1200 OSL_PCI_WRITE_CONFIG(osh
, PCI_SPROM_CONTROL
, sizeof(uint32
), val32
&
1204 if ((CHIPID(sih
->chip
) == BCM4331_CHIP_ID
) ||
1205 (CHIPID(sih
->chip
) == BCM43431_CHIP_ID
) ||
1206 (CHIPID(sih
->chip
) == BCM4360_CHIP_ID
) ||
1207 (CHIPID(sih
->chip
) == BCM43460_CHIP_ID
) ||
1208 (CHIPID(sih
->chip
) == BCM4352_CHIP_ID
)) {
1209 /* Restore config after reading SROM */
1210 si_chipcontrl_restore(sih
, ccval
);
1213 } else if (BUSTYPE(bustype
) == PCMCIA_BUS
) {
1214 /* enable writes to the SPROM */
1215 if (sprom_cmd_pcmcia(osh
, SROM_WEN
))
1217 bcm_mdelay(WRITE_ENABLE_DELAY
);
1219 for (i
= 0; i
< nw
; i
++) {
1220 if (old
[i
] != new[i
]) {
1221 sprom_write_pcmcia(osh
, (uint16
)(i
), new[i
]);
1222 bcm_mdelay(WRITE_WORD_DELAY
);
1225 /* disable writes to the SPROM */
1226 if (sprom_cmd_pcmcia(osh
, SROM_WDS
))
1228 } else if (BUSTYPE(bustype
) == SI_BUS
) {
1229 #if defined(BCMUSBDEV)
1230 if (SPROMBUS
== PCMCIA_BUS
) {
1235 origidx
= si_coreidx(sih
);
1236 regs
= si_setcore(sih
, PCMCIA_CORE_ID
, 0);
1238 regs
= si_setcore(sih
, SDIOD_CORE_ID
, 0);
1239 ASSERT(regs
!= NULL
);
1241 if (!(wasup
= si_iscoreup(sih
)))
1242 si_core_reset(sih
, 0, 0);
1244 rc
= set_si_pcmcia_srom(sih
, osh
, regs
, byteoff
, buf
, nbytes
);
1247 si_core_disable(sih
, 0);
1249 si_setcoreidx(sih
, origidx
);
1258 bcm_mdelay(WRITE_ENABLE_DELAY
);
1263 MFREE(osh
, old
, SROM_MAXW
* sizeof(uint16
));
1265 MFREE(osh
, new, SROM_MAXW
* sizeof(uint16
));
1271 #if defined(BCMUSBDEV)
1272 #define SI_PCMCIA_READ(osh, regs, fcr) \
1273 R_REG(osh, (volatile uint8 *)(regs) + 0x600 + (fcr) - 0x700 / 2)
1274 #define SI_PCMCIA_WRITE(osh, regs, fcr, v) \
1275 W_REG(osh, (volatile uint8 *)(regs) + 0x600 + (fcr) - 0x700 / 2, v)
1277 /* set PCMCIA srom command register */
1279 srom_cmd_si_pcmcia(osl_t
*osh
, uint8
*pcmregs
, uint8 cmd
)
1284 /* write srom command register */
1285 SI_PCMCIA_WRITE(osh
, pcmregs
, SROM_CS
, cmd
);
1288 while (++wait_cnt
< 1000000) {
1289 status
= SI_PCMCIA_READ(osh
, pcmregs
, SROM_CS
);
1290 if (status
& SROM_DONE
)
1295 BS_ERROR(("sr_cmd: Give up after %d tries, stat = 0x%x\n", wait_cnt
, status
));
1299 /* read a word from the PCMCIA srom over SI */
1301 srom_read_si_pcmcia(osl_t
*osh
, uint8
*pcmregs
, uint16 addr
, uint16
*data
)
1303 uint8 addr_l
, addr_h
, data_l
, data_h
;
1305 addr_l
= (uint8
)((addr
* 2) & 0xff);
1306 addr_h
= (uint8
)(((addr
* 2) >> 8) & 0xff);
1309 SI_PCMCIA_WRITE(osh
, pcmregs
, SROM_ADDRH
, addr_h
);
1310 SI_PCMCIA_WRITE(osh
, pcmregs
, SROM_ADDRL
, addr_l
);
1313 if (srom_cmd_si_pcmcia(osh
, pcmregs
, SROM_READ
))
1317 data_h
= SI_PCMCIA_READ(osh
, pcmregs
, SROM_DATAH
);
1318 data_l
= SI_PCMCIA_READ(osh
, pcmregs
, SROM_DATAL
);
1319 *data
= ((uint16
)data_h
<< 8) | data_l
;
1324 #if defined(WLTEST) || defined(DHD_SPROM) || defined(BCMDBG)
1325 /* write a word to the PCMCIA srom over SI */
1327 srom_write_si_pcmcia(osl_t
*osh
, uint8
*pcmregs
, uint16 addr
, uint16 data
)
1329 uint8 addr_l
, addr_h
, data_l
, data_h
;
1332 addr_l
= (uint8
)((addr
* 2) & 0xff);
1333 addr_h
= (uint8
)(((addr
* 2) >> 8) & 0xff);
1336 SI_PCMCIA_WRITE(osh
, pcmregs
, SROM_ADDRH
, addr_h
);
1337 SI_PCMCIA_WRITE(osh
, pcmregs
, SROM_ADDRL
, addr_l
);
1339 data_l
= (uint8
)(data
& 0xff);
1340 data_h
= (uint8
)((data
>> 8) & 0xff);
1343 SI_PCMCIA_WRITE(osh
, pcmregs
, SROM_DATAH
, data_h
);
1344 SI_PCMCIA_WRITE(osh
, pcmregs
, SROM_DATAL
, data_l
);
1347 rc
= srom_cmd_si_pcmcia(osh
, pcmregs
, SROM_WRITE
);
1354 * Read the srom for the pcmcia-srom over si case.
1355 * Return 0 on success, nonzero on error.
1358 get_si_pcmcia_srom(si_t
*sih
, osl_t
*osh
, uint8
*pcmregs
,
1359 uint boff
, uint16
*srom
, uint bsz
, bool check_crc
)
1361 uint i
, nw
, woff
, wsz
;
1364 /* read must be at word boundary */
1365 ASSERT((boff
& 1) == 0 && (bsz
& 1) == 0);
1367 /* read sprom size and validate the parms */
1368 if ((nw
= srom_size(sih
, osh
)) == 0) {
1369 BS_ERROR(("get_si_pcmcia_srom: sprom size unknown\n"));
1373 if (boff
+ bsz
> 2 * nw
) {
1374 BS_ERROR(("get_si_pcmcia_srom: sprom size exceeded\n"));
1379 /* read in sprom contents */
1380 for (woff
= boff
/ 2, wsz
= bsz
/ 2, i
= 0;
1381 woff
< nw
&& i
< wsz
; woff
++, i
++) {
1382 if (srom_read_si_pcmcia(osh
, pcmregs
, (uint16
)woff
, &srom
[i
])) {
1383 BS_ERROR(("get_si_pcmcia_srom: sprom read failed\n"));
1390 if (srom
[0] == 0xffff) {
1391 /* The hardware thinks that an srom that starts with 0xffff
1392 * is blank, regardless of the rest of the content, so declare
1395 BS_ERROR(("%s: srom[0] == 0xffff, assuming unprogrammed srom\n",
1401 /* fixup the endianness so crc8 will pass */
1402 htol16_buf(srom
, nw
* 2);
1403 if (hndcrc8((uint8
*)srom
, nw
* 2, CRC8_INIT_VALUE
) != CRC8_GOOD_VALUE
) {
1404 BS_ERROR(("%s: bad crc\n", __FUNCTION__
));
1407 /* now correct the endianness of the byte array */
1408 ltoh16_buf(srom
, nw
* 2);
1415 #if defined(WLTEST) || defined(DHD_SPROM) || defined(BCMDBG)
1417 * Write the srom for the pcmcia-srom over si case.
1418 * Return 0 on success, nonzero on error.
1421 set_si_pcmcia_srom(si_t
*sih
, osl_t
*osh
, uint8
*pcmregs
,
1422 uint boff
, uint16
*srom
, uint bsz
)
1424 uint i
, nw
, woff
, wsz
;
1429 /* write must be at word boundary */
1430 ASSERT((boff
& 1) == 0 && (bsz
& 1) == 0);
1432 /* read sprom size and validate the parms */
1433 if ((nw
= srom_size(sih
, osh
)) == 0) {
1434 BS_ERROR(("set_si_pcmcia_srom: sprom size unknown\n"));
1438 if (boff
+ bsz
> 2 * nw
) {
1439 BS_ERROR(("set_si_pcmcia_srom: sprom size exceeded\n"));
1445 if (srom_cmd_si_pcmcia(osh
, pcmregs
, SROM_WEN
)) {
1446 BS_ERROR(("set_si_pcmcia_srom: sprom wen failed\n"));
1451 /* write buffer to sprom */
1452 for (woff
= boff
/ 2, wsz
= bsz
/ 2, i
= 0;
1453 woff
< nw
&& i
< wsz
; woff
++, i
++) {
1454 if (srom_write_si_pcmcia(osh
, pcmregs
, (uint16
)woff
, srom
[i
])) {
1455 BS_ERROR(("set_si_pcmcia_srom: sprom write failed\n"));
1462 crc
= CRC8_INIT_VALUE
;
1463 for (woff
= 0; woff
< nw
; woff
++) {
1464 if (srom_read_si_pcmcia(osh
, pcmregs
, (uint16
)woff
, &word
)) {
1465 BS_ERROR(("set_si_pcmcia_srom: sprom fix crc read failed\n"));
1469 word
= htol16(word
);
1470 crc
= hndcrc8((uint8
*)&word
, woff
!= nw
- 1 ? 2 : 1, crc
);
1472 word
= (~crc
<< 8) + (ltoh16(word
) & 0xff);
1473 if (srom_write_si_pcmcia(osh
, pcmregs
, (uint16
)(woff
- 1), word
)) {
1474 BS_ERROR(("set_si_pcmcia_srom: sprom fix crc write failed\n"));
1480 if (srom_cmd_si_pcmcia(osh
, pcmregs
, SROM_WDS
)) {
1481 BS_ERROR(("set_si_pcmcia_srom: sprom wds failed\n"));
1492 static const char BCMATTACHDATA(vstr_manf
)[] = "manf=%s";
1493 static const char BCMATTACHDATA(vstr_productname
)[] = "productname=%s";
1494 static const char BCMATTACHDATA(vstr_manfid
)[] = "manfid=0x%x";
1495 static const char BCMATTACHDATA(vstr_prodid
)[] = "prodid=0x%x";
1496 static const char BCMATTACHDATA(vstr_regwindowsz
)[] = "regwindowsz=%d";
1497 static const char BCMATTACHDATA(vstr_sromrev
)[] = "sromrev=%d";
1498 static const char BCMATTACHDATA(vstr_chiprev
)[] = "chiprev=%d";
1499 static const char BCMATTACHDATA(vstr_subvendid
)[] = "subvendid=0x%x";
1500 static const char BCMATTACHDATA(vstr_subdevid
)[] = "subdevid=0x%x";
1501 static const char BCMATTACHDATA(vstr_boardrev
)[] = "boardrev=0x%x";
1502 static const char BCMATTACHDATA(vstr_aa2g
)[] = "aa2g=0x%x";
1503 static const char BCMATTACHDATA(vstr_aa5g
)[] = "aa5g=0x%x";
1504 static const char BCMATTACHDATA(vstr_ag
)[] = "ag%d=0x%x";
1505 static const char BCMATTACHDATA(vstr_cc
)[] = "cc=%d";
1506 static const char BCMATTACHDATA(vstr_opo
)[] = "opo=%d";
1507 static const char BCMATTACHDATA(vstr_pa0b
)[][9] = { "pa0b0=%d", "pa0b1=%d", "pa0b2=%d" };
1508 static const char BCMATTACHDATA(vstr_pa0itssit
)[] = "pa0itssit=%d";
1509 static const char BCMATTACHDATA(vstr_pa0maxpwr
)[] = "pa0maxpwr=%d";
1510 static const char BCMATTACHDATA(vstr_pa1b
)[][9] = { "pa1b0=%d", "pa1b1=%d", "pa1b2=%d" };
1511 static const char BCMATTACHDATA(vstr_pa1lob
)[][11] =
1512 { "pa1lob0=%d", "pa1lob1=%d", "pa1lob2=%d" };
1513 static const char BCMATTACHDATA(vstr_pa1hib
)[][11] =
1514 { "pa1hib0=%d", "pa1hib1=%d", "pa1hib2=%d" };
1515 static const char BCMATTACHDATA(vstr_pa1itssit
)[] = "pa1itssit=%d";
1516 static const char BCMATTACHDATA(vstr_pa1maxpwr
)[] = "pa1maxpwr=%d";
1517 static const char BCMATTACHDATA(vstr_pa1lomaxpwr
)[] = "pa1lomaxpwr=%d";
1518 static const char BCMATTACHDATA(vstr_pa1himaxpwr
)[] = "pa1himaxpwr=%d";
1519 static const char BCMATTACHDATA(vstr_oem
)[] = "oem=%02x%02x%02x%02x%02x%02x%02x%02x";
1520 static const char BCMATTACHDATA(vstr_boardflags
)[] = "boardflags=0x%x";
1521 static const char BCMATTACHDATA(vstr_boardflags2
)[] = "boardflags2=0x%x";
1522 static const char BCMATTACHDATA(vstr_boardflags3
)[] = "boardflags3=0x%x";
1523 static const char BCMATTACHDATA(vstr_ledbh
)[] = "ledbh%d=0x%x";
1524 static const char BCMATTACHDATA(vstr_noccode
)[] = "ccode=0x0";
1525 static const char BCMATTACHDATA(vstr_ccode
)[] = "ccode=%c%c";
1526 static const char BCMATTACHDATA(vstr_cctl
)[] = "cctl=0x%x";
1527 static const char BCMATTACHDATA(vstr_cckpo
)[] = "cckpo=0x%x";
1528 static const char BCMATTACHDATA(vstr_ofdmpo
)[] = "ofdmpo=0x%x";
1529 static const char BCMATTACHDATA(vstr_rdlid
)[] = "rdlid=0x%x";
1530 static const char BCMATTACHDATA(vstr_rdlrndis
)[] = "rdlrndis=%d";
1531 static const char BCMATTACHDATA(vstr_rdlrwu
)[] = "rdlrwu=%d";
1532 static const char BCMATTACHDATA(vstr_usbfs
)[] = "usbfs=%d";
1533 static const char BCMATTACHDATA(vstr_wpsgpio
)[] = "wpsgpio=%d";
1534 static const char BCMATTACHDATA(vstr_wpsled
)[] = "wpsled=%d";
1535 static const char BCMATTACHDATA(vstr_rdlsn
)[] = "rdlsn=%d";
1536 static const char BCMATTACHDATA(vstr_rssismf2g
)[] = "rssismf2g=%d";
1537 static const char BCMATTACHDATA(vstr_rssismc2g
)[] = "rssismc2g=%d";
1538 static const char BCMATTACHDATA(vstr_rssisav2g
)[] = "rssisav2g=%d";
1539 static const char BCMATTACHDATA(vstr_bxa2g
)[] = "bxa2g=%d";
1540 static const char BCMATTACHDATA(vstr_rssismf5g
)[] = "rssismf5g=%d";
1541 static const char BCMATTACHDATA(vstr_rssismc5g
)[] = "rssismc5g=%d";
1542 static const char BCMATTACHDATA(vstr_rssisav5g
)[] = "rssisav5g=%d";
1543 static const char BCMATTACHDATA(vstr_bxa5g
)[] = "bxa5g=%d";
1544 static const char BCMATTACHDATA(vstr_tri2g
)[] = "tri2g=%d";
1545 static const char BCMATTACHDATA(vstr_tri5gl
)[] = "tri5gl=%d";
1546 static const char BCMATTACHDATA(vstr_tri5g
)[] = "tri5g=%d";
1547 static const char BCMATTACHDATA(vstr_tri5gh
)[] = "tri5gh=%d";
1548 static const char BCMATTACHDATA(vstr_rxpo2g
)[] = "rxpo2g=%d";
1549 static const char BCMATTACHDATA(vstr_rxpo5g
)[] = "rxpo5g=%d";
1550 static const char BCMATTACHDATA(vstr_boardtype
)[] = "boardtype=0x%x";
1551 static const char BCMATTACHDATA(vstr_leddc
)[] = "leddc=0x%04x";
1552 static const char BCMATTACHDATA(vstr_vendid
)[] = "vendid=0x%x";
1553 static const char BCMATTACHDATA(vstr_devid
)[] = "devid=0x%x";
1554 static const char BCMATTACHDATA(vstr_xtalfreq
)[] = "xtalfreq=%d";
1555 static const char BCMATTACHDATA(vstr_txchain
)[] = "txchain=0x%x";
1556 static const char BCMATTACHDATA(vstr_rxchain
)[] = "rxchain=0x%x";
1557 static const char BCMNMIATTACHDATA(vstr_elna2g
)[] = "elna2g=0x%x";
1558 static const char BCMNMIATTACHDATA(vstr_elna5g
)[] = "elna5g=0x%x";
1559 static const char BCMATTACHDATA(vstr_antswitch
)[] = "antswitch=0x%x";
1560 static const char BCMATTACHDATA(vstr_regrev
)[] = "regrev=0x%x";
1561 static const char BCMATTACHDATA(vstr_antswctl2g
)[] = "antswctl2g=0x%x";
1562 static const char BCMATTACHDATA(vstr_triso2g
)[] = "triso2g=0x%x";
1563 static const char BCMATTACHDATA(vstr_pdetrange2g
)[] = "pdetrange2g=0x%x";
1564 static const char BCMATTACHDATA(vstr_extpagain2g
)[] = "extpagain2g=0x%x";
1565 static const char BCMATTACHDATA(vstr_tssipos2g
)[] = "tssipos2g=0x%x";
1566 static const char BCMATTACHDATA(vstr_antswctl5g
)[] = "antswctl5g=0x%x";
1567 static const char BCMATTACHDATA(vstr_triso5g
)[] = "triso5g=0x%x";
1568 static const char BCMATTACHDATA(vstr_pdetrange5g
)[] = "pdetrange5g=0x%x";
1569 static const char BCMATTACHDATA(vstr_extpagain5g
)[] = "extpagain5g=0x%x";
1570 static const char BCMATTACHDATA(vstr_tssipos5g
)[] = "tssipos5g=0x%x";
1571 static const char BCMATTACHDATA(vstr_maxp2ga
)[] = "maxp2ga%d=0x%x";
1572 static const char BCMATTACHDATA(vstr_itt2ga0
)[] = "itt2ga0=0x%x";
1573 static const char BCMATTACHDATA(vstr_pa
)[] = "pa%dgw%da%d=0x%x";
1574 static const char BCMATTACHDATA(vstr_pahl
)[] = "pa%dg%cw%da%d=0x%x";
1575 static const char BCMATTACHDATA(vstr_maxp5ga0
)[] = "maxp5ga0=0x%x";
1576 static const char BCMATTACHDATA(vstr_itt5ga0
)[] = "itt5ga0=0x%x";
1577 static const char BCMATTACHDATA(vstr_maxp5gha0
)[] = "maxp5gha0=0x%x";
1578 static const char BCMATTACHDATA(vstr_maxp5gla0
)[] = "maxp5gla0=0x%x";
1579 static const char BCMATTACHDATA(vstr_itt2ga1
)[] = "itt2ga1=0x%x";
1580 static const char BCMATTACHDATA(vstr_maxp5ga1
)[] = "maxp5ga1=0x%x";
1581 static const char BCMATTACHDATA(vstr_itt5ga1
)[] = "itt5ga1=0x%x";
1582 static const char BCMATTACHDATA(vstr_maxp5gha1
)[] = "maxp5gha1=0x%x";
1583 static const char BCMATTACHDATA(vstr_maxp5gla1
)[] = "maxp5gla1=0x%x";
1584 static const char BCMATTACHDATA(vstr_cck2gpo
)[] = "cck2gpo=0x%x";
1585 static const char BCMATTACHDATA(vstr_ofdm2gpo
)[] = "ofdm2gpo=0x%x";
1586 static const char BCMATTACHDATA(vstr_ofdm5gpo
)[] = "ofdm5gpo=0x%x";
1587 static const char BCMATTACHDATA(vstr_ofdm5glpo
)[] = "ofdm5glpo=0x%x";
1588 static const char BCMATTACHDATA(vstr_ofdm5ghpo
)[] = "ofdm5ghpo=0x%x";
1589 static const char BCMATTACHDATA(vstr_cddpo
)[] = "cddpo=0x%x";
1590 static const char BCMATTACHDATA(vstr_stbcpo
)[] = "stbcpo=0x%x";
1591 static const char BCMATTACHDATA(vstr_bw40po
)[] = "bw40po=0x%x";
1592 static const char BCMATTACHDATA(vstr_bwduppo
)[] = "bwduppo=0x%x";
1593 static const char BCMATTACHDATA(vstr_mcspo
)[] = "mcs%dgpo%d=0x%x";
1594 static const char BCMATTACHDATA(vstr_mcspohl
)[] = "mcs%dg%cpo%d=0x%x";
1595 static const char BCMATTACHDATA(vstr_custom
)[] = "customvar%d=0x%x";
1596 static const char BCMATTACHDATA(vstr_cckdigfilttype
)[] = "cckdigfilttype=%d";
1597 static const char BCMATTACHDATA(vstr_usbflags
)[] = "usbflags=0x%x";
1598 #ifdef BCM_BOOTLOADER
1599 static const char BCMATTACHDATA(vstr_mdio
)[] = "mdio%d=0x%%x";
1600 static const char BCMATTACHDATA(vstr_mdioex
)[] = "mdioex%d=0x%%x";
1601 static const char BCMATTACHDATA(vstr_brmin
)[] = "brmin=0x%x";
1602 static const char BCMATTACHDATA(vstr_brmax
)[] = "brmax=0x%x";
1603 static const char BCMATTACHDATA(vstr_pllreg
)[] = "pll%d=0x%x";
1604 static const char BCMATTACHDATA(vstr_ccreg
)[] = "chipc%d=0x%x";
1605 static const char BCMATTACHDATA(vstr_regctrl
)[] = "reg%d=0x%x";
1606 static const char BCMATTACHDATA(vstr_time
)[] = "r%dt=0x%x";
1607 static const char BCMATTACHDATA(vstr_depreg
)[] = "r%dd=0x%x";
1608 static const char BCMATTACHDATA(vstr_usbpredly
)[] = "usbpredly=0x%x";
1609 static const char BCMATTACHDATA(vstr_usbpostdly
)[] = "usbpostdly=0x%x";
1610 static const char BCMATTACHDATA(vstr_usbrdy
)[] = "usbrdy=0x%x";
1611 static const char BCMATTACHDATA(vstr_hsicphyctrl1
)[] = "hsicphyctrl1=0x%x";
1612 static const char BCMATTACHDATA(vstr_hsicphyctrl2
)[] = "hsicphyctrl2=0x%x";
1613 static const char BCMATTACHDATA(vstr_usbdevctrl
)[] = "usbdevctrl=0x%x";
1614 static const char BCMATTACHDATA(vstr_bldr_reset_timeout
)[] = "bldr_to=0x%x";
1615 static const char BCMATTACHDATA(vstr_muxenab
)[] = "muxenab=0x%x";
1616 #endif /* BCM_BOOTLOADER */
1617 static const char BCMATTACHDATA(vstr_boardnum
)[] = "boardnum=%d";
1618 static const char BCMATTACHDATA(vstr_macaddr
)[] = "macaddr=%s";
1619 static const char BCMATTACHDATA(vstr_usbepnum
)[] = "usbepnum=0x%x";
1621 /* Power per rate for SROM V9 */
1622 static const char BCMATTACHDATA(vstr_cckbw202gpo
)[][19] =
1623 { "cckbw202gpo=0x%x", "cckbw20ul2gpo=0x%x" };
1624 static const char BCMATTACHDATA(vstr_legofdmbw202gpo
)[][22] =
1625 { "legofdmbw202gpo=0x%x", "legofdmbw20ul2gpo=0x%x" };
1626 static const char BCMATTACHDATA(vstr_legofdmbw205gpo
)[][24] =
1627 { "legofdmbw205glpo=0x%x", "legofdmbw20ul5glpo=0x%x",
1628 "legofdmbw205gmpo=0x%x", "legofdmbw20ul5gmpo=0x%x",
1629 "legofdmbw205ghpo=0x%x", "legofdmbw20ul5ghpo=0x%x" };
1631 static const char BCMATTACHDATA(vstr_mcs2gpo
)[][19] =
1632 { "mcsbw202gpo=0x%x", "mcsbw20ul2gpo=0x%x", "mcsbw402gpo=0x%x"};
1634 static const char BCMATTACHDATA(vstr_mcs5glpo
)[][20] =
1635 { "mcsbw205glpo=0x%x", "mcsbw20ul5glpo=0x%x", "mcsbw405glpo=0x%x"};
1637 static const char BCMATTACHDATA(vstr_mcs5gmpo
)[][20] =
1638 { "mcsbw205gmpo=0x%x", "mcsbw20ul5gmpo=0x%x", "mcsbw405gmpo=0x%x"};
1640 static const char BCMATTACHDATA(vstr_mcs5ghpo
)[][20] =
1641 { "mcsbw205ghpo=0x%x", "mcsbw20ul5ghpo=0x%x", "mcsbw405ghpo=0x%x"};
1643 static const char BCMATTACHDATA(vstr_mcs32po
)[] = "mcs32po=0x%x";
1644 static const char BCMATTACHDATA(vstr_legofdm40duppo
)[] = "legofdm40duppo=0x%x";
1647 static const char BCMATTACHDATA(vstr_tempthresh
)[] = "tempthresh=%d"; /* HNBU_TEMPTHRESH */
1648 static const char BCMATTACHDATA(vstr_temps_period
)[] = "temps_period=%d";
1649 static const char BCMATTACHDATA(vstr_temp_hysteresis
)[] = "temp_hysteresis=%d";
1650 static const char BCMATTACHDATA(vstr_tempoffset
)[] = "tempoffset=%d";
1651 static const char BCMATTACHDATA(vstr_temp_corrx
)[] = "tempcorrx=%d";
1652 static const char BCMATTACHDATA(vstr_tempsense_option
)[] = "tempsense_option=%d";
1653 static const char BCMATTACHDATA(vstr_phycal_tempdelta
)[] = "phycal_tempdelta=%d";
1654 static const char BCMATTACHDATA(vstr_tssiposslopeg
)[] = "tssiposslope%dg=%d"; /* HNBU_FEM_CFG */
1655 static const char BCMATTACHDATA(vstr_epagaing
)[] = "epagain%dg=%d";
1656 static const char BCMATTACHDATA(vstr_pdgaing
)[] = "pdgain%dg=%d";
1657 static const char BCMATTACHDATA(vstr_tworangetssi
)[] = "tworangetssi%dg=%d";
1658 static const char BCMATTACHDATA(vstr_papdcap
)[] = "papdcap%dg=%d";
1659 static const char BCMATTACHDATA(vstr_femctrl
)[] = "femctrl=%d";
1660 static const char BCMATTACHDATA(vstr_gainctrlsph
)[] = "gainctrlsph=%d";
1661 static const char BCMATTACHDATA(vstr_subband5gver
)[] = "subband5gver=%d"; /* HNBU_ACPA_CX */
1662 static const char BCMATTACHDATA(vstr_pa2ga
)[] = "pa2ga%d=0x%x,0x%x,0x%x";
1663 static const char BCMATTACHDATA(vstr_maxp5ga
)[] = "maxp5ga%d=0x%x,0x%x,0x%x,0x%x";
1664 static const char BCMATTACHDATA(vstr_pa5ga
)[] = "pa5ga%d=0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,"
1665 "0x%x,0x%x,0x%x,0x%x,0x%x,0x%x";
1666 static const char BCMATTACHDATA(vstr_rxgainsgelnagaina
)[] = "rxgains%dgelnagaina=%d";
1667 static const char BCMATTACHDATA(vstr_rxgainsgtrisoa
)[] = "rxgains%dgtrisoa%d=%d";
1668 static const char BCMATTACHDATA(vstr_rxgainsgtrelnabypa
)[] = "rxgains%dgtrelnabypa%d=%d";
1669 static const char BCMATTACHDATA(vstr_measpower
)[] = "measpower%d=0x%x"; /* HNBU_MEAS_PWR */
1670 static const char BCMATTACHDATA(vstr_measpowerX
)[] = "measpower%d=0x%x";
1671 static const char BCMATTACHDATA(vstr_rawtempsense
)[] = "rawtempsense=0x%x";
1672 /* HNBU_ACPPR_2GPO */
1673 static const char BCMATTACHDATA(vstr_dot11agofdmhrbw202gpo
)[] = "dot11agofdmhrbw202gpo=0x%x";
1674 static const char BCMATTACHDATA(vstr_ofdmlrbw202gpo
)[] = "ofdmlrbw202gpo=0x%x";
1675 static const char BCMATTACHDATA(vstr_mcsbw805glpo
)[] = "mcsbw805glpo=0x%x"; /* HNBU_ACPPR_5GPO */
1676 static const char BCMATTACHDATA(vstr_mcsbw1605glpo
)[] = "mcsbw1605glpo=0x%x";
1677 static const char BCMATTACHDATA(vstr_mcsbw805gmpo
)[] = "mcsbw805gmpo=0x%x";
1678 static const char BCMATTACHDATA(vstr_mcsbw1605gmpo
)[] = "mcsbw1605gmpo=0x%x";
1679 static const char BCMATTACHDATA(vstr_mcsbw805ghpo
)[] = "mcsbw805ghpo=0x%x";
1680 static const char BCMATTACHDATA(vstr_mcsbw1605ghpo
)[] = "mcsbw1605ghpo=0x%x";
1681 static const char BCMATTACHDATA(vstr_mcslr5rlpo
)[] = "mcslr5rlpo=0x%x";
1682 static const char BCMATTACHDATA(vstr_mcslr5gmpo
)[] = "mcslr5gmpo=0x%x";
1683 static const char BCMATTACHDATA(vstr_mcslr5ghpo
)[] = "mcslr5ghpo=0x%x";
1684 static const char BCMATTACHDATA(vstr_sb20in40rrpo
)[] = "sb20in40%crrpo=0x%x"; /* HNBU_ACPPR_SBPO */
1685 static const char BCMATTACHDATA(vstr_sb20in80and160r5gpo
)[] = "sb20in80and160%cr5g%cpo=0x%x";
1686 static const char BCMATTACHDATA(vstr_sb40and80r5gpo
)[] = "sb40and80%cr5g%cpo=0x%x";
1687 static const char BCMATTACHDATA(vstr_dot11agduprpo
)[] = "dot11agdup%crpo=0x%x";
1688 static const char BCMATTACHDATA(vstr_noiselvl2ga
)[] = "noiselvl2ga%d=%d"; /* HNBU_NOISELVL */
1689 static const char BCMATTACHDATA(vstr_noiselvl5ga
)[] = "noiselvl5g%ca%d=%d";
1690 static const char BCMATTACHDATA(vstr_rxgainerr2g
)[] = "rxgainerr2g=0x%x"; /* HNBU_RXGAIN_ERR */
1691 static const char BCMATTACHDATA(vstr_rxgainerr5g
)[] = "rxgainerr5g=0x%x,0x%x,0x%x,0x%x";
1692 static const char BCMATTACHDATA(vstr_agbg
)[] = "agbg%d=0x%x"; /* HNBU_AGBGA */
1693 static const char BCMATTACHDATA(vstr_aga
)[] = "aga%d=0x%x";
1695 static const char BCMATTACHDATA(vstr_uuid
)[] = "uuid=%s";
1697 static const char BCMATTACHDATA(vstr_end
)[] = "END\0";
1699 uint8 patch_pair
= 0;
1701 /* For dongle HW, accept partial calibration parameters */
1702 #if defined(BCMUSBDEV)
1703 #define BCMDONGLECASE(n) case n:
1705 #define BCMDONGLECASE(n)
1708 #ifdef BCM_BOOTLOADER
1709 /* The format of the PMUREGS OTP Tuple ->
1710 * 1 byte -> Lower 5 bits has the address of the register
1711 * Higher 3 bits has the mode of the register like
1712 * PLL, ChipCtrl, RegCtrl, UpDwn or Dependency mask
1713 * 4 bytes -> Value of the register to be updated.
1715 #define PMUREGS_MODE_MASK 0xE0
1716 #define PMUREGS_MODE_SHIFT 5
1717 #define PMUREGS_ADDR_MASK 0x1F
1718 #define PMUREGS_TPL_SIZE 5
1728 #define USBREGS_TPL_SIZE 5
1735 #define USBRDY_DLY_TYPE 0x8000 /* Bit indicating if the byte is pre or post delay value */
1736 #define USBRDY_DLY_MASK 0x7FFF /* Bits indicating the amount of delay */
1737 #define USBRDY_MAXOTP_SIZE 5 /* Max size of the OTP parameter */
1739 #endif /* BCM_BOOTLOADER */
1741 #ifdef BCM_BMAC_VARS_APPEND
1743 BCMATTACHFN(srom_probe_boardtype
)(uint8
*pcis
[], uint ciscnt
)
1747 uint8
*cis
, tup
, tlen
;
1749 for (cisnum
= 0; cisnum
< ciscnt
; cisnum
++) {
1754 if (tup
== CISTPL_NULL
|| tup
== CISTPL_END
)
1759 if ((i
+ tlen
) >= CIS_SIZE
)
1762 if ((tup
== CISTPL_BRCM_HNBU
) && (cis
[i
] == HNBU_BOARDTYPE
)) {
1763 return (int)((cis
[i
+ 2] << 8) + cis
[i
+ 1]);
1768 } while (tup
!= CISTPL_END
);
1773 #endif /* BCM_BMAC_VARS_APPEND */
1776 BCMATTACHFN(srom_parsecis
)(osl_t
*osh
, uint8
*pcis
[], uint ciscnt
, char **vars
, uint
*count
)
1781 uint8
*cis
, tup
, tlen
, sromrev
= 1;
1783 #ifndef BCM_BOOTLOADER
1784 bool ag_init
= FALSE
;
1793 ASSERT(vars
!= NULL
);
1794 ASSERT(count
!= NULL
);
1798 base
= MALLOC(osh
, MAXSZ_NVRAM_VARS
);
1799 ASSERT(base
!= NULL
);
1803 varbuf_init(&b
, base
, MAXSZ_NVRAM_VARS
);
1804 bzero(base
, MAXSZ_NVRAM_VARS
);
1805 #ifdef BCM_BMAC_VARS_APPEND
1806 /* 43236 use defaultsromvars_43236usb as the base,
1807 * then append and update it with the content from OTP.
1808 * Only revision/board specfic content or updates used to override
1809 * the driver default will be stored in OTP
1811 *count
-= (strlen(vstr_end
) + 1 + 1); /* back off the termnating END\0\0 from fakenvram */
1812 bcopy(*vars
, base
, *count
);
1814 #endif /* BCM_BMAC_VARS_APPEND */
1816 for (cisnum
= 0; cisnum
< ciscnt
; cisnum
++) {
1820 standard_cis
= TRUE
;
1824 if (tup
== CISTPL_NULL
|| tup
== CISTPL_END
)
1829 if (cis
[i
] == CISTPL_NULL
|| cis
[i
] == CISTPL_END
) {
1834 tup
= CISTPL_BRCM_HNBU
;
1838 if ((i
+ tlen
) >= CIS_SIZE
)
1843 /* assume the strings are good if the version field checks out */
1844 if (((cis
[i
+ 1] << 8) + cis
[i
]) >= 0x0008) {
1845 varbuf_append(&b
, vstr_manf
, &cis
[i
+ 2]);
1846 varbuf_append(&b
, vstr_productname
,
1847 &cis
[i
+ 3 + strlen((char *)&cis
[i
+ 2])]);
1852 varbuf_append(&b
, vstr_manfid
, (cis
[i
+ 1] << 8) + cis
[i
]);
1853 varbuf_append(&b
, vstr_prodid
, (cis
[i
+ 3] << 8) + cis
[i
+ 2]);
1862 case CISTPL_FID_SDIO
:
1866 /* set macaddr if HNBU_MACADDR not seen yet */
1867 if (eabuf
[0] == '\0' && cis
[i
] == LAN_NID
&&
1868 !(ETHER_ISNULLADDR(&cis
[i
+ 2])) &&
1869 !(ETHER_ISMULTI(&cis
[i
+ 2]))) {
1870 ASSERT(cis
[i
+ 1] == ETHER_ADDR_LEN
);
1871 bcm_ether_ntoa((struct ether_addr
*)&cis
[i
+ 2],
1874 /* set boardnum if HNBU_BOARDNUM not seen yet */
1876 boardnum
= (cis
[i
+ 6] << 8) + cis
[i
+ 7];
1882 case CISTPL_CFTABLE
:
1883 varbuf_append(&b
, vstr_regwindowsz
, (cis
[i
+ 7] << 8) | cis
[i
+ 6]);
1886 case CISTPL_BRCM_HNBU
:
1889 sromrev
= cis
[i
+ 1];
1890 varbuf_append(&b
, vstr_sromrev
, sromrev
);
1894 varbuf_append(&b
, vstr_xtalfreq
,
1895 (cis
[i
+ 4] << 24) |
1896 (cis
[i
+ 3] << 16) |
1902 varbuf_append(&b
, vstr_vendid
, (cis
[i
+ 2] << 8) +
1904 varbuf_append(&b
, vstr_devid
, (cis
[i
+ 4] << 8) +
1907 varbuf_append(&b
, vstr_chiprev
,
1908 (cis
[i
+ 6] << 8) + cis
[i
+ 5]);
1911 varbuf_append(&b
, vstr_subvendid
,
1912 (cis
[i
+ 8] << 8) + cis
[i
+ 7]);
1915 varbuf_append(&b
, vstr_subdevid
,
1916 (cis
[i
+ 10] << 8) + cis
[i
+ 9]);
1917 /* subdevid doubles for boardtype */
1918 varbuf_append(&b
, vstr_boardtype
,
1919 (cis
[i
+ 10] << 8) + cis
[i
+ 9]);
1924 boardnum
= (cis
[i
+ 2] << 8) + cis
[i
+ 1];
1929 char vstr_paddr
[16];
1930 char vstr_pdata
[16];
1932 /* retrieve the patch pairs
1933 * from tlen/6; where 6 is
1934 * sizeof(patch addr(2)) +
1935 * sizeof(patch data(4)).
1937 patch_pair
= tlen
/6;
1939 for (j
= 0; j
< patch_pair
; j
++) {
1940 snprintf(vstr_paddr
, sizeof(vstr_paddr
),
1942 snprintf(vstr_pdata
, sizeof(vstr_pdata
),
1945 varbuf_append(&b
, vstr_paddr
,
1946 (cis
[i
+ (j
*6) + 2] << 8) |
1947 cis
[i
+ (j
*6) + 1]);
1949 varbuf_append(&b
, vstr_pdata
,
1950 (cis
[i
+ (j
*6) + 6] << 24) |
1951 (cis
[i
+ (j
*6) + 5] << 16) |
1952 (cis
[i
+ (j
*6) + 4] << 8) |
1953 cis
[i
+ (j
*6) + 3]);
1960 varbuf_append(&b
, vstr_boardrev
, cis
[i
+ 1]);
1962 varbuf_append(&b
, vstr_boardrev
,
1963 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
1966 case HNBU_BOARDFLAGS
:
1967 w32
= (cis
[i
+ 2] << 8) + cis
[i
+ 1];
1969 w32
|= ((cis
[i
+ 4] << 24) + (cis
[i
+ 3] << 16));
1970 varbuf_append(&b
, vstr_boardflags
, w32
);
1973 w32
= (cis
[i
+ 6] << 8) + cis
[i
+ 5];
1975 w32
|= ((cis
[i
+ 8] << 24) +
1976 (cis
[i
+ 7] << 16));
1977 varbuf_append(&b
, vstr_boardflags2
, w32
);
1980 w32
= (cis
[i
+ 10] << 8) + cis
[i
+ 9];
1982 w32
|= ((cis
[i
+ 12] << 24) +
1983 (cis
[i
+ 11] << 16));
1984 varbuf_append(&b
, vstr_boardflags3
, w32
);
1989 varbuf_append(&b
, vstr_usbfs
, cis
[i
+ 1]);
1992 case HNBU_BOARDTYPE
:
1993 varbuf_append(&b
, vstr_boardtype
,
1994 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
1999 * what follows is a nonstandard HNBU CIS
2000 * that lacks CISTPL_BRCM_HNBU tags
2002 * skip 0xff (end of standard CIS)
2006 standard_cis
= FALSE
;
2010 varbuf_append(&b
, vstr_usbepnum
,
2011 (cis
[i
+ 2] << 8) | cis
[i
+ 1]);
2014 case HNBU_PATCH_AUTOINC
: {
2015 char vstr_paddr
[16];
2016 char vstr_pdata
[16];
2020 addr_inc
= (cis
[i
+ 4] << 24) |
2021 (cis
[i
+ 3] << 16) |
2025 pcnt
= (tlen
- 5)/4;
2026 for (j
= 0; j
< pcnt
; j
++) {
2027 snprintf(vstr_paddr
, sizeof(vstr_paddr
),
2028 "pa%d=0x%%x", j
+ patch_pair
);
2029 snprintf(vstr_pdata
, sizeof(vstr_pdata
),
2030 "pd%d=0x%%x", j
+ patch_pair
);
2032 varbuf_append(&b
, vstr_paddr
, addr_inc
);
2033 varbuf_append(&b
, vstr_pdata
,
2034 (cis
[i
+ (j
*4) + 8] << 24) |
2035 (cis
[i
+ (j
*4) + 7] << 16) |
2036 (cis
[i
+ (j
*4) + 6] << 8) |
2037 cis
[i
+ (j
*4) + 5]);
2045 char vstr_paddr
[16];
2046 char vstr_pdata
[16];
2048 /* retrieve the patch pairs
2049 * from tlen/8; where 8 is
2050 * sizeof(patch addr(4)) +
2051 * sizeof(patch data(4)).
2053 patch_pair
= tlen
/8;
2055 for (j
= 0; j
< patch_pair
; j
++) {
2056 snprintf(vstr_paddr
, sizeof(vstr_paddr
),
2058 snprintf(vstr_pdata
, sizeof(vstr_pdata
),
2061 varbuf_append(&b
, vstr_paddr
,
2062 (cis
[i
+ (j
*8) + 4] << 24) |
2063 (cis
[i
+ (j
*8) + 3] << 16) |
2064 (cis
[i
+ (j
*8) + 2] << 8) |
2065 cis
[i
+ (j
*8) + 1]);
2067 varbuf_append(&b
, vstr_pdata
,
2068 (cis
[i
+ (j
*8) + 8] << 24) |
2069 (cis
[i
+ (j
*8) + 7] << 16) |
2070 (cis
[i
+ (j
*8) + 6] << 8) |
2071 cis
[i
+ (j
*8) + 5]);
2076 varbuf_append(&b
, vstr_usbflags
,
2077 (cis
[i
+ 4] << 24) |
2078 (cis
[i
+ 3] << 16) |
2082 #ifdef BCM_BOOTLOADER
2083 case HNBU_MDIOEX_REGLIST
:
2084 case HNBU_MDIO_REGLIST
: {
2085 /* Format: addr (8 bits) | val (16 bits) */
2086 const uint8 msize
= 3;
2088 const char *mdiodesc
;
2091 mdiodesc
= (cis
[i
] == HNBU_MDIO_REGLIST
) ?
2092 vstr_mdio
: vstr_mdioex
;
2094 ASSERT(((tlen
- 1) % msize
) == 0);
2096 st
= &cis
[i
+ 1]; /* start of reg list */
2097 for (j
= 0; j
< (tlen
- 1); j
+= msize
, st
+= msize
) {
2098 snprintf(mdiostr
, sizeof(mdiostr
),
2100 varbuf_append(&b
, mdiostr
, (st
[2] << 8) | st
[1]);
2105 varbuf_append(&b
, vstr_brmin
,
2106 (cis
[i
+ 4] << 24) |
2107 (cis
[i
+ 3] << 16) |
2113 varbuf_append(&b
, vstr_brmax
,
2114 (cis
[i
+ 4] << 24) |
2115 (cis
[i
+ 3] << 16) |
2119 #endif /* BCM_BOOTLOADER */
2122 varbuf_append(&b
, vstr_rdlid
,
2123 (cis
[i
+ 2] << 8) | cis
[i
+ 1]);
2130 * |len| <== variable, multiple of 5
2131 * |tup| <== tupletype
2132 * |ccreg_ix0|<== ix of ccreg [1byte]
2133 * |ccreg_val0|<= corr value [4bytes]
2135 * Multiple registers are possible. for eg: we
2136 * can specify reg_ix3val3 and reg_ix5val5, etc
2138 char vstr_gci_ccreg_entry
[16];
2139 int num_entries
= 0;
2141 /* retrieve the index-value pairs
2142 * from tlen/5; where 5 is
2143 * sizeof(ccreg_ix(1)) +
2144 * sizeof(ccreg_val(4)).
2146 num_entries
= tlen
/5;
2148 for (j
= 0; j
< num_entries
; j
++) {
2149 snprintf(vstr_gci_ccreg_entry
,
2150 sizeof(vstr_gci_ccreg_entry
),
2151 "gcr%d=0x%%x", cis
[i
+ (j
*5) + 1]);
2153 varbuf_append(&b
, vstr_gci_ccreg_entry
,
2154 (cis
[i
+ (j
*5) + 5] << 24) |
2155 (cis
[i
+ (j
*5) + 4] << 16) |
2156 (cis
[i
+ (j
*5) + 3] << 8) |
2157 cis
[i
+ (j
*5) + 2]);
2162 #ifdef BCM_BOOTLOADER
2164 varbuf_append(&b
, vstr_rdlrndis
, cis
[i
+ 1]);
2168 varbuf_append(&b
, vstr_rdlrwu
, cis
[i
+ 1]);
2173 varbuf_append(&b
, vstr_rdlsn
,
2174 (cis
[i
+ 4] << 24) |
2175 (cis
[i
+ 3] << 16) |
2179 varbuf_append(&b
, vstr_rdlsn
,
2186 uint8 offset
= 1, mode_addr
, mode
, addr
;
2190 mode_addr
= cis
[i
+offset
];
2192 mode
= (mode_addr
& PMUREGS_MODE_MASK
)
2193 >> PMUREGS_MODE_SHIFT
;
2194 addr
= mode_addr
& PMUREGS_ADDR_MASK
;
2197 case PMU_PLLREG_MODE
:
2200 case PMU_CCREG_MODE
:
2203 case PMU_VOLTREG_MODE
:
2206 case PMU_RES_TIME_MODE
:
2209 case PMU_RESDEPEND_MODE
:
2218 varbuf_append(&b
, fmt
, addr
,
2219 (cis
[i
+ offset
+ 4] << 24) |
2220 (cis
[i
+ offset
+ 3] << 16) |
2221 (cis
[i
+ offset
+ 2] << 8) |
2222 cis
[i
+ offset
+ 1]);
2225 offset
+= PMUREGS_TPL_SIZE
;
2226 } while (offset
< tlen
);
2232 uint8 offset
= 1, usb_reg
;
2236 usb_reg
= cis
[i
+offset
];
2239 case USB_DEV_CTRL_REG
:
2240 fmt
= vstr_usbdevctrl
;
2242 case HSIC_PHY_CTRL1_REG
:
2243 fmt
= vstr_hsicphyctrl1
;
2245 case HSIC_PHY_CTRL2_REG
:
2246 fmt
= vstr_hsicphyctrl2
;
2254 varbuf_append(&b
, fmt
,
2255 (cis
[i
+ offset
+ 4] << 24) |
2256 (cis
[i
+ offset
+ 3] << 16) |
2257 (cis
[i
+ offset
+ 2] << 8) |
2258 cis
[i
+ offset
+ 1]);
2261 offset
+= USBREGS_TPL_SIZE
;
2262 } while (offset
< tlen
);
2267 /* The first byte of this tuple indicate if the host
2268 * needs to be informed about the readiness of
2269 * the HSIC/USB for enumeration on which GPIO should
2270 * the device assert this event.
2272 varbuf_append(&b
, vstr_usbrdy
, cis
[i
+ 1]);
2274 /* The following fields in this OTP are optional.
2275 * The remaining bytes will indicate the delay required
2276 * before and/or after the ch_init(). The delay is defined
2277 * using 16-bits of this the MSB(bit15 of 15:0) will be
2278 * used indicate if the parameter is for Pre or Post delay.
2280 for (j
= 2; j
< USBRDY_MAXOTP_SIZE
&& j
< tlen
;
2284 usb_delay
= cis
[i
+ j
] | (cis
[i
+ j
+ 1] << 8);
2286 /* The bit-15 of the delay field will indicate the
2287 * type of delay (pre or post).
2289 if (usb_delay
& USBRDY_DLY_TYPE
) {
2290 varbuf_append(&b
, vstr_usbpostdly
,
2291 (usb_delay
& USBRDY_DLY_MASK
));
2293 varbuf_append(&b
, vstr_usbpredly
,
2294 (usb_delay
& USBRDY_DLY_MASK
));
2299 case HNBU_BLDR_TIMEOUT
:
2300 /* The Delay after USBConnect for timeout till dongle
2301 * receives get_descriptor request.
2303 varbuf_append(&b
, vstr_bldr_reset_timeout
,
2304 (cis
[i
+ 1] | (cis
[i
+ 2] << 8)));
2307 varbuf_append(&b
, vstr_muxenab
, cis
[i
+ 1]);
2311 varbuf_append(&b
, vstr_aa2g
, cis
[i
+ 1]);
2313 varbuf_append(&b
, vstr_aa5g
, cis
[i
+ 2]);
2317 varbuf_append(&b
, vstr_ag
, 0, cis
[i
+ 1]);
2319 varbuf_append(&b
, vstr_ag
, 1, cis
[i
+ 2]);
2321 varbuf_append(&b
, vstr_ag
, 2, cis
[i
+ 3]);
2323 varbuf_append(&b
, vstr_ag
, 3, cis
[i
+ 4]);
2328 varbuf_append(&b
, vstr_aa5g
, cis
[i
+ 1]);
2329 varbuf_append(&b
, vstr_ag
, 1, cis
[i
+ 2]);
2333 ASSERT(sromrev
== 1);
2334 varbuf_append(&b
, vstr_cc
, cis
[i
+ 1]);
2340 ASSERT(sromrev
== 1);
2341 varbuf_append(&b
, vstr_pa0maxpwr
, cis
[i
+ 1]);
2344 ASSERT(sromrev
>= 2);
2345 varbuf_append(&b
, vstr_opo
, cis
[i
+ 9]);
2348 varbuf_append(&b
, vstr_pa0maxpwr
, cis
[i
+ 8]);
2351 varbuf_append(&b
, vstr_pa0itssit
, cis
[i
+ 7]);
2354 for (j
= 0; j
< 3; j
++) {
2355 varbuf_append(&b
, vstr_pa0b
[j
],
2356 (cis
[i
+ (j
* 2) + 2] << 8) +
2357 cis
[i
+ (j
* 2) + 1]);
2361 ASSERT((tlen
== 2) || (tlen
== 9) || (tlen
== 10));
2366 case HNBU_PAPARMS5G
:
2367 ASSERT((sromrev
== 2) || (sromrev
== 3));
2370 varbuf_append(&b
, vstr_pa1himaxpwr
, cis
[i
+ 22]);
2371 varbuf_append(&b
, vstr_pa1lomaxpwr
, cis
[i
+ 21]);
2372 varbuf_append(&b
, vstr_pa1maxpwr
, cis
[i
+ 20]);
2375 varbuf_append(&b
, vstr_pa1itssit
, cis
[i
+ 19]);
2378 for (j
= 0; j
< 3; j
++) {
2379 varbuf_append(&b
, vstr_pa1b
[j
],
2380 (cis
[i
+ (j
* 2) + 2] << 8) +
2381 cis
[i
+ (j
* 2) + 1]);
2383 for (j
= 3; j
< 6; j
++) {
2384 varbuf_append(&b
, vstr_pa1lob
[j
- 3],
2385 (cis
[i
+ (j
* 2) + 2] << 8) +
2386 cis
[i
+ (j
* 2) + 1]);
2388 for (j
= 6; j
< 9; j
++) {
2389 varbuf_append(&b
, vstr_pa1hib
[j
- 6],
2390 (cis
[i
+ (j
* 2) + 2] << 8) +
2391 cis
[i
+ (j
* 2) + 1]);
2395 ASSERT((tlen
== 19) ||
2396 (tlen
== 20) || (tlen
== 23));
2402 ASSERT(sromrev
== 1);
2403 varbuf_append(&b
, vstr_oem
,
2404 cis
[i
+ 1], cis
[i
+ 2],
2405 cis
[i
+ 3], cis
[i
+ 4],
2406 cis
[i
+ 5], cis
[i
+ 6],
2407 cis
[i
+ 7], cis
[i
+ 8]);
2411 for (j
= 1; j
<= 4; j
++) {
2412 if (cis
[i
+ j
] != 0xff) {
2413 varbuf_append(&b
, vstr_ledbh
, j
-1,
2420 ASSERT(sromrev
> 1);
2421 if ((cis
[i
+ 1] == 0) || (cis
[i
+ 2] == 0))
2422 varbuf_append(&b
, vstr_noccode
);
2424 varbuf_append(&b
, vstr_ccode
,
2425 cis
[i
+ 1], cis
[i
+ 2]);
2426 varbuf_append(&b
, vstr_cctl
, cis
[i
+ 3]);
2430 ASSERT(sromrev
> 2);
2431 varbuf_append(&b
, vstr_cckpo
,
2432 (cis
[i
+ 2] << 8) | cis
[i
+ 1]);
2436 ASSERT(sromrev
> 2);
2437 varbuf_append(&b
, vstr_ofdmpo
,
2438 (cis
[i
+ 4] << 24) |
2439 (cis
[i
+ 3] << 16) |
2445 varbuf_append(&b
, vstr_wpsgpio
, cis
[i
+ 1]);
2447 varbuf_append(&b
, vstr_wpsled
, cis
[i
+ 2]);
2450 case HNBU_RSSISMBXA2G
:
2451 ASSERT(sromrev
== 3);
2452 varbuf_append(&b
, vstr_rssismf2g
, cis
[i
+ 1] & 0xf);
2453 varbuf_append(&b
, vstr_rssismc2g
, (cis
[i
+ 1] >> 4) & 0xf);
2454 varbuf_append(&b
, vstr_rssisav2g
, cis
[i
+ 2] & 0x7);
2455 varbuf_append(&b
, vstr_bxa2g
, (cis
[i
+ 2] >> 3) & 0x3);
2458 case HNBU_RSSISMBXA5G
:
2459 ASSERT(sromrev
== 3);
2460 varbuf_append(&b
, vstr_rssismf5g
, cis
[i
+ 1] & 0xf);
2461 varbuf_append(&b
, vstr_rssismc5g
, (cis
[i
+ 1] >> 4) & 0xf);
2462 varbuf_append(&b
, vstr_rssisav5g
, cis
[i
+ 2] & 0x7);
2463 varbuf_append(&b
, vstr_bxa5g
, (cis
[i
+ 2] >> 3) & 0x3);
2467 ASSERT(sromrev
== 3);
2468 varbuf_append(&b
, vstr_tri2g
, cis
[i
+ 1]);
2472 ASSERT(sromrev
== 3);
2473 varbuf_append(&b
, vstr_tri5gl
, cis
[i
+ 1]);
2474 varbuf_append(&b
, vstr_tri5g
, cis
[i
+ 2]);
2475 varbuf_append(&b
, vstr_tri5gh
, cis
[i
+ 3]);
2479 ASSERT(sromrev
== 3);
2480 varbuf_append(&b
, vstr_rxpo2g
, cis
[i
+ 1]);
2484 ASSERT(sromrev
== 3);
2485 varbuf_append(&b
, vstr_rxpo5g
, cis
[i
+ 1]);
2489 if (!(ETHER_ISNULLADDR(&cis
[i
+1])) &&
2490 !(ETHER_ISMULTI(&cis
[i
+1]))) {
2491 bcm_ether_ntoa((struct ether_addr
*)&cis
[i
+ 1],
2494 /* set boardnum if HNBU_BOARDNUM not seen yet */
2496 boardnum
= (cis
[i
+ 5] << 8) + cis
[i
+ 6];
2501 /* CIS leddc only has 16bits, convert it to 32bits */
2502 w32
= ((cis
[i
+ 2] << 24) | /* oncount */
2503 (cis
[i
+ 1] << 8)); /* offcount */
2504 varbuf_append(&b
, vstr_leddc
, w32
);
2507 case HNBU_CHAINSWITCH
:
2508 varbuf_append(&b
, vstr_txchain
, cis
[i
+ 1]);
2509 varbuf_append(&b
, vstr_rxchain
, cis
[i
+ 2]);
2510 varbuf_append(&b
, vstr_antswitch
,
2511 (cis
[i
+ 4] << 8) + cis
[i
+ 3]);
2515 varbuf_append(&b
, vstr_elna2g
, cis
[i
+ 1]);
2519 varbuf_append(&b
, vstr_elna5g
, cis
[i
+ 1]);
2523 varbuf_append(&b
, vstr_regrev
, cis
[i
+ 1]);
2527 uint16 fem
= (cis
[i
+ 2] << 8) + cis
[i
+ 1];
2528 varbuf_append(&b
, vstr_antswctl2g
, (fem
&
2529 SROM8_FEM_ANTSWLUT_MASK
) >>
2530 SROM8_FEM_ANTSWLUT_SHIFT
);
2531 varbuf_append(&b
, vstr_triso2g
, (fem
&
2532 SROM8_FEM_TR_ISO_MASK
) >>
2533 SROM8_FEM_TR_ISO_SHIFT
);
2534 varbuf_append(&b
, vstr_pdetrange2g
, (fem
&
2535 SROM8_FEM_PDET_RANGE_MASK
) >>
2536 SROM8_FEM_PDET_RANGE_SHIFT
);
2537 varbuf_append(&b
, vstr_extpagain2g
, (fem
&
2538 SROM8_FEM_EXTPA_GAIN_MASK
) >>
2539 SROM8_FEM_EXTPA_GAIN_SHIFT
);
2540 varbuf_append(&b
, vstr_tssipos2g
, (fem
&
2541 SROM8_FEM_TSSIPOS_MASK
) >>
2542 SROM8_FEM_TSSIPOS_SHIFT
);
2543 if (tlen
< 5) break;
2545 fem
= (cis
[i
+ 4] << 8) + cis
[i
+ 3];
2546 varbuf_append(&b
, vstr_antswctl5g
, (fem
&
2547 SROM8_FEM_ANTSWLUT_MASK
) >>
2548 SROM8_FEM_ANTSWLUT_SHIFT
);
2549 varbuf_append(&b
, vstr_triso5g
, (fem
&
2550 SROM8_FEM_TR_ISO_MASK
) >>
2551 SROM8_FEM_TR_ISO_SHIFT
);
2552 varbuf_append(&b
, vstr_pdetrange5g
, (fem
&
2553 SROM8_FEM_PDET_RANGE_MASK
) >>
2554 SROM8_FEM_PDET_RANGE_SHIFT
);
2555 varbuf_append(&b
, vstr_extpagain5g
, (fem
&
2556 SROM8_FEM_EXTPA_GAIN_MASK
) >>
2557 SROM8_FEM_EXTPA_GAIN_SHIFT
);
2558 varbuf_append(&b
, vstr_tssipos5g
, (fem
&
2559 SROM8_FEM_TSSIPOS_MASK
) >>
2560 SROM8_FEM_TSSIPOS_SHIFT
);
2564 case HNBU_PAPARMS_C0
:
2565 varbuf_append(&b
, vstr_maxp2ga
, 0, cis
[i
+ 1]);
2566 varbuf_append(&b
, vstr_itt2ga0
, cis
[i
+ 2]);
2567 varbuf_append(&b
, vstr_pa
, 2, 0, 0,
2568 (cis
[i
+ 4] << 8) + cis
[i
+ 3]);
2569 varbuf_append(&b
, vstr_pa
, 2, 1, 0,
2570 (cis
[i
+ 6] << 8) + cis
[i
+ 5]);
2571 varbuf_append(&b
, vstr_pa
, 2, 2, 0,
2572 (cis
[i
+ 8] << 8) + cis
[i
+ 7]);
2573 if (tlen
< 31) break;
2575 varbuf_append(&b
, vstr_maxp5ga0
, cis
[i
+ 9]);
2576 varbuf_append(&b
, vstr_itt5ga0
, cis
[i
+ 10]);
2577 varbuf_append(&b
, vstr_maxp5gha0
, cis
[i
+ 11]);
2578 varbuf_append(&b
, vstr_maxp5gla0
, cis
[i
+ 12]);
2579 varbuf_append(&b
, vstr_pa
, 5, 0, 0,
2580 (cis
[i
+ 14] << 8) + cis
[i
+ 13]);
2581 varbuf_append(&b
, vstr_pa
, 5, 1, 0,
2582 (cis
[i
+ 16] << 8) + cis
[i
+ 15]);
2583 varbuf_append(&b
, vstr_pa
, 5, 2, 0,
2584 (cis
[i
+ 18] << 8) + cis
[i
+ 17]);
2585 varbuf_append(&b
, vstr_pahl
, 5, 'l', 0, 0,
2586 (cis
[i
+ 20] << 8) + cis
[i
+ 19]);
2587 varbuf_append(&b
, vstr_pahl
, 5, 'l', 1, 0,
2588 (cis
[i
+ 22] << 8) + cis
[i
+ 21]);
2589 varbuf_append(&b
, vstr_pahl
, 5, 'l', 2, 0,
2590 (cis
[i
+ 24] << 8) + cis
[i
+ 23]);
2591 varbuf_append(&b
, vstr_pahl
, 5, 'h', 0, 0,
2592 (cis
[i
+ 26] << 8) + cis
[i
+ 25]);
2593 varbuf_append(&b
, vstr_pahl
, 5, 'h', 1, 0,
2594 (cis
[i
+ 28] << 8) + cis
[i
+ 27]);
2595 varbuf_append(&b
, vstr_pahl
, 5, 'h', 2, 0,
2596 (cis
[i
+ 30] << 8) + cis
[i
+ 29]);
2599 case HNBU_PAPARMS_C1
:
2600 varbuf_append(&b
, vstr_maxp2ga
, 1, cis
[i
+ 1]);
2601 varbuf_append(&b
, vstr_itt2ga1
, cis
[i
+ 2]);
2602 varbuf_append(&b
, vstr_pa
, 2, 0, 1,
2603 (cis
[i
+ 4] << 8) + cis
[i
+ 3]);
2604 varbuf_append(&b
, vstr_pa
, 2, 1, 1,
2605 (cis
[i
+ 6] << 8) + cis
[i
+ 5]);
2606 varbuf_append(&b
, vstr_pa
, 2, 2, 1,
2607 (cis
[i
+ 8] << 8) + cis
[i
+ 7]);
2608 if (tlen
< 31) break;
2610 varbuf_append(&b
, vstr_maxp5ga1
, cis
[i
+ 9]);
2611 varbuf_append(&b
, vstr_itt5ga1
, cis
[i
+ 10]);
2612 varbuf_append(&b
, vstr_maxp5gha1
, cis
[i
+ 11]);
2613 varbuf_append(&b
, vstr_maxp5gla1
, cis
[i
+ 12]);
2614 varbuf_append(&b
, vstr_pa
, 5, 0, 1,
2615 (cis
[i
+ 14] << 8) + cis
[i
+ 13]);
2616 varbuf_append(&b
, vstr_pa
, 5, 1, 1,
2617 (cis
[i
+ 16] << 8) + cis
[i
+ 15]);
2618 varbuf_append(&b
, vstr_pa
, 5, 2, 1,
2619 (cis
[i
+ 18] << 8) + cis
[i
+ 17]);
2620 varbuf_append(&b
, vstr_pahl
, 5, 'l', 0, 1,
2621 (cis
[i
+ 20] << 8) + cis
[i
+ 19]);
2622 varbuf_append(&b
, vstr_pahl
, 5, 'l', 1, 1,
2623 (cis
[i
+ 22] << 8) + cis
[i
+ 21]);
2624 varbuf_append(&b
, vstr_pahl
, 5, 'l', 2, 1,
2625 (cis
[i
+ 24] << 8) + cis
[i
+ 23]);
2626 varbuf_append(&b
, vstr_pahl
, 5, 'h', 0, 1,
2627 (cis
[i
+ 26] << 8) + cis
[i
+ 25]);
2628 varbuf_append(&b
, vstr_pahl
, 5, 'h', 1, 1,
2629 (cis
[i
+ 28] << 8) + cis
[i
+ 27]);
2630 varbuf_append(&b
, vstr_pahl
, 5, 'h', 2, 1,
2631 (cis
[i
+ 30] << 8) + cis
[i
+ 29]);
2634 case HNBU_PO_CCKOFDM
:
2635 varbuf_append(&b
, vstr_cck2gpo
,
2636 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
2637 varbuf_append(&b
, vstr_ofdm2gpo
,
2638 (cis
[i
+ 6] << 24) + (cis
[i
+ 5] << 16) +
2639 (cis
[i
+ 4] << 8) + cis
[i
+ 3]);
2640 if (tlen
< 19) break;
2642 varbuf_append(&b
, vstr_ofdm5gpo
,
2643 (cis
[i
+ 10] << 24) + (cis
[i
+ 9] << 16) +
2644 (cis
[i
+ 8] << 8) + cis
[i
+ 7]);
2645 varbuf_append(&b
, vstr_ofdm5glpo
,
2646 (cis
[i
+ 14] << 24) + (cis
[i
+ 13] << 16) +
2647 (cis
[i
+ 12] << 8) + cis
[i
+ 11]);
2648 varbuf_append(&b
, vstr_ofdm5ghpo
,
2649 (cis
[i
+ 18] << 24) + (cis
[i
+ 17] << 16) +
2650 (cis
[i
+ 16] << 8) + cis
[i
+ 15]);
2654 for (j
= 0; j
<= (tlen
/2); j
++) {
2655 varbuf_append(&b
, vstr_mcspo
, 2, j
,
2656 (cis
[i
+ 2 + 2*j
] << 8) + cis
[i
+ 1 + 2*j
]);
2660 case HNBU_PO_MCS5GM
:
2661 for (j
= 0; j
<= (tlen
/2); j
++) {
2662 varbuf_append(&b
, vstr_mcspo
, 5, j
,
2663 (cis
[i
+ 2 + 2*j
] << 8) + cis
[i
+ 1 + 2*j
]);
2667 case HNBU_PO_MCS5GLH
:
2668 for (j
= 0; j
<= (tlen
/4); j
++) {
2669 varbuf_append(&b
, vstr_mcspohl
, 5, 'l', j
,
2670 (cis
[i
+ 2 + 2*j
] << 8) + cis
[i
+ 1 + 2*j
]);
2673 for (j
= 0; j
<= (tlen
/4); j
++) {
2674 varbuf_append(&b
, vstr_mcspohl
, 5, 'h', j
,
2675 (cis
[i
+ ((tlen
/2)+2) + 2*j
] << 8) +
2676 cis
[i
+ ((tlen
/2)+1) + 2*j
]);
2682 varbuf_append(&b
, vstr_cddpo
,
2683 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
2687 varbuf_append(&b
, vstr_stbcpo
,
2688 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
2692 varbuf_append(&b
, vstr_bw40po
,
2693 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
2696 case HNBU_PO_40MDUP
:
2697 varbuf_append(&b
, vstr_bwduppo
,
2698 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
2702 varbuf_append(&b
, vstr_ofdm5gpo
,
2703 (cis
[i
+ 4] << 24) + (cis
[i
+ 3] << 16) +
2704 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
2705 varbuf_append(&b
, vstr_ofdm5glpo
,
2706 (cis
[i
+ 8] << 24) + (cis
[i
+ 7] << 16) +
2707 (cis
[i
+ 6] << 8) + cis
[i
+ 5]);
2708 varbuf_append(&b
, vstr_ofdm5ghpo
,
2709 (cis
[i
+ 12] << 24) + (cis
[i
+ 11] << 16) +
2710 (cis
[i
+ 10] << 8) + cis
[i
+ 9]);
2712 /* Power per rate for SROM V9 */
2713 case HNBU_CCKBW202GPO
:
2714 varbuf_append(&b
, vstr_cckbw202gpo
[0],
2715 ((cis
[i
+ 2] << 8) + cis
[i
+ 1]));
2717 varbuf_append(&b
, vstr_cckbw202gpo
[1],
2718 ((cis
[i
+ 4] << 8) + cis
[i
+ 3]));
2721 case HNBU_LEGOFDMBW202GPO
:
2722 varbuf_append(&b
, vstr_legofdmbw202gpo
[0],
2723 ((cis
[i
+ 4] << 24) + (cis
[i
+ 3] << 16) +
2724 (cis
[i
+ 2] << 8) + cis
[i
+ 1]));
2726 varbuf_append(&b
, vstr_legofdmbw202gpo
[1],
2727 ((cis
[i
+ 8] << 24) + (cis
[i
+ 7] << 16) +
2728 (cis
[i
+ 6] << 8) + cis
[i
+ 5]));
2732 case HNBU_LEGOFDMBW205GPO
:
2733 for (j
= 0; j
< 6; j
++) {
2734 if (tlen
< (2 + 4 * j
))
2736 varbuf_append(&b
, vstr_legofdmbw205gpo
[j
],
2737 ((cis
[4 * j
+ i
+ 4] << 24)
2738 + (cis
[4 * j
+ i
+ 3] << 16)
2739 + (cis
[4 * j
+ i
+ 2] << 8)
2740 + cis
[4 * j
+ i
+ 1]));
2745 for (j
= 0; j
< 3; j
++) {
2746 if (tlen
< (2 + 4 * j
))
2748 varbuf_append(&b
, vstr_mcs2gpo
[j
],
2749 ((cis
[4 * j
+ i
+ 4] << 24)
2750 + (cis
[4 * j
+ i
+ 3] << 16)
2751 + (cis
[4 * j
+ i
+ 2] << 8)
2752 + cis
[4 * j
+ i
+ 1]));
2757 for (j
= 0; j
< 3; j
++) {
2758 if (tlen
< (2 + 4 * j
))
2760 varbuf_append(&b
, vstr_mcs5glpo
[j
],
2761 ((cis
[4 * j
+ i
+ 4] << 24)
2762 + (cis
[4 * j
+ i
+ 3] << 16)
2763 + (cis
[4 * j
+ i
+ 2] << 8)
2764 + cis
[4 * j
+ i
+ 1]));
2769 for (j
= 0; j
< 3; j
++) {
2770 if (tlen
< (2 + 4 * j
))
2772 varbuf_append(&b
, vstr_mcs5gmpo
[j
],
2773 ((cis
[4 * j
+ i
+ 4] << 24)
2774 + (cis
[4 * j
+ i
+ 3] << 16)
2775 + (cis
[4 * j
+ i
+ 2] << 8)
2776 + cis
[4 * j
+ i
+ 1]));
2781 for (j
= 0; j
< 3; j
++) {
2782 if (tlen
< (2 + 4 * j
))
2784 varbuf_append(&b
, vstr_mcs5ghpo
[j
],
2785 ((cis
[4 * j
+ i
+ 4] << 24)
2786 + (cis
[4 * j
+ i
+ 3] << 16)
2787 + (cis
[4 * j
+ i
+ 2] << 8)
2788 + cis
[4 * j
+ i
+ 1]));
2793 varbuf_append(&b
, vstr_mcs32po
,
2794 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
2797 case HNBU_LEG40DUPPO
:
2798 varbuf_append(&b
, vstr_legofdm40duppo
,
2799 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
2803 varbuf_append(&b
, vstr_custom
, 1, ((cis
[i
+ 4] << 24) +
2804 (cis
[i
+ 3] << 16) + (cis
[i
+ 2] << 8) +
2808 #if defined(BCMCCISSR3)
2809 case HNBU_SROM3SWRGN
:
2812 uint8 srev
= cis
[i
+ 1 + 70];
2814 /* make tuple value 16-bit aligned and parse it */
2815 bcopy(&cis
[i
+ 1], srom
, sizeof(srom
));
2816 _initvars_srom_pci(srev
, srom
, SROM3_SWRGN_OFF
, &b
);
2817 /* 2.4G antenna gain is included in SROM */
2819 /* Ethernet MAC address is included in SROM */
2823 /* create extra variables */
2825 varbuf_append(&b
, vstr_vendid
,
2826 (cis
[i
+ 1 + 73] << 8) +
2829 varbuf_append(&b
, vstr_devid
,
2830 (cis
[i
+ 1 + 75] << 8) +
2833 varbuf_append(&b
, vstr_xtalfreq
,
2834 (cis
[i
+ 1 + 77] << 8) +
2839 case HNBU_CCKFILTTYPE
:
2840 varbuf_append(&b
, vstr_cckdigfilttype
,
2844 case HNBU_TEMPTHRESH
:
2845 varbuf_append(&b
, vstr_tempthresh
,
2847 /* period in msb nibble */
2848 varbuf_append(&b
, vstr_temps_period
,
2850 /* hysterisis in lsb nibble */
2851 varbuf_append(&b
, vstr_temp_hysteresis
,
2852 (cis
[i
+ 2] & 0xF));
2854 varbuf_append(&b
, vstr_tempoffset
,
2857 varbuf_append(&b
, vstr_temp_corrx
,
2859 varbuf_append(&b
, vstr_tempsense_option
,
2860 (cis
[i
+ 4] & 0x3));
2863 varbuf_append(&b
, vstr_phycal_tempdelta
,
2869 varbuf_append(&b
, vstr_tssiposslopeg
, 2,
2870 (cis
[i
+ 1] & 0x1));
2871 varbuf_append(&b
, vstr_epagaing
, 2,
2872 (cis
[i
+ 1] & 0xe) >> 1);
2873 varbuf_append(&b
, vstr_pdgaing
, 2,
2874 ((cis
[i
+ 2] & 0x1) << 8) +
2875 ((cis
[i
+ 1] & 0xf0) >> 4));
2876 varbuf_append(&b
, vstr_tworangetssi
, 2,
2877 (cis
[i
+ 2] & 0x2) >> 1);
2878 varbuf_append(&b
, vstr_papdcap
, 2,
2879 (cis
[i
+ 2] & 0x4) >> 2);
2880 varbuf_append(&b
, vstr_femctrl
,
2881 (cis
[i
+ 2] & 0xf8) >> 3);
2883 varbuf_append(&b
, vstr_tssiposslopeg
, 5,
2884 (cis
[i
+ 3] & 0x1));
2885 varbuf_append(&b
, vstr_epagaing
, 5,
2886 (cis
[i
+ 3] & 0xe) >> 1);
2887 varbuf_append(&b
, vstr_pdgaing
, 5,
2888 ((cis
[i
+ 4] & 0x1) << 8) +
2889 ((cis
[i
+ 3] & 0xf0) >> 4));
2890 varbuf_append(&b
, vstr_tworangetssi
, 2,
2891 (cis
[i
+ 4] & 0x2) >> 1);
2892 varbuf_append(&b
, vstr_papdcap
, 5,
2893 (cis
[i
+ 4] & 0x4) >> 2);
2894 varbuf_append(&b
, vstr_gainctrlsph
,
2895 (cis
[i
+ 4] & 0xf8) >> 3);
2902 varbuf_append(&b
, vstr_subband5gver
,
2903 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
2904 varbuf_append(&b
, vstr_maxp2ga
, a
,
2905 (cis
[i
+ 4] << 8) + cis
[i
+ 3]);
2907 varbuf_append(&b
, vstr_pa2ga
, 2, a
,
2908 (cis
[i
+ 6] << 8) + cis
[i
+ 5],
2909 (cis
[i
+ 8] << 8) + cis
[i
+ 7],
2910 (cis
[i
+ 10] << 8) + cis
[i
+ 9]);
2912 varbuf_append(&b
, vstr_rxgainsgelnagaina
, 2, a
,
2914 varbuf_append(&b
, vstr_rxgainsgtrisoa
, 2, a
,
2915 (cis
[i
+ 11] & 0x78) >> 3);
2916 varbuf_append(&b
, vstr_rxgainsgtrelnabypa
, 2, a
,
2917 (cis
[i
+ 11] & 0x80) >> 7);
2918 varbuf_append(&b
, vstr_rxgainsgelnagaina
, 5, a
,
2920 varbuf_append(&b
, vstr_rxgainsgtrisoa
, 5, a
,
2921 (cis
[i
+ 12] & 0x78) >> 3);
2922 varbuf_append(&b
, vstr_rxgainsgtrelnabypa
, 5, a
,
2923 (cis
[i
+ 12] & 0x80) >> 7);
2925 varbuf_append(&b
, vstr_maxp5ga
, a
,
2931 varbuf_append(&b
, vstr_pa5ga
, a
,
2932 (cis
[i
+ 18] << 8) + cis
[i
+ 17],
2933 (cis
[i
+ 20] << 8) + cis
[i
+ 19],
2934 (cis
[i
+ 22] << 8) + cis
[i
+ 21],
2935 (cis
[i
+ 24] << 8) + cis
[i
+ 23],
2936 (cis
[i
+ 26] << 8) + cis
[i
+ 25],
2937 (cis
[i
+ 28] << 8) + cis
[i
+ 27],
2938 (cis
[i
+ 30] << 8) + cis
[i
+ 29],
2939 (cis
[i
+ 32] << 8) + cis
[i
+ 31],
2940 (cis
[i
+ 34] << 8) + cis
[i
+ 33],
2941 (cis
[i
+ 36] << 8) + cis
[i
+ 35],
2942 (cis
[i
+ 38] << 8) + cis
[i
+ 37],
2943 (cis
[i
+ 40] << 8) + cis
[i
+ 39]);
2951 varbuf_append(&b
, vstr_maxp2ga
, a
,
2952 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
2954 varbuf_append(&b
, vstr_pa2ga
, 2, a
,
2955 (cis
[i
+ 4] << 8) + cis
[i
+ 3],
2956 (cis
[i
+ 6] << 8) + cis
[i
+ 5],
2957 (cis
[i
+ 8] << 8) + cis
[i
+ 7]);
2959 varbuf_append(&b
, vstr_rxgainsgelnagaina
, 2, a
,
2961 varbuf_append(&b
, vstr_rxgainsgtrisoa
, 2, a
,
2962 (cis
[i
+ 9] & 0x78) >> 3);
2963 varbuf_append(&b
, vstr_rxgainsgtrelnabypa
, 2, a
,
2964 (cis
[i
+ 9] & 0x80) >> 7);
2965 varbuf_append(&b
, vstr_rxgainsgelnagaina
, 5, a
,
2967 varbuf_append(&b
, vstr_rxgainsgtrisoa
, 5, a
,
2968 (cis
[i
+ 10] & 0x78) >> 3);
2969 varbuf_append(&b
, vstr_rxgainsgtrelnabypa
, 5, a
,
2970 (cis
[i
+ 10] & 0x80) >> 7);
2972 varbuf_append(&b
, vstr_maxp5ga
, a
,
2978 varbuf_append(&b
, vstr_pa5ga
, a
,
2979 (cis
[i
+ 16] << 8) + cis
[i
+ 15],
2980 (cis
[i
+ 18] << 8) + cis
[i
+ 17],
2981 (cis
[i
+ 20] << 8) + cis
[i
+ 19],
2982 (cis
[i
+ 22] << 8) + cis
[i
+ 21],
2983 (cis
[i
+ 24] << 8) + cis
[i
+ 23],
2984 (cis
[i
+ 26] << 8) + cis
[i
+ 25],
2985 (cis
[i
+ 28] << 8) + cis
[i
+ 27],
2986 (cis
[i
+ 30] << 8) + cis
[i
+ 29],
2987 (cis
[i
+ 32] << 8) + cis
[i
+ 31],
2988 (cis
[i
+ 34] << 8) + cis
[i
+ 33],
2989 (cis
[i
+ 36] << 8) + cis
[i
+ 35],
2990 (cis
[i
+ 38] << 8) + cis
[i
+ 37]);
2998 varbuf_append(&b
, vstr_maxp2ga
, a
,
2999 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
3001 varbuf_append(&b
, vstr_pa2ga
, 2, a
,
3002 (cis
[i
+ 4] << 8) + cis
[i
+ 3],
3003 (cis
[i
+ 6] << 8) + cis
[i
+ 5],
3004 (cis
[i
+ 8] << 8) + cis
[i
+ 7]);
3006 varbuf_append(&b
, vstr_rxgainsgelnagaina
, 2, a
,
3008 varbuf_append(&b
, vstr_rxgainsgtrisoa
, 2, a
,
3009 (cis
[i
+ 9] & 0x78) >> 3);
3010 varbuf_append(&b
, vstr_rxgainsgtrelnabypa
, 2, a
,
3011 (cis
[i
+ 9] & 0x80) >> 7);
3012 varbuf_append(&b
, vstr_rxgainsgelnagaina
, 5, a
,
3014 varbuf_append(&b
, vstr_rxgainsgtrisoa
, 5, a
,
3015 (cis
[i
+ 10] & 0x78) >> 3);
3016 varbuf_append(&b
, vstr_rxgainsgtrelnabypa
, 5, a
,
3017 (cis
[i
+ 10] & 0x80) >> 7);
3019 varbuf_append(&b
, vstr_maxp5ga
, a
,
3025 varbuf_append(&b
, vstr_pa5ga
, a
,
3026 (cis
[i
+ 16] << 8) + cis
[i
+ 15],
3027 (cis
[i
+ 18] << 8) + cis
[i
+ 17],
3028 (cis
[i
+ 20] << 8) + cis
[i
+ 19],
3029 (cis
[i
+ 22] << 8) + cis
[i
+ 21],
3030 (cis
[i
+ 24] << 8) + cis
[i
+ 23],
3031 (cis
[i
+ 26] << 8) + cis
[i
+ 25],
3032 (cis
[i
+ 28] << 8) + cis
[i
+ 27],
3033 (cis
[i
+ 30] << 8) + cis
[i
+ 29],
3034 (cis
[i
+ 32] << 8) + cis
[i
+ 31],
3035 (cis
[i
+ 34] << 8) + cis
[i
+ 33],
3036 (cis
[i
+ 36] << 8) + cis
[i
+ 35],
3037 (cis
[i
+ 38] << 8) + cis
[i
+ 37]);
3042 varbuf_append(&b
, vstr_measpower
, cis
[i
+ 1]);
3043 varbuf_append(&b
, vstr_measpowerX
, 1, (cis
[i
+ 2]));
3044 varbuf_append(&b
, vstr_measpowerX
, 2, (cis
[i
+ 3]));
3045 varbuf_append(&b
, vstr_rawtempsense
,
3046 ((cis
[i
+ 5] & 0x1) << 8) + cis
[i
+ 4]);
3049 case HNBU_ACPPR_2GPO
:
3050 varbuf_append(&b
, vstr_dot11agofdmhrbw202gpo
,
3051 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
3052 varbuf_append(&b
, vstr_ofdmlrbw202gpo
,
3053 (cis
[i
+ 4] << 8) + cis
[i
+ 3]);
3056 case HNBU_ACPPR_5GPO
:
3057 varbuf_append(&b
, vstr_mcsbw805glpo
,
3058 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
3059 varbuf_append(&b
, vstr_mcsbw1605glpo
,
3060 (cis
[i
+ 4] << 8) + cis
[i
+ 3]);
3061 varbuf_append(&b
, vstr_mcsbw805gmpo
,
3062 (cis
[i
+ 6] << 8) + cis
[i
+ 5]);
3063 varbuf_append(&b
, vstr_mcsbw1605gmpo
,
3064 (cis
[i
+ 8] << 8) + cis
[i
+ 7]);
3065 varbuf_append(&b
, vstr_mcsbw805ghpo
,
3066 (cis
[i
+ 10] << 8) + cis
[i
+ 9]);
3067 varbuf_append(&b
, vstr_mcsbw1605ghpo
,
3068 (cis
[i
+ 12] << 8) + cis
[i
+ 11]);
3069 varbuf_append(&b
, vstr_mcslr5rlpo
,
3070 (cis
[i
+ 14] << 8) + cis
[i
+ 13]);
3071 varbuf_append(&b
, vstr_mcslr5gmpo
,
3072 (cis
[i
+ 16] << 8) + cis
[i
+ 15]);
3073 varbuf_append(&b
, vstr_mcslr5ghpo
,
3074 (cis
[i
+ 18] << 8) + cis
[i
+ 17]);
3077 case HNBU_ACPPR_SBPO
:
3078 varbuf_append(&b
, vstr_sb20in40rrpo
, 'h',
3079 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
3080 varbuf_append(&b
, vstr_sb20in80and160r5gpo
, 'h', 'l',
3081 (cis
[i
+ 4] << 8) + cis
[i
+ 3]);
3082 varbuf_append(&b
, vstr_sb40and80r5gpo
, 'h', 'l',
3083 (cis
[i
+ 6] << 8) + cis
[i
+ 5]);
3084 varbuf_append(&b
, vstr_sb20in80and160r5gpo
, 'h', 'm',
3085 (cis
[i
+ 8] << 8) + cis
[i
+ 7]);
3086 varbuf_append(&b
, vstr_sb40and80r5gpo
, 'h', 'm',
3087 (cis
[i
+ 10] << 8) + cis
[i
+ 9]);
3088 varbuf_append(&b
, vstr_sb20in80and160r5gpo
, 'h', 'h',
3089 (cis
[i
+ 12] << 8) + cis
[i
+ 11]);
3090 varbuf_append(&b
, vstr_sb40and80r5gpo
, 'h', 'h',
3091 (cis
[i
+ 14] << 8) + cis
[i
+ 13]);
3092 varbuf_append(&b
, vstr_sb20in40rrpo
, 'l',
3093 (cis
[i
+ 16] << 8) + cis
[i
+ 15]);
3094 varbuf_append(&b
, vstr_sb20in80and160r5gpo
, 'l', 'l',
3095 (cis
[i
+ 18] << 8) + cis
[i
+ 17]);
3096 varbuf_append(&b
, vstr_sb40and80r5gpo
, 'l', 'l',
3097 (cis
[i
+ 20] << 8) + cis
[i
+ 19]);
3098 varbuf_append(&b
, vstr_sb20in80and160r5gpo
, 'l', 'm',
3099 (cis
[i
+ 22] << 8) + cis
[i
+ 21]);
3100 varbuf_append(&b
, vstr_sb40and80r5gpo
, 'l', 'm',
3101 (cis
[i
+ 24] << 8) + cis
[i
+ 23]);
3102 varbuf_append(&b
, vstr_sb20in80and160r5gpo
, 'l', 'h',
3103 (cis
[i
+ 26] << 8) + cis
[i
+ 25]);
3104 varbuf_append(&b
, vstr_sb40and80r5gpo
, 'l', 'h',
3105 (cis
[i
+ 28] << 8) + cis
[i
+ 27]);
3106 varbuf_append(&b
, vstr_dot11agduprpo
, 'h',
3107 (cis
[i
+ 30] << 8) + cis
[i
+ 24]);
3108 varbuf_append(&b
, vstr_dot11agduprpo
, 'l',
3109 (cis
[i
+ 32] << 8) + cis
[i
+ 26]);
3114 varbuf_append(&b
, vstr_noiselvl2ga
, 0,
3115 (cis
[i
+ 1] & 0x1f));
3116 varbuf_append(&b
, vstr_noiselvl2ga
, 1,
3117 ((cis
[i
+ 2] & 0x3) << 4) +
3118 ((cis
[i
+ 1] & 0xe0) >> 4));
3119 varbuf_append(&b
, vstr_noiselvl2ga
, 2,
3120 (cis
[i
+ 2] & 0x7c) >> 2);
3122 varbuf_append(&b
, vstr_noiselvl5ga
, 'l', 0,
3123 (cis
[i
+ 3] & 0x1f));
3124 varbuf_append(&b
, vstr_noiselvl5ga
, 'l', 1,
3125 ((cis
[i
+ 4] & 0x3) << 4) +
3126 ((cis
[i
+ 3] & 0xe0) >> 4));
3127 varbuf_append(&b
, vstr_noiselvl5ga
, 'l', 2,
3128 (cis
[i
+ 4] & 0x7c) >> 2);
3130 varbuf_append(&b
, vstr_noiselvl5ga
, 'm', 0,
3131 (cis
[i
+ 5] & 0x1f));
3132 varbuf_append(&b
, vstr_noiselvl5ga
, 'm', 1,
3133 ((cis
[i
+ 6] & 0x3) << 4) +
3134 ((cis
[i
+ 5] & 0xe0) >> 4));
3135 varbuf_append(&b
, vstr_noiselvl5ga
, 'm', 2,
3136 (cis
[i
+ 6] & 0x7c) >> 2);
3138 varbuf_append(&b
, vstr_noiselvl5ga
, 'h', 0,
3139 (cis
[i
+ 7] & 0x1f));
3140 varbuf_append(&b
, vstr_noiselvl5ga
, 'h', 1,
3141 ((cis
[i
+ 8] & 0x3) << 4) +
3142 ((cis
[i
+ 7] & 0xe0) >> 4));
3143 varbuf_append(&b
, vstr_noiselvl5ga
, 'h', 2,
3144 (cis
[i
+ 8] & 0x7c) >> 2);
3146 varbuf_append(&b
, vstr_noiselvl5ga
, 'u', 0,
3147 (cis
[i
+ 9] & 0x1f));
3148 varbuf_append(&b
, vstr_noiselvl5ga
, 'u', 1,
3149 ((cis
[i
+ 10] & 0x3) << 4) +
3150 ((cis
[i
+ 9] & 0xe0) >> 4));
3151 varbuf_append(&b
, vstr_noiselvl5ga
, 'u', 2,
3152 (cis
[i
+ 10] & 0x7c) >> 2);
3155 case HNBU_RXGAIN_ERR
:
3156 varbuf_append(&b
, vstr_rxgainerr2g
,
3157 (cis
[i
+ 2] << 8) + cis
[i
+ 1]);
3158 varbuf_append(&b
, vstr_rxgainerr5g
,
3159 (cis
[i
+ 4] << 8) + cis
[i
+ 3],
3160 (cis
[i
+ 6] << 8) + cis
[i
+ 5],
3161 (cis
[i
+ 8] << 8) + cis
[i
+ 7],
3162 (cis
[i
+ 10] << 8) + cis
[i
+ 9]);
3166 varbuf_append(&b
, vstr_agbg
, 0, cis
[i
+ 1]);
3167 varbuf_append(&b
, vstr_agbg
, 1, cis
[i
+ 2]);
3168 varbuf_append(&b
, vstr_agbg
, 2, cis
[i
+ 3]);
3169 varbuf_append(&b
, vstr_aga
, 3, cis
[i
+ 4]);
3170 varbuf_append(&b
, vstr_aga
, 4, cis
[i
+ 5]);
3171 varbuf_append(&b
, vstr_aga
, 5, cis
[i
+ 6]);
3176 /* uuid format 12345678-1234-5678-1234-567812345678 */
3178 char uuidstr
[37]; /* 32 ids, 4 '-', 1 Null */
3180 snprintf(uuidstr
, sizeof(uuidstr
),
3181 "%02X%02X%02X%02X-%02X%02X-%02X%02X-"
3182 "%02X%02X-%02X%02X%02X%02X%02X%02X",
3183 cis
[i
+ 1], cis
[i
+ 2], cis
[i
+ 3], cis
[i
+ 4],
3184 cis
[i
+ 5], cis
[i
+ 6], cis
[i
+ 7], cis
[i
+ 8],
3185 cis
[i
+ 9], cis
[i
+ 10], cis
[i
+ 11], cis
[i
+ 12],
3186 cis
[i
+ 13], cis
[i
+ 14], cis
[i
+ 15], cis
[i
+ 16]);
3188 varbuf_append(&b
, vstr_uuid
, uuidstr
);
3192 #endif /* !BCM_BOOTLOADER */
3198 } while (tup
!= CISTPL_END
);
3201 if (boardnum
!= -1) {
3202 varbuf_append(&b
, vstr_boardnum
, boardnum
);
3206 varbuf_append(&b
, vstr_macaddr
, eabuf
);
3209 #ifndef BCM_BOOTLOADER
3210 /* if there is no antenna gain field, set default */
3211 if (getvar(NULL
, "ag0") == NULL
&& ag_init
== FALSE
) {
3212 varbuf_append(&b
, vstr_ag
, 0, 0xff);
3216 #if defined(BCMUSBDEV_BMAC) || defined(BCM_BMAC_VARS_APPEND)
3217 varbuf_append(&b
, vstr_end
, NULL
);
3218 #endif /* BCMUSBDEV_BMAC */
3220 /* final nullbyte terminator */
3221 ASSERT(b
.size
>= 1);
3224 ASSERT(b
.buf
- base
<= MAXSZ_NVRAM_VARS
);
3225 err
= initvars_table(osh
, base
, b
.buf
, vars
, count
);
3227 MFREE(osh
, base
, MAXSZ_NVRAM_VARS
);
3231 /* set PCMCIA sprom command register */
3233 sprom_cmd_pcmcia(osl_t
*osh
, uint8 cmd
)
3236 uint wait_cnt
= 1000;
3238 /* write sprom command register */
3239 OSL_PCMCIA_WRITE_ATTR(osh
, SROM_CS
, &cmd
, 1);
3242 while (wait_cnt
--) {
3243 OSL_PCMCIA_READ_ATTR(osh
, SROM_CS
, &status
, 1);
3244 if (status
& SROM_DONE
)
3251 /* read a word from the PCMCIA srom */
3253 sprom_read_pcmcia(osl_t
*osh
, uint16 addr
, uint16
*data
)
3255 uint8 addr_l
, addr_h
, data_l
, data_h
;
3257 addr_l
= (uint8
)((addr
* 2) & 0xff);
3258 addr_h
= (uint8
)(((addr
* 2) >> 8) & 0xff);
3261 OSL_PCMCIA_WRITE_ATTR(osh
, SROM_ADDRH
, &addr_h
, 1);
3262 OSL_PCMCIA_WRITE_ATTR(osh
, SROM_ADDRL
, &addr_l
, 1);
3265 if (sprom_cmd_pcmcia(osh
, SROM_READ
))
3269 data_h
= data_l
= 0;
3270 OSL_PCMCIA_READ_ATTR(osh
, SROM_DATAH
, &data_h
, 1);
3271 OSL_PCMCIA_READ_ATTR(osh
, SROM_DATAL
, &data_l
, 1);
3273 *data
= (data_h
<< 8) | data_l
;
3277 #if defined(WLTEST) || defined(DHD_SPROM) || defined(BCMDBG)
3278 /* write a word to the PCMCIA srom */
3280 sprom_write_pcmcia(osl_t
*osh
, uint16 addr
, uint16 data
)
3282 uint8 addr_l
, addr_h
, data_l
, data_h
;
3284 addr_l
= (uint8
)((addr
* 2) & 0xff);
3285 addr_h
= (uint8
)(((addr
* 2) >> 8) & 0xff);
3286 data_l
= (uint8
)(data
& 0xff);
3287 data_h
= (uint8
)((data
>> 8) & 0xff);
3290 OSL_PCMCIA_WRITE_ATTR(osh
, SROM_ADDRH
, &addr_h
, 1);
3291 OSL_PCMCIA_WRITE_ATTR(osh
, SROM_ADDRL
, &addr_l
, 1);
3294 OSL_PCMCIA_WRITE_ATTR(osh
, SROM_DATAH
, &data_h
, 1);
3295 OSL_PCMCIA_WRITE_ATTR(osh
, SROM_DATAL
, &data_l
, 1);
3298 return sprom_cmd_pcmcia(osh
, SROM_WRITE
);
3302 /* In chips with chipcommon rev 32 and later, the srom is in chipcommon,
3303 * not in the bus cores.
3306 srom_cc_cmd(si_t
*sih
, osl_t
*osh
, void *ccregs
, uint32 cmd
, uint wordoff
, uint16 data
)
3308 chipcregs_t
*cc
= (chipcregs_t
*)ccregs
;
3309 uint wait_cnt
= 1000;
3311 if ((cmd
== SRC_OP_READ
) || (cmd
== SRC_OP_WRITE
)) {
3312 W_REG(osh
, &cc
->sromaddress
, wordoff
* 2);
3313 if (cmd
== SRC_OP_WRITE
)
3314 W_REG(osh
, &cc
->sromdata
, data
);
3317 W_REG(osh
, &cc
->sromcontrol
, SRC_START
| cmd
);
3319 while (wait_cnt
--) {
3320 if ((R_REG(osh
, &cc
->sromcontrol
) & SRC_BUSY
) == 0)
3325 BS_ERROR(("%s: Command 0x%x timed out\n", __FUNCTION__
, cmd
));
3328 if (cmd
== SRC_OP_READ
)
3329 return (uint16
)R_REG(osh
, &cc
->sromdata
);
3335 * Read in and validate sprom.
3336 * Return 0 on success, nonzero on error.
3339 sprom_read_pci(osl_t
*osh
, si_t
*sih
, uint16
*sprom
, uint wordoff
, uint16
*buf
, uint nwords
,
3344 void *ccregs
= NULL
;
3347 if ((CHIPID(sih
->chip
) == BCM4331_CHIP_ID
) ||
3348 (CHIPID(sih
->chip
) == BCM43431_CHIP_ID
) ||
3349 (CHIPID(sih
->chip
) == BCM4360_CHIP_ID
) ||
3350 (CHIPID(sih
->chip
) == BCM43460_CHIP_ID
) ||
3351 (CHIPID(sih
->chip
) == BCM4352_CHIP_ID
)) {
3352 /* save current control setting */
3353 ccval
= si_chipcontrl_read(sih
);
3356 if ((CHIPID(sih
->chip
) == BCM4331_CHIP_ID
) ||
3357 (CHIPID(sih
->chip
) == BCM43431_CHIP_ID
)) {
3358 /* Disable Ext PA lines to allow reading from SROM */
3359 si_chipcontrl_epa4331(sih
, FALSE
);
3360 } else if ((CHIPID(sih
->chip
) == BCM4360_CHIP_ID
) ||
3361 (CHIPID(sih
->chip
) == BCM43460_CHIP_ID
) ||
3362 (CHIPID(sih
->chip
) == BCM4352_CHIP_ID
)) {
3363 si_chipcontrl_srom4360(sih
, TRUE
);
3366 /* read the sprom */
3367 for (i
= 0; i
< nwords
; i
++) {
3369 if (sih
->ccrev
> 31 && ISSIM_ENAB(sih
)) {
3370 /* use indirect since direct is too slow on QT */
3371 if ((sih
->cccaps
& CC_CAP_SROM
) == 0) {
3376 ccregs
= (void *)((uint8
*)sprom
- CC_SROM_OTP
);
3377 buf
[i
] = srom_cc_cmd(sih
, osh
, ccregs
, SRC_OP_READ
, wordoff
+ i
, 0);
3380 if (ISSIM_ENAB(sih
))
3381 buf
[i
] = R_REG(osh
, &sprom
[wordoff
+ i
]);
3383 buf
[i
] = R_REG(osh
, &sprom
[wordoff
+ i
]);
3388 /* bypass crc checking for simulation to allow srom hack */
3389 if (ISSIM_ENAB(sih
)) {
3395 if (buf
[0] == 0xffff) {
3396 /* The hardware thinks that an srom that starts with 0xffff
3397 * is blank, regardless of the rest of the content, so declare
3400 BS_ERROR(("%s: buf[0] = 0x%x, returning bad-crc\n", __FUNCTION__
, buf
[0]));
3405 /* fixup the endianness so crc8 will pass */
3406 htol16_buf(buf
, nwords
* 2);
3407 if (hndcrc8((uint8
*)buf
, nwords
* 2, CRC8_INIT_VALUE
) != CRC8_GOOD_VALUE
) {
3408 /* DBG only pci always read srom4 first, then srom8/9 */
3409 /* BS_ERROR(("%s: bad crc\n", __FUNCTION__)); */
3412 /* now correct the endianness of the byte array */
3413 ltoh16_buf(buf
, nwords
* 2);
3417 if ((CHIPID(sih
->chip
) == BCM4331_CHIP_ID
) ||
3418 (CHIPID(sih
->chip
) == BCM43431_CHIP_ID
) ||
3419 (CHIPID(sih
->chip
) == BCM4360_CHIP_ID
) ||
3420 (CHIPID(sih
->chip
) == BCM43460_CHIP_ID
) ||
3421 (CHIPID(sih
->chip
) == BCM4352_CHIP_ID
)) {
3423 /* Restore config after reading SROM */
3424 si_chipcontrl_restore(sih
, ccval
);
3430 #if defined(BCMNVRAMW) || defined(BCMNVRAMR)
3432 otp_read_pci(osl_t
*osh
, si_t
*sih
, uint16
*buf
, uint bufsz
)
3435 uint sz
= OTP_SZ_MAX
/2; /* size in words */
3438 ASSERT(bufsz
<= OTP_SZ_MAX
);
3440 if ((otp
= MALLOC(osh
, OTP_SZ_MAX
)) == NULL
) {
3444 bzero(otp
, OTP_SZ_MAX
);
3446 err
= otp_read_region(sih
, OTP_HW_RGN
, (uint16
*)otp
, &sz
);
3449 MFREE(osh
, otp
, OTP_SZ_MAX
);
3453 bcopy(otp
, buf
, bufsz
);
3455 MFREE(osh
, otp
, OTP_SZ_MAX
);
3458 if (buf
[0] == 0xffff) {
3459 /* The hardware thinks that an srom that starts with 0xffff
3460 * is blank, regardless of the rest of the content, so declare
3463 BS_ERROR(("%s: buf[0] = 0x%x, returning bad-crc\n", __FUNCTION__
, buf
[0]));
3467 /* fixup the endianness so crc8 will pass */
3468 htol16_buf(buf
, bufsz
);
3469 if (hndcrc8((uint8
*)buf
, SROM4_WORDS
* 2, CRC8_INIT_VALUE
) != CRC8_GOOD_VALUE
&&
3470 hndcrc8((uint8
*)buf
, SROM10_WORDS
* 2, CRC8_INIT_VALUE
) != CRC8_GOOD_VALUE
) {
3471 BS_ERROR(("%s: bad crc\n", __FUNCTION__
));
3474 /* now correct the endianness of the byte array */
3475 ltoh16_buf(buf
, bufsz
);
3479 #endif /* defined(BCMNVRAMW) || defined(BCMNVRAMR) */
3481 #if defined(WLTEST) || defined(BCMDBG)
3483 srom_otp_write_region_crc(si_t
*sih
, uint nbytes
, uint16
* buf16
, bool write
)
3485 int err
= 0, crc
= 0;
3488 /* Check nbytes is not odd or too big */
3489 if ((nbytes
& 1) || (nbytes
> SROM_MAX
))
3492 /* block invalid buffer size */
3493 if (nbytes
< SROM4_WORDS
* 2)
3494 return BCME_BUFTOOSHORT
;
3495 else if (nbytes
> SROM10_WORDS
* 2)
3496 return BCME_BUFTOOLONG
;
3498 /* Verify signatures */
3499 if (!((buf16
[SROM4_SIGN
] == SROM4_SIGNATURE
) ||
3500 (buf16
[SROM8_SIGN
] == SROM4_SIGNATURE
) ||
3501 (buf16
[SROM10_SIGN
] == SROM4_SIGNATURE
))) {
3502 BS_ERROR(("%s: wrong signature SROM4_SIGN %x SROM8_SIGN %x SROM10_SIGN %x\n",
3503 __FUNCTION__
, buf16
[SROM4_SIGN
], buf16
[SROM8_SIGN
], buf16
[SROM10_SIGN
]));
3508 if (buf16
[0] == 0xffff) {
3509 /* The hardware thinks that an srom that starts with 0xffff
3510 * is blank, regardless of the rest of the content, so declare
3513 BS_ERROR(("%s: invalid buf16[0] = 0x%x\n", __FUNCTION__
, buf16
[0]));
3517 buf8
= (uint8
*)buf16
;
3518 /* fixup the endianness and then calculate crc */
3519 htol16_buf(buf8
, nbytes
);
3520 crc
= ~hndcrc8(buf8
, nbytes
- 1, CRC8_INIT_VALUE
);
3521 /* now correct the endianness of the byte array */
3522 ltoh16_buf(buf8
, nbytes
);
3523 if (nbytes
== SROM10_WORDS
* 2)
3524 buf16
[SROM10_CRCREV
] = (crc
<< 8) | (buf16
[SROM10_CRCREV
] & 0xff);
3526 buf16
[SROM4_CRCREV
] = (crc
<< 8) | (buf16
[SROM4_CRCREV
] & 0xff);
3529 /* Write the CRC back */
3531 err
= otp_write_region(sih
, OTP_HW_RGN
, buf16
, nbytes
/2);
3532 #endif /* BCMNVRAMW */
3535 return write
? err
: crc
;
3540 * Create variable table from memory.
3541 * Return 0 on success, nonzero on error.
3544 BCMATTACHFN(initvars_table
)(osl_t
*osh
, char *start
, char *end
, char **vars
, uint
*count
)
3546 int c
= (int)(end
- start
);
3548 /* do it only when there is more than just the null string */
3550 char *vp
= MALLOC(osh
, c
);
3554 bcopy(start
, vp
, c
);
3567 * Find variables with <devpath> from flash. 'base' points to the beginning
3568 * of the table upon enter and to the end of the table upon exit when success.
3569 * Return 0 on success, nonzero on error.
3572 BCMATTACHFN(initvars_flash
)(si_t
*sih
, osl_t
*osh
, char **base
, uint len
)
3578 uint l
, dl
, copy_len
;
3579 char devpath
[SI_DEVPATH_BUFSZ
];
3580 char coded_name
[SI_DEVPATH_BUFSZ
] = {0};
3581 int path_len
, coded_len
, devid_len
;
3583 /* allocate memory and read in flash */
3584 if (!(flash
= MALLOC(osh
, NVRAM_SPACE
)))
3586 if ((err
= nvram_getall(flash
, NVRAM_SPACE
)))
3589 /* create legacy devpath prefix */
3590 si_devpath(sih
, devpath
, sizeof(devpath
));
3591 path_len
= strlen(devpath
);
3593 /* create coded devpath prefix */
3594 si_coded_devpathvar(sih
, coded_name
, sizeof(coded_name
), "devid");
3596 /* coded_name now is 'xx:devid, eat ending 'devid' */
3598 devid_len
= strlen("devid");
3599 coded_len
= strlen(coded_name
);
3600 if (coded_len
> devid_len
) {
3601 coded_name
[coded_len
- devid_len
] = '\0';
3602 coded_len
-= devid_len
;
3607 /* grab vars with the <devpath> prefix or <coded_name> previx in name */
3608 for (s
= flash
; s
&& *s
; s
+= l
+ 1) {
3611 /* skip non-matching variable */
3612 if (strncmp(s
, devpath
, path_len
) == 0)
3614 else if (coded_len
&& strncmp(s
, coded_name
, coded_len
) == 0)
3619 /* is there enough room to copy? */
3620 copy_len
= l
- dl
+ 1;
3621 if (len
< copy_len
) {
3622 err
= BCME_BUFTOOSHORT
;
3626 /* no prefix, just the name=value */
3627 strncpy(vp
, &s
[dl
], copy_len
);
3632 /* add null string as terminator */
3634 err
= BCME_BUFTOOSHORT
;
3641 exit
: MFREE(osh
, flash
, NVRAM_SPACE
);
3645 #if !defined(BCMUSBDEV_ENABLED) && !defined(BCMSDIODEV_ENABLED)
3647 * Initialize nonvolatile variable table from flash.
3648 * Return 0 on success, nonzero on error.
3651 BCMATTACHFN(initvars_flash_si
)(si_t
*sih
, char **vars
, uint
*count
)
3653 osl_t
*osh
= si_osh(sih
);
3657 ASSERT(vars
!= NULL
);
3658 ASSERT(count
!= NULL
);
3660 base
= vp
= MALLOC(osh
, MAXSZ_NVRAM_VARS
);
3665 if ((err
= initvars_flash(sih
, osh
, &vp
, MAXSZ_NVRAM_VARS
)) == 0)
3666 err
= initvars_table(osh
, base
, vp
, vars
, count
);
3668 MFREE(osh
, base
, MAXSZ_NVRAM_VARS
);
3674 /* Parse SROM and create name=value pairs. 'srom' points to
3675 * the SROM word array. 'off' specifies the offset of the
3676 * first word 'srom' points to, which should be either 0 or
3677 * SROM3_SWRG_OFF (full SROM or software region).
3681 mask_shift(uint16 mask
)
3684 for (i
= 0; i
< (sizeof(mask
) << 3); i
++) {
3685 if (mask
& (1 << i
))
3693 mask_width(uint16 mask
)
3696 for (i
= (sizeof(mask
) << 3) - 1; i
>= 0; i
--) {
3697 if (mask
& (1 << i
))
3698 return (uint
)(i
- mask_shift(mask
) + 1);
3704 #ifdef BCMASSERT_SUPPORT
3706 mask_valid(uint16 mask
)
3708 uint shift
= mask_shift(mask
);
3709 uint width
= mask_width(mask
);
3710 return mask
== ((~0 << shift
) & ~(~0 << (shift
+ width
)));
3715 BCMATTACHFN(_initvars_srom_pci
)(uint8 sromrev
, uint16
*srom
, uint off
, varbuf_t
*b
)
3719 const sromvar_t
*srv
;
3722 uint32 sr
= (1 << sromrev
);
3723 bool in_array
= FALSE
;
3724 static char array_temp
[256];
3725 uint array_curr
= 0;
3726 const char* array_name
= NULL
;
3728 varbuf_append(b
, "sromrev=%d", sromrev
);
3730 for (srv
= pci_sromvars
; srv
->name
!= NULL
; srv
++) {
3732 static bool in_array
= FALSE
;
3733 static char array_temp
[256];
3734 static uint array_curr
= 0;
3735 static const char* array_name
= NULL
;
3737 if ((srv
->revmask
& sr
) == 0)
3746 /* This entry is for mfgc only. Don't generate param for it, */
3747 if (flags
& SRFL_NOVAR
)
3750 if (flags
& SRFL_ETHADDR
) {
3751 char eabuf
[ETHER_ADDR_STR_LEN
];
3752 struct ether_addr ea
;
3754 ea
.octet
[0] = (srom
[srv
->off
- off
] >> 8) & 0xff;
3755 ea
.octet
[1] = srom
[srv
->off
- off
] & 0xff;
3756 ea
.octet
[2] = (srom
[srv
->off
+ 1 - off
] >> 8) & 0xff;
3757 ea
.octet
[3] = srom
[srv
->off
+ 1 - off
] & 0xff;
3758 ea
.octet
[4] = (srom
[srv
->off
+ 2 - off
] >> 8) & 0xff;
3759 ea
.octet
[5] = srom
[srv
->off
+ 2 - off
] & 0xff;
3760 bcm_ether_ntoa(&ea
, eabuf
);
3762 varbuf_append(b
, "%s=%s", name
, eabuf
);
3765 ASSERT(mask_valid(srv
->mask
));
3766 ASSERT(mask_width(srv
->mask
));
3768 /* Start of an array */
3769 if (sromrev
>= 10 && (srv
->flags
& SRFL_ARRAY
) && !in_array
) {
3771 array_name
= (const char*)srv
->name
;
3772 memset((void*)array_temp
, 0, sizeof(array_temp
));
3776 w
= srom
[srv
->off
- off
];
3777 val
= (w
& srv
->mask
) >> mask_shift(srv
->mask
);
3778 width
= mask_width(srv
->mask
);
3780 while (srv
->flags
& SRFL_MORE
) {
3782 ASSERT(srv
->name
!= NULL
);
3784 if (srv
->off
== 0 || srv
->off
< off
)
3787 ASSERT(mask_valid(srv
->mask
));
3788 ASSERT(mask_width(srv
->mask
));
3790 w
= srom
[srv
->off
- off
];
3791 val
+= ((w
& srv
->mask
) >> mask_shift(srv
->mask
)) << width
;
3792 width
+= mask_width(srv
->mask
);
3795 if ((flags
& SRFL_NOFFS
) && ((int)val
== (1 << width
) - 1))
3798 /* Array support starts in sromrev 10. Skip arrays for sromrev <= 9 */
3799 if (sromrev
<= 9 && srv
->flags
& SRFL_ARRAY
) {
3800 while (srv
->flags
& SRFL_ARRAY
)
3808 if (flags
& SRFL_PRHEX
) {
3809 ret
= snprintf(array_temp
+ array_curr
,
3810 sizeof(array_temp
) - array_curr
, "0x%x,", val
);
3811 } else if ((flags
& SRFL_PRSIGN
) &&
3812 (val
& (1 << (width
- 1)))) {
3813 ret
= snprintf(array_temp
+ array_curr
,
3814 sizeof(array_temp
) - array_curr
, "%d,",
3815 (int)(val
| (~0 << width
)));
3817 ret
= snprintf(array_temp
+ array_curr
,
3818 sizeof(array_temp
) - array_curr
, "%u,", val
);
3824 BS_ERROR(("%s: array %s parsing error. buffer too short.\n",
3825 __FUNCTION__
, array_name
));
3828 /* buffer too small, skip this param */
3829 while (srv
->flags
& SRFL_ARRAY
)
3836 if (!(srv
->flags
& SRFL_ARRAY
)) { /* Array ends */
3837 /* Remove the last ',' */
3838 array_temp
[array_curr
-1] = '\0';
3840 varbuf_append(b
, "%s=%s", array_name
, array_temp
);
3842 } else if (flags
& SRFL_CCODE
) {
3844 varbuf_append(b
, "ccode=");
3846 varbuf_append(b
, "ccode=%c%c", (val
>> 8), (val
& 0xff));
3848 /* LED Powersave duty cycle has to be scaled:
3849 *(oncount >> 24) (offcount >> 8)
3851 else if (flags
& SRFL_LEDDC
) {
3852 uint32 w32
= (((val
>> 8) & 0xff) << 24) | /* oncount */
3853 (((val
& 0xff)) << 8); /* offcount */
3854 varbuf_append(b
, "leddc=%d", w32
);
3856 else if (flags
& SRFL_PRHEX
)
3857 varbuf_append(b
, "%s=0x%x", name
, val
);
3858 else if ((flags
& SRFL_PRSIGN
) && (val
& (1 << (width
- 1))))
3859 varbuf_append(b
, "%s=%d", name
, (int)(val
| (~0 << width
)));
3861 varbuf_append(b
, "%s=%u", name
, val
);
3866 /* Do per-path variables */
3867 uint p
, pb
, psz
, path_num
;
3869 if (sromrev
>= 11) {
3871 psz
= SROM11_PATH1
- SROM11_PATH0
;
3872 path_num
= MAX_PATH_SROM_11
;
3873 } else if (sromrev
>= 8) {
3875 psz
= SROM8_PATH1
- SROM8_PATH0
;
3876 path_num
= MAX_PATH_SROM
;
3879 psz
= SROM4_PATH1
- SROM4_PATH0
;
3880 path_num
= MAX_PATH_SROM
;
3883 for (p
= 0; p
< path_num
; p
++) {
3884 for (srv
= perpath_pci_sromvars
; srv
->name
!= NULL
; srv
++) {
3885 if ((srv
->revmask
& sr
) == 0)
3888 if (pb
+ srv
->off
< off
)
3891 /* This entry is for mfgc only. Don't generate param for it, */
3892 if (srv
->flags
& SRFL_NOVAR
)
3895 /* Start of an array */
3896 if (sromrev
>= 10 && (srv
->flags
& SRFL_ARRAY
) && !in_array
) {
3898 array_name
= (const char*)srv
->name
;
3899 memset((void*)array_temp
, 0, sizeof(array_temp
));
3903 w
= srom
[pb
+ srv
->off
- off
];
3905 ASSERT(mask_valid(srv
->mask
));
3906 val
= (w
& srv
->mask
) >> mask_shift(srv
->mask
);
3907 width
= mask_width(srv
->mask
);
3911 /* Cheating: no per-path var is more than 1 word */
3913 if ((srv
->flags
& SRFL_NOFFS
) && ((int)val
== (1 << width
) - 1))
3919 if (flags
& SRFL_PRHEX
) {
3920 ret
= snprintf(array_temp
+ array_curr
,
3921 sizeof(array_temp
) - array_curr
, "0x%x,", val
);
3922 } else if ((flags
& SRFL_PRSIGN
) &&
3923 (val
& (1 << (width
- 1)))) {
3924 ret
= snprintf(array_temp
+ array_curr
,
3925 sizeof(array_temp
) - array_curr
, "%d,",
3926 (int)(val
| (~0 << width
)));
3928 ret
= snprintf(array_temp
+ array_curr
,
3929 sizeof(array_temp
) - array_curr
, "%u,", val
);
3936 ("%s: array %s parsing error. buffer too short.\n",
3937 __FUNCTION__
, array_name
));
3940 /* buffer too small, skip this param */
3941 while (srv
->flags
& SRFL_ARRAY
)
3948 if (!(srv
->flags
& SRFL_ARRAY
)) { /* Array ends */
3949 /* Remove the last ',' */
3950 array_temp
[array_curr
-1] = '\0';
3952 varbuf_append(b
, "%s%d=%s",
3953 array_name
, p
, array_temp
);
3955 } else if (srv
->flags
& SRFL_PRHEX
)
3956 varbuf_append(b
, "%s%d=0x%x", srv
->name
, p
, val
);
3958 varbuf_append(b
, "%s%d=%d", srv
->name
, p
, val
);
3966 * Initialize nonvolatile variable table from sprom.
3967 * Return 0 on success, nonzero on error.
3970 BCMATTACHFN(initvars_srom_pci
)(si_t
*sih
, void *curmap
, char **vars
, uint
*count
)
3972 uint16
*srom
, *sromwindow
;
3976 char *vp
, *base
= NULL
;
3977 osl_t
*osh
= si_osh(sih
);
3982 * Apply CRC over SROM content regardless SROM is present or not,
3983 * and use variable <devpath>sromrev's existance in flash to decide
3984 * if we should return an error when CRC fails or read SROM variables
3987 srom
= MALLOC(osh
, SROM_MAX
);
3988 ASSERT(srom
!= NULL
);
3992 sromwindow
= (uint16
*)SROM_OFFSET(sih
);
3993 if (si_is_sprom_available(sih
)) {
3994 err
= sprom_read_pci(osh
, sih
, sromwindow
, 0, srom
, SROM11_WORDS
, TRUE
);
3997 if (srom
[SROM11_SIGN
] == SROM11_SIGNATURE
) /* srom 11 */
3998 sromrev
= srom
[SROM11_CRCREV
] & 0xff;
4000 err
= sprom_read_pci(osh
, sih
, sromwindow
, 0, srom
, SROM4_WORDS
, TRUE
);
4003 if ((srom
[SROM4_SIGN
] == SROM4_SIGNATURE
) || /* srom 4 */
4004 (srom
[SROM8_SIGN
] == SROM4_SIGNATURE
) ) { /* srom 8, 9 */
4005 sromrev
= srom
[SROM4_CRCREV
] & 0xff;
4008 err
= sprom_read_pci(osh
, sih
, sromwindow
, 0,
4009 srom
, SROM_WORDS
, TRUE
);
4012 /* srom is good and is rev < 4 */
4013 /* top word of sprom contains version and crc8 */
4014 sromrev
= srom
[SROM_CRCREV
] & 0xff;
4015 /* bcm4401 sroms misprogrammed */
4016 if (sromrev
== 0x10)
4023 #if defined(BCMNVRAMW) || defined(BCMNVRAMR)
4024 /* Use OTP if SPROM not available */
4025 else if ((err
= otp_read_pci(osh
, sih
, srom
, SROM_MAX
)) == 0) {
4026 /* OTP only contain SROM rev8/rev9/rev10/Rev11 for now */
4027 if (srom
[SROM11_SIGN
] == SROM11_SIGNATURE
)
4028 sromrev
= srom
[SROM11_CRCREV
] & 0xff;
4029 else if (srom
[SROM10_SIGN
] == SROM10_SIGNATURE
)
4030 sromrev
= srom
[SROM10_CRCREV
] & 0xff;
4032 sromrev
= srom
[SROM4_CRCREV
] & 0xff;
4034 #endif /* defined(BCMNVRAMW) || defined(BCMNVRAMR) */
4037 BS_ERROR(("Neither SPROM nor OTP has valid image\n"));
4040 BS_ERROR(("srom rev:%d\n", sromrev
));
4043 /* We want internal/wltest driver to come up with default sromvars so we can
4044 * program a blank SPROM/OTP.
4052 if ((value
= si_getdevpathvar(sih
, "sromrev"))) {
4053 sromrev
= (uint8
)bcm_strtoul(value
, NULL
, 0);
4058 BS_ERROR(("%s, SROM CRC Error\n", __FUNCTION__
));
4061 if ((value
= si_getnvramflvar(sih
, "sromrev"))) {
4066 /* BCMHOSTVARS is enabled only if WLTEST is enabled or BCMEXTNVM is enabled */
4067 #if defined(BCMHOSTVARS)
4068 val
= OSL_PCI_READ_CONFIG(osh
, PCI_SPROM_CONTROL
, sizeof(uint32
));
4069 if ((si_is_sprom_available(sih
) && srom
[0] == 0xffff) ||
4070 (val
& SPROM_OTPIN_USE
)) {
4071 vp
= base
= mfgsromvars
;
4073 if (defvarslen
== 0) {
4074 BS_ERROR(("No nvm file, use generic default (for programming"
4075 " SPROM/OTP only)\n"));
4077 if (((sih
->chip
== BCM4331_CHIP_ID
) ||
4078 (sih
->chip
== BCM43431_CHIP_ID
)) &&
4079 (sih
->chiprev
< 3)) {
4081 defvarslen
= srom_vars_len(defaultsromvars_4331
);
4082 bcopy(defaultsromvars_4331
, vp
, defvarslen
);
4085 /* For 4311 A1 there is no signature to indicate that OTP is
4086 * programmed, so can't really verify the OTP is
4087 * unprogrammed or a bad OTP.
4089 if (sih
->chip
== BCM4311_CHIP_ID
) {
4090 const char *devid
= "devid=0x4311";
4091 const size_t devid_strlen
= strlen(devid
);
4092 BS_ERROR(("setting the devid to be 4311\n"));
4093 bcopy(devid
, vp
, devid_strlen
+ 1);
4094 vp
+= devid_strlen
+ 1;
4096 defvarslen
= srom_vars_len(defaultsromvars_wltest
);
4097 bcopy(defaultsromvars_wltest
, vp
, defvarslen
);
4100 BS_ERROR(("Use nvm file as default\n"));
4104 /* add final null terminator */
4107 BS_ERROR(("Used %d bytes of defaultsromvars\n", defvarslen
));
4110 } else if ((((sih
->chip
== BCM4331_CHIP_ID
) ||
4111 (sih
->chip
== BCM43431_CHIP_ID
)) &&
4112 (sih
->chiprev
< 3)) || (sih
->chip
== BCM4360_CHIP_ID
) ||
4113 (sih
->chip
== BCM43460_CHIP_ID
) ||
4114 (sih
->chip
== BCM4352_CHIP_ID
)) {
4115 base
= vp
= mfgsromvars
;
4117 if ((sih
->chip
== BCM4360_CHIP_ID
) ||
4118 (sih
->chip
== BCM43460_CHIP_ID
) ||
4119 (sih
->chip
== BCM4352_CHIP_ID
))
4120 BS_ERROR(("4360 BOOT w/o SPROM or OTP\n"));
4122 BS_ERROR(("4331 BOOT w/o SPROM or OTP\n"));
4124 defvarslen
= srom_vars_len(defaultsromvars_4331
);
4125 bcopy(defaultsromvars_4331
, vp
, defvarslen
);
4138 /* Bitmask for the sromrev */
4141 /* srom version check: Current valid versions: 1-5, 8-11, SROM_MAXREV */
4142 if ((sr
& 0xf3e) == 0) {
4143 BS_ERROR(("Invalid SROM rev %d\n", sromrev
));
4148 ASSERT(vars
!= NULL
);
4149 ASSERT(count
!= NULL
);
4151 base
= vp
= MALLOC(osh
, MAXSZ_NVRAM_VARS
);
4158 /* read variables from flash */
4160 if ((err
= initvars_flash(sih
, osh
, &vp
, MAXSZ_NVRAM_VARS
)))
4165 varbuf_init(&b
, base
, MAXSZ_NVRAM_VARS
);
4167 /* parse SROM into name=value pairs. */
4168 _initvars_srom_pci(sromrev
, srom
, 0, &b
);
4171 /* final nullbyte terminator */
4172 ASSERT(b
.size
>= 1);
4176 ASSERT((vp
- base
) <= MAXSZ_NVRAM_VARS
);
4179 err
= initvars_table(osh
, base
, vp
, vars
, count
);
4182 /* BCMHOSTVARS are enabled only if WLTEST is enabled or BCMEXTNVM is enabled */
4183 #if defined(BCMHOSTVARS)
4184 if (base
&& (base
!= mfgsromvars
))
4188 MFREE(osh
, base
, MAXSZ_NVRAM_VARS
);
4190 MFREE(osh
, srom
, SROM_MAX
);
4195 * Read the cis and call parsecis to initialize the vars.
4196 * Return 0 on success, nonzero on error.
4199 BCMATTACHFN(initvars_cis_pcmcia
)(si_t
*sih
, osl_t
*osh
, char **vars
, uint
*count
)
4205 data_sz
= (sih
->buscorerev
== 1) ? SROM_MAX
: CIS_SIZE
;
4207 if ((cis
= MALLOC(osh
, data_sz
)) == NULL
)
4210 if (sih
->buscorerev
== 1) {
4211 if (srom_read(sih
, PCMCIA_BUS
, (void *)NULL
, osh
, 0, data_sz
, (uint16
*)cis
,
4213 MFREE(osh
, cis
, data_sz
);
4216 /* fix up endianess for 16-bit data vs 8-bit parsing */
4217 htol16_buf((uint16
*)cis
, data_sz
);
4219 OSL_PCMCIA_READ_ATTR(osh
, 0, cis
, data_sz
);
4221 rc
= srom_parsecis(osh
, &cis
, SROM_CIS_SINGLE
, vars
, count
);
4223 MFREE(osh
, cis
, data_sz
);
4231 * Read the SPI cis and call parsecis to initialize the vars.
4232 * Return 0 on success, nonzero on error.
4235 BCMATTACHFN(initvars_cis_spi
)(osl_t
*osh
, char **vars
, uint
*count
)
4240 #if defined(NDIS) && !defined(UNDER_CE)
4241 uint8 cisd
[SBSDIO_CIS_SIZE_LIMIT
];
4244 if ((cis
= MALLOC(osh
, SBSDIO_CIS_SIZE_LIMIT
)) == NULL
) {
4247 #endif /* defined(NDIS) && (!defined(UNDER_CE)) */
4249 bzero(cis
, SBSDIO_CIS_SIZE_LIMIT
);
4251 if (bcmsdh_cis_read(NULL
, SDIO_FUNC_1
, cis
, SBSDIO_CIS_SIZE_LIMIT
) != 0) {
4252 #if defined(NDIS) && !defined(UNDER_CE)
4255 MFREE(osh
, cis
, SBSDIO_CIS_SIZE_LIMIT
);
4256 #endif /* defined(NDIS) && (!defined(UNDER_CE)) */
4260 rc
= srom_parsecis(osh
, &cis
, SDIO_FUNC_1
, vars
, count
);
4262 #if defined(NDIS) && !defined(UNDER_CE)
4263 /* nothing to do here */
4265 MFREE(osh
, cis
, SBSDIO_CIS_SIZE_LIMIT
);
4272 #if defined(BCMUSBDEV)
4273 /* Return sprom size in 16-bit words */
4275 srom_size(si_t
*sih
, osl_t
*osh
)
4278 if (SPROMBUS
== PCMCIA_BUS
) {
4280 sdpcmd_regs_t
*pcmregs
;
4283 origidx
= si_coreidx(sih
);
4284 pcmregs
= si_setcore(sih
, PCMCIA_CORE_ID
, 0);
4286 pcmregs
= si_setcore(sih
, SDIOD_CORE_ID
, 0);
4289 if (!(wasup
= si_iscoreup(sih
)))
4290 si_core_reset(sih
, 0, 0);
4292 /* not worry about earlier core revs */
4293 /* valid for only pcmcia core */
4294 if (si_coreid(sih
) == PCMCIA_CORE_ID
)
4295 if (si_corerev(sih
) < 8)
4299 switch (SI_PCMCIA_READ(osh
, pcmregs
, SROM_INFO
) & SRI_SZ_MASK
) {
4301 size
= 256; /* SROM_INFO == 1 means 4kbit */
4304 size
= 1024; /* SROM_INFO == 2 means 16kbit */
4312 si_core_disable(sih
, 0);
4314 si_setcoreidx(sih
, origidx
);
4321 * initvars are different for BCMUSBDEV and BCMSDIODEV. This is OK when supporting both at
4322 * the same time, but only because all of the code is in attach functions and not in ROM.
4325 #if defined(BCMUSBDEV_ENABLED)
4326 #if defined(BCMUSBDEV_BMAC) || defined(BCM_BMAC_VARS_APPEND)
4328 * Read the USB cis and call parsecis to initialize the vars.
4329 * Return 0 on success, nonzero on error.
4332 BCMATTACHFN(initvars_cis_usbdriver
)(si_t
*sih
, osl_t
*osh
, char **vars
, uint
*count
)
4335 uint sz
= OTP_SZ_MAX
/2; /* size in words */
4338 if ((cis
= MALLOC(osh
, OTP_SZ_MAX
)) == NULL
) {
4342 bzero(cis
, OTP_SZ_MAX
);
4344 if (otp_read_region(sih
, OTP_SW_RGN
, (uint16
*)cis
, &sz
)) {
4345 BS_ERROR(("%s: OTP read SW region failure.\n*", __FUNCTION__
));
4348 BS_ERROR(("%s: OTP programmed. use OTP for srom vars\n*", __FUNCTION__
));
4349 rc
= srom_parsecis(osh
, &cis
, SROM_CIS_SINGLE
, vars
, count
);
4352 MFREE(osh
, cis
, OTP_SZ_MAX
);
4357 /* For driver(not bootloader), if nvram is not downloadable or missing, use default */
4359 BCMATTACHFN(initvars_srom_si_usbdriver
)(si_t
*sih
, osl_t
*osh
, char **vars
, uint
*varsz
)
4366 base
= fakevars
= NULL
;
4368 switch (CHIPID(sih
->chip
)) {
4369 case BCM4322_CHIP_ID
: case BCM43221_CHIP_ID
: case BCM43231_CHIP_ID
:
4370 fakevars
= defaultsromvars_4322usb
;
4372 case BCM43236_CHIP_ID
: case BCM43235_CHIP_ID
: case BCM43238_CHIP_ID
:
4373 case BCM43234_CHIP_ID
:
4374 /* check against real chipid instead of compile time flag */
4375 if (sih
->chip
== BCM43234_CHIP_ID
) {
4376 fakevars
= defaultsromvars_43234usb
;
4377 } else if (sih
->chip
== BCM43235_CHIP_ID
) {
4378 fakevars
= defaultsromvars_43235usb
;
4380 fakevars
= defaultsromvars_43236usb
;
4383 case BCM4319_CHIP_ID
:
4384 fakevars
= defaultsromvars_4319usb
;
4386 case BCM4360_CHIP_ID
:
4387 case BCM43460_CHIP_ID
:
4388 case BCM43526_CHIP_ID
:
4389 fakevars
= defaultsromvars_4360usb
;
4396 #ifndef BCM_BMAC_VARS_APPEND
4397 if (BCME_OK
== initvars_cis_usbdriver(sih
, osh
, vars
, varsz
)) {
4398 /* Make OTP/SROM variables global */
4399 if (srvars_inited
== FALSE
)
4400 nvram_append((void *)sih
, *vars
, *varsz
);
4403 #endif /* BCM_BMAC_VARS_APPEND */
4405 /* NO OTP, if nvram downloaded, use it */
4406 if ((_varsz
!= 0) && (_vars
!= NULL
)) {
4407 len
= _varsz
+ (strlen(vstr_end
));
4408 base
= MALLOC(osh
, len
+ 2); /* plus 2 terminating \0 */
4410 BS_ERROR(("initvars_srom_si: MALLOC failed.\n"));
4413 bzero(base
, len
+ 2);
4415 /* make a copy of the _vars, _vars is at the top of the memory, cannot append
4416 * END\0\0 to it. copy the download vars to base, back of the terminating \0,
4417 * then append END\0\0
4419 bcopy((void *)_vars
, base
, _varsz
);
4420 /* backoff all the terminating \0s except the one the for the last string */
4422 while (!base
[len
- 1])
4424 len
++; /* \0 for the last string */
4425 /* append END\0\0 to the end */
4426 bcopy((void *)vstr_end
, (base
+ len
), strlen(vstr_end
));
4427 len
+= (strlen(vstr_end
) + 2);
4431 BS_ERROR(("%s USB nvram downloaded %d bytes\n", __FUNCTION__
, _varsz
));
4433 /* Fall back to fake srom vars if OTP not programmed */
4434 len
= srom_vars_len(fakevars
);
4435 base
= MALLOC(osh
, (len
+ 1));
4437 BS_ERROR(("initvars_srom_si: MALLOC failed.\n"));
4440 bzero(base
, (len
+ 1));
4441 bcopy(fakevars
, base
, len
);
4442 *(base
+ len
) = '\0'; /* add final nullbyte terminator */
4445 BS_ERROR(("initvars_srom_usbdriver: faked nvram %d bytes\n", len
));
4448 #ifdef BCM_BMAC_VARS_APPEND
4449 if (BCME_OK
== initvars_cis_usbdriver(sih
, osh
, vars
, varsz
)) {
4451 MFREE(osh
, base
, (len
+ 1));
4453 #endif /* BCM_BMAC_VARS_APPEND */
4454 /* Make OTP/SROM variables global */
4455 if (srvars_inited
== FALSE
) {
4456 nvram_append((void *)sih
, *vars
, *varsz
);
4457 srvars_inited
= TRUE
;
4462 #endif /* BCMUSBDEV_BMAC || BCM_BMAC_VARS_APPEND */
4464 #ifdef BCM_DONGLEVARS
4466 BCMATTACHFN(initvars_srom_si_bl
)(si_t
*sih
, osl_t
*osh
, void *curmap
, char **vars
, uint
*varsz
)
4468 int sel
= 0; /* where to read srom/cis: 0 - none, 1 - otp, 2 - sprom */
4469 uint sz
= 0; /* srom size in bytes */
4473 if ((oh
= otp_init(sih
)) != NULL
&& (otp_status(oh
) & OTPS_GUP_SW
)) {
4474 /* Access OTP if it is present, powered on, and programmed */
4477 } else if ((sz
= srom_size(sih
, osh
)) != 0) {
4478 /* Access the SPROM if it is present */
4483 /* Read CIS in OTP/SPROM */
4491 /* Allocate memory */
4492 if ((srom
= (uint16
*)MALLOC(osh
, sz
)) == NULL
)
4498 rc
= otp_read_region(sih
, OTP_SW_RGN
, srom
, &otpsz
);
4500 body
= (uint8
*)srom
;
4503 rc
= srom_read(sih
, SI_BUS
, curmap
, osh
, 0, sz
, srom
, TRUE
);
4504 /* sprom has 8 byte h/w header */
4505 body
= (uint8
*)srom
+ SBSDIO_SPROM_CIS_OFFSET
;
4508 /* impossible to come here */
4514 if (rc
== BCME_OK
) {
4515 /* each word is in host endian */
4516 htol16_buf((uint8
*)srom
, sz
);
4518 rc
= srom_parsecis(osh
, &body
, SROM_CIS_SINGLE
, vars
, varsz
);
4521 MFREE(osh
, srom
, sz
); /* Clean up */
4523 /* Make SROM variables global */
4525 nvram_append((void *)sih
, *vars
, *varsz
);
4530 #endif /* #ifdef BCM_DONGLEVARS */
4533 BCMATTACHFN(initvars_srom_si
)(si_t
*sih
, osl_t
*osh
, void *curmap
, char **vars
, uint
*varsz
)
4536 /* Bail out if we've dealt with OTP/SPROM before! */
4540 #if defined(BCMUSBDEV_BMAC) || defined(BCM_BMAC_VARS_APPEND)
4541 /* read OTP or use faked var array */
4542 switch (CHIPID(sih
->chip
)) {
4543 case BCM4322_CHIP_ID
: case BCM43221_CHIP_ID
: case BCM43231_CHIP_ID
:
4544 case BCM43236_CHIP_ID
: case BCM43235_CHIP_ID
: case BCM43238_CHIP_ID
:
4545 case BCM43234_CHIP_ID
:
4546 case BCM4319_CHIP_ID
:
4547 case BCM4360_CHIP_ID
:
4548 case BCM43460_CHIP_ID
:
4549 case BCM4352_CHIP_ID
:
4550 if (BCME_OK
!= initvars_srom_si_usbdriver(sih
, osh
, vars
, varsz
))
4554 UNUSED_PARAMETER(defaultsromvars_4322usb
);
4555 UNUSED_PARAMETER(defaultsromvars_43234usb
);
4556 UNUSED_PARAMETER(defaultsromvars_43235usb
);
4557 UNUSED_PARAMETER(defaultsromvars_43236usb
);
4558 UNUSED_PARAMETER(defaultsromvars_4319usb
);
4560 #endif /* BCMUSBDEV_BMAC || BCM_BMAC_VARS_APPEND */
4562 #ifdef BCM_DONGLEVARS /* this flag should be defined for usb bootloader, to read \
4564 if (BCME_OK
!= initvars_srom_si_bl(sih
, osh
, curmap
, vars
, varsz
))
4568 /* update static local var to skip for next call */
4569 srvars_inited
= TRUE
;
4572 /* Tell the caller there is no individual SROM variables */
4576 /* return OK so the driver will load & use defaults if bad srom/otp */
4580 #elif defined(BCMSDIODEV_ENABLED)
4582 #ifdef BCM_DONGLEVARS
4583 static uint8
BCMATTACHDATA(defcis4325
)[] = { 0x20, 0x4, 0xd0, 0x2, 0x25, 0x43, 0xff, 0xff };
4584 static uint8
BCMATTACHDATA(defcis4315
)[] = { 0x20, 0x4, 0xd0, 0x2, 0x15, 0x43, 0xff, 0xff };
4585 static uint8
BCMATTACHDATA(defcis4329
)[] = { 0x20, 0x4, 0xd0, 0x2, 0x29, 0x43, 0xff, 0xff };
4586 static uint8
BCMATTACHDATA(defcis4319
)[] = { 0x20, 0x4, 0xd0, 0x2, 0x19, 0x43, 0xff, 0xff };
4587 static uint8
BCMATTACHDATA(defcis4336
)[] = { 0x20, 0x4, 0xd0, 0x2, 0x36, 0x43, 0xff, 0xff };
4588 static uint8
BCMATTACHDATA(defcis4330
)[] = { 0x20, 0x4, 0xd0, 0x2, 0x30, 0x43, 0xff, 0xff };
4589 static uint8
BCMATTACHDATA(defcis43237
)[] = { 0x20, 0x4, 0xd0, 0x2, 0xe5, 0xa8, 0xff, 0xff };
4590 static uint8
BCMATTACHDATA(defcis4324
)[] = { 0x20, 0x4, 0xd0, 0x2, 0x24, 0x43, 0xff, 0xff };
4591 static uint8
BCMATTACHDATA(defcis4335
)[] = { 0x20, 0x4, 0xd0, 0x2, 0x24, 0x43, 0xff, 0xff };
4593 #ifdef BCM_BMAC_VARS_APPEND
4595 static char BCMATTACHDATA(defaultsromvars_4319sdio
)[] =
4599 "boardtype=0x05a1\0"
4601 "boardflags=0x400201\0"
4602 "boardflags2=0x80\0"
4617 "cckdigfilttype=6\0"
4620 "ofdmpo=0x55553333\0"
4627 "macaddr=00:90:4c:06:c0:19\0"
4630 static char BCMATTACHDATA(defaultsromvars_4319sdio_hmb
)[] =
4634 "boardtype=0x058c\0"
4636 "boardflags=0x400201\0"
4637 "boardflags2=0x80\0"
4652 "cckdigfilttype=6\0"
4655 "ofdmpo=0x55553333\0"
4662 "macaddr=00:90:4c:06:c0:19\0"
4665 static char BCMATTACHDATA(defaultsromvars_4319sdio_usbsd
)[] =
4669 "boardtype=0x05a2\0"
4671 "boardflags=0x400201\0"
4672 "boardflags2=0x80\0"
4687 "cckdigfilttype=6\0"
4690 "ofdmpo=0x55553333\0"
4697 "macaddr=00:90:4c:08:90:00\0"
4700 static char BCMATTACHDATA(defaultsromvars_43237
)[] =
4703 "boardtype=0x0583\0"
4706 "boardflags=0x200\0"
4709 "macaddr=00:90:4c:51:a8:e4\0"
4740 "pa1lomaxpwr=0x3a\0"
4741 "pa1himaxpwr=0x3c\0"
4819 "pa5glw0a0=0xfeaa\0"
4820 "pa5glw1a0=0x14b9\0"
4821 "pa5glw2a0=0xfaf0\0"
4822 "pa5ghw0a0=0xfec5\0"
4823 "pa5ghw1a0=0x1439\0"
4824 "pa5ghw2a0=0xfb18\0"
4839 "pa5glw0a1=0xfece\0"
4840 "pa5glw1a1=0x1361\0"
4841 "pa5glw2a1=0xfb5f\0"
4842 "pa5ghw0a1=0xfe9e\0"
4843 "pa5ghw1a1=0x12ca\0"
4844 "pa5ghw2a1=0xfb41\0"
4848 srom_load_nvram(si_t
*sih
, osl_t
*osh
, uint8
*pcis
[], uint ciscnt
, char **vars
, uint
*varsz
)
4850 uint len
= 0, base_len
;
4854 base
= fakevars
= NULL
;
4855 switch (CHIPID(sih
->chip
)) {
4856 case BCM4319_CHIP_ID
:
4857 printf("load driver default for chip %x\n", CHIPID(sih
->chip
));
4858 fakevars
= defaultsromvars_4319sdio
;
4859 if (si_cis_source(sih
) == CIS_OTP
) {
4860 switch (srom_probe_boardtype(pcis
, ciscnt
)) {
4861 case BCM94319SDHMB_SSID
:
4862 fakevars
= defaultsromvars_4319sdio_hmb
;
4864 case BCM94319USBSDB_SSID
:
4865 fakevars
= defaultsromvars_4319sdio_usbsd
;
4868 fakevars
= defaultsromvars_4319sdio
;
4873 case BCM43237_CHIP_ID
:
4874 printf("load driver default for chip %x\n", CHIPID(sih
->chip
));
4875 fakevars
= defaultsromvars_43237
;
4878 printf("unknown chip %x\n", CHIPID(sih
->chip
));
4879 return BCME_ERROR
; /* fakevars == NULL for switch default */
4883 /* NO OTP, if nvram downloaded, use it */
4884 if ((_varsz
!= 0) && (_vars
!= NULL
)) {
4885 len
= _varsz
+ (strlen(vstr_end
));
4886 base_len
= len
+ 2; /* plus 2 terminating \0 */
4887 base
= MALLOC(osh
, base_len
);
4889 BS_ERROR(("initvars_srom_si: MALLOC failed.\n"));
4892 bzero(base
, base_len
);
4894 /* make a copy of the _vars, _vars is at the top of the memory, cannot append
4895 * END\0\0 to it. copy the download vars to base, back of the terminating \0,
4896 * then append END\0\0
4898 bcopy((void *)_vars
, base
, _varsz
);
4899 /* backoff all the terminating \0s except the one the for the last string */
4901 while (!base
[len
- 1])
4903 len
++; /* \0 for the last string */
4904 /* append END\0\0 to the end */
4905 bcopy((void *)vstr_end
, (base
+ len
), strlen(vstr_end
));
4906 len
+= (strlen(vstr_end
) + 2);
4910 BS_ERROR(("%s nvram downloaded %d bytes\n", __FUNCTION__
, _varsz
));
4912 /* Fall back to fake srom vars if OTP not programmed */
4913 len
= srom_vars_len(fakevars
);
4914 base
= MALLOC(osh
, (len
+ 1));
4917 BS_ERROR(("initvars_srom_si: MALLOC failed.\n"));
4920 bzero(base
, base_len
);
4921 bcopy(fakevars
, base
, len
);
4922 *(base
+ len
) = '\0'; /* add final nullbyte terminator */
4925 BS_ERROR(("srom_load_driver)default: faked nvram %d bytes\n", len
));
4928 if ((srom_parsecis(osh
, pcis
, ciscnt
, vars
, varsz
)) == BCME_OK
)
4929 nvram_append((void *)sih
, *vars
, *varsz
);
4930 MFREE(osh
, base
, base_len
);
4934 #endif /* BCM_BMAC_VARS_APPEND */
4937 BCMATTACHFN(initvars_srom_si
)(si_t
*sih
, osl_t
*osh
, void *curmap
, char **vars
, uint
*varsz
)
4944 bool new_cisformat
= FALSE
;
4946 uint16
*cisbuf
= NULL
;
4948 /* # sdiod fns + common + extra */
4949 uint8
*cis
[SBSDIO_NUM_FUNCTION
+ 2] = { 0 };
4955 /* Bail out if we've dealt with OTP/SPROM before! */
4959 /* Initialize default and cis format count */
4960 switch (CHIPID(sih
->chip
)) {
4961 case BCM4325_CHIP_ID
: ciss
= 3; defcis
= defcis4325
; hdrsz
= 8; break;
4962 case BCM4315_CHIP_ID
: ciss
= 3; defcis
= defcis4315
; hdrsz
= 8; break;
4963 case BCM4329_CHIP_ID
: ciss
= 4; defcis
= defcis4329
; hdrsz
= 12; break;
4964 case BCM4319_CHIP_ID
: ciss
= 3; defcis
= defcis4319
; hdrsz
= 12; break;
4965 case BCM4336_CHIP_ID
: ciss
= 1; defcis
= defcis4336
; hdrsz
= 4; break;
4966 case BCM43362_CHIP_ID
: ciss
= 1; defcis
= defcis4336
; hdrsz
= 4; break;
4967 case BCM4330_CHIP_ID
: ciss
= 1; defcis
= defcis4330
; hdrsz
= 4; break;
4968 case BCM43237_CHIP_ID
: ciss
= 1; defcis
= defcis43237
; hdrsz
= 4; break;
4969 case BCM4324_CHIP_ID
: ciss
= 1; defcis
= defcis4324
; hdrsz
= 4; break;
4970 case BCM4314_CHIP_ID
: ciss
= 1; defcis
= defcis4330
; hdrsz
= 4; break;
4971 case BCM4334_CHIP_ID
: ciss
= 1; defcis
= defcis4330
; hdrsz
= 4; break;
4972 case BCM4335_CHIP_ID
: ciss
= 1; defcis
= defcis4335
; hdrsz
= 4; break;
4974 BS_ERROR(("%s: Unknown chip 0x%04x\n", __FUNCTION__
, sih
->chip
));
4977 if (sih
->ccrev
>= 36) {
4979 otplayout
= si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, otplayout
), 0, 0);
4980 if (otplayout
& OTP_CISFORMAT_NEW
) {
4983 new_cisformat
= TRUE
;
4991 cis_src
= si_cis_source(sih
);
4994 sz
= srom_size(sih
, osh
) << 1;
4997 if (((oh
= otp_init(sih
)) != NULL
) && (otp_status(oh
) & OTPS_GUP_HW
))
5003 if ((cisbuf
= (uint16
*)MALLOC(osh
, sz
)) == NULL
)
5009 rc
= srom_read(sih
, SI_BUS
, curmap
, osh
, 0, sz
, cisbuf
, FALSE
);
5013 rc
= otp_read_region(sih
, OTP_HW_RGN
, cisbuf
, &sz
);
5019 if (rc
== BCME_OK
) {
5020 if ((cisbuf
[0] == 0xffff) || (cisbuf
[0] == 0)) {
5021 MFREE(osh
, cisbuf
, msz
);
5023 } else if (new_cisformat
) {
5024 cis
[0] = (uint8
*)(cisbuf
+ hdrsz
);
5026 cis
[0] = (uint8
*)cisbuf
+ hdrsz
;
5027 cis
[1] = (uint8
*)cisbuf
+ hdrsz
+
5028 (cisbuf
[1] >> 8) + ((cisbuf
[2] & 0x00ff) << 8) -
5029 SBSDIO_CIS_BASE_COMMON
;
5030 cis
[2] = (uint8
*)cisbuf
+ hdrsz
+
5031 cisbuf
[3] - SBSDIO_CIS_BASE_COMMON
;
5032 cis
[3] = (uint8
*)cisbuf
+ hdrsz
+
5033 cisbuf
[4] - SBSDIO_CIS_BASE_COMMON
;
5034 ASSERT((cis
[1] >= cis
[0]) && (cis
[1] < (uint8
*)cisbuf
+ sz
));
5035 ASSERT((cis
[2] >= cis
[0]) && (cis
[2] < (uint8
*)cisbuf
+ sz
));
5036 ASSERT(((cis
[3] >= cis
[0]) && (cis
[3] < (uint8
*)cisbuf
+ sz
)) ||
5042 /* Use default if strapped to, or strapped source empty */
5043 if (cisbuf
== NULL
) {
5048 #ifdef BCM_BMAC_VARS_APPEND
5049 srom_load_nvram(sih
, osh
, cis
, ciss
, vars
, varsz
);
5052 if (rc
== BCME_OK
) {
5053 if ((rc
= srom_parsecis(osh
, cis
, ciss
, vars
, varsz
)) == BCME_OK
)
5054 nvram_append((void *)sih
, *vars
, *varsz
);
5056 #endif /* BCM_BMAC_VARS_APPEND */
5059 MFREE(osh
, cisbuf
, msz
);
5061 srvars_inited
= TRUE
;
5063 /* Tell the caller there is no individual SROM variables */
5067 /* return OK so the driver will load & use defaults if bad srom/otp */
5070 #else /* BCM_DONGLEVARS */
5072 BCMATTACHFN(initvars_srom_si
)(si_t
*sih
, osl_t
*osh
, void *curmap
, char **vars
, uint
*varsz
)
5078 #endif /* BCM_DONGLEVARS */
5080 #else /* !BCMUSBDEV && !BCMSDIODEV */
5083 BCMATTACHFN(initvars_srom_si
)(si_t
*sih
, osl_t
*osh
, void *curmap
, char **vars
, uint
*varsz
)
5085 /* Search flash nvram section for srom variables */
5086 return initvars_flash_si(sih
, vars
, varsz
);
5091 srom_var_deinit(si_t
*sih
)
5093 srvars_inited
= FALSE
;
5096 extern void _make_gcc_happy_about_unused_variabe_(void);
5098 _make_gcc_happy_about_unused_variabe_(void)
5100 #if defined(BCMUSBDEV)
5101 #if defined(BCMUSBDEV_BMAC) || defined(BCM_BMAC_VARS_APPEND)
5102 UNUSED_PARAMETER(defaultsromvars_4322usb
);
5103 UNUSED_PARAMETER(defaultsromvars_43234usb
);
5104 UNUSED_PARAMETER(defaultsromvars_43235usb
);
5105 UNUSED_PARAMETER(defaultsromvars_43236usb
);
5106 UNUSED_PARAMETER(defaultsromvars_4319usb
);
5107 #endif /* BCMUSBDEV_BMAC || BCM_BMAC_VARS_APPEND */
5108 #endif /* BCMUSBDEV */