diff options
author | Ben Dooks <ben-linux@fluff.org> | 2008-02-04 19:02:11 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2008-02-11 11:06:29 -0500 |
commit | 29d52e545f6f077d8c29fa35d1c52d95e4a2185a (patch) | |
tree | 6616b6142343855a0b9bcd6a934a32bddd252df4 /drivers | |
parent | 9a2f037cdbe8409c5ff92e8dce5fcdfe2ebb2084 (diff) |
DM9000: Add ethtool support for reading and writing EEPROM
Add ethtool support to access the configuration EEPROM
connected to the DM9000.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/dm9000.c | 66 |
1 files changed, 60 insertions, 6 deletions
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index a769c89a3690..082372515432 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c | |||
@@ -186,7 +186,8 @@ static int dm9000_phy_read(struct net_device *dev, int phyaddr_unsused, int reg) | |||
186 | static void dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, | 186 | static void dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, |
187 | int value); | 187 | int value); |
188 | 188 | ||
189 | static void dm9000_read_eeprom(board_info_t *, int addr, unsigned char *to); | 189 | static void dm9000_read_eeprom(board_info_t *, int addr, u8 *to); |
190 | static void dm9000_write_eeprom(board_info_t *, int addr, u8 *dp); | ||
190 | static void dm9000_rx(struct net_device *); | 191 | static void dm9000_rx(struct net_device *); |
191 | static void dm9000_hash_table(struct net_device *); | 192 | static void dm9000_hash_table(struct net_device *); |
192 | 193 | ||
@@ -409,12 +410,65 @@ static u32 dm9000_get_link(struct net_device *dev) | |||
409 | return mii_link_ok(&dm->mii); | 410 | return mii_link_ok(&dm->mii); |
410 | } | 411 | } |
411 | 412 | ||
413 | #define DM_EEPROM_MAGIC (0x444D394B) | ||
414 | |||
415 | static int dm9000_get_eeprom_len(struct net_device *dev) | ||
416 | { | ||
417 | return 128; | ||
418 | } | ||
419 | |||
420 | static int dm9000_get_eeprom(struct net_device *dev, | ||
421 | struct ethtool_eeprom *ee, u8 *data) | ||
422 | { | ||
423 | board_info_t *dm = to_dm9000_board(dev); | ||
424 | int offset = ee->offset; | ||
425 | int len = ee->len; | ||
426 | int i; | ||
427 | |||
428 | /* EEPROM access is aligned to two bytes */ | ||
429 | |||
430 | if ((len & 1) != 0 || (offset & 1) != 0) | ||
431 | return -EINVAL; | ||
432 | |||
433 | ee->magic = DM_EEPROM_MAGIC; | ||
434 | |||
435 | for (i = 0; i < len; i += 2) | ||
436 | dm9000_read_eeprom(dm, (offset + i) / 2, data + i); | ||
437 | |||
438 | return 0; | ||
439 | } | ||
440 | |||
441 | static int dm9000_set_eeprom(struct net_device *dev, | ||
442 | struct ethtool_eeprom *ee, u8 *data) | ||
443 | { | ||
444 | board_info_t *dm = to_dm9000_board(dev); | ||
445 | int offset = ee->offset; | ||
446 | int len = ee->len; | ||
447 | int i; | ||
448 | |||
449 | /* EEPROM access is aligned to two bytes */ | ||
450 | |||
451 | if ((len & 1) != 0 || (offset & 1) != 0) | ||
452 | return -EINVAL; | ||
453 | |||
454 | if (ee->magic != DM_EEPROM_MAGIC) | ||
455 | return -EINVAL; | ||
456 | |||
457 | for (i = 0; i < len; i += 2) | ||
458 | dm9000_write_eeprom(dm, (offset + i) / 2, data + i); | ||
459 | |||
460 | return 0; | ||
461 | } | ||
462 | |||
412 | static const struct ethtool_ops dm9000_ethtool_ops = { | 463 | static const struct ethtool_ops dm9000_ethtool_ops = { |
413 | .get_drvinfo = dm9000_get_drvinfo, | 464 | .get_drvinfo = dm9000_get_drvinfo, |
414 | .get_settings = dm9000_get_settings, | 465 | .get_settings = dm9000_get_settings, |
415 | .set_settings = dm9000_set_settings, | 466 | .set_settings = dm9000_set_settings, |
416 | .nway_reset = dm9000_nway_reset, | 467 | .nway_reset = dm9000_nway_reset, |
417 | .get_link = dm9000_get_link, | 468 | .get_link = dm9000_get_link, |
469 | .get_eeprom_len = dm9000_get_eeprom_len, | ||
470 | .get_eeprom = dm9000_get_eeprom, | ||
471 | .set_eeprom = dm9000_set_eeprom, | ||
418 | }; | 472 | }; |
419 | 473 | ||
420 | 474 | ||
@@ -1008,7 +1062,7 @@ dm9000_rx(struct net_device *dev) | |||
1008 | * Read a word data from EEPROM | 1062 | * Read a word data from EEPROM |
1009 | */ | 1063 | */ |
1010 | static void | 1064 | static void |
1011 | dm9000_read_eeprom(board_info_t *db, int offset, unsigned char *to) | 1065 | dm9000_read_eeprom(board_info_t *db, int offset, u8 *to) |
1012 | { | 1066 | { |
1013 | mutex_lock(&db->addr_lock); | 1067 | mutex_lock(&db->addr_lock); |
1014 | 1068 | ||
@@ -1024,18 +1078,17 @@ dm9000_read_eeprom(board_info_t *db, int offset, unsigned char *to) | |||
1024 | mutex_unlock(&db->addr_lock); | 1078 | mutex_unlock(&db->addr_lock); |
1025 | } | 1079 | } |
1026 | 1080 | ||
1027 | #ifdef DM9000_PROGRAM_EEPROM | ||
1028 | /* | 1081 | /* |
1029 | * Write a word data to SROM | 1082 | * Write a word data to SROM |
1030 | */ | 1083 | */ |
1031 | static void | 1084 | static void |
1032 | write_srom_word(board_info_t * db, int offset, u16 val) | 1085 | dm9000_write_eeprom(board_info_t *db, int offset, u8 *data) |
1033 | { | 1086 | { |
1034 | mutex_lock(&db->addr_lock); | 1087 | mutex_lock(&db->addr_lock); |
1035 | 1088 | ||
1036 | iow(db, DM9000_EPAR, offset); | 1089 | iow(db, DM9000_EPAR, offset); |
1037 | iow(db, DM9000_EPDRH, ((val >> 8) & 0xff)); | 1090 | iow(db, DM9000_EPDRH, data[1]); |
1038 | iow(db, DM9000_EPDRL, (val & 0xff)); | 1091 | iow(db, DM9000_EPDRL, data[0]); |
1039 | iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW); | 1092 | iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW); |
1040 | mdelay(8); /* same shit */ | 1093 | mdelay(8); /* same shit */ |
1041 | iow(db, DM9000_EPCR, 0); | 1094 | iow(db, DM9000_EPCR, 0); |
@@ -1043,6 +1096,7 @@ write_srom_word(board_info_t * db, int offset, u16 val) | |||
1043 | mutex_unlock(&db->addr_lock); | 1096 | mutex_unlock(&db->addr_lock); |
1044 | } | 1097 | } |
1045 | 1098 | ||
1099 | #ifdef DM9000_PROGRAM_EEPROM | ||
1046 | /* | 1100 | /* |
1047 | * Only for development: | 1101 | * Only for development: |
1048 | * Here we write static data to the eeprom in case | 1102 | * Here we write static data to the eeprom in case |