Exemple #1
0
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;
}
Exemple #2
0
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;
}