diff options
author | Michael Buesch <mbuesch@freenet.de> | 2006-02-19 08:09:20 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2006-03-27 11:18:36 -0500 |
commit | ea0922b067a0863f9a4198740651fd47a22af7f1 (patch) | |
tree | b8632f6842be02a10a3fe52d58aa89663e16c789 /drivers/net/wireless | |
parent | 489423c8d0ba2b4311530502f7b5a331da9a60f9 (diff) |
[PATCH] bcm43xx: Move sprom lowlevel reading/writing to its own functions.
Signed-off-by: Michael Buesch <mbuesch@freenet.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_main.c | 93 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_main.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_wx.c | 66 |
3 files changed, 86 insertions, 76 deletions
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index 3443bd3c23e4..bcbd009a5339 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c | |||
@@ -916,13 +916,84 @@ u8 bcm43xx_sprom_crc(const u16 *sprom) | |||
916 | return crc; | 916 | return crc; |
917 | } | 917 | } |
918 | 918 | ||
919 | 919 | int bcm43xx_sprom_read(struct bcm43xx_private *bcm, u16 *sprom) | |
920 | static int bcm43xx_read_sprom(struct bcm43xx_private *bcm) | ||
921 | { | 920 | { |
922 | int i; | 921 | int i; |
922 | u8 crc, expected_crc; | ||
923 | |||
924 | for (i = 0; i < BCM43xx_SPROM_SIZE; i++) | ||
925 | sprom[i] = bcm43xx_read16(bcm, BCM43xx_SPROM_BASE + (i * 2)); | ||
926 | /* CRC-8 check. */ | ||
927 | crc = bcm43xx_sprom_crc(sprom); | ||
928 | expected_crc = (sprom[BCM43xx_SPROM_VERSION] & 0xFF00) >> 8; | ||
929 | if (crc != expected_crc) { | ||
930 | printk(KERN_WARNING PFX "WARNING: Invalid SPROM checksum " | ||
931 | "(0x%02X, expected: 0x%02X)\n", | ||
932 | crc, expected_crc); | ||
933 | return -EINVAL; | ||
934 | } | ||
935 | |||
936 | return 0; | ||
937 | } | ||
938 | |||
939 | int bcm43xx_sprom_write(struct bcm43xx_private *bcm, const u16 *sprom) | ||
940 | { | ||
941 | int i, err; | ||
942 | u8 crc, expected_crc; | ||
943 | u32 spromctl; | ||
944 | |||
945 | /* CRC-8 validation of the input data. */ | ||
946 | crc = bcm43xx_sprom_crc(sprom); | ||
947 | expected_crc = (sprom[BCM43xx_SPROM_VERSION] & 0xFF00) >> 8; | ||
948 | if (crc != expected_crc) { | ||
949 | printk(KERN_ERR PFX "SPROM input data: Invalid CRC\n"); | ||
950 | return -EINVAL; | ||
951 | } | ||
952 | |||
953 | printk(KERN_INFO PFX "Writing SPROM. Do NOT turn off the power! Please stand by...\n"); | ||
954 | err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCICFG_SPROMCTL, &spromctl); | ||
955 | if (err) | ||
956 | goto err_ctlreg; | ||
957 | spromctl |= 0x10; /* SPROM WRITE enable. */ | ||
958 | bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl); | ||
959 | if (err) | ||
960 | goto err_ctlreg; | ||
961 | /* We must burn lots of CPU cycles here, but that does not | ||
962 | * really matter as one does not write the SPROM every other minute... | ||
963 | */ | ||
964 | printk(KERN_INFO PFX "[ 0%%"); | ||
965 | mdelay(500); | ||
966 | for (i = 0; i < BCM43xx_SPROM_SIZE; i++) { | ||
967 | if (i == 16) | ||
968 | printk("25%%"); | ||
969 | else if (i == 32) | ||
970 | printk("50%%"); | ||
971 | else if (i == 48) | ||
972 | printk("75%%"); | ||
973 | else if (i % 2) | ||
974 | printk("."); | ||
975 | bcm43xx_write16(bcm, BCM43xx_SPROM_BASE + (i * 2), sprom[i]); | ||
976 | mdelay(20); | ||
977 | } | ||
978 | spromctl &= ~0x10; /* SPROM WRITE enable. */ | ||
979 | bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl); | ||
980 | if (err) | ||
981 | goto err_ctlreg; | ||
982 | mdelay(500); | ||
983 | printk("100%% ]\n"); | ||
984 | printk(KERN_INFO PFX "SPROM written.\n"); | ||
985 | bcm43xx_controller_restart(bcm, "SPROM update"); | ||
986 | |||
987 | return 0; | ||
988 | err_ctlreg: | ||
989 | printk(KERN_ERR PFX "Could not access SPROM control register.\n"); | ||
990 | return -ENODEV; | ||
991 | } | ||
992 | |||
993 | static int bcm43xx_sprom_extract(struct bcm43xx_private *bcm) | ||
994 | { | ||
923 | u16 value; | 995 | u16 value; |
924 | u16 *sprom; | 996 | u16 *sprom; |
925 | u8 crc, expected_crc; | ||
926 | #ifdef CONFIG_BCM947XX | 997 | #ifdef CONFIG_BCM947XX |
927 | char *c; | 998 | char *c; |
928 | #endif | 999 | #endif |
@@ -930,7 +1001,7 @@ static int bcm43xx_read_sprom(struct bcm43xx_private *bcm) | |||
930 | sprom = kzalloc(BCM43xx_SPROM_SIZE * sizeof(u16), | 1001 | sprom = kzalloc(BCM43xx_SPROM_SIZE * sizeof(u16), |
931 | GFP_KERNEL); | 1002 | GFP_KERNEL); |
932 | if (!sprom) { | 1003 | if (!sprom) { |
933 | printk(KERN_ERR PFX "read_sprom OOM\n"); | 1004 | printk(KERN_ERR PFX "sprom_extract OOM\n"); |
934 | return -ENOMEM; | 1005 | return -ENOMEM; |
935 | } | 1006 | } |
936 | #ifdef CONFIG_BCM947XX | 1007 | #ifdef CONFIG_BCM947XX |
@@ -953,17 +1024,7 @@ static int bcm43xx_read_sprom(struct bcm43xx_private *bcm) | |||
953 | 1024 | ||
954 | sprom[BCM43xx_SPROM_BOARDREV] = atoi(nvram_get("boardrev")); | 1025 | sprom[BCM43xx_SPROM_BOARDREV] = atoi(nvram_get("boardrev")); |
955 | #else | 1026 | #else |
956 | for (i = 0; i < BCM43xx_SPROM_SIZE; i++) | 1027 | bcm43xx_sprom_read(bcm, sprom); |
957 | sprom[i] = bcm43xx_read16(bcm, BCM43xx_SPROM_BASE + (i * 2)); | ||
958 | |||
959 | /* CRC-8 check. */ | ||
960 | crc = bcm43xx_sprom_crc(sprom); | ||
961 | expected_crc = (sprom[BCM43xx_SPROM_VERSION] & 0xFF00) >> 8; | ||
962 | if (crc != expected_crc) { | ||
963 | printk(KERN_WARNING PFX "WARNING: Invalid SPROM checksum " | ||
964 | "(0x%02X, expected: 0x%02X)\n", | ||
965 | crc, expected_crc); | ||
966 | } | ||
967 | #endif | 1028 | #endif |
968 | 1029 | ||
969 | /* boardflags2 */ | 1030 | /* boardflags2 */ |
@@ -3632,7 +3693,7 @@ static int bcm43xx_attach_board(struct bcm43xx_private *bcm) | |||
3632 | goto err_chipset_detach; | 3693 | goto err_chipset_detach; |
3633 | } | 3694 | } |
3634 | 3695 | ||
3635 | err = bcm43xx_read_sprom(bcm); | 3696 | err = bcm43xx_sprom_extract(bcm); |
3636 | if (err) | 3697 | if (err) |
3637 | goto err_chipset_detach; | 3698 | goto err_chipset_detach; |
3638 | err = bcm43xx_leds_init(bcm); | 3699 | err = bcm43xx_leds_init(bcm); |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.h b/drivers/net/wireless/bcm43xx/bcm43xx_main.h index 298e24b4ab64..0c4bd08568c5 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.h | |||
@@ -280,4 +280,7 @@ u8 bcm43xx_sprom_crc(const u16 *sprom); | |||
280 | 280 | ||
281 | void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason); | 281 | void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason); |
282 | 282 | ||
283 | int bcm43xx_sprom_read(struct bcm43xx_private *bcm, u16 *sprom); | ||
284 | int bcm43xx_sprom_write(struct bcm43xx_private *bcm, const u16 *sprom); | ||
285 | |||
283 | #endif /* BCM43xx_MAIN_H_ */ | 286 | #endif /* BCM43xx_MAIN_H_ */ |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c index 4c972cdc0a24..df37d28996c9 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c | |||
@@ -782,7 +782,6 @@ static int hex2sprom(u16 *sprom, const char *dump, unsigned int len) | |||
782 | char tmp[5] = { 0 }; | 782 | char tmp[5] = { 0 }; |
783 | int cnt = 0; | 783 | int cnt = 0; |
784 | unsigned long parsed; | 784 | unsigned long parsed; |
785 | u8 crc, expected_crc; | ||
786 | 785 | ||
787 | if (len < BCM43xx_SPROM_SIZE * sizeof(u16) * 2) | 786 | if (len < BCM43xx_SPROM_SIZE * sizeof(u16) * 2) |
788 | return -EINVAL; | 787 | return -EINVAL; |
@@ -793,13 +792,6 @@ static int hex2sprom(u16 *sprom, const char *dump, unsigned int len) | |||
793 | sprom[cnt++] = swab16((u16)parsed); | 792 | sprom[cnt++] = swab16((u16)parsed); |
794 | } | 793 | } |
795 | 794 | ||
796 | crc = bcm43xx_sprom_crc(sprom); | ||
797 | expected_crc = (sprom[BCM43xx_SPROM_VERSION] & 0xFF00) >> 8; | ||
798 | if (crc != expected_crc) { | ||
799 | printk(KERN_ERR PFX "SPROM input data: Invalid CRC\n"); | ||
800 | return -EINVAL; | ||
801 | } | ||
802 | |||
803 | return 0; | 795 | return 0; |
804 | } | 796 | } |
805 | 797 | ||
@@ -809,7 +801,7 @@ static int bcm43xx_wx_sprom_read(struct net_device *net_dev, | |||
809 | char *extra) | 801 | char *extra) |
810 | { | 802 | { |
811 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); | 803 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); |
812 | int err = -EPERM, i; | 804 | int err = -EPERM; |
813 | u16 *sprom; | 805 | u16 *sprom; |
814 | unsigned long flags; | 806 | unsigned long flags; |
815 | 807 | ||
@@ -828,13 +820,10 @@ static int bcm43xx_wx_sprom_read(struct net_device *net_dev, | |||
828 | spin_unlock_irqrestore(&bcm->lock, flags); | 820 | spin_unlock_irqrestore(&bcm->lock, flags); |
829 | goto out_kfree; | 821 | goto out_kfree; |
830 | } | 822 | } |
831 | for (i = 0; i < BCM43xx_SPROM_SIZE; i++) | 823 | err = bcm43xx_sprom_read(bcm, sprom); |
832 | sprom[i] = bcm43xx_read16(bcm, BCM43xx_SPROM_BASE + (i * 2)); | ||
833 | spin_unlock_irqrestore(&bcm->lock, flags); | 824 | spin_unlock_irqrestore(&bcm->lock, flags); |
834 | 825 | if (!err) | |
835 | data->data.length = sprom2hex(sprom, extra); | 826 | data->data.length = sprom2hex(sprom, extra); |
836 | |||
837 | err = 0; | ||
838 | out_kfree: | 827 | out_kfree: |
839 | kfree(sprom); | 828 | kfree(sprom); |
840 | out: | 829 | out: |
@@ -852,8 +841,6 @@ static int bcm43xx_wx_sprom_write(struct net_device *net_dev, | |||
852 | unsigned long flags; | 841 | unsigned long flags; |
853 | char *input; | 842 | char *input; |
854 | unsigned int len; | 843 | unsigned int len; |
855 | u32 spromctl; | ||
856 | int i; | ||
857 | 844 | ||
858 | if (!capable(CAP_SYS_RAWIO)) | 845 | if (!capable(CAP_SYS_RAWIO)) |
859 | goto out; | 846 | goto out; |
@@ -878,50 +865,9 @@ static int bcm43xx_wx_sprom_write(struct net_device *net_dev, | |||
878 | 865 | ||
879 | spin_lock_irqsave(&bcm->lock, flags); | 866 | spin_lock_irqsave(&bcm->lock, flags); |
880 | err = -ENODEV; | 867 | err = -ENODEV; |
881 | if (!bcm->initialized) { | 868 | if (!bcm->initialized) |
882 | spin_unlock_irqrestore(&bcm->lock, flags); | ||
883 | goto out_kfree; | ||
884 | } | ||
885 | |||
886 | printk(KERN_INFO PFX "Writing SPROM. Do NOT turn off the power! Please stand by...\n"); | ||
887 | err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCICFG_SPROMCTL, &spromctl); | ||
888 | if (err) { | ||
889 | printk(KERN_ERR PFX "Could not access SPROM control register.\n"); | ||
890 | goto out_unlock; | ||
891 | } | ||
892 | spromctl |= 0x10; /* SPROM WRITE enable. */ | ||
893 | bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl); | ||
894 | if (err) { | ||
895 | printk(KERN_ERR PFX "Could not access SPROM control register.\n"); | ||
896 | goto out_unlock; | ||
897 | } | ||
898 | /* We must burn lots of CPU cycles here, but that does not | ||
899 | * really matter as one does not write the SPROM every other minute... | ||
900 | */ | ||
901 | printk(KERN_INFO PFX "[ 0%%"); | ||
902 | mdelay(500); | ||
903 | for (i = 0; i < BCM43xx_SPROM_SIZE; i++) { | ||
904 | if (i == 16) | ||
905 | printk("25%%"); | ||
906 | else if (i == 32) | ||
907 | printk("50%%"); | ||
908 | else if (i == 48) | ||
909 | printk("75%%"); | ||
910 | else if (i % 2) | ||
911 | printk("."); | ||
912 | bcm43xx_write16(bcm, BCM43xx_SPROM_BASE + (i * 2), sprom[i]); | ||
913 | mdelay(20); | ||
914 | } | ||
915 | spromctl &= ~0x10; /* SPROM WRITE enable. */ | ||
916 | bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl); | ||
917 | if (err) { | ||
918 | printk(KERN_ERR PFX "Could not access SPROM control register.\n"); | ||
919 | goto out_unlock; | 869 | goto out_unlock; |
920 | } | 870 | err = bcm43xx_sprom_write(bcm, sprom); |
921 | mdelay(500); | ||
922 | printk("100%% ]\n"); | ||
923 | printk(KERN_INFO PFX "SPROM written.\n"); | ||
924 | err = 0; | ||
925 | out_unlock: | 871 | out_unlock: |
926 | spin_unlock_irqrestore(&bcm->lock, flags); | 872 | spin_unlock_irqrestore(&bcm->lock, flags); |
927 | out_kfree: | 873 | out_kfree: |