static int ag71xx_rx_packets(struct ag71xx *ag, int limit) { struct net_device *dev = ag->dev; struct ag71xx_ring *ring = &ag->rx_ring; int done = 0; DBG("%s: rx packets, limit=%d, curr=%u, dirty=%u\n", dev->name, limit, ring->curr, ring->dirty); while (done < limit) { unsigned int i = ring->curr % AG71XX_RX_RING_SIZE; struct ag71xx_desc *desc = &ring->descs[i]; struct sk_buff *skb; int pktlen; if (ag71xx_desc_empty(desc)) break; if ((ring->dirty + AG71XX_RX_RING_SIZE) == ring->curr) { ag71xx_assert(0); break; } ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); skb = ring->buf[i].skb; pktlen = ag71xx_desc_pktlen(desc); pktlen -= ETH_FCS_LEN; skb_put(skb, pktlen); skb->dev = dev; skb->ip_summed = CHECKSUM_NONE; dev->last_rx = jiffies; dev->stats.rx_packets++; dev->stats.rx_bytes += pktlen; if (ag71xx_remove_ar8216_header(ag, skb) != 0) { dev->stats.rx_dropped++; kfree_skb(skb); } else { skb->protocol = eth_type_trans(skb, dev); netif_receive_skb(skb); } ring->buf[i].skb = NULL; done++; ring->curr++; } ag71xx_ring_rx_refill(ag); DBG("%s: rx finish, curr=%u, dirty=%u, done=%d\n", dev->name, ring->curr, ring->dirty, done); return done; }
static int ag71xx_rx_packets(struct ag71xx *ag, int limit) { struct net_device *dev = ag->dev; struct ag71xx_ring *ring = &ag->rx_ring; #ifndef AG71XX_NAPI_TX struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); unsigned long flags; #endif int done = 0; #ifndef AG71XX_NAPI_TX spin_lock_irqsave(&ag->lock, flags); ar71xx_ddr_flush(pdata->flush_reg); spin_unlock_irqrestore(&ag->lock, flags); #endif DBG("%s: rx packets, limit=%d, curr=%u, dirty=%u\n", dev->name, limit, ring->curr, ring->dirty); while (done < limit) { unsigned int i = ring->curr % AG71XX_RX_RING_SIZE; struct ag71xx_desc *desc = &ring->descs[i]; struct sk_buff *skb; int pktlen; if (ag71xx_desc_empty(desc)) break; if ((ring->dirty + AG71XX_RX_RING_SIZE) == ring->curr) { ag71xx_assert(0); break; } skb = ring->buf[i].skb; pktlen = ag71xx_desc_pktlen(desc); pktlen -= ETH_FCS_LEN; /* TODO: move it into the refill function */ dma_cache_wback_inv((unsigned long)skb->data, pktlen); skb_put(skb, pktlen); skb->dev = dev; skb->protocol = eth_type_trans(skb, dev); skb->ip_summed = CHECKSUM_UNNECESSARY; netif_receive_skb(skb); dev->last_rx = jiffies; dev->stats.rx_packets++; dev->stats.rx_bytes += pktlen; ring->buf[i].skb = NULL; done++; ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); ring->curr++; if ((ring->curr - ring->dirty) > (AG71XX_RX_RING_SIZE / 4)) ag71xx_ring_rx_refill(ag); } ag71xx_ring_rx_refill(ag); DBG("%s: rx finish, curr=%u, dirty=%u, done=%d\n", dev->name, ring->curr, ring->dirty, done); return done; }