aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211
diff options
context:
space:
mode:
authorArend van Spriel <arend@broadcom.com>2011-10-18 08:03:06 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-11-08 15:54:07 -0500
commit888153b3db3fb10a048768c0c262951e2bc19719 (patch)
tree8a026a6ff5b7970fc8c4977fb455de4094f9ded3 /drivers/net/wireless/brcm80211
parent32cb68bf57b726f4b9161cdc110ffe45134aab69 (diff)
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: Alwin Beukers <alwin@broadcom.com> Reviewed-by: Roland Vossen <rvossen@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/brcm80211')
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/srom.c69
1 files changed, 30 insertions, 39 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/srom.c b/drivers/net/wireless/brcm80211/brcmsmac/srom.c
index a884fe072dac..66aa0e772bb2 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/srom.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/srom.c
@@ -586,14 +586,13 @@ static const struct brcms_sromvar perpath_pci_sromvars[] = {
586 * shared between devices. */ 586 * shared between devices. */
587static u8 brcms_srom_crc8_table[CRC8_TABLE_SIZE]; 587static u8 brcms_srom_crc8_table[CRC8_TABLE_SIZE];
588 588
589static u16 __iomem * 589static u8 __iomem *
590srom_window_address(struct si_pub *sih, u8 __iomem *curmap) 590srom_window_address(struct si_pub *sih, u8 __iomem *curmap)
591{ 591{
592 if (sih->ccrev < 32) 592 if (sih->ccrev < 32)
593 return (u16 __iomem *)(curmap + PCI_BAR0_SPROM_OFFSET); 593 return curmap + PCI_BAR0_SPROM_OFFSET;
594 if (sih->cccaps & CC_CAP_SROM) 594 if (sih->cccaps & CC_CAP_SROM)
595 return (u16 __iomem *) 595 return curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP;
596 (curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP);
597 596
598 return NULL; 597 return NULL;
599} 598}
@@ -782,37 +781,34 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list)
782 * Return 0 on success, nonzero on error. 781 * Return 0 on success, nonzero on error.
783 */ 782 */
784static int 783static int
785sprom_read_pci(struct si_pub *sih, u16 __iomem *sprom, uint wordoff, 784sprom_read_pci(struct si_pub *sih, u8 __iomem *sprom, uint wordoff,
786 u16 *buf, uint nwords, bool check_crc) 785 u16 *buf, uint nwords, bool check_crc)
787{ 786{
788 int err = 0; 787 int err = 0;
789 uint i; 788 uint i;
789 u8 *bbuf = (u8 *)buf; /* byte buffer */
790 uint nbytes = nwords << 1;
790 791
791 /* read the sprom */ 792 /* read the sprom in bytes */
792 for (i = 0; i < nwords; i++) 793 for (i = 0; i < nbytes; i++)
793 buf[i] = R_REG(&sprom[wordoff + i]); 794 bbuf[i] = readb(sprom+i);
794 795
795 if (check_crc) { 796 if (buf[0] == 0xffff)
796 797 /*
797 if (buf[0] == 0xffff) 798 * The hardware thinks that an srom that starts with
798 /* 799 * 0xffff is blank, regardless of the rest of the
799 * The hardware thinks that an srom that starts with 800 * content, so declare it bad.
800 * 0xffff is blank, regardless of the rest of the 801 */
801 * content, so declare it bad. 802 return -ENODATA;
802 */
803 return -ENODATA;
804
805 /* fixup the endianness so crc8 will pass */
806 htol16_buf(buf, nwords * 2);
807 if (crc8(brcms_srom_crc8_table, (u8 *) buf, nwords * 2,
808 CRC8_INIT_VALUE) !=
809 CRC8_GOOD_VALUE(brcms_srom_crc8_table))
810 /* DBG only pci always read srom4 first, then srom8/9 */
811 err = -EIO;
812 803
804 if (check_crc &&
805 crc8(brcms_srom_crc8_table, bbuf, nbytes, CRC8_INIT_VALUE) !=
806 CRC8_GOOD_VALUE(brcms_srom_crc8_table))
807 err = -EIO;
808 else
813 /* now correct the endianness of the byte array */ 809 /* now correct the endianness of the byte array */
814 ltoh16_buf(buf, nwords * 2); 810 ltoh16_buf(buf, nbytes);
815 } 811
816 return err; 812 return err;
817} 813}
818 814
@@ -859,7 +855,7 @@ static int otp_read_pci(struct si_pub *sih, u16 *buf, uint bufsz)
859static int initvars_srom_pci(struct si_pub *sih, void __iomem *curmap) 855static int initvars_srom_pci(struct si_pub *sih, void __iomem *curmap)
860{ 856{
861 u16 *srom; 857 u16 *srom;
862 u16 __iomem *sromwindow; 858 u8 __iomem *sromwindow;
863 u8 sromrev = 0; 859 u8 sromrev = 0;
864 u32 sr; 860 u32 sr;
865 int err = 0; 861 int err = 0;
@@ -875,18 +871,13 @@ static int initvars_srom_pci(struct si_pub *sih, void __iomem *curmap)
875 871
876 crc8_populate_lsb(brcms_srom_crc8_table, SROM_CRC8_POLY); 872 crc8_populate_lsb(brcms_srom_crc8_table, SROM_CRC8_POLY);
877 if (ai_is_sprom_available(sih)) { 873 if (ai_is_sprom_available(sih)) {
878 err = sprom_read_pci(sih, sromwindow, 0, srom, SROM_WORDS, 874 err = sprom_read_pci(sih, sromwindow, 0, srom,
879 true); 875 SROM4_WORDS, true);
880 876
881 if ((sih->buscoretype == PCIE_CORE_ID && sih->buscorerev >= 6) 877 if (err == 0)
882 || (sih->buscoretype == PCI_CORE_ID && 878 /* srom read and passed crc */
883 sih->buscorerev >= 0xe)) { 879 /* top word of sprom contains version and crc8 */
884 err = sprom_read_pci(sih, sromwindow, 0, srom,
885 SROM4_WORDS, true);
886 sromrev = srom[SROM4_CRCREV] & 0xff; 880 sromrev = srom[SROM4_CRCREV] & 0xff;
887 } else {
888 err = -EIO;
889 }
890 } else { 881 } else {
891 /* Use OTP if SPROM not available */ 882 /* Use OTP if SPROM not available */
892 err = otp_read_pci(sih, srom, SROM_MAX); 883 err = otp_read_pci(sih, srom, SROM_MAX);