aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMichael Buesch <mbuesch@freenet.de>2006-02-19 08:09:20 -0500
committerJohn W. Linville <linville@tuxdriver.com>2006-03-27 11:18:36 -0500
commitea0922b067a0863f9a4198740651fd47a22af7f1 (patch)
treeb8632f6842be02a10a3fe52d58aa89663e16c789 /drivers
parent489423c8d0ba2b4311530502f7b5a331da9a60f9 (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')
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.c93
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.h3
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_wx.c66
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 919int bcm43xx_sprom_read(struct bcm43xx_private *bcm, u16 *sprom)
920static 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
939int 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;
988err_ctlreg:
989 printk(KERN_ERR PFX "Could not access SPROM control register.\n");
990 return -ENODEV;
991}
992
993static 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
281void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason); 281void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason);
282 282
283int bcm43xx_sprom_read(struct bcm43xx_private *bcm, u16 *sprom);
284int 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;
838out_kfree: 827out_kfree:
839 kfree(sprom); 828 kfree(sprom);
840out: 829out:
@@ -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;
925out_unlock: 871out_unlock:
926 spin_unlock_irqrestore(&bcm->lock, flags); 872 spin_unlock_irqrestore(&bcm->lock, flags);
927out_kfree: 873out_kfree: