/* support only 16-bit word read from srom */ int srom_read(uint bus, void *curmap, void *osh, uint byteoff, uint nbytes, uint16 *buf) { void *srom; uint i, off, nw; /* check input - 16-bit access only */ if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2)) return 1; if (bus == PCI_BUS) { if (!curmap) return 1; srom = (void *)((uint)curmap + PCI_BAR0_SPROM_OFFSET); if (sprom_read_pci(srom, byteoff, buf, nbytes, FALSE)) return 1; } else if (bus == PCMCIA_BUS) { off = byteoff / 2; nw = nbytes / 2; for (i = 0; i < nw; i++) { if (sprom_read_pcmcia(osh, (uint16)(off + i), (uint16*)(buf + i))) return 1; } } else { return 1; } return 0; }
/* support only 16-bit word read from srom */ int srom_read(uint bustype, void *curmap, void *osh, uint byteoff, uint nbytes, uint16 *buf) { void *srom; uint i, off, nw; ASSERT(bustype == BUSTYPE(bustype)); /* check input - 16-bit access only */ if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2)) return 1; off = byteoff / 2; nw = nbytes / 2; if (BUSTYPE(bustype) == PCI_BUS) { if (!curmap) return 1; srom = (uchar*)curmap + PCI_BAR0_SPROM_OFFSET; if (sprom_read_pci(srom, off, buf, nw, FALSE)) return 1; } else if (BUSTYPE(bustype) == PCMCIA_BUS) { for (i = 0; i < nw; i++) { if (sprom_read_pcmcia(osh, (uint16)(off + i), (uint16*)(buf + i))) return 1; } } else { return 1; } return 0; }
static int initvars_srom_pci(void *curmap, char **vars, int *count) { uint16 w, b[64]; uint8 sromrev; struct ether_addr ea; char eabuf[32]; int c, woff, i; char *vp, *base; if (sprom_read_pci((void *)((uint)curmap + PCI_BAR0_SPROM_OFFSET), 0, b, sizeof (b), TRUE)) return (-1); /* top word of sprom contains version and crc8 */ sromrev = b[63] & 0xff; if ((sromrev != 1) && (sromrev != 2)) { return (-2); } ASSERT(vars); ASSERT(count); base = vp = MALLOC(VARS_MAX); ASSERT(vp); vp += sprintf(vp, "sromrev=%d", sromrev); vp++; if (sromrev >= 2) { /* New section takes over the 4th hardware function space */ /* Word 28 is boardflags2 */ vp += sprintf(vp, "boardflags2=%d", b[28]); vp++; /* Word 29 is max power 11a high/low */ w = b[29]; vp += sprintf(vp, "pa1himaxpwr=%d", w & 0xff); vp++; vp += sprintf(vp, "pa1lomaxpwr=%d", (w >> 8) & 0xff); vp++; /* Words 30-32 set the 11alow pa settings, * 33-35 are the 11ahigh ones. */ for (i = 0; i < 3; i++) { vp += sprintf(vp, "pa1lob%d=%d", i, b[30 + i]); vp++; vp += sprintf(vp, "pa1hib%d=%d", i, b[33 + i]); vp++; } w = b[59]; if (w == 0) vp += sprintf(vp, "ccode="); else vp += sprintf(vp, "ccode=%c%c", (w >> 8), (w & 0xff)); vp++; }
/* support only 16-bit word read from srom */ int srom_read(si_t *sih, uint bustype, void *curmap, uint byteoff, uint nbytes, u16 *buf, bool check_crc) { uint off, nw; #ifdef BCMSDIO uint i; #endif /* BCMSDIO */ ASSERT(bustype == bustype); /* check input - 16-bit access only */ if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > SROM_MAX) return 1; off = byteoff / 2; nw = nbytes / 2; if (bustype == PCI_BUS) { if (!curmap) return 1; if (si_is_sprom_available(sih)) { u16 *srom; srom = (u16 *) SROM_OFFSET(sih); if (srom == NULL) return 1; if (sprom_read_pci (sih, srom, off, buf, nw, check_crc)) return 1; } #if defined(BCMNVRAMR) else { if (otp_read_pci(sih, buf, SROM_MAX)) return 1; } #endif #ifdef BCMSDIO } else if (bustype == SDIO_BUS) { off = byteoff / 2; nw = nbytes / 2; for (i = 0; i < nw; i++) { if (sprom_read_sdio ((u16) (off + i), (u16 *) (buf + i))) return 1; } #endif /* BCMSDIO */ } else if (bustype == SI_BUS) { return 1; } else { return 1; } return 0; }
/* * Initialize nonvolatile variable table from sprom. * Return 0 on success, nonzero on error. */ static int initvars_srom_pci(void *sbh, void *curmap, char **vars, uint *count) { uint16 w, *b; uint8 sromrev = 0; struct ether_addr ea; char eabuf[32]; uint32 w32; int woff, i; char *vp, *base; osl_t *osh = sb_osh(sbh); bool flash = FALSE; char name[SB_DEVPATH_BUFSZ+16], *value; char devpath[SB_DEVPATH_BUFSZ]; int err; /* * Apply CRC over SROM content regardless SROM is present or not, * and use variable <devpath>sromrev's existance in flash to decide * if we should return an error when CRC fails or read SROM variables * from flash. */ b = MALLOC(osh, SROM_MAX); ASSERT(b); if (!b) return -2; err = sprom_read_pci(osh, (void*)((int8*)curmap + PCI_BAR0_SPROM_OFFSET), 0, b, 64, TRUE); if (b[SROM4_SIGN] == SROM4_SIGNATURE) { /* sromrev >= 4, read more */ err = sprom_read_pci(osh, (void*)((int8*)curmap + PCI_BAR0_SPROM_OFFSET), 0, b, SROM4_WORDS, TRUE); sromrev = b[SROM4_WORDS - 1] & 0xff; } else if (err == 0) { /* srom is good and is rev < 4 */ /* top word of sprom contains version and crc8 */ sromrev = b[63] & 0xff; /* bcm4401 sroms misprogrammed */ if (sromrev == 0x10) sromrev = 1; } if (err) { #ifdef WLTEST BS_ERROR(("SROM Crc Error, so see if we could use a default\n")); w32 = OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32)); if (w32 & SPROM_OTPIN_USE) { BS_ERROR(("srom crc failed with OTP, use default vars....\n")); vp = base = mfgsromvars; if (sb_chip(sbh) == BCM4311_CHIP_ID) { BS_ERROR(("setting the devid to be 4311\n")); vp += sprintf(vp, "devid=0x4311"); vp++; } bcopy(defaultsromvars, vp, MFGSROM_DEFVARSLEN); vp += MFGSROM_DEFVARSLEN; goto varsdone; } else { BS_ERROR(("srom crc failed with SPROM....\n")); #endif /* WLTEST */ if ((err = sb_devpath(sbh, devpath, sizeof(devpath)))) return err; sprintf(name, "%ssromrev", devpath); if (!(value = getvar(NULL, name))) return (-1); sromrev = (uint8)bcm_strtoul(value, NULL, 0); flash = TRUE; #ifdef WLTEST } #endif /* WLTEST */ } /* srom version check */ if (sromrev > 4) return (-2); ASSERT(vars); ASSERT(count); base = vp = MALLOC(osh, VARS_MAX); ASSERT(vp); if (!vp) return -2; /* read variables from flash */ if (flash) { if ((err = initvars_flash(osh, &vp, VARS_MAX, devpath))) goto err; goto varsdone; } vp += sprintf(vp, "sromrev=%d", sromrev); vp++; if (sromrev >= 4) { uint path, pathbase; const uint pathbases[MAX_PATH] = {SROM4_PATH0, SROM4_PATH1, SROM4_PATH2, SROM4_PATH3}; vp += sprintf(vp, "boardrev=%d", b[SROM4_BREV]); vp++; vp += sprintf(vp, "boardflags=%d", (b[SROM4_BFL1] << 16) | b[SROM4_BFL0]); vp++; vp += sprintf(vp, "boardflags2=%d", (b[SROM4_BFL3] << 16) | b[SROM4_BFL2]); vp++; /* The macaddr */ ea.octet[0] = (b[SROM4_MACHI] >> 8) & 0xff; ea.octet[1] = b[SROM4_MACHI] & 0xff; ea.octet[2] = (b[SROM4_MACMID] >> 8) & 0xff; ea.octet[3] = b[SROM4_MACMID] & 0xff; ea.octet[4] = (b[SROM4_MACLO] >> 8) & 0xff; ea.octet[5] = b[SROM4_MACLO] & 0xff; bcm_ether_ntoa(&ea, eabuf); vp += sprintf(vp, "macaddr=%s", eabuf); vp++; w = b[SROM4_CCODE]; if (w == 0) vp += sprintf(vp, "ccode="); else vp += sprintf(vp, "ccode=%c%c", (w >> 8), (w & 0xff)); vp++; vp += sprintf(vp, "regrev=%d", b[SROM4_REGREV]); vp++; w = b[SROM4_LEDBH10]; if ((w != 0) && (w != 0xffff)) { /* ledbh0 */ vp += sprintf(vp, "ledbh0=%d", (w & 0xff)); vp++; /* ledbh1 */ vp += sprintf(vp, "ledbh1=%d", (w >> 8) & 0xff); vp++; }