static irqreturn_t greth_interrupt(int irq, void *dev_id) { struct net_device *dev = dev_id; struct greth_private *greth; u32 status, ctrl; irqreturn_t retval = IRQ_NONE; greth = netdev_priv(dev); spin_lock(&greth->devlock); /* Get the interrupt events that caused us to be here. */ status = GRETH_REGLOAD(greth->regs->status); /* Must see if interrupts are enabled also, INT_TX|INT_RX flags may be * set regardless of whether IRQ is enabled or not. Especially * important when shared IRQ. */ ctrl = GRETH_REGLOAD(greth->regs->control); /* Handle rx and tx interrupts through poll */ if (((status & (GRETH_INT_RE | GRETH_INT_RX)) && (ctrl & GRETH_RXI)) || ((status & (GRETH_INT_TE | GRETH_INT_TX)) && (ctrl & GRETH_TXI))) { retval = IRQ_HANDLED; /* Disable interrupts and schedule poll() */ greth_disable_irqs(greth); napi_schedule(&greth->napi); } mmiowb(); spin_unlock(&greth->devlock); return retval; }
static irqreturn_t greth_interrupt(int irq, void *dev_id) { struct net_device *dev = dev_id; struct greth_private *greth; u32 status; irqreturn_t retval = IRQ_NONE; greth = netdev_priv(dev); spin_lock(&greth->devlock); /* Get the interrupt events that caused us to be here. */ status = GRETH_REGLOAD(greth->regs->status); /* Handle rx and tx interrupts through poll */ if (status & (GRETH_INT_RX | GRETH_INT_TX)) { /* Clear interrupt status */ GRETH_REGORIN(greth->regs->status, status & (GRETH_INT_RX | GRETH_INT_TX)); retval = IRQ_HANDLED; /* Disable interrupts and schedule poll() */ greth_disable_irqs(greth); napi_schedule(&greth->napi); } mmiowb(); spin_unlock(&greth->devlock); return retval; }
static int greth_close(struct net_device *dev) { struct greth_private *greth = netdev_priv(dev); napi_disable(&greth->napi); greth_disable_irqs(greth); greth_disable_tx(greth); greth_disable_rx(greth); netif_stop_queue(dev); free_irq(greth->irq, (void *) dev); greth_clean_rings(greth); return 0; }