Skip to content

Commit

Permalink
DM9000: Fix delays used by EEPROM read and write
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Ben Dooks authored and Jeff Garzik committed Feb 11, 2008
1 parent c991d16 commit 39c341a
Showing 1 changed file with 51 additions and 3 deletions.
54 changes: 51 additions & 3 deletions drivers/net/dm9000.c
Original file line number Diff line number Diff line change
Expand Up @@ -1048,6 +1048,50 @@ dm9000_rx(struct net_device *dev)
} 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
*/
Expand All @@ -1065,8 +1109,10 @@ dm9000_read_eeprom(board_info_t *db, int offset, u8 *to)

spin_unlock_irqrestore(&db->lock, flags);

mdelay(8); /* according to the datasheet 200us should be enough,
but it doesn't work */
dm9000_wait_eeprom(db);

/* delay for at-least 150uS */
msleep(1);

spin_lock_irqsave(&db->lock, flags);

Expand Down Expand Up @@ -1097,7 +1143,9 @@ dm9000_write_eeprom(board_info_t *db, int offset, u8 *data)
iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW);
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);
iow(db, DM9000_EPCR, 0);
Expand Down

0 comments on commit 39c341a

Please sign in to comment.