Example #1
0
/* Packet receive function */
static int sh_eth_rx(struct net_device *ndev)
{
    struct sh_eth_private *mdp = netdev_priv(ndev);
    struct sh_eth_rxdesc *rxdesc;

    int entry = mdp->cur_rx % RX_RING_SIZE;
    int boguscnt = (mdp->dirty_rx + RX_RING_SIZE) - mdp->cur_rx;
    struct sk_buff *skb;
    u16 pkt_len = 0;
    u32 desc_status, reserve = 0;

    rxdesc = &mdp->rx_ring[entry];
    while (!(rxdesc->status & cpu_to_edmac(mdp, RD_RACT))) {
        desc_status = edmac_to_cpu(mdp, rxdesc->status);
        pkt_len = rxdesc->frame_length;

        if (--boguscnt < 0)
            break;

        if (!(desc_status & RDFEND))
            mdp->stats.rx_length_errors++;

        if (desc_status & (RD_RFS1 | RD_RFS2 | RD_RFS3 | RD_RFS4 |
                           RD_RFS5 | RD_RFS6 | RD_RFS10)) {
            mdp->stats.rx_errors++;
            if (desc_status & RD_RFS1)
                mdp->stats.rx_crc_errors++;
            if (desc_status & RD_RFS2)
                mdp->stats.rx_frame_errors++;
            if (desc_status & RD_RFS3)
                mdp->stats.rx_length_errors++;
            if (desc_status & RD_RFS4)
                mdp->stats.rx_length_errors++;
            if (desc_status & RD_RFS6)
                mdp->stats.rx_missed_errors++;
            if (desc_status & RD_RFS10)
                mdp->stats.rx_over_errors++;
        } else {
            swaps((char *)(rxdesc->addr & ~0x3), pkt_len + 2);
            skb = mdp->rx_skbuff[entry];
            mdp->rx_skbuff[entry] = NULL;
            skb_put(skb, pkt_len);
            skb->protocol = eth_type_trans(skb, ndev);
            netif_rx(skb);
            mdp->stats.rx_packets++;
            mdp->stats.rx_bytes += pkt_len;
        }
        rxdesc->status |= cpu_to_edmac(mdp, RD_RACT);
        entry = (++mdp->cur_rx) % RX_RING_SIZE;
    }

    /* Refill the Rx ring buffers. */
    for (; mdp->cur_rx - mdp->dirty_rx > 0; mdp->dirty_rx++) {
        entry = mdp->dirty_rx % RX_RING_SIZE;
        rxdesc = &mdp->rx_ring[entry];
        /* The size of the buffer is 16 byte boundary. */
        rxdesc->buffer_length = (mdp->rx_buf_sz + 16) & ~0x0F;

        if (mdp->rx_skbuff[entry] == NULL) {
            skb = dev_alloc_skb(mdp->rx_buf_sz);
            mdp->rx_skbuff[entry] = skb;
            if (skb == NULL)
                break;	/* Better luck next round. */
            skb->dev = ndev;
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
            reserve = SH7763_SKB_ALIGN
                      - ((uint32_t)skb->data & (SH7763_SKB_ALIGN-1));
            if (reserve)
                skb_reserve(skb, reserve);
#else
            skb_reserve(skb, RX_OFFSET);
#endif
            skb->ip_summed = CHECKSUM_NONE;
            rxdesc->addr = (u32)skb->data & ~0x3UL;
        }
        if (entry >= RX_RING_SIZE - 1)
            rxdesc->status |=
                cpu_to_edmac(mdp, RD_RACT | RD_RFP | RD_RDEL);
        else
            rxdesc->status |=
                cpu_to_edmac(mdp, RD_RACT | RD_RFP);
    }

    /* Restart Rx engine if stopped. */
    /* If we don't need to check status, don't. -KDU */
    if (!(ctrl_inl(ndev->base_addr + EDRRR) & EDRRR_R))
        ctrl_outl(EDRRR_R, ndev->base_addr + EDRRR);

    return 0;
}
Example #2
0
/* Packet receive function */
static int sh_eth_rx(struct net_device *ndev)
{
	struct sh_eth_private *mdp = netdev_priv(ndev);
	struct sh_eth_rxdesc *rxdesc;

	int entry = mdp->cur_rx % RX_RING_SIZE;
	int boguscnt = (mdp->dirty_rx + RX_RING_SIZE) - mdp->cur_rx;
	struct sk_buff *skb;
	u16 pkt_len = 0;
	u32 desc_status;

	rxdesc = &mdp->rx_ring[entry];
	while (!(rxdesc->status & cpu_to_edmac(mdp, RD_RACT))) {
		desc_status = edmac_to_cpu(mdp, rxdesc->status);
		pkt_len = rxdesc->frame_length;

		if (--boguscnt < 0)
			break;

		if (!(desc_status & RDFEND))
			mdp->stats.rx_length_errors++;

		if (desc_status & (RD_RFS1 | RD_RFS2 | RD_RFS3 | RD_RFS4 |
				   RD_RFS5 | RD_RFS6 | RD_RFS10)) {
			mdp->stats.rx_errors++;
			if (desc_status & RD_RFS1)
				mdp->stats.rx_crc_errors++;
			if (desc_status & RD_RFS2)
				mdp->stats.rx_frame_errors++;
			if (desc_status & RD_RFS3)
				mdp->stats.rx_length_errors++;
			if (desc_status & RD_RFS4)
				mdp->stats.rx_length_errors++;
			if (desc_status & RD_RFS6)
				mdp->stats.rx_missed_errors++;
			if (desc_status & RD_RFS10)
				mdp->stats.rx_over_errors++;
		} else {
			if (!mdp->cd->hw_swap)
				sh_eth_soft_swap(
					phys_to_virt(ALIGN(rxdesc->addr, 4)),
					pkt_len + 2);
			skb = mdp->rx_skbuff[entry];
			mdp->rx_skbuff[entry] = NULL;
			if (mdp->cd->rpadir)
				skb_reserve(skb, NET_IP_ALIGN);
			skb_put(skb, pkt_len);
			skb->protocol = eth_type_trans(skb, ndev);
			netif_rx(skb);
			mdp->stats.rx_packets++;
			mdp->stats.rx_bytes += pkt_len;
		}
		rxdesc->status |= cpu_to_edmac(mdp, RD_RACT);
		entry = (++mdp->cur_rx) % RX_RING_SIZE;
		rxdesc = &mdp->rx_ring[entry];
	}

	/* Refill the Rx ring buffers. */
	for (; mdp->cur_rx - mdp->dirty_rx > 0; mdp->dirty_rx++) {
		entry = mdp->dirty_rx % RX_RING_SIZE;
		rxdesc = &mdp->rx_ring[entry];
		/* The size of the buffer is 16 byte boundary. */
		rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16);

		if (mdp->rx_skbuff[entry] == NULL) {
			skb = dev_alloc_skb(mdp->rx_buf_sz);
			mdp->rx_skbuff[entry] = skb;
			if (skb == NULL)
				break;	/* Better luck next round. */
			dma_map_single(&ndev->dev, skb->tail, mdp->rx_buf_sz,
					DMA_FROM_DEVICE);
			skb->dev = ndev;
			sh_eth_set_receive_align(skb);

			skb_checksum_none_assert(skb);
			rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4));
		}
		if (entry >= RX_RING_SIZE - 1)
			rxdesc->status |=
				cpu_to_edmac(mdp, RD_RACT | RD_RFP | RD_RDEL);
		else
			rxdesc->status |=
				cpu_to_edmac(mdp, RD_RACT | RD_RFP);
	}

	/* Restart Rx engine if stopped. */
	/* If we don't need to check status, don't. -KDU */
	if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R))
		sh_eth_write(ndev, EDRRR_R, EDRRR);

	return 0;
}