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>
This commit is contained in:
Ben Dooks 2008-02-05 00:02:11 +00:00 committed by Jeff Garzik
parent 9a2f037cdb
commit 29d52e545f

View File

@ -186,7 +186,8 @@ static int dm9000_phy_read(struct net_device *dev, int phyaddr_unsused, int reg)
static void dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg,
int value);
static void dm9000_read_eeprom(board_info_t *, int addr, unsigned char *to);
static void dm9000_read_eeprom(board_info_t *, int addr, u8 *to);
static void dm9000_write_eeprom(board_info_t *, int addr, u8 *dp);
static void dm9000_rx(struct net_device *);
static void dm9000_hash_table(struct net_device *);
@ -409,12 +410,65 @@ static u32 dm9000_get_link(struct net_device *dev)
return mii_link_ok(&dm->mii);
}
#define DM_EEPROM_MAGIC (0x444D394B)
static int dm9000_get_eeprom_len(struct net_device *dev)
{
return 128;
}
static int dm9000_get_eeprom(struct net_device *dev,
struct ethtool_eeprom *ee, u8 *data)
{
board_info_t *dm = to_dm9000_board(dev);
int offset = ee->offset;
int len = ee->len;
int i;
/* EEPROM access is aligned to two bytes */
if ((len & 1) != 0 || (offset & 1) != 0)
return -EINVAL;
ee->magic = DM_EEPROM_MAGIC;
for (i = 0; i < len; i += 2)
dm9000_read_eeprom(dm, (offset + i) / 2, data + i);
return 0;
}
static int dm9000_set_eeprom(struct net_device *dev,
struct ethtool_eeprom *ee, u8 *data)
{
board_info_t *dm = to_dm9000_board(dev);
int offset = ee->offset;
int len = ee->len;
int i;
/* EEPROM access is aligned to two bytes */
if ((len & 1) != 0 || (offset & 1) != 0)
return -EINVAL;
if (ee->magic != DM_EEPROM_MAGIC)
return -EINVAL;
for (i = 0; i < len; i += 2)
dm9000_write_eeprom(dm, (offset + i) / 2, data + i);
return 0;
}
static const struct ethtool_ops dm9000_ethtool_ops = {
.get_drvinfo = dm9000_get_drvinfo,
.get_settings = dm9000_get_settings,
.set_settings = dm9000_set_settings,
.nway_reset = dm9000_nway_reset,
.get_link = dm9000_get_link,
.get_eeprom_len = dm9000_get_eeprom_len,
.get_eeprom = dm9000_get_eeprom,
.set_eeprom = dm9000_set_eeprom,
};
@ -1008,7 +1062,7 @@ dm9000_rx(struct net_device *dev)
* Read a word data from EEPROM
*/
static void
dm9000_read_eeprom(board_info_t *db, int offset, unsigned char *to)
dm9000_read_eeprom(board_info_t *db, int offset, u8 *to)
{
mutex_lock(&db->addr_lock);
@ -1024,18 +1078,17 @@ dm9000_read_eeprom(board_info_t *db, int offset, unsigned char *to)
mutex_unlock(&db->addr_lock);
}
#ifdef DM9000_PROGRAM_EEPROM
/*
* Write a word data to SROM
*/
static void
write_srom_word(board_info_t * db, int offset, u16 val)
dm9000_write_eeprom(board_info_t *db, int offset, u8 *data)
{
mutex_lock(&db->addr_lock);
iow(db, DM9000_EPAR, offset);
iow(db, DM9000_EPDRH, ((val >> 8) & 0xff));
iow(db, DM9000_EPDRL, (val & 0xff));
iow(db, DM9000_EPDRH, data[1]);
iow(db, DM9000_EPDRL, data[0]);
iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW);
mdelay(8); /* same shit */
iow(db, DM9000_EPCR, 0);
@ -1043,6 +1096,7 @@ write_srom_word(board_info_t * db, int offset, u16 val)
mutex_unlock(&db->addr_lock);
}
#ifdef DM9000_PROGRAM_EEPROM
/*
* Only for development:
* Here we write static data to the eeprom in case