[U-Boot-Users] [PATCH 1/7] eth_receive() for standalone receiving Ethernet frame

Rafal Jaworowski raj at semihalf.com
Wed Oct 3 12:03:29 CEST 2007


diff --git a/net/eth.c b/net/eth.c
index c8f92a5..032c926 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -59,8 +59,15 @@ extern int npe_initialize(bd_t *);
 extern int uec_initialize(int);
 extern int bfin_EMAC_initialize(bd_t *);
 extern int atstk1000_eth_initialize(bd_t *);
+extern void (*push_packet)(volatile void *, int);
+
+static struct {
+	uchar data[PKTSIZE];
+	int length;
+} eth_rcv_bufs[PKTBUFSRX];
 
 static struct eth_device *eth_devices, *eth_current;
+static unsigned int eth_rcv_current = 0, eth_rcv_last = 0;
 
 struct eth_device *eth_get_dev(void)
 {
@@ -404,6 +411,51 @@ int eth_rx(void)
 	return eth_current->recv(eth_current);
 }
 
+static void eth_save_packet(volatile void *packet, int length)
+{
+	volatile char *p = packet;
+	int i;
+
+	if ((eth_rcv_last+1) % PKTBUFSRX == eth_rcv_current)
+		return;
+
+	if (PKTSIZE < length)
+		return;
+
+	for (i = 0; i < length; i++)
+		eth_rcv_bufs[eth_rcv_last].data[i] = p[i];
+
+	eth_rcv_bufs[eth_rcv_last].length = length;
+	eth_rcv_last = (eth_rcv_last+1) % PKTBUFSRX;
+}
+
+int eth_receive(volatile void *packet, int length)
+{
+	volatile char *p = packet;
+	void *pp = push_packet;
+	int i;
+
+	if (eth_rcv_current == eth_rcv_last) {
+		push_packet = eth_save_packet;
+		eth_rx();
+		push_packet = pp;
+
+		if (eth_rcv_current == eth_rcv_last)
+			return -1;
+	}
+
+	if (length < eth_rcv_bufs[eth_rcv_current].length)
+		return -1;
+
+	length = eth_rcv_bufs[eth_rcv_current].length;
+
+	for (i = 0; i < length; i++)
+		p[i] = eth_rcv_bufs[eth_rcv_current].data[i];
+
+	eth_rcv_current = (eth_rcv_current+1) % PKTBUFSRX;
+	return length;
+}
+
 void eth_try_another(int first_restart)
 {
 	static struct eth_device *first_failed = NULL;
diff --git a/net/net.c b/net/net.c
index e9d7757..ae7c372 100644
--- a/net/net.c
+++ b/net/net.c
@@ -133,6 +133,7 @@ uchar		NetBcastAddr[6] =	/* Ethernet bcast address		*/
 			{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 uchar		NetEtherNullAddr[6] =
 			{ 0, 0, 0, 0, 0, 0 };
+void		(*push_packet)(volatile void *, int len) = 0;
 #if defined(CONFIG_CMD_CDP)
 uchar		NetCDPAddr[6] =		/* Ethernet bcast address		*/
 			{ 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc };
@@ -1157,6 +1158,11 @@ NetReceive(volatile uchar * inpkt, int len)
 	if (len < ETHER_HDR_SIZE)
 		return;
 
+	if (push_packet) {
+		(*push_packet)(inpkt, len);
+		return;
+	}
+
 #if defined(CONFIG_CMD_CDP)
 	/* keep track if packet is CDP */
 	iscdp = memcmp(et->et_dest, NetCDPAddr, 6) == 0;




More information about the U-Boot mailing list