Commit ea0922b0 authored by Michael Buesch's avatar Michael Buesch Committed by John W. Linville

[PATCH] bcm43xx: Move sprom lowlevel reading/writing to its own functions.

Signed-off-by: default avatarMichael Buesch <mbuesch@freenet.de>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 489423c8
...@@ -916,13 +916,84 @@ u8 bcm43xx_sprom_crc(const u16 *sprom) ...@@ -916,13 +916,84 @@ u8 bcm43xx_sprom_crc(const u16 *sprom)
return crc; return crc;
} }
int bcm43xx_sprom_read(struct bcm43xx_private *bcm, u16 *sprom)
static int bcm43xx_read_sprom(struct bcm43xx_private *bcm)
{ {
int i; 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 value;
u16 *sprom; u16 *sprom;
u8 crc, expected_crc;
#ifdef CONFIG_BCM947XX #ifdef CONFIG_BCM947XX
char *c; char *c;
#endif #endif
...@@ -930,7 +1001,7 @@ static int bcm43xx_read_sprom(struct bcm43xx_private *bcm) ...@@ -930,7 +1001,7 @@ static int bcm43xx_read_sprom(struct bcm43xx_private *bcm)
sprom = kzalloc(BCM43xx_SPROM_SIZE * sizeof(u16), sprom = kzalloc(BCM43xx_SPROM_SIZE * sizeof(u16),
GFP_KERNEL); GFP_KERNEL);
if (!sprom) { if (!sprom) {
printk(KERN_ERR PFX "read_sprom OOM\n"); printk(KERN_ERR PFX "sprom_extract OOM\n");
return -ENOMEM; return -ENOMEM;
} }
#ifdef CONFIG_BCM947XX #ifdef CONFIG_BCM947XX
...@@ -953,17 +1024,7 @@ static int bcm43xx_read_sprom(struct bcm43xx_private *bcm) ...@@ -953,17 +1024,7 @@ static int bcm43xx_read_sprom(struct bcm43xx_private *bcm)
sprom[BCM43xx_SPROM_BOARDREV] = atoi(nvram_get("boardrev")); sprom[BCM43xx_SPROM_BOARDREV] = atoi(nvram_get("boardrev"));
#else #else
for (i = 0; i < BCM43xx_SPROM_SIZE; i++) bcm43xx_sprom_read(bcm, sprom);
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);
}
#endif #endif
/* boardflags2 */ /* boardflags2 */
...@@ -3632,7 +3693,7 @@ static int bcm43xx_attach_board(struct bcm43xx_private *bcm) ...@@ -3632,7 +3693,7 @@ static int bcm43xx_attach_board(struct bcm43xx_private *bcm)
goto err_chipset_detach; goto err_chipset_detach;
} }
err = bcm43xx_read_sprom(bcm); err = bcm43xx_sprom_extract(bcm);
if (err) if (err)
goto err_chipset_detach; goto err_chipset_detach;
err = bcm43xx_leds_init(bcm); err = bcm43xx_leds_init(bcm);
......
...@@ -280,4 +280,7 @@ u8 bcm43xx_sprom_crc(const u16 *sprom); ...@@ -280,4 +280,7 @@ u8 bcm43xx_sprom_crc(const u16 *sprom);
void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason); 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_ */ #endif /* BCM43xx_MAIN_H_ */
...@@ -782,7 +782,6 @@ static int hex2sprom(u16 *sprom, const char *dump, unsigned int len) ...@@ -782,7 +782,6 @@ static int hex2sprom(u16 *sprom, const char *dump, unsigned int len)
char tmp[5] = { 0 }; char tmp[5] = { 0 };
int cnt = 0; int cnt = 0;
unsigned long parsed; unsigned long parsed;
u8 crc, expected_crc;
if (len < BCM43xx_SPROM_SIZE * sizeof(u16) * 2) if (len < BCM43xx_SPROM_SIZE * sizeof(u16) * 2)
return -EINVAL; return -EINVAL;
...@@ -793,13 +792,6 @@ static int hex2sprom(u16 *sprom, const char *dump, unsigned int len) ...@@ -793,13 +792,6 @@ static int hex2sprom(u16 *sprom, const char *dump, unsigned int len)
sprom[cnt++] = swab16((u16)parsed); 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; return 0;
} }
...@@ -809,7 +801,7 @@ static int bcm43xx_wx_sprom_read(struct net_device *net_dev, ...@@ -809,7 +801,7 @@ static int bcm43xx_wx_sprom_read(struct net_device *net_dev,
char *extra) char *extra)
{ {
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
int err = -EPERM, i; int err = -EPERM;
u16 *sprom; u16 *sprom;
unsigned long flags; unsigned long flags;
...@@ -828,13 +820,10 @@ static int bcm43xx_wx_sprom_read(struct net_device *net_dev, ...@@ -828,13 +820,10 @@ static int bcm43xx_wx_sprom_read(struct net_device *net_dev,
spin_unlock_irqrestore(&bcm->lock, flags); spin_unlock_irqrestore(&bcm->lock, flags);
goto out_kfree; goto out_kfree;
} }
for (i = 0; i < BCM43xx_SPROM_SIZE; i++) err = bcm43xx_sprom_read(bcm, sprom);
sprom[i] = bcm43xx_read16(bcm, BCM43xx_SPROM_BASE + (i * 2));
spin_unlock_irqrestore(&bcm->lock, flags); spin_unlock_irqrestore(&bcm->lock, flags);
if (!err)
data->data.length = sprom2hex(sprom, extra); data->data.length = sprom2hex(sprom, extra);
err = 0;
out_kfree: out_kfree:
kfree(sprom); kfree(sprom);
out: out:
...@@ -852,8 +841,6 @@ static int bcm43xx_wx_sprom_write(struct net_device *net_dev, ...@@ -852,8 +841,6 @@ static int bcm43xx_wx_sprom_write(struct net_device *net_dev,
unsigned long flags; unsigned long flags;
char *input; char *input;
unsigned int len; unsigned int len;
u32 spromctl;
int i;
if (!capable(CAP_SYS_RAWIO)) if (!capable(CAP_SYS_RAWIO))
goto out; goto out;
...@@ -878,50 +865,9 @@ static int bcm43xx_wx_sprom_write(struct net_device *net_dev, ...@@ -878,50 +865,9 @@ static int bcm43xx_wx_sprom_write(struct net_device *net_dev,
spin_lock_irqsave(&bcm->lock, flags); spin_lock_irqsave(&bcm->lock, flags);
err = -ENODEV; err = -ENODEV;
if (!bcm->initialized) { 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");
goto out_unlock; goto out_unlock;
} err = bcm43xx_sprom_write(bcm, sprom);
mdelay(500);
printk("100%% ]\n");
printk(KERN_INFO PFX "SPROM written.\n");
err = 0;
out_unlock: out_unlock:
spin_unlock_irqrestore(&bcm->lock, flags); spin_unlock_irqrestore(&bcm->lock, flags);
out_kfree: out_kfree:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment