DM9000: Fix delays used by EEPROM read and write
The code was using a delay of 8ms, when it should have been using the EEPROM status flag from the device to indicate the EEPROM transaction had finished. Signed-off-by: Ben Dooks <ben-linux@fluff.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
@@ -1048,6 +1048,50 @@ dm9000_rx(struct net_device *dev)
|
|||||||
} while (rxbyte == DM9000_PKT_RDY);
|
} while (rxbyte == DM9000_PKT_RDY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
dm9000_read_locked(board_info_t *db, int reg)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
unsigned int ret;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&db->lock, flags);
|
||||||
|
ret = ior(db, reg);
|
||||||
|
spin_unlock_irqrestore(&db->lock, flags);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dm9000_wait_eeprom(board_info_t *db)
|
||||||
|
{
|
||||||
|
unsigned int status;
|
||||||
|
int timeout = 8; /* wait max 8msec */
|
||||||
|
|
||||||
|
/* The DM9000 data sheets say we should be able to
|
||||||
|
* poll the ERRE bit in EPCR to wait for the EEPROM
|
||||||
|
* operation. From testing several chips, this bit
|
||||||
|
* does not seem to work.
|
||||||
|
*
|
||||||
|
* We attempt to use the bit, but fall back to the
|
||||||
|
* timeout (which is why we do not return an error
|
||||||
|
* on expiry) to say that the EEPROM operation has
|
||||||
|
* completed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
status = dm9000_read_locked(db, DM9000_EPCR);
|
||||||
|
|
||||||
|
if ((status & EPCR_ERRE) == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (timeout-- < 0) {
|
||||||
|
dev_dbg(db->dev, "timeout waiting EEPROM\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read a word data from EEPROM
|
* Read a word data from EEPROM
|
||||||
*/
|
*/
|
||||||
@@ -1065,8 +1109,10 @@ dm9000_read_eeprom(board_info_t *db, int offset, u8 *to)
|
|||||||
|
|
||||||
spin_unlock_irqrestore(&db->lock, flags);
|
spin_unlock_irqrestore(&db->lock, flags);
|
||||||
|
|
||||||
mdelay(8); /* according to the datasheet 200us should be enough,
|
dm9000_wait_eeprom(db);
|
||||||
but it doesn't work */
|
|
||||||
|
/* delay for at-least 150uS */
|
||||||
|
msleep(1);
|
||||||
|
|
||||||
spin_lock_irqsave(&db->lock, flags);
|
spin_lock_irqsave(&db->lock, flags);
|
||||||
|
|
||||||
@@ -1097,7 +1143,9 @@ dm9000_write_eeprom(board_info_t *db, int offset, u8 *data)
|
|||||||
iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW);
|
iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW);
|
||||||
spin_unlock_irqrestore(&db->lock, flags);
|
spin_unlock_irqrestore(&db->lock, flags);
|
||||||
|
|
||||||
mdelay(8); /* same shit */
|
dm9000_wait_eeprom(db);
|
||||||
|
|
||||||
|
mdelay(1); /* wait at least 150uS to clear */
|
||||||
|
|
||||||
spin_lock_irqsave(&db->lock, flags);
|
spin_lock_irqsave(&db->lock, flags);
|
||||||
iow(db, DM9000_EPCR, 0);
|
iow(db, DM9000_EPCR, 0);
|
||||||
|
Reference in New Issue
Block a user