diff options
-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) return crc; } - -static int bcm43xx_read_sprom(struct bcm43xx_private *bcm) +int bcm43xx_sprom_read(struct bcm43xx_private *bcm, u16 *sprom) { int i; + u8 crc, expected_crc; + + for (i = 0; i < BCM43xx_SPROM_SIZE; i++) + sprom[i] = bcm43xx_read16(bcm, BCM43xx_SPROM_BASE + (i * 2)); + /* CRC-8 check. */ + crc = bcm43xx_sprom_crc(sprom); + expected_crc = (sprom[BCM43xx_SPROM_VERSION] & 0xFF00) >> 8; + if (crc != expected_crc) { + printk(KERN_WARNING PFX "WARNING: Invalid SPROM checksum " + "(0x%02X, expected: 0x%02X)\n", + crc, expected_crc); + return -EINVAL; + } + + return 0; +} + +int bcm43xx_sprom_write(struct bcm43xx_private *bcm, const u16 *sprom) +{ + int i, err; + u8 crc, expected_crc; + u32 spromctl; + + /* CRC-8 validation of the input data. */ + crc = bcm43xx_sprom_crc(sprom); + expected_crc = (sprom[BCM43xx_SPROM_VERSION] & 0xFF00) >> 8; + if (crc != expected_crc) { + printk(KERN_ERR PFX "SPROM input data: Invalid CRC\n"); + return -EINVAL; + } + + printk(KERN_INFO PFX "Writing SPROM. Do NOT turn off the power! Please stand by...\n"); + err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCICFG_SPROMCTL, &spromctl); + if (err) + goto err_ctlreg; + spromctl |= 0x10; /* SPROM WRITE enable. */ + bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl); + if (err) + goto err_ctlreg; + /* We must burn lots of CPU cycles here, but that does not + * really matter as one does not write the SPROM every other minute... + */ + printk(KERN_INFO PFX "[ 0%%"); + mdelay(500); + for (i = 0; i < BCM43xx_SPROM_SIZE; i++) { + if (i == 16) + printk("25%%"); + else if (i == 32) + printk("50%%"); + else if (i == 48) + printk("75%%"); + else if (i % 2) + printk("."); + bcm43xx_write16(bcm, BCM43xx_SPROM_BASE + (i * 2), sprom[i]); + mdelay(20); + } + spromctl &= ~0x10; /* SPROM WRITE enable. */ + bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl); + if (err) + goto err_ctlreg; + mdelay(500); + printk("100%% ]\n"); + printk(KERN_INFO PFX "SPROM written.\n"); + bcm43xx_controller_restart(bcm, "SPROM update"); + + return 0; +err_ctlreg: + printk(KERN_ERR PFX "Could not access SPROM control register.\n"); + return -ENODEV; +} + +static int bcm43xx_sprom_extract(struct bcm43xx_private *bcm) +{ u16 value; u16 *sprom; - u8 crc, expected_crc; #ifdef CONFIG_BCM947XX char *c; #endif @@ -930,7 +1001,7 @@ static int bcm43xx_read_sprom(struct bcm43xx_private *bcm) sprom = kzalloc(BCM43xx_SPROM_SIZE * sizeof(u16), GFP_KERNEL); if (!sprom) { - printk(KERN_ERR PFX "read_sprom OOM\n"); + printk(KERN_ERR PFX "sprom_extract OOM\n"); return -ENOMEM; } #ifdef CONFIG_BCM947XX @@ -953,17 +1024,7 @@ static int bcm43xx_read_sprom(struct bcm43xx_private *bcm) sprom[BCM43xx_SPROM_BOARDREV] = atoi(nvram_get("boardrev")); #else - for (i = 0; i < BCM43xx_SPROM_SIZE; i++) - sprom[i] = bcm43xx_read16(bcm, BCM43xx_SPROM_BASE + (i * 2)); - - /* CRC-8 check. */ - crc = bcm43xx_sprom_crc(sprom); - expected_crc = (sprom[BCM43xx_SPROM_VERSION] & 0xFF00) >> 8; - if (crc != expected_crc) { - printk(KERN_WARNING PFX "WARNING: Invalid SPROM checksum " - "(0x%02X, expected: 0x%02X)\n", - crc, expected_crc); - } + bcm43xx_sprom_read(bcm, sprom); #endif /* boardflags2 */ @@ -3632,7 +3693,7 @@ static int bcm43xx_attach_board(struct bcm43xx_private *bcm) goto err_chipset_detach; } - err = bcm43xx_read_sprom(bcm); + err = bcm43xx_sprom_extract(bcm); if (err) goto err_chipset_detach; 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); void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason); +int bcm43xx_sprom_read(struct bcm43xx_private *bcm, u16 *sprom); +int bcm43xx_sprom_write(struct bcm43xx_private *bcm, const u16 *sprom); + #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) char tmp[5] = { 0 }; int cnt = 0; unsigned long parsed; - u8 crc, expected_crc; if (len < BCM43xx_SPROM_SIZE * sizeof(u16) * 2) return -EINVAL; @@ -793,13 +792,6 @@ static int hex2sprom(u16 *sprom, const char *dump, unsigned int len) sprom[cnt++] = swab16((u16)parsed); } - crc = bcm43xx_sprom_crc(sprom); - expected_crc = (sprom[BCM43xx_SPROM_VERSION] & 0xFF00) >> 8; - if (crc != expected_crc) { - printk(KERN_ERR PFX "SPROM input data: Invalid CRC\n"); - return -EINVAL; - } - return 0; } @@ -809,7 +801,7 @@ static int bcm43xx_wx_sprom_read(struct net_device *net_dev, char *extra) { struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - int err = -EPERM, i; + int err = -EPERM; u16 *sprom; unsigned long flags; @@ -828,13 +820,10 @@ static int bcm43xx_wx_sprom_read(struct net_device *net_dev, spin_unlock_irqrestore(&bcm->lock, flags); goto out_kfree; } - for (i = 0; i < BCM43xx_SPROM_SIZE; i++) - sprom[i] = bcm43xx_read16(bcm, BCM43xx_SPROM_BASE + (i * 2)); + err = bcm43xx_sprom_read(bcm, sprom); spin_unlock_irqrestore(&bcm->lock, flags); - - data->data.length = sprom2hex(sprom, extra); - - err = 0; + if (!err) + data->data.length = sprom2hex(sprom, extra); out_kfree: kfree(sprom); out: @@ -852,8 +841,6 @@ static int bcm43xx_wx_sprom_write(struct net_device *net_dev, unsigned long flags; char *input; unsigned int len; - u32 spromctl; - int i; if (!capable(CAP_SYS_RAWIO)) goto out; @@ -878,50 +865,9 @@ static int bcm43xx_wx_sprom_write(struct net_device *net_dev, spin_lock_irqsave(&bcm->lock, flags); err = -ENODEV; - if (!bcm->initialized) { - spin_unlock_irqrestore(&bcm->lock, flags); - goto out_kfree; - } - - printk(KERN_INFO PFX "Writing SPROM. Do NOT turn off the power! Please stand by...\n"); - err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCICFG_SPROMCTL, &spromctl); - if (err) { - printk(KERN_ERR PFX "Could not access SPROM control register.\n"); - goto out_unlock; - } - spromctl |= 0x10; /* SPROM WRITE enable. */ - bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl); - if (err) { - printk(KERN_ERR PFX "Could not access SPROM control register.\n"); - goto out_unlock; - } - /* We must burn lots of CPU cycles here, but that does not - * really matter as one does not write the SPROM every other minute... - */ - printk(KERN_INFO PFX "[ 0%%"); - mdelay(500); - for (i = 0; i < BCM43xx_SPROM_SIZE; i++) { - if (i == 16) - printk("25%%"); - else if (i == 32) - printk("50%%"); - else if (i == 48) - printk("75%%"); - else if (i % 2) - printk("."); - bcm43xx_write16(bcm, BCM43xx_SPROM_BASE + (i * 2), sprom[i]); - mdelay(20); - } - spromctl &= ~0x10; /* SPROM WRITE enable. */ - bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl); - if (err) { - printk(KERN_ERR PFX "Could not access SPROM control register.\n"); + if (!bcm->initialized) goto out_unlock; - } - mdelay(500); - printk("100%% ]\n"); - printk(KERN_INFO PFX "SPROM written.\n"); - err = 0; + err = bcm43xx_sprom_write(bcm, sprom); out_unlock: spin_unlock_irqrestore(&bcm->lock, flags); out_kfree: |