/* The interrupt handler. * This is called from the MPC core interrupt. */ static irqreturn_t fec_enet_interrupt(int irq, void * dev_id) { struct net_device *dev = dev_id; volatile fec_t *fecp; uint int_events; #ifdef CONFIG_FEC_PACKETHOOK struct fec_enet_private *fep = dev->priv; __u32 regval; if (fep->ph_regaddr) regval = *fep->ph_regaddr; #endif fecp = (volatile fec_t*)dev->base_addr; /* Get the interrupt events that caused us to be here. */ while ((int_events = fecp->fec_ievent) != 0) { fecp->fec_ievent = int_events; if ((int_events & (FEC_ENET_HBERR | FEC_ENET_BABR | FEC_ENET_BABT | FEC_ENET_EBERR)) != 0) { printk("FEC ERROR %x\n", int_events); } /* Handle receive event in its own function. */ if (int_events & FEC_ENET_RXF) { #ifdef CONFIG_FEC_PACKETHOOK fec_enet_rx(dev, regval); #else fec_enet_rx(dev); #endif } /* Transmit OK, or non-fatal error. Update the buffer descriptors. FEC handles all errors, we just discover them as part of the transmit process. */ if (int_events & FEC_ENET_TXF) { #ifdef CONFIG_FEC_PACKETHOOK fec_enet_tx(dev, regval); #else fec_enet_tx(dev); #endif } if (int_events & FEC_ENET_MII) { #ifdef CONFIG_USE_MDIO fec_enet_mii(dev); #else printk("%s[%d] %s: unexpected FEC_ENET_MII event\n", __FILE__,__LINE__,__FUNCTION__); #endif /* CONFIG_USE_MDIO */ } } return IRQ_RETVAL(IRQ_HANDLED); }
static irqreturn_t fec_enet_interrupt(int irq, void *dev_id) { struct net_device *ndev = dev_id; struct fec_enet_private *fep = netdev_priv(ndev); uint int_events; irqreturn_t ret = IRQ_NONE; do { int_events = readl(fep->hwp + FEC_IEVENT); writel(int_events, fep->hwp + FEC_IEVENT); if (int_events & FEC_ENET_RXF) { ret = IRQ_HANDLED; fec_enet_rx(ndev); } /* Transmit OK, or non-fatal error. Update the buffer * descriptors. FEC handles all errors, we just discover * them as part of the transmit process. */ if (int_events & FEC_ENET_TXF) { ret = IRQ_HANDLED; fec_enet_tx(ndev); } if (int_events & FEC_ENET_MII) { ret = IRQ_HANDLED; complete(&fep->mdio_done); } } while (int_events); return ret; }
static int fec_enet_rx_napi(struct napi_struct *napi, int budget) { struct net_device *ndev = napi->dev; int pkts = fec_enet_rx(ndev, budget); struct fec_enet_private *fep = netdev_priv(ndev); if (pkts < budget) { napi_complete(napi); writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); } return pkts; }
static irqreturn_t fec_enet_interrupt(int irq, void *dev_id) { struct net_device *ndev = dev_id; struct fec_enet_private *fep = netdev_priv(ndev); struct fec_ptp_private *fpp = fep->ptp_priv; uint int_events; ulong flags; irqreturn_t ret = IRQ_NONE; do { int_events = readl(fep->hwp + FEC_IEVENT); writel(int_events, fep->hwp + FEC_IEVENT); if (int_events & FEC_ENET_RXF) { ret = IRQ_HANDLED; spin_lock_irqsave(&fep->hw_lock, flags); if (fep->use_napi) { /* Disable the RX interrupt */ if (napi_schedule_prep(&fep->napi)) { fec_rx_int_is_enabled(ndev, false); __napi_schedule(&fep->napi); } } else fec_enet_rx(ndev); spin_unlock_irqrestore(&fep->hw_lock, flags); } /* Transmit OK, or non-fatal error. Update the buffer * descriptors. FEC handles all errors, we just discover * them as part of the transmit process. */ if (int_events & FEC_ENET_TXF) { ret = IRQ_HANDLED; fec_enet_tx(ndev); } if (int_events & FEC_ENET_TS_TIMER) { ret = IRQ_HANDLED; if (fep->ptimer_present && fpp) fpp->prtc++; } if (int_events & FEC_ENET_MII) { ret = IRQ_HANDLED; complete(&fep->mdio_done); } } while (int_events); return ret; }
static int fec_enet_interrupt(rtdm_irq_t *irq_handle) { struct rtnet_device *ndev = rtdm_irq_get_arg(irq_handle, struct rtnet_device); /* RTnet */ struct fec_enet_private *fep = rtnetdev_priv(ndev); uint int_events; irqreturn_t ret = RTDM_IRQ_NONE; /* RTnet */ nanosecs_abs_t time_stamp = rtdm_clock_read(); int packets = 0; do { int_events = readl(fep->hwp + FEC_IEVENT); writel(int_events, fep->hwp + FEC_IEVENT); if (int_events & FEC_ENET_RXF) { ret = RTDM_IRQ_HANDLED; fec_enet_rx(ndev, &packets, &time_stamp); } /* Transmit OK, or non-fatal error. Update the buffer * descriptors. FEC handles all errors, we just discover * them as part of the transmit process. */ if (int_events & FEC_ENET_TXF) { ret = RTDM_IRQ_HANDLED; fec_enet_tx(ndev); } if (int_events & FEC_ENET_MII) { ret = RTDM_IRQ_HANDLED; rtdm_nrtsig_pend(&fep->mdio_done_sig); } } while (int_events); if (packets > 0) rt_mark_stack_mgr(ndev); return ret; }