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