微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARM-Linux驱动--DM9000网卡驱动分析(四)

ARM-Linux驱动--DM9000网卡驱动分析(四)

时间:11-20 来源:互联网 点击:

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);

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top