diff options
Diffstat (limited to 'drivers/net/dm9000.c')
-rw-r--r-- | drivers/net/dm9000.c | 54 |
1 files changed, 51 insertions, 3 deletions
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 851618338b2e..1d790a8e3a98 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c | |||
@@ -1048,6 +1048,50 @@ dm9000_rx(struct net_device *dev) | |||
1048 | } while (rxbyte == DM9000_PKT_RDY); | 1048 | } while (rxbyte == DM9000_PKT_RDY); |
1049 | } | 1049 | } |
1050 | 1050 | ||
1051 | static unsigned int | ||
1052 | dm9000_read_locked(board_info_t *db, int reg) | ||
1053 | { | ||
1054 | unsigned long flags; | ||
1055 | unsigned int ret; | ||
1056 | |||
1057 | spin_lock_irqsave(&db->lock, flags); | ||
1058 | ret = ior(db, reg); | ||
1059 | spin_unlock_irqrestore(&db->lock, flags); | ||
1060 | |||
1061 | return ret; | ||
1062 | } | ||
1063 | |||
1064 | static int dm9000_wait_eeprom(board_info_t *db) | ||
1065 | { | ||
1066 | unsigned int status; | ||
1067 | int timeout = 8; /* wait max 8msec */ | ||
1068 | |||
1069 | /* The DM9000 data sheets say we should be able to | ||
1070 | * poll the ERRE bit in EPCR to wait for the EEPROM | ||
1071 | * operation. From testing several chips, this bit | ||
1072 | * does not seem to work. | ||
1073 | * | ||
1074 | * We attempt to use the bit, but fall back to the | ||
1075 | * timeout (which is why we do not return an error | ||
1076 | * on expiry) to say that the EEPROM operation has | ||
1077 | * completed. | ||
1078 | */ | ||
1079 | |||
1080 | while (1) { | ||
1081 | status = dm9000_read_locked(db, DM9000_EPCR); | ||
1082 | |||
1083 | if ((status & EPCR_ERRE) == 0) | ||
1084 | break; | ||
1085 | |||
1086 | if (timeout-- < 0) { | ||
1087 | dev_dbg(db->dev, "timeout waiting EEPROM\n"); | ||
1088 | break; | ||
1089 | } | ||
1090 | } | ||
1091 | |||
1092 | return 0; | ||
1093 | } | ||
1094 | |||
1051 | /* | 1095 | /* |
1052 | * Read a word data from EEPROM | 1096 | * Read a word data from EEPROM |
1053 | */ | 1097 | */ |
@@ -1065,8 +1109,10 @@ dm9000_read_eeprom(board_info_t *db, int offset, u8 *to) | |||
1065 | 1109 | ||
1066 | spin_unlock_irqrestore(&db->lock, flags); | 1110 | spin_unlock_irqrestore(&db->lock, flags); |
1067 | 1111 | ||
1068 | mdelay(8); /* according to the datasheet 200us should be enough, | 1112 | dm9000_wait_eeprom(db); |
1069 | but it doesn't work */ | 1113 | |
1114 | /* delay for at-least 150uS */ | ||
1115 | msleep(1); | ||
1070 | 1116 | ||
1071 | spin_lock_irqsave(&db->lock, flags); | 1117 | spin_lock_irqsave(&db->lock, flags); |
1072 | 1118 | ||
@@ -1097,7 +1143,9 @@ dm9000_write_eeprom(board_info_t *db, int offset, u8 *data) | |||
1097 | iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW); | 1143 | iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW); |
1098 | spin_unlock_irqrestore(&db->lock, flags); | 1144 | spin_unlock_irqrestore(&db->lock, flags); |
1099 | 1145 | ||
1100 | mdelay(8); /* same shit */ | 1146 | dm9000_wait_eeprom(db); |
1147 | |||
1148 | mdelay(1); /* wait at least 150uS to clear */ | ||
1101 | 1149 | ||
1102 | spin_lock_irqsave(&db->lock, flags); | 1150 | spin_lock_irqsave(&db->lock, flags); |
1103 | iow(db, DM9000_EPCR, 0); | 1151 | iow(db, DM9000_EPCR, 0); |