|
@@ -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
|
|
|
*/
|
|
@@ -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);
|
|
|
|
|
@@ -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);
|