static int ag71xx_poll(struct napi_struct *napi, int limit) { struct ag71xx *ag = container_of(napi, struct ag71xx, napi); #ifdef AG71XX_NAPI_TX struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); #endif struct net_device *dev = ag->dev; unsigned long flags; u32 status; int done; #ifdef AG71XX_NAPI_TX ar71xx_ddr_flush(pdata->flush_reg); ag71xx_tx_packets(ag); #endif DBG("%s: processing RX ring\n", dev->name); done = ag71xx_rx_packets(ag, limit); /* TODO: add OOM handler */ status = ag71xx_rr(ag, AG71XX_REG_INT_STATUS); status &= AG71XX_INT_POLL; if ((done < limit) && (!status)) { DBG("%s: disable polling mode, done=%d, status=%x\n", dev->name, done, status); netif_rx_complete(dev, napi); /* enable interrupts */ spin_lock_irqsave(&ag->lock, flags); ag71xx_int_enable(ag, AG71XX_INT_POLL); spin_unlock_irqrestore(&ag->lock, flags); return 0; } if (status & AG71XX_INT_RX_OF) { if (netif_msg_rx_err(ag)) printk(KERN_ALERT "%s: rx owerflow, restarting dma\n", dev->name); /* ack interrupt */ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_OF); /* restart RX */ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE); } DBG("%s: stay in polling mode, done=%d, status=%x\n", dev->name, done, status); return 1; }
static int ag71xx_poll(struct napi_struct *napi, int limit) { struct ag71xx *ag = container_of(napi, struct ag71xx, napi); struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); struct net_device *dev = ag->dev; struct ag71xx_ring *rx_ring; unsigned long flags; u32 status; int done; pdata->ddr_flush(); ag71xx_tx_packets(ag); DBG("%s: processing RX ring\n", dev->name); done = ag71xx_rx_packets(ag, limit); rx_ring = &ag->rx_ring; if (rx_ring->buf[rx_ring->dirty % AG71XX_RX_RING_SIZE].skb == NULL) goto oom; status = ag71xx_rr(ag, AG71XX_REG_RX_STATUS); if (unlikely(status & RX_STATUS_OF)) { ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_OF); dev->stats.rx_fifo_errors++; /* restart RX */ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE); } if (done < limit) { if (status & RX_STATUS_PR) goto more; status = ag71xx_rr(ag, AG71XX_REG_TX_STATUS); if (status & TX_STATUS_PS) goto more; DBG("%s: disable polling mode, done=%d, limit=%d\n", dev->name, done, limit); netif_rx_complete(dev, napi); /* enable interrupts */ spin_lock_irqsave(&ag->lock, flags); ag71xx_int_enable(ag, AG71XX_INT_POLL); spin_unlock_irqrestore(&ag->lock, flags); return done; } more: DBG("%s: stay in polling mode, done=%d, limit=%d\n", dev->name, done, limit); return done; oom: if (netif_msg_rx_err(ag)) printk(KERN_DEBUG "%s: out of memory\n", dev->name); mod_timer(&ag->oom_timer, jiffies + AG71XX_OOM_REFILL); netif_rx_complete(dev, napi); return 0; }