コード例 #1
0
ファイル: ag71xx_main.c プロジェクト: mirko/openwrt-x-burst
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;
}
コード例 #2
0
ファイル: ag71xx_main.c プロジェクト: Cribstone/linino
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;
}