spin_unlock_irqrestore(&db->lock, flags);
return ret;
}
static int dm9000_wait_eeprom(board_info_t *db)
{
unsigned int status;
int timeout = 8;
while (1) {
status = dm9000_read_locked(db, DM9000_EPCR);
if ((status & EPCR_ERRE) == 0)
break;
msleep(1);
if (timeout-- < 0) {
dev_dbg(db->dev, "timeout waiting EEPROM\n");
break;
}
}
return 0;
}
static void
dm9000_read_eeprom(board_info_t *db, int offset, u8 *to)
{
unsigned long flags;
if (db->flags & DM9000_PLATF_NO_EEPROM) {
to[0] = 0xff;
to[1] = 0xff;
return;
}
mutex_lock(&db->addr_lock);
spin_lock_irqsave(&db->lock, flags);
iow(db, DM9000_EPAR, offset);
iow(db, DM9000_EPCR, EPCR_ERPRR);
spin_unlock_irqrestore(&db->lock, flags);
dm9000_wait_eeprom(db);
msleep(1);
spin_lock_irqsave(&db->lock, flags);
iow(db, DM9000_EPCR, 0x0);
to[0] = ior(db, DM9000_EPDRL);
to[1] = ior(db, DM9000_EPDRH);
spin_unlock_irqrestore(&db->lock, flags);
mutex_unlock(&db->addr_lock);
}
static void
dm9000_write_eeprom(board_info_t *db, int offset, u8 *data)
{
unsigned long flags;
if (db->flags & DM9000_PLATF_NO_EEPROM)
return;
mutex_lock(&db->addr_lock);
spin_lock_irqsave(&db->lock, flags);
iow(db, DM9000_EPAR, offset);
iow(db, DM9000_EPDRH, data[1]);
iow(db, DM9000_EPDRL, data[0]);
iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW);
spin_unlock_irqrestore(&db->lock, flags);
dm9000_wait_eeprom(db);
mdelay(1);
spin_lock_irqsave(&db->lock, flags);
iow(db, DM9000_EPCR, 0);
spin_unlock_irqrestore(&db->lock, flags);
mutex_unlock(&db->addr_lock);
}
static void dm9000_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
{
board_info_t *dm = to_dm9000_board(dev);
strcpy(info->driver, CARDNAME);
strcpy(info->version, DRV_VERSION);
strcpy(info->bus_info, to_platform_device(dm->dev)->name);
}
static u32 dm9000_get_msglevel(struct net_device *dev)
{
board_info_t *dm = to_dm9000_board(dev);
return dm->msg_enable;
}
static void dm9000_set_msglevel(struct net_device *dev, u32 value)
{
board_info_t *dm = to_dm9000_board(dev);
dm->msg_enable = value;
}
static int dm9000_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
board_info_t *dm = to_dm9000_board(dev);
mii_ethtool_gset(&dm->mii, cmd);
return 0;
}
static int dm9000_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
board_info_t *dm = to_dm9000_board(dev);
return mii_ethtool_sset(&dm->mii, cmd);
}
static int dm9000_nway_reset(struct net_device *dev)
{
board_info_t *dm = to_dm9000_board(dev);
return mii_nway_restart(&dm->mii);
}
static uint32_t dm9000_get_rx_csum(struct net_device *dev)
{
board_info_t *dm = to_dm9000_board(dev);
return dm->rx_csum;
}
static int dm9000_set_rx_csum_unlocked(struct net_device *dev, uint32_t data)
{
board_info_t *dm = to_dm9000_board(dev);
if (dm->can_csum) {
dm->rx_csum = data;
iow(dm, DM9000_RCSR, dm->rx_csum ? RCSR_CSUM : 0);
return 0;
}
return -EOPNOTSUPP;
}
static int dm9000_set_rx_csum(struct net_device *dev, uint32_t data)
{
board_info_t *dm = to_dm9000_board(dev);
unsigned long flags;
int ret;
spin_lock_irqsave(&dm->lock, flags);
ret = dm9000_set_rx_csum_unlocked(dev, data);
spin_unlock_irqrestore(&dm->lock, flags);
return ret;
}
static int dm9000_set_tx_csum(struct net_device *dev, uint32_t data)
{
board_info_t *dm = to_dm9000_board(dev);
int ret = -EOPNOTSUPP;
if (dm->can_csum)
ret = ethtool_op_set_tx_csum(dev, data);
return ret;
}
static u32 dm9000_get_link(struct net_device *dev)
{
board_info_t *dm = to_dm9000_board(dev);