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

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

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

if (db->rx_csum) {

if ((((rxbyte & 0x1c) < 3) & rxbyte) == 0)

skb->ip_summed = CHECKSUM_UNNECESSARY;

else

skb->ip_summed = CHECKSUM_NONE;

}

netif_rx(skb);

dev->stats.rx_packets++;

} else {

(db->dumpblk)(db->io_data, RxLen);

}

} while (rxbyte & DM9000_PKT_RDY);

}

static irqreturn_t dm9000_interrupt(int irq, void *dev_id)

{

struct net_device *dev = dev_id;

board_info_t *db = netdev_priv(dev);

int int_status;

unsigned long flags;

u8 reg_save;

dm9000_dbg(db, 3, "entering %s\n", __func__);

spin_lock_irqsave(&db->lock, flags);

reg_save = readb(db->io_addr);

iow(db, DM9000_IMR, IMR_PAR);

int_status = ior(db, DM9000_ISR);

iow(db, DM9000_ISR, int_status);

if (netif_msg_intr(db))

dev_dbg(db->dev, "interrupt status x\n", int_status);

if (int_status & ISR_PRS)

dm9000_rx(dev);

if (int_status & ISR_PTS)

dm9000_tx_done(dev, db);

if (db->type != TYPE_DM9000E) {

if (int_status & ISR_LNKCHNG) {

schedule_delayed_work(&db->phy_poll, 1);

}

}

iow(db, DM9000_IMR, db->imr_all);

writeb(reg_save, db->io_addr);

spin_unlock_irqrestore(&db->lock, flags);

return IRQ_HANDLED;

}

static irqreturn_t dm9000_wol_interrupt(int irq, void *dev_id)

{

struct net_device *dev = dev_id;

board_info_t *db = netdev_priv(dev);

unsigned long flags;

unsigned nsr, wcr;

spin_lock_irqsave(&db->lock, flags);

nsr = ior(db, DM9000_NSR);

wcr = ior(db, DM9000_WCR);

dev_dbg(db->dev, "%s: NSR=0xx, WCR=0xx\n", __func__, nsr, wcr);

if (nsr & NSR_WAKEST) {

iow(db, DM9000_NSR, NSR_WAKEST);

if (wcr & WCR_LINKST)

dev_info(db->dev, "wake by link status change\n");

if (wcr & WCR_SAMPLEST)

dev_info(db->dev, "wake by sample packet\n");

if (wcr & WCR_MAGICST )

dev_info(db->dev, "wake by magic packet\n");

if (!(wcr & (WCR_LINKST | WCR_SAMPLEST | WCR_MAGICST)))

dev_err(db->dev, "wake signalled with no reason? "

"NSR=0xx, WSR=0xx\n", nsr, wcr);

}

spin_unlock_irqrestore(&db->lock, flags);

return (nsr & NSR_WAKEST) ? IRQ_HANDLED : IRQ_NONE;

}

#ifdef CONFIG_NET_POLL_CONTROLLER

static void dm9000_poll_controller(struct net_device *dev)

{

disable_irq(dev->irq);

dm9000_interrupt(dev->irq, dev);

enable_irq(dev->irq);

}

#endif

static int

dm9000_open(struct net_device *dev)

{

board_info_t *db = netdev_priv(dev);

unsigned long irqflags = db->irq_res->flags & IRQF_TRIGGER_MASK;

if (netif_msg_ifup(db))

dev_dbg(db->dev, "enabling %s\n", dev->name);

if (irqflags == IRQF_TRIGGER_NONE)

dev_warn(db->dev, "WARNING: no IRQ resource flags set.\n");

irqflags |= IRQF_SHARED;

if (request_irq(dev->irq, dm9000_interrupt, irqflags, dev->name, dev))

return -EAGAIN;

dm9000_reset(db);

dm9000_init_dm9000(dev);

db->dbug_cnt = 0;

mii_check_media(&db->mii, netif_msg_link(db), 1);

netif_start_queue(dev);

dm9000_schedule_poll(db);

return 0;

}

static void dm9000_msleep(board_info_t *db, unsigned int ms)

{

if (db->in_suspend)

mdelay(ms);

else

msleep(ms);

}

static int

dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)

{

board_info_t *db = netdev_priv(dev);

unsigned long flags;

unsigned int reg_save;

int ret;

mutex_lock(&db->addr_lock);

spin_lock_irqsave(&db->lock,flags);

reg_save = readb(db->io_addr);

iow(db, DM9000_EPAR, DM9000_PHY | reg);

iow(db, DM9000_EPCR, EPCR_ERPRR | EPCR_EPOS);

writeb(reg_save, db->io_addr);

spin_unlock_irqrestore(&db->lock,flags);

dm9000_msleep(db, 1);

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

网站地图

Top