Skip to content

Commit

Permalink
DM9000: Add ethtool support for reading and writing EEPROM
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Ben Dooks authored and Jeff Garzik committed Feb 11, 2008
1 parent 9a2f037 commit 29d52e5
Showing 1 changed file with 60 additions and 6 deletions.
66 changes: 60 additions & 6 deletions drivers/net/dm9000.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);

Expand Down Expand Up @@ -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,
};


Expand Down Expand Up @@ -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);

Expand All @@ -1024,25 +1078,25 @@ 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);

mutex_unlock(&db->addr_lock);
}

#ifdef DM9000_PROGRAM_EEPROM
/*
* Only for development:
* Here we write static data to the eeprom in case
Expand Down

0 comments on commit 29d52e5

Please sign in to comment.