arm linux 移植ethtool,ARM-Linux驱动--DM9000网卡驱动分析(四)

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值