Commit 888153b3 authored by Arend van Spriel's avatar Arend van Spriel Committed by John W. Linville

brcm80211: smac: avoid sprom endianess conversions for crc8 check

The data from the sprom consists of u16 values stored in little
endian notation over which a crc8 was determined. To validate this
the buffer needed to be converted for big-endian systems. Reading
the sprom data is now done per byte so conversion is only done
after a successful crc8 check.
Reviewed-by: default avatarAlwin Beukers <alwin@broadcom.com>
Reviewed-by: default avatarRoland Vossen <rvossen@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 32cb68bf
...@@ -586,14 +586,13 @@ static const struct brcms_sromvar perpath_pci_sromvars[] = { ...@@ -586,14 +586,13 @@ static const struct brcms_sromvar perpath_pci_sromvars[] = {
* shared between devices. */ * shared between devices. */
static u8 brcms_srom_crc8_table[CRC8_TABLE_SIZE]; static u8 brcms_srom_crc8_table[CRC8_TABLE_SIZE];
static u16 __iomem * static u8 __iomem *
srom_window_address(struct si_pub *sih, u8 __iomem *curmap) srom_window_address(struct si_pub *sih, u8 __iomem *curmap)
{ {
if (sih->ccrev < 32) if (sih->ccrev < 32)
return (u16 __iomem *)(curmap + PCI_BAR0_SPROM_OFFSET); return curmap + PCI_BAR0_SPROM_OFFSET;
if (sih->cccaps & CC_CAP_SROM) if (sih->cccaps & CC_CAP_SROM)
return (u16 __iomem *) return curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP;
(curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP);
return NULL; return NULL;
} }
...@@ -782,37 +781,34 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list) ...@@ -782,37 +781,34 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list)
* Return 0 on success, nonzero on error. * Return 0 on success, nonzero on error.
*/ */
static int static int
sprom_read_pci(struct si_pub *sih, u16 __iomem *sprom, uint wordoff, sprom_read_pci(struct si_pub *sih, u8 __iomem *sprom, uint wordoff,
u16 *buf, uint nwords, bool check_crc) u16 *buf, uint nwords, bool check_crc)
{ {
int err = 0; int err = 0;
uint i; uint i;
u8 *bbuf = (u8 *)buf; /* byte buffer */
uint nbytes = nwords << 1;
/* read the sprom */ /* read the sprom in bytes */
for (i = 0; i < nwords; i++) for (i = 0; i < nbytes; i++)
buf[i] = R_REG(&sprom[wordoff + i]); bbuf[i] = readb(sprom+i);
if (check_crc) { if (buf[0] == 0xffff)
/*
if (buf[0] == 0xffff) * The hardware thinks that an srom that starts with
/* * 0xffff is blank, regardless of the rest of the
* The hardware thinks that an srom that starts with * content, so declare it bad.
* 0xffff is blank, regardless of the rest of the */
* content, so declare it bad. return -ENODATA;
*/
return -ENODATA;
/* fixup the endianness so crc8 will pass */
htol16_buf(buf, nwords * 2);
if (crc8(brcms_srom_crc8_table, (u8 *) buf, nwords * 2,
CRC8_INIT_VALUE) !=
CRC8_GOOD_VALUE(brcms_srom_crc8_table))
/* DBG only pci always read srom4 first, then srom8/9 */
err = -EIO;
if (check_crc &&
crc8(brcms_srom_crc8_table, bbuf, nbytes, CRC8_INIT_VALUE) !=
CRC8_GOOD_VALUE(brcms_srom_crc8_table))
err = -EIO;
else
/* now correct the endianness of the byte array */ /* now correct the endianness of the byte array */
ltoh16_buf(buf, nwords * 2); ltoh16_buf(buf, nbytes);
}
return err; return err;
} }
...@@ -859,7 +855,7 @@ static int otp_read_pci(struct si_pub *sih, u16 *buf, uint bufsz) ...@@ -859,7 +855,7 @@ static int otp_read_pci(struct si_pub *sih, u16 *buf, uint bufsz)
static int initvars_srom_pci(struct si_pub *sih, void __iomem *curmap) static int initvars_srom_pci(struct si_pub *sih, void __iomem *curmap)
{ {
u16 *srom; u16 *srom;
u16 __iomem *sromwindow; u8 __iomem *sromwindow;
u8 sromrev = 0; u8 sromrev = 0;
u32 sr; u32 sr;
int err = 0; int err = 0;
...@@ -875,18 +871,13 @@ static int initvars_srom_pci(struct si_pub *sih, void __iomem *curmap) ...@@ -875,18 +871,13 @@ static int initvars_srom_pci(struct si_pub *sih, void __iomem *curmap)
crc8_populate_lsb(brcms_srom_crc8_table, SROM_CRC8_POLY); crc8_populate_lsb(brcms_srom_crc8_table, SROM_CRC8_POLY);
if (ai_is_sprom_available(sih)) { if (ai_is_sprom_available(sih)) {
err = sprom_read_pci(sih, sromwindow, 0, srom, SROM_WORDS, err = sprom_read_pci(sih, sromwindow, 0, srom,
true); SROM4_WORDS, true);
if ((sih->buscoretype == PCIE_CORE_ID && sih->buscorerev >= 6) if (err == 0)
|| (sih->buscoretype == PCI_CORE_ID && /* srom read and passed crc */
sih->buscorerev >= 0xe)) { /* top word of sprom contains version and crc8 */
err = sprom_read_pci(sih, sromwindow, 0, srom,
SROM4_WORDS, true);
sromrev = srom[SROM4_CRCREV] & 0xff; sromrev = srom[SROM4_CRCREV] & 0xff;
} else {
err = -EIO;
}
} else { } else {
/* Use OTP if SPROM not available */ /* Use OTP if SPROM not available */
err = otp_read_pci(sih, srom, SROM_MAX); err = otp_read_pci(sih, srom, SROM_MAX);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment