diff options
author | Arend van Spriel <arend@broadcom.com> | 2011-10-18 08:03:06 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-11-08 15:54:07 -0500 |
commit | 888153b3db3fb10a048768c0c262951e2bc19719 (patch) | |
tree | 8a026a6ff5b7970fc8c4977fb455de4094f9ded3 /drivers/net/wireless/brcm80211 | |
parent | 32cb68bf57b726f4b9161cdc110ffe45134aab69 (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.c | 69 |
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. */ |
587 | static u8 brcms_srom_crc8_table[CRC8_TABLE_SIZE]; | 587 | static u8 brcms_srom_crc8_table[CRC8_TABLE_SIZE]; |
588 | 588 | ||
589 | static u16 __iomem * | 589 | static u8 __iomem * |
590 | srom_window_address(struct si_pub *sih, u8 __iomem *curmap) | 590 | srom_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 | */ |
784 | static int | 783 | static int |
785 | sprom_read_pci(struct si_pub *sih, u16 __iomem *sprom, uint wordoff, | 784 | sprom_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) | |||
859 | static int initvars_srom_pci(struct si_pub *sih, void __iomem *curmap) | 855 | static 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); |