Exemple #1
0
static int macb_recv(struct eth_device *netdev)
{
	struct macb_device *macb = to_macb(netdev);
	unsigned int rx_tail = macb->rx_tail;
	void *buffer;
	int length;
	int wrapped = 0;
	u32 status;
        
                
	for (;;) {
		macb_invalidate_ring_desc(macb, RX);

		if (!(macb->rx_ring[rx_tail].addr & RXADDR_USED))
			return -1;

		status = macb->rx_ring[rx_tail].ctrl;
		if (status & RXBUF_FRAME_START) {
			if (rx_tail != macb->rx_tail)
				reclaim_rx_buffers(macb, rx_tail);
			wrapped = 0;
		}

		if (status & RXBUF_FRAME_END) {
			buffer = macb->rx_buffer + 128 * macb->rx_tail;
			length = status & RXBUF_FRMLEN_MASK;

			macb_invalidate_rx_buffer(macb);
			if (wrapped) {
				unsigned int headlen, taillen;

				headlen = 128 * (MACB_RX_RING_SIZE
						 - macb->rx_tail);
				taillen = length - headlen;
				memcpy((void *)NetRxPackets[0],
				       buffer, headlen);
				memcpy((void *)NetRxPackets[0] + headlen,
				       macb->rx_buffer, taillen);
				buffer = (void *)NetRxPackets[0];
			}

			NetReceive(buffer, length);
			if (++rx_tail >= MACB_RX_RING_SIZE)
				rx_tail = 0;
			reclaim_rx_buffers(macb, rx_tail);
		} else {
			if (++rx_tail >= MACB_RX_RING_SIZE) {
				wrapped = 1;
				rx_tail = 0;
			}
		}
		barrier();
	} 
	return 0;
}
Exemple #2
0
static int _macb_recv(struct macb_device *macb, uchar **packetp)
{
	unsigned int next_rx_tail = macb->next_rx_tail;
	void *buffer;
	int length;
	u32 status;

	macb->wrapped = false;
	for (;;) {
		macb_invalidate_ring_desc(macb, RX);

		if (!(macb->rx_ring[next_rx_tail].addr & RXADDR_USED))
			return -EAGAIN;

		status = macb->rx_ring[next_rx_tail].ctrl;
		if (status & RXBUF_FRAME_START) {
			if (next_rx_tail != macb->rx_tail)
				reclaim_rx_buffers(macb, next_rx_tail);
			macb->wrapped = false;
		}

		if (status & RXBUF_FRAME_END) {
			buffer = macb->rx_buffer + 128 * macb->rx_tail;
			length = status & RXBUF_FRMLEN_MASK;

			macb_invalidate_rx_buffer(macb);
			if (macb->wrapped) {
				unsigned int headlen, taillen;

				headlen = 128 * (MACB_RX_RING_SIZE
						 - macb->rx_tail);
				taillen = length - headlen;
				memcpy((void *)net_rx_packets[0],
				       buffer, headlen);
				memcpy((void *)net_rx_packets[0] + headlen,
				       macb->rx_buffer, taillen);
				*packetp = (void *)net_rx_packets[0];
			} else {
				*packetp = buffer;
			}

			if (++next_rx_tail >= MACB_RX_RING_SIZE)
				next_rx_tail = 0;
			macb->next_rx_tail = next_rx_tail;
			return length;
		} else {
			if (++next_rx_tail >= MACB_RX_RING_SIZE) {
				macb->wrapped = true;
				next_rx_tail = 0;
			}
		}
		barrier();
	}
}