aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/dm9000.c
diff options
context:
space:
mode:
authorBen Dooks <ben-linux@fluff.org>2008-02-04 19:02:11 -0500
committerJeff Garzik <jeff@garzik.org>2008-02-11 11:06:29 -0500
commit29d52e545f6f077d8c29fa35d1c52d95e4a2185a (patch)
tree6616b6142343855a0b9bcd6a934a32bddd252df4 /drivers/net/dm9000.c
parent9a2f037cdbe8409c5ff92e8dce5fcdfe2ebb2084 (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/net/dm9000.c')
-rw-r--r--drivers/net/dm9000.c66
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)
186static void dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, 186static void dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg,
187 int value); 187 int value);
188 188
189static void dm9000_read_eeprom(board_info_t *, int addr, unsigned char *to); 189static void dm9000_read_eeprom(board_info_t *, int addr, u8 *to);
190static void dm9000_write_eeprom(board_info_t *, int addr, u8 *dp);
190static void dm9000_rx(struct net_device *); 191static void dm9000_rx(struct net_device *);
191static void dm9000_hash_table(struct net_device *); 192static 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
415static int dm9000_get_eeprom_len(struct net_device *dev)
416{
417 return 128;
418}
419
420static 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
441static 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
412static const struct ethtool_ops dm9000_ethtool_ops = { 463static 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 */
1010static void 1064static void
1011dm9000_read_eeprom(board_info_t *db, int offset, unsigned char *to) 1065dm9000_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 */
1031static void 1084static void
1032write_srom_word(board_info_t * db, int offset, u16 val) 1085dm9000_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