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 inline void greth_enable_irqs(struct greth_private *greth) { GRETH_REGORIN(greth->regs->control, GRETH_RXI | GRETH_TXI); }
static inline void greth_enable_rx(struct greth_private *greth) { wmb(); GRETH_REGORIN(greth->regs->control, GRETH_RXEN); }
static inline void greth_enable_tx_and_irq(struct greth_private *greth) { wmb(); /* BDs must been written to memory before enabling TX */ GRETH_REGORIN(greth->regs->control, GRETH_TXEN | GRETH_TXI); }