static irqreturn_t sh_eth_interrupt(int irq, void *netdev) { struct net_device *ndev = netdev; struct sh_eth_private *mdp = netdev_priv(ndev); irqreturn_t ret = IRQ_NONE; u32 ioaddr, boguscnt = RX_RING_SIZE; u32 intr_status = 0; ioaddr = ndev->base_addr; spin_lock(&mdp->lock); /* Get interrpt stat */ intr_status = ctrl_inl(ioaddr + EESR); /* Clear interrupt */ if (intr_status & (EESR_FRC | EESR_RMAF | EESR_RRF | EESR_RTLF | EESR_RTSF | EESR_PRE | EESR_CERF | TX_CHECK | EESR_ERR_CHECK)) { ctrl_outl(intr_status, ioaddr + EESR); ret = IRQ_HANDLED; } else goto other_irq; if (intr_status & (EESR_FRC | /* Frame recv*/ EESR_RMAF | /* Multi cast address recv*/ EESR_RRF | /* Bit frame recv */ EESR_RTLF | /* Long frame recv*/ EESR_RTSF | /* short frame recv */ EESR_PRE | /* PHY-LSI recv error */ EESR_CERF)) { /* recv frame CRC error */ sh_eth_rx(ndev); } /* Tx Check */ if (intr_status & TX_CHECK) { sh_eth_txfree(ndev); netif_wake_queue(ndev); } if (intr_status & EESR_ERR_CHECK) sh_eth_error(ndev, intr_status); if (--boguscnt < 0) { printk(KERN_WARNING "%s: Too much work at interrupt, status=0x%4.4x.\n", ndev->name, intr_status); } other_irq: spin_unlock(&mdp->lock); return ret; }
static irqreturn_t sh_eth_interrupt(int irq, void *netdev) { struct net_device *ndev = netdev; struct sh_eth_private *mdp = netdev_priv(ndev); struct sh_eth_cpu_data *cd = mdp->cd; irqreturn_t ret = IRQ_NONE; u32 ioaddr, intr_status = 0; ioaddr = ndev->base_addr; spin_lock(&mdp->lock); /* Get interrpt stat */ intr_status = readl(ioaddr + EESR); /* Clear interrupt */ if (intr_status & (EESR_FRC | EESR_RMAF | EESR_RRF | EESR_RTLF | EESR_RTSF | EESR_PRE | EESR_CERF | cd->tx_check | cd->eesr_err_check)) { writel(intr_status, ioaddr + EESR); ret = IRQ_HANDLED; } else goto other_irq; if (intr_status & (EESR_FRC | /* Frame recv*/ EESR_RMAF | /* Multi cast address recv*/ EESR_RRF | /* Bit frame recv */ EESR_RTLF | /* Long frame recv*/ EESR_RTSF | /* short frame recv */ EESR_PRE | /* PHY-LSI recv error */ EESR_CERF)){ /* recv frame CRC error */ sh_eth_rx(ndev); } /* Tx Check */ if (intr_status & cd->tx_check) { sh_eth_txfree(ndev); netif_wake_queue(ndev); } if (intr_status & cd->eesr_err_check) sh_eth_error(ndev, intr_status); other_irq: spin_unlock(&mdp->lock); return ret; }