/* * Read in and validate sprom. * Return 0 on success, nonzero on error. */ static int sprom_read_pci(uint16 *sprom, uint byteoff, uint16 *buf, uint nbytes, bool check_crc) { int off, nw; uint8 chk8; int i; off = byteoff / 2; nw = ROUNDUP(nbytes, 2) / 2; /* read the sprom */ for (i = 0; i < nw; i++) buf[i] = R_REG(&sprom[off + i]); if (check_crc) { /* fixup the endianness so crc8 will pass */ htol16_buf(buf, nw * 2); if ((chk8 = crc8((uchar*)buf, nbytes, CRC8_INIT_VALUE)) != CRC8_GOOD_VALUE) return (1); /* now correct the endianness of the byte array */ ltoh16_buf(buf, nw * 2); } return (0); }
/* * Read in and validate sprom. * Return 0 on success, nonzero on error. */ static int sprom_read_pci(osl_t *osh, uint16 *sprom, uint wordoff, uint16 *buf, uint nwords, bool check_crc) { int err = 0; uint i; /* read the sprom */ for (i = 0; i < nwords; i++) buf[i] = R_REG(osh, &sprom[wordoff + i]); if (check_crc) { /* fixup the endianness so crc8 will pass */ htol16_buf(buf, nwords * 2); if (hndcrc8((uint8*)buf, nwords * 2, CRC8_INIT_VALUE) != CRC8_GOOD_VALUE) err = 1; /* now correct the endianness of the byte array */ ltoh16_buf(buf, nwords * 2); } return err; }
/* * Read in and validate sprom. * Return 0 on success, nonzero on error. */ static int sprom_read_pci(uint16 *sprom, uint wordoff, uint16 *buf, uint nwords, bool check_crc) { uint8 chk8; uint i; /* read the sprom */ for (i = 0; i < nwords; i++) buf[i] = R_REG(&sprom[wordoff + i]); if (check_crc) { /* fixup the endianness so crc8 will pass */ htol16_buf(buf, nwords * 2); if ((chk8 = hndcrc8((uchar*)buf, nwords * 2, CRC8_INIT_VALUE)) != CRC8_GOOD_VALUE) return (1); /* now correct the endianness of the byte array */ ltoh16_buf(buf, nwords * 2); } return (0); }
/* support only 16-bit word write into srom */ int srom_write(uint bus, void *curmap, void *osh, uint byteoff, uint nbytes, uint16 *buf) { uint16 *srom; uint i, off, nw, crc_range; uint16 image[SPROM_SIZE], *p; uint8 crc; volatile uint32 val32; /* check input - 16-bit access only */ if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2)) return 1; crc_range = ((bus == PCMCIA_BUS) ? SPROM_SIZE : SPROM_CRC_RANGE) * 2; /* if changes made inside crc cover range */ if (byteoff < crc_range) { nw = (((byteoff + nbytes) > crc_range) ? byteoff + nbytes : crc_range) / 2; /* read data including entire first 64 words from srom */ if (srom_read(bus, curmap, osh, 0, nw * 2, image)) return 1; /* make changes */ bcopy((void*)buf, (void*)&image[byteoff / 2], nbytes); /* calculate crc */ htol16_buf(image, crc_range); crc = ~crc8((uint8 *)image, crc_range - 1, CRC8_INIT_VALUE); ltoh16_buf(image, crc_range); image[(crc_range / 2) - 1] = (crc << 8) | (image[(crc_range / 2) - 1] & 0xff); p = image; off = 0; } else { p = buf; off = byteoff / 2; nw = nbytes / 2; } if (bus == PCI_BUS) { srom = (uint16*)((uint)curmap + PCI_BAR0_SPROM_OFFSET); /* enable writes to the SPROM */ val32 = OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32)); val32 |= SPROM_WRITEEN; OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32); bcm_mdelay(500); /* write srom */ for (i = 0; i < nw; i++) { W_REG(&srom[off + i], p[i]); bcm_mdelay(20); } /* disable writes to the SPROM */ OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32 & ~SPROM_WRITEEN); } else if (bus == PCMCIA_BUS) { /* enable writes to the SPROM */ if (sprom_cmd_pcmcia(osh, SROM_WEN)) return 1; bcm_mdelay(500); /* write srom */ for (i = 0; i < nw; i++) { sprom_write_pcmcia(osh, (uint16)(off + i), p[i]); bcm_mdelay(20); } /* disable writes to the SPROM */ if (sprom_cmd_pcmcia(osh, SROM_WDS)) return 1; } else { return 1; } bcm_mdelay(500); return 0; }
/* support only 16-bit word write into srom */ int srom_write(uint bustype, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf) { uint16 *srom; uint i, nw, crc_range; uint16 image[SPROM_SIZE]; uint8 crc; volatile uint32 val32; ASSERT(bustype == BUSTYPE(bustype)); /* check input - 16-bit access only */ if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2)) return 1; /* Are we writing the whole thing at once? */ if ((byteoff == 0) && ((nbytes == SPROM_SIZE) || (nbytes == (SPROM_CRC_RANGE * 2)) || (nbytes == (SROM4_WORDS * 2)))) { crc_range = nbytes; bcopy((void*)buf, (void*)image, nbytes); nw = nbytes / 2; } else { if ((BUSTYPE(bustype) == PCMCIA_BUS) || (BUSTYPE(bustype) == SDIO_BUS)) crc_range = SPROM_SIZE; else crc_range = SPROM_CRC_RANGE * 2; /* Tentative */ nw = crc_range / 2; /* read first 64 words from srom */ if (srom_read(bustype, curmap, osh, 0, crc_range, image)) return 1; if (image[SROM4_SIGN] == SROM4_SIGNATURE) { crc_range = SROM4_WORDS; nw = crc_range / 2; if (srom_read(bustype, curmap, osh, 0, crc_range, image)) return 1; } /* make changes */ bcopy((void*)buf, (void*)&image[byteoff / 2], nbytes); } /* calculate crc */ htol16_buf(image, crc_range); crc = ~hndcrc8((uint8 *)image, crc_range - 1, CRC8_INIT_VALUE); ltoh16_buf(image, crc_range); image[(crc_range / 2) - 1] = (crc << 8) | (image[(crc_range / 2) - 1] & 0xff); if (BUSTYPE(bustype) == PCI_BUS) { srom = (uint16*)((uchar*)curmap + PCI_BAR0_SPROM_OFFSET); /* enable writes to the SPROM */ val32 = OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32)); val32 |= SPROM_WRITEEN; OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32); bcm_mdelay(WRITE_ENABLE_DELAY); /* write srom */ for (i = 0; i < nw; i++) { W_REG(osh, &srom[i], image[i]); bcm_mdelay(WRITE_WORD_DELAY); } /* disable writes to the SPROM */ OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32 & ~SPROM_WRITEEN); } else if (BUSTYPE(bustype) == PCMCIA_BUS) { /* enable writes to the SPROM */ if (sprom_cmd_pcmcia(osh, SROM_WEN)) return 1; bcm_mdelay(WRITE_ENABLE_DELAY); /* write srom */ for (i = 0; i < nw; i++) { sprom_write_pcmcia(osh, (uint16)(i), image[i]); bcm_mdelay(WRITE_WORD_DELAY); } /* disable writes to the SPROM */ if (sprom_cmd_pcmcia(osh, SROM_WDS)) return 1; } else { return 1; } bcm_mdelay(WRITE_ENABLE_DELAY); return 0; }