2 * Misc useful routines to access NIC SROM/OTP .
4 * Copyright 2006, Broadcom Corporation
7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
11 * $Id: bcmsrom.c,v 1.1.1.14 2006/04/15 01:28:25 michael Exp $
20 #include <bcmendian.h>
28 #define BS_ERROR(args) printf args
30 #define BS_ERROR(args)
31 #endif /* BCMDBG_ERR || WLTEST */
33 #define VARS_MAX 4096 /* should be reduced */
35 #define WRITE_ENABLE_DELAY 500 /* 500 ms after write enable/disable toggle */
36 #define WRITE_WORD_DELAY 20 /* 20 ms between each word write */
38 static int initvars_srom_pci(void *sbh
, void *curmap
, char **vars
, uint
*count
);
39 static int initvars_cis_pcmcia(void *sbh
, osl_t
*osh
, char **vars
, uint
*count
);
40 static int initvars_flash_sb(void *sbh
, char **vars
, uint
*count
);
41 static int srom_parsecis(osl_t
*osh
, uint8
**pcis
, uint ciscnt
, char **vars
, uint
*count
);
42 static int sprom_cmd_pcmcia(osl_t
*osh
, uint8 cmd
);
43 static int sprom_read_pcmcia(osl_t
*osh
, uint16 addr
, uint16
*data
);
44 static int sprom_write_pcmcia(osl_t
*osh
, uint16 addr
, uint16 data
);
45 static int sprom_read_pci(osl_t
*osh
, uint16
*sprom
, uint wordoff
, uint16
*buf
, uint nwords
,
48 static int initvars_table(osl_t
*osh
, char *start
, char *end
, char **vars
, uint
*count
);
49 static int initvars_flash(osl_t
*osh
, char **vp
, uint len
, char *devpath
);
52 * Initialize local vars from the right source for this platform.
53 * Return 0 on success, nonzero on error.
56 srom_var_init(void *sbh
, uint bustype
, void *curmap
, osl_t
*osh
, char **vars
, uint
*count
)
58 ASSERT(bustype
== BUSTYPE(bustype
));
59 if (vars
== NULL
|| count
== NULL
)
62 switch (BUSTYPE(bustype
)) {
65 return initvars_flash_sb(sbh
, vars
, count
);
68 ASSERT(curmap
); /* can not be NULL */
69 return initvars_srom_pci(sbh
, curmap
, vars
, count
);
72 return initvars_cis_pcmcia(sbh
, osh
, vars
, count
);
81 /* support only 16-bit word read from srom */
83 srom_read(uint bustype
, void *curmap
, osl_t
*osh
, uint byteoff
, uint nbytes
, uint16
*buf
)
88 ASSERT(bustype
== BUSTYPE(bustype
));
90 /* check input - 16-bit access only */
91 if (byteoff
& 1 || nbytes
& 1 || (byteoff
+ nbytes
) > (SPROM_SIZE
* 2))
97 if (BUSTYPE(bustype
) == PCI_BUS
) {
100 srom
= (uchar
*)curmap
+ PCI_BAR0_SPROM_OFFSET
;
101 if (sprom_read_pci(osh
, srom
, off
, buf
, nw
, FALSE
))
103 } else if (BUSTYPE(bustype
) == PCMCIA_BUS
) {
104 for (i
= 0; i
< nw
; i
++) {
105 if (sprom_read_pcmcia(osh
, (uint16
)(off
+ i
), (uint16
*)(buf
+ i
)))
115 /* support only 16-bit word write into srom */
117 srom_write(uint bustype
, void *curmap
, osl_t
*osh
, uint byteoff
, uint nbytes
, uint16
*buf
)
120 uint i
, nw
, crc_range
;
121 uint16 image
[SPROM_SIZE
];
123 volatile uint32 val32
;
125 ASSERT(bustype
== BUSTYPE(bustype
));
127 /* check input - 16-bit access only */
128 if (byteoff
& 1 || nbytes
& 1 || (byteoff
+ nbytes
) > (SPROM_SIZE
* 2))
131 /* Are we writing the whole thing at once? */
132 if ((byteoff
== 0) &&
133 ((nbytes
== SPROM_SIZE
) ||
134 (nbytes
== (SPROM_CRC_RANGE
* 2)) ||
135 (nbytes
== (SROM4_WORDS
* 2)))) {
137 bcopy((void*)buf
, (void*)image
, nbytes
);
140 if ((BUSTYPE(bustype
) == PCMCIA_BUS
) || (BUSTYPE(bustype
) == SDIO_BUS
))
141 crc_range
= SPROM_SIZE
;
143 crc_range
= SPROM_CRC_RANGE
* 2; /* Tentative */
146 /* read first 64 words from srom */
147 if (srom_read(bustype
, curmap
, osh
, 0, crc_range
, image
))
149 if (image
[SROM4_SIGN
] == SROM4_SIGNATURE
) {
150 crc_range
= SROM4_WORDS
;
152 if (srom_read(bustype
, curmap
, osh
, 0, crc_range
, image
))
156 bcopy((void*)buf
, (void*)&image
[byteoff
/ 2], nbytes
);
160 htol16_buf(image
, crc_range
);
161 crc
= ~hndcrc8((uint8
*)image
, crc_range
- 1, CRC8_INIT_VALUE
);
162 ltoh16_buf(image
, crc_range
);
163 image
[(crc_range
/ 2) - 1] = (crc
<< 8) | (image
[(crc_range
/ 2) - 1] & 0xff);
165 if (BUSTYPE(bustype
) == PCI_BUS
) {
166 srom
= (uint16
*)((uchar
*)curmap
+ PCI_BAR0_SPROM_OFFSET
);
167 /* enable writes to the SPROM */
168 val32
= OSL_PCI_READ_CONFIG(osh
, PCI_SPROM_CONTROL
, sizeof(uint32
));
169 val32
|= SPROM_WRITEEN
;
170 OSL_PCI_WRITE_CONFIG(osh
, PCI_SPROM_CONTROL
, sizeof(uint32
), val32
);
171 bcm_mdelay(WRITE_ENABLE_DELAY
);
173 for (i
= 0; i
< nw
; i
++) {
174 W_REG(osh
, &srom
[i
], image
[i
]);
175 bcm_mdelay(WRITE_WORD_DELAY
);
177 /* disable writes to the SPROM */
178 OSL_PCI_WRITE_CONFIG(osh
, PCI_SPROM_CONTROL
, sizeof(uint32
), val32
&
180 } else if (BUSTYPE(bustype
) == PCMCIA_BUS
) {
181 /* enable writes to the SPROM */
182 if (sprom_cmd_pcmcia(osh
, SROM_WEN
))
184 bcm_mdelay(WRITE_ENABLE_DELAY
);
186 for (i
= 0; i
< nw
; i
++) {
187 sprom_write_pcmcia(osh
, (uint16
)(i
), image
[i
]);
188 bcm_mdelay(WRITE_WORD_DELAY
);
190 /* disable writes to the SPROM */
191 if (sprom_cmd_pcmcia(osh
, SROM_WDS
))
197 bcm_mdelay(WRITE_ENABLE_DELAY
);
203 srom_parsecis(osl_t
*osh
, uint8
**pcis
, uint ciscnt
, char **vars
, uint
*count
)
207 uint8
*cis
, tup
, tlen
, sromrev
= 1;
210 bool ag_init
= FALSE
;
216 base
= vp
= MALLOC(osh
, VARS_MAX
);
227 if ((i
+ tlen
) >= CIS_SIZE
)
232 vp
+= sprintf(vp
, "manfid=%d", (cis
[i
+ 1] << 8) + cis
[i
]);
234 vp
+= sprintf(vp
, "prodid=%d", (cis
[i
+ 3] << 8) + cis
[i
+ 2]);
241 ASSERT(cis
[i
+ 1] == 6);
242 bcm_ether_ntoa((struct ether_addr
*)&cis
[i
+ 2], eabuf
);
243 vp
+= sprintf(vp
, "il0macaddr=%s", eabuf
);
246 case 1: /* SDIO Extended Data */
247 vp
+= sprintf(vp
, "sdmaxblk=%d",
248 (cis
[i
+ 13] << 8) | cis
[i
+ 12]);
255 vp
+= sprintf(vp
, "regwindowsz=%d", (cis
[i
+ 7] << 8) | cis
[i
+ 6]);
259 case CISTPL_BRCM_HNBU
:
262 sromrev
= cis
[i
+ 1];
266 vp
+= sprintf(vp
, "vendid=%d", (cis
[i
+ 2] << 8) +
269 vp
+= sprintf(vp
, "devid=%d", (cis
[i
+ 4] << 8) +
273 vp
+= sprintf(vp
, "chiprev=%d",
274 (cis
[i
+ 6] << 8) + cis
[i
+ 5]);
280 vp
+= sprintf(vp
, "boardrev=%d", cis
[i
+ 1]);
285 vp
+= sprintf(vp
, "aa2g=%d", cis
[i
+ 1]);
290 vp
+= sprintf(vp
, "ag0=%d", cis
[i
+ 1]);
296 ASSERT(sromrev
== 1);
297 vp
+= sprintf(vp
, "cc=%d", cis
[i
+ 1]);
303 ASSERT(sromrev
== 1);
304 vp
+= sprintf(vp
, "pa0maxpwr=%d", cis
[i
+ 1]);
306 } else if (tlen
>= 9) {
308 ASSERT(sromrev
== 2);
309 vp
+= sprintf(vp
, "opo=%d", cis
[i
+ 9]);
314 for (j
= 0; j
< 3; j
++) {
315 vp
+= sprintf(vp
, "pa0b%d=%d", j
,
316 (cis
[i
+ (j
* 2) + 2] << 8) +
317 cis
[i
+ (j
* 2) + 1]);
320 vp
+= sprintf(vp
, "pa0itssit=%d", cis
[i
+ 7]);
322 vp
+= sprintf(vp
, "pa0maxpwr=%d", cis
[i
+ 8]);
329 ASSERT(sromrev
== 1);
330 vp
+= sprintf(vp
, "oem=%02x%02x%02x%02x%02x%02x%02x%02x",
331 cis
[i
+ 1], cis
[i
+ 2],
332 cis
[i
+ 3], cis
[i
+ 4],
333 cis
[i
+ 5], cis
[i
+ 6],
334 cis
[i
+ 7], cis
[i
+ 8]);
338 case HNBU_BOARDFLAGS
:
339 w32
= (cis
[i
+ 2] << 8) + cis
[i
+ 1];
341 w32
|= (cis
[i
+ 4] << 24) + (cis
[i
+ 3] << 16);
342 vp
+= sprintf(vp
, "boardflags=0x%x", w32
);
347 if (cis
[i
+ 1] != 0xff) {
348 vp
+= sprintf(vp
, "ledbh0=%d", cis
[i
+ 1]);
351 if (cis
[i
+ 2] != 0xff) {
352 vp
+= sprintf(vp
, "ledbh1=%d", cis
[i
+ 2]);
355 if (cis
[i
+ 3] != 0xff) {
356 vp
+= sprintf(vp
, "ledbh2=%d", cis
[i
+ 3]);
359 if (cis
[i
+ 4] != 0xff) {
360 vp
+= sprintf(vp
, "ledbh3=%d", cis
[i
+ 4]);
372 vp
+= sprintf(vp
, "ccode=%s", str
);
374 vp
+= sprintf(vp
, "cctl=0x%x", cis
[i
+ 3]);
381 vp
+= sprintf(vp
, "cckpo=0x%x",
382 (cis
[i
+ 2] << 8) | cis
[i
+ 1]);
388 vp
+= sprintf(vp
, "ofdmpo=0x%x",
400 } while (tup
!= 0xff);
403 /* Set the srom version */
404 vp
+= sprintf(vp
, "sromrev=%d", sromrev
);
407 /* if there is no antenna gain field, set default */
408 if (ag_init
== FALSE
) {
409 ASSERT(sromrev
== 1);
410 vp
+= sprintf(vp
, "ag0=%d", 0xff);
414 /* final nullbyte terminator */
416 varsize
= (uint
)(vp
- base
);
418 ASSERT((vp
- base
) < VARS_MAX
);
420 if (varsize
== VARS_MAX
) {
423 vp
= MALLOC(osh
, varsize
);
426 bcopy(base
, vp
, varsize
);
427 MFREE(osh
, base
, VARS_MAX
);
440 /* set PCMCIA sprom command register */
442 sprom_cmd_pcmcia(osl_t
*osh
, uint8 cmd
)
445 uint wait_cnt
= 1000;
447 /* write sprom command register */
448 OSL_PCMCIA_WRITE_ATTR(osh
, SROM_CS
, &cmd
, 1);
452 OSL_PCMCIA_READ_ATTR(osh
, SROM_CS
, &status
, 1);
453 if (status
& SROM_DONE
)
460 /* read a word from the PCMCIA srom */
462 sprom_read_pcmcia(osl_t
*osh
, uint16 addr
, uint16
*data
)
464 uint8 addr_l
, addr_h
, data_l
, data_h
;
466 addr_l
= (uint8
)((addr
* 2) & 0xff);
467 addr_h
= (uint8
)(((addr
* 2) >> 8) & 0xff);
470 OSL_PCMCIA_WRITE_ATTR(osh
, SROM_ADDRH
, &addr_h
, 1);
471 OSL_PCMCIA_WRITE_ATTR(osh
, SROM_ADDRL
, &addr_l
, 1);
474 if (sprom_cmd_pcmcia(osh
, SROM_READ
))
479 OSL_PCMCIA_READ_ATTR(osh
, SROM_DATAH
, &data_h
, 1);
480 OSL_PCMCIA_READ_ATTR(osh
, SROM_DATAL
, &data_l
, 1);
482 *data
= (data_h
<< 8) | data_l
;
486 /* write a word to the PCMCIA srom */
488 sprom_write_pcmcia(osl_t
*osh
, uint16 addr
, uint16 data
)
490 uint8 addr_l
, addr_h
, data_l
, data_h
;
492 addr_l
= (uint8
)((addr
* 2) & 0xff);
493 addr_h
= (uint8
)(((addr
* 2) >> 8) & 0xff);
494 data_l
= (uint8
)(data
& 0xff);
495 data_h
= (uint8
)((data
>> 8) & 0xff);
498 OSL_PCMCIA_WRITE_ATTR(osh
, SROM_ADDRH
, &addr_h
, 1);
499 OSL_PCMCIA_WRITE_ATTR(osh
, SROM_ADDRL
, &addr_l
, 1);
502 OSL_PCMCIA_WRITE_ATTR(osh
, SROM_DATAH
, &data_h
, 1);
503 OSL_PCMCIA_WRITE_ATTR(osh
, SROM_DATAL
, &data_l
, 1);
506 return sprom_cmd_pcmcia(osh
, SROM_WRITE
);
510 * Read in and validate sprom.
511 * Return 0 on success, nonzero on error.
514 sprom_read_pci(osl_t
*osh
, uint16
*sprom
, uint wordoff
, uint16
*buf
, uint nwords
, bool check_crc
)
520 for (i
= 0; i
< nwords
; i
++)
521 buf
[i
] = R_REG(osh
, &sprom
[wordoff
+ i
]);
524 /* fixup the endianness so crc8 will pass */
525 htol16_buf(buf
, nwords
* 2);
526 if (hndcrc8((uint8
*)buf
, nwords
* 2, CRC8_INIT_VALUE
) != CRC8_GOOD_VALUE
)
528 /* now correct the endianness of the byte array */
529 ltoh16_buf(buf
, nwords
* 2);
536 * Create variable table from memory.
537 * Return 0 on success, nonzero on error.
540 initvars_table(osl_t
*osh
, char *start
, char *end
, char **vars
, uint
*count
)
542 int c
= (int)(end
- start
);
544 /* do it only when there is more than just the null string */
546 char *vp
= MALLOC(osh
, c
);
563 * Find variables with <devpath> from flash. 'base' points to the beginning
564 * of the table upon enter and to the end of the table upon exit when success.
565 * Return 0 on success, nonzero on error.
568 initvars_flash(osl_t
*osh
, char **base
, uint len
, char *devpath
)
574 uint l
, dl
, copy_len
;
576 /* allocate memory and read in flash */
577 if (!(flash
= MALLOC(osh
, NVRAM_SPACE
)))
579 if ((err
= nvram_getall(flash
, NVRAM_SPACE
)))
582 /* grab vars with the <devpath> prefix in name */
583 dl
= strlen(devpath
);
584 for (s
= flash
; s
&& *s
; s
+= l
+ 1) {
587 /* skip non-matching variable */
588 if (strncmp(s
, devpath
, dl
))
591 /* is there enough room to copy? */
592 copy_len
= l
- dl
+ 1;
593 if (len
< copy_len
) {
594 err
= BCME_BUFTOOSHORT
;
598 /* no prefix, just the name=value */
604 /* add null string as terminator */
606 err
= BCME_BUFTOOSHORT
;
613 exit
: MFREE(osh
, flash
, NVRAM_SPACE
);
618 * Initialize nonvolatile variable table from flash.
619 * Return 0 on success, nonzero on error.
622 initvars_flash_sb(void *sbh
, char **vars
, uint
*count
)
624 osl_t
*osh
= sb_osh(sbh
);
625 char devpath
[SB_DEVPATH_BUFSZ
];
632 if ((err
= sb_devpath(sbh
, devpath
, sizeof(devpath
))))
635 base
= vp
= MALLOC(osh
, VARS_MAX
);
640 if ((err
= initvars_flash(osh
, &vp
, VARS_MAX
, devpath
)))
643 err
= initvars_table(osh
, base
, vp
, vars
, count
);
645 err
: MFREE(osh
, base
, VARS_MAX
);
650 char mfgsromvars
[256];
651 char *defaultsromvars
= "il0macaddr=00:11:22:33:44:51\0"
652 "et0macaddr=00:11:22:33:44:52\0"
653 "et1macaddr=00:11:22:33:44:53\0"
659 #define MFGSROM_DEFVARSLEN 147 /* default srom len */
663 * Initialize nonvolatile variable table from sprom.
664 * Return 0 on success, nonzero on error.
667 initvars_srom_pci(void *sbh
, void *curmap
, char **vars
, uint
*count
)
671 struct ether_addr ea
;
676 osl_t
*osh
= sb_osh(sbh
);
678 char name
[SB_DEVPATH_BUFSZ
+16], *value
;
679 char devpath
[SB_DEVPATH_BUFSZ
];
683 * Apply CRC over SROM content regardless SROM is present or not,
684 * and use variable <devpath>sromrev's existance in flash to decide
685 * if we should return an error when CRC fails or read SROM variables
688 b
= MALLOC(osh
, SROM_MAX
);
693 err
= sprom_read_pci(osh
, (void*)((int8
*)curmap
+ PCI_BAR0_SPROM_OFFSET
), 0, b
,
695 if (b
[SROM4_SIGN
] == SROM4_SIGNATURE
) {
696 /* sromrev >= 4, read more */
697 err
= sprom_read_pci(osh
, (void*)((int8
*)curmap
+ PCI_BAR0_SPROM_OFFSET
), 0, b
, SROM4_WORDS
, TRUE
);
698 sromrev
= b
[SROM4_WORDS
- 1] & 0xff;
699 } else if (err
== 0) {
700 /* srom is good and is rev < 4 */
701 /* top word of sprom contains version and crc8 */
702 sromrev
= b
[63] & 0xff;
703 /* bcm4401 sroms misprogrammed */
710 BS_ERROR(("SROM Crc Error, so see if we could use a default\n"));
711 w32
= OSL_PCI_READ_CONFIG(osh
, PCI_SPROM_CONTROL
, sizeof(uint32
));
712 if (w32
& SPROM_OTPIN_USE
) {
713 BS_ERROR(("srom crc failed with OTP, use default vars....\n"));
714 vp
= base
= mfgsromvars
;
715 if (sb_chip(sbh
) == BCM4311_CHIP_ID
) {
716 BS_ERROR(("setting the devid to be 4311\n"));
717 vp
+= sprintf(vp
, "devid=0x4311");
720 bcopy(defaultsromvars
, vp
, MFGSROM_DEFVARSLEN
);
721 vp
+= MFGSROM_DEFVARSLEN
;
724 BS_ERROR(("srom crc failed with SPROM....\n"));
726 if ((err
= sb_devpath(sbh
, devpath
, sizeof(devpath
))))
728 sprintf(name
, "%ssromrev", devpath
);
729 if (!(value
= getvar(NULL
, name
)))
731 sromrev
= (uint8
)bcm_strtoul(value
, NULL
, 0);
738 /* srom version check */
745 base
= vp
= MALLOC(osh
, VARS_MAX
);
750 /* read variables from flash */
752 if ((err
= initvars_flash(osh
, &vp
, VARS_MAX
, devpath
)))
757 vp
+= sprintf(vp
, "sromrev=%d", sromrev
);
762 const uint pathbases
[MAX_PATH
] = {SROM4_PATH0
, SROM4_PATH1
,
763 SROM4_PATH2
, SROM4_PATH3
};
765 vp
+= sprintf(vp
, "boardrev=%d", b
[SROM4_BREV
]);
768 vp
+= sprintf(vp
, "boardflags=%d", (b
[SROM4_BFL1
] << 16) | b
[SROM4_BFL0
]);
771 vp
+= sprintf(vp
, "boardflags2=%d", (b
[SROM4_BFL3
] << 16) | b
[SROM4_BFL2
]);
775 ea
.octet
[0] = (b
[SROM4_MACHI
] >> 8) & 0xff;
776 ea
.octet
[1] = b
[SROM4_MACHI
] & 0xff;
777 ea
.octet
[2] = (b
[SROM4_MACMID
] >> 8) & 0xff;
778 ea
.octet
[3] = b
[SROM4_MACMID
] & 0xff;
779 ea
.octet
[4] = (b
[SROM4_MACLO
] >> 8) & 0xff;
780 ea
.octet
[5] = b
[SROM4_MACLO
] & 0xff;
781 bcm_ether_ntoa(&ea
, eabuf
);
782 vp
+= sprintf(vp
, "macaddr=%s", eabuf
);
787 vp
+= sprintf(vp
, "ccode=");
789 vp
+= sprintf(vp
, "ccode=%c%c", (w
>> 8), (w
& 0xff));
791 vp
+= sprintf(vp
, "regrev=%d", b
[SROM4_REGREV
]);
794 w
= b
[SROM4_LEDBH10
];
795 if ((w
!= 0) && (w
!= 0xffff)) {
797 vp
+= sprintf(vp
, "ledbh0=%d", (w
& 0xff));
801 vp
+= sprintf(vp
, "ledbh1=%d", (w
>> 8) & 0xff);
804 w
= b
[SROM4_LEDBH32
];
805 if ((w
!= 0) && (w
!= 0xffff)) {
807 vp
+= sprintf(vp
, "ledbh2=%d", w
& 0xff);
811 vp
+= sprintf(vp
, "ledbh3=%d", (w
>> 8) & 0xff);
814 /* LED Powersave duty cycle (oncount >> 24) (offcount >> 8) */
817 w32
= ((uint32
)((unsigned char)(w
>> 8) & 0xff) << 24) | /* oncount */
818 ((uint32
)((unsigned char)(w
& 0xff)) << 8); /* offcount */
819 vp
+= sprintf(vp
, "leddc=%d", w32
);
824 vp
+= sprintf(vp
, "aa2g=%d", w
& SROM4_AA2G_MASK
);
826 vp
+= sprintf(vp
, "aa5g=%d", w
>> SROM4_AA5G_SHIFT
);
830 vp
+= sprintf(vp
, "ag0=%d", w
& 0xff);
832 vp
+= sprintf(vp
, "ag1=%d", (w
>> 8) & 0xff);
835 vp
+= sprintf(vp
, "ag2=%d", w
& 0xff);
837 vp
+= sprintf(vp
, "ag3=%d", (w
>> 8) & 0xff);
840 /* Fixed power indices when power control is disabled */
841 for (i
= 0; i
< 2; i
++) {
842 w
= b
[SROM4_TXPID2G
+ i
];
843 vp
+= sprintf(vp
, "txpid2ga%d=%d", 2 * i
, w
& 0xff);
845 vp
+= sprintf(vp
, "txpid2ga%d=%d", (2 * i
) + 1, (w
>> 8) & 0xff);
847 w
= b
[SROM4_TXPID5G
+ i
];
848 vp
+= sprintf(vp
, "txpid5ga%d=%d", 2 * i
, w
& 0xff);
850 vp
+= sprintf(vp
, "txpid5ga%d=%d", (2 * i
) + 1, (w
>> 8) & 0xff);
852 w
= b
[SROM4_TXPID5GL
+ i
];
853 vp
+= sprintf(vp
, "txpid5gla%d=%d", 2 * i
, w
& 0xff);
855 vp
+= sprintf(vp
, "txpid5gla%d=%d", (2 * i
) + 1, (w
>> 8) & 0xff);
857 w
= b
[SROM4_TXPID5GH
+ i
];
858 vp
+= sprintf(vp
, "txpid5gha%d=%d", 2 * i
, w
& 0xff);
860 vp
+= sprintf(vp
, "txpid5gha%d=%d", (2 * i
) + 1, (w
>> 8) & 0xff);
864 /* Per path variables */
865 for (path
= 0; path
< MAX_PATH
; path
++) {
866 pathbase
= pathbases
[path
];
867 w
= b
[pathbase
+ SROM4_2G_ITT_MAXP
];
868 vp
+= sprintf(vp
, "itt2ga%d=%d", path
, w
>> B2G_ITT_SHIFT
);
870 vp
+= sprintf(vp
, "maxp2ga%d=%d", path
, w
& B2G_MAXP_MASK
);
873 for (i
= 0; i
< 4; i
++) {
874 vp
+= sprintf(vp
, "pa2gw%da%d=%d", i
, path
,
875 b
[pathbase
+ SROM4_2G_PA
+ i
]);
879 w
= b
[pathbase
+ SROM4_5G_ITT_MAXP
];
880 vp
+= sprintf(vp
, "itt5ga%d=%d", path
, w
>> B5G_ITT_SHIFT
);
882 vp
+= sprintf(vp
, "maxp5ga%d=%d", path
, w
& B5G_MAXP_MASK
);
885 w
= b
[pathbase
+ SROM4_5GLH_MAXP
];
886 vp
+= sprintf(vp
, "maxp5lga%d=%d", path
, w
>> B5GL_MAXP_SHIFT
);
888 vp
+= sprintf(vp
, "maxp5gha%d=%d", path
, w
& B5GH_MAXP_MASK
);
891 for (i
= 0; i
< 4; i
++) {
892 vp
+= sprintf(vp
, "pa5gw%da%d=%d", i
, path
,
893 b
[pathbase
+ SROM4_5G_PA
+ i
]);
895 vp
+= sprintf(vp
, "pa5glw%da%d=%d", i
, path
,
896 b
[pathbase
+ SROM4_5GL_PA
+ i
]);
898 vp
+= sprintf(vp
, "pa5hgw%da%d=%d", i
, path
,
899 b
[pathbase
+ SROM4_5GH_PA
+ i
]);
904 vp
+= sprintf(vp
, "cck2gpo=%d", b
[SROM4_2G_CCKPO
]);
907 w32
= ((uint32
)b
[SROM4_2G_OFDMPO
+ 1] << 16) | b
[SROM4_2G_OFDMPO
];
908 vp
+= sprintf(vp
, "ofdm2gpo=%d", w32
);
911 w32
= ((uint32
)b
[SROM4_5G_OFDMPO
+ 1] << 16) | b
[SROM4_5G_OFDMPO
];
912 vp
+= sprintf(vp
, "ofdm5gpo=%d", w32
);
915 w32
= ((uint32
)b
[SROM4_5GL_OFDMPO
+ 1] << 16) | b
[SROM4_5GL_OFDMPO
];
916 vp
+= sprintf(vp
, "ofdm5glpo=%d", w32
);
919 w32
= ((uint32
)b
[SROM4_5GH_OFDMPO
+ 1] << 16) | b
[SROM4_5GH_OFDMPO
];
920 vp
+= sprintf(vp
, "ofdm5ghpo=%d", w32
);
923 for (i
= 0; i
< 8; i
++) {
924 vp
+= sprintf(vp
, "mcs2gpo%d=%d", i
, b
[SROM4_2G_MCSPO
]);
926 vp
+= sprintf(vp
, "mcs5gpo%d=%d", i
, b
[SROM4_5G_MCSPO
]);
928 vp
+= sprintf(vp
, "mcs5glpo%d=%d", i
, b
[SROM4_5GL_MCSPO
]);
930 vp
+= sprintf(vp
, "mcs5ghpo%d=%d", i
, b
[SROM4_5GH_MCSPO
]);
934 vp
+= sprintf(vp
, "ccdpo%d=%d", i
, b
[SROM4_CCDPO
]);
936 vp
+= sprintf(vp
, "stbcpo%d=%d", i
, b
[SROM4_STBCPO
]);
938 vp
+= sprintf(vp
, "bw40po%d=%d", i
, b
[SROM4_BW40PO
]);
940 vp
+= sprintf(vp
, "bwduppo%d=%d", i
, b
[SROM4_BWDUPPO
]);
946 /* New section takes over the 3th hardware function space */
948 /* Words 22+23 are 11a (mid) ofdm power offsets */
949 w32
= ((uint32
)b
[23] << 16) | b
[22];
950 vp
+= sprintf(vp
, "ofdmapo=%d", w32
);
953 /* Words 24+25 are 11a (low) ofdm power offsets */
954 w32
= ((uint32
)b
[25] << 16) | b
[24];
955 vp
+= sprintf(vp
, "ofdmalpo=%d", w32
);
958 /* Words 26+27 are 11a (high) ofdm power offsets */
959 w32
= ((uint32
)b
[27] << 16) | b
[26];
960 vp
+= sprintf(vp
, "ofdmahpo=%d", w32
);
963 /* LED Powersave duty cycle (oncount >> 24) (offcount >> 8) */
964 w32
= ((uint32
)((unsigned char)(b
[21] >> 8) & 0xff) << 24) | /* oncount */
965 ((uint32
)((unsigned char)(b
[21] & 0xff)) << 8); /* offcount */
966 vp
+= sprintf(vp
, "leddc=%d", w32
);
972 /* New section takes over the 4th hardware function space */
974 /* Word 29 is max power 11a high/low */
976 vp
+= sprintf(vp
, "pa1himaxpwr=%d", w
& 0xff);
978 vp
+= sprintf(vp
, "pa1lomaxpwr=%d", (w
>> 8) & 0xff);
981 /* Words 30-32 set the 11alow pa settings,
982 * 33-35 are the 11ahigh ones.
984 for (i
= 0; i
< 3; i
++) {
985 vp
+= sprintf(vp
, "pa1lob%d=%d", i
, b
[30 + i
]);
987 vp
+= sprintf(vp
, "pa1hib%d=%d", i
, b
[33 + i
]);
992 vp
+= sprintf(vp
, "ccode=");
994 vp
+= sprintf(vp
, "ccode=%c%c", (w
>> 8), (w
& 0xff));
999 /* parameter section of sprom starts at byte offset 72 */
1002 /* first 6 bytes are il0macaddr */
1003 ea
.octet
[0] = (b
[woff
] >> 8) & 0xff;
1004 ea
.octet
[1] = b
[woff
] & 0xff;
1005 ea
.octet
[2] = (b
[woff
+1] >> 8) & 0xff;
1006 ea
.octet
[3] = b
[woff
+1] & 0xff;
1007 ea
.octet
[4] = (b
[woff
+2] >> 8) & 0xff;
1008 ea
.octet
[5] = b
[woff
+2] & 0xff;
1010 bcm_ether_ntoa(&ea
, eabuf
);
1011 vp
+= sprintf(vp
, "il0macaddr=%s", eabuf
);
1014 /* next 6 bytes are et0macaddr */
1015 ea
.octet
[0] = (b
[woff
] >> 8) & 0xff;
1016 ea
.octet
[1] = b
[woff
] & 0xff;
1017 ea
.octet
[2] = (b
[woff
+1] >> 8) & 0xff;
1018 ea
.octet
[3] = b
[woff
+1] & 0xff;
1019 ea
.octet
[4] = (b
[woff
+2] >> 8) & 0xff;
1020 ea
.octet
[5] = b
[woff
+2] & 0xff;
1022 bcm_ether_ntoa(&ea
, eabuf
);
1023 vp
+= sprintf(vp
, "et0macaddr=%s", eabuf
);
1026 /* next 6 bytes are et1macaddr */
1027 ea
.octet
[0] = (b
[woff
] >> 8) & 0xff;
1028 ea
.octet
[1] = b
[woff
] & 0xff;
1029 ea
.octet
[2] = (b
[woff
+1] >> 8) & 0xff;
1030 ea
.octet
[3] = b
[woff
+1] & 0xff;
1031 ea
.octet
[4] = (b
[woff
+2] >> 8) & 0xff;
1032 ea
.octet
[5] = b
[woff
+2] & 0xff;
1034 bcm_ether_ntoa(&ea
, eabuf
);
1035 vp
+= sprintf(vp
, "et1macaddr=%s", eabuf
);
1039 * Enet phy settings one or two singles or a dual
1040 * Bits 4-0 : MII address for enet0 (0x1f for not there)
1041 * Bits 9-5 : MII address for enet1 (0x1f for not there)
1042 * Bit 14 : Mdio for enet0
1043 * Bit 15 : Mdio for enet1
1046 vp
+= sprintf(vp
, "et0phyaddr=%d", (w
& 0x1f));
1048 vp
+= sprintf(vp
, "et1phyaddr=%d", ((w
>> 5) & 0x1f));
1050 vp
+= sprintf(vp
, "et0mdcport=%d", ((w
>> 14) & 0x1));
1052 vp
+= sprintf(vp
, "et1mdcport=%d", ((w
>> 15) & 0x1));
1055 /* Word 46 has board rev, antennas 0/1 & Country code/control */
1057 vp
+= sprintf(vp
, "boardrev=%d", w
& 0xff);
1061 vp
+= sprintf(vp
, "cctl=%d", (w
>> 8) & 0xf);
1063 vp
+= sprintf(vp
, "cc=%d", (w
>> 8) & 0xf);
1066 vp
+= sprintf(vp
, "aa2g=%d", (w
>> 12) & 0x3);
1069 vp
+= sprintf(vp
, "aa5g=%d", (w
>> 14) & 0x3);
1072 /* Words 47-49 set the (wl) pa settings */
1075 for (i
= 0; i
< 3; i
++) {
1076 vp
+= sprintf(vp
, "pa0b%d=%d", i
, b
[woff
+i
]);
1078 vp
+= sprintf(vp
, "pa1b%d=%d", i
, b
[woff
+i
+6]);
1083 * Words 50-51 set the customer-configured wl led behavior.
1084 * 8 bits/gpio pin. High bit: activehi=0, activelo=1;
1085 * LED behavior values defined in wlioctl.h .
1088 if ((w
!= 0) && (w
!= 0xffff)) {
1090 vp
+= sprintf(vp
, "ledbh0=%d", (w
& 0xff));
1094 vp
+= sprintf(vp
, "ledbh1=%d", (w
>> 8) & 0xff);
1098 if ((w
!= 0) && (w
!= 0xffff)) {
1100 vp
+= sprintf(vp
, "ledbh2=%d", w
& 0xff);
1104 vp
+= sprintf(vp
, "ledbh3=%d", (w
>> 8) & 0xff);
1108 /* Word 52 is max power 0/1 */
1110 vp
+= sprintf(vp
, "pa0maxpwr=%d", w
& 0xff);
1112 vp
+= sprintf(vp
, "pa1maxpwr=%d", (w
>> 8) & 0xff);
1115 /* Word 56 is idle tssi target 0/1 */
1117 vp
+= sprintf(vp
, "pa0itssit=%d", w
& 0xff);
1119 vp
+= sprintf(vp
, "pa1itssit=%d", (w
>> 8) & 0xff);
1122 /* Word 57 is boardflags, if not programmed make it zero */
1123 w32
= (uint32
)b
[57];
1124 if (w32
== 0xffff) w32
= 0;
1126 /* Word 28 is the high bits of boardflags */
1127 w32
|= (uint32
)b
[28] << 16;
1129 vp
+= sprintf(vp
, "boardflags=%d", w32
);
1132 /* Word 58 is antenna gain 0/1 */
1134 vp
+= sprintf(vp
, "ag0=%d", w
& 0xff);
1137 vp
+= sprintf(vp
, "ag1=%d", (w
>> 8) & 0xff);
1141 /* set the oem string */
1142 vp
+= sprintf(vp
, "oem=%02x%02x%02x%02x%02x%02x%02x%02x",
1143 ((b
[59] >> 8) & 0xff), (b
[59] & 0xff),
1144 ((b
[60] >> 8) & 0xff), (b
[60] & 0xff),
1145 ((b
[61] >> 8) & 0xff), (b
[61] & 0xff),
1146 ((b
[62] >> 8) & 0xff), (b
[62] & 0xff));
1148 } else if (sromrev
== 2) {
1149 /* Word 60 OFDM tx power offset from CCK level */
1150 /* OFDM Power Offset - opo */
1151 vp
+= sprintf(vp
, "opo=%d", b
[60] & 0xff);
1154 /* Word 60: cck power offsets */
1155 vp
+= sprintf(vp
, "cckpo=%d", b
[60]);
1158 /* Words 61+62: 11g ofdm power offsets */
1159 w32
= ((uint32
)b
[62] << 16) | b
[61];
1160 vp
+= sprintf(vp
, "ofdmgpo=%d", w32
);
1164 /* final nullbyte terminator */
1167 ASSERT((vp
- base
) <= VARS_MAX
);
1170 err
= initvars_table(osh
, base
, vp
, vars
, count
);
1174 if (base
!= mfgsromvars
)
1176 MFREE(osh
, base
, VARS_MAX
);
1177 MFREE(osh
, b
, SROM_MAX
);
1182 * Read the cis and call parsecis to initialize the vars.
1183 * Return 0 on success, nonzero on error.
1186 initvars_cis_pcmcia(void *sbh
, osl_t
*osh
, char **vars
, uint
*count
)
1192 data_sz
= (sb_pcmciarev(sbh
) == 1) ? (SPROM_SIZE
* 2) : CIS_SIZE
;
1194 if ((cis
= MALLOC(osh
, data_sz
)) == NULL
)
1197 if (sb_pcmciarev(sbh
) == 1) {
1198 if (srom_read(PCMCIA_BUS
, (void *)NULL
, osh
, 0, data_sz
, (uint16
*)cis
)) {
1199 MFREE(osh
, cis
, data_sz
);
1202 /* fix up endianess for 16-bit data vs 8-bit parsing */
1203 ltoh16_buf((uint16
*)cis
, data_sz
);
1205 OSL_PCMCIA_READ_ATTR(osh
, 0, cis
, data_sz
);
1207 rc
= srom_parsecis(osh
, &cis
, 1, vars
, count
);
1209 MFREE(osh
, cis
, data_sz
);
This page took 0.125271 seconds and 5 git commands to generate.