[U-Boot-Users] Pull request: u-boot-freebsd

Rafal Jaworowski raj at semihalf.com
Thu Dec 27 18:19:02 CET 2007


Hi Ben,

On Thu, Dec 27, 2007 at 11:27:50AM -0500, Ben Warren wrote:
> >>    
> >>>      [Net] Introduce standalone eth_receive() routine
> >>>      
> >>This adds a lot of code to the networking code which is not neede dby
> >>most of the boards. Please make this an optional feature that get's
> >>only compiled in for boards that explicitely request it. Then run this
> >>patch separately through the network custodian.
> >>
> >>    
> >
> >I already sent this patch to Ben and the list some time ago and got an 
> >initial
> >ACK, but I'll re-spin with.
> >
> >  
> When you send the re-spun patch I'll be sure to pull it in.
> 

The patch is included below. I'm only wondering if it makes sense to run this patch through you and the rest of my changes separately, while they all belong to the same changeset and kind of depend on this one...

kind regards,
Rafal


[PATCH] [Net] Introduce standalone eth_receive() routine.

The purpose of this routine is receiving a single network frame, outside of
U-Boot's NetLoop(). Exporting it to standalone programs that run on top of
U-Boot will let them utilise networking facilities. For sending a raw frame
the already existing eth_send() can be used.

The direct consumer of this routine is the newly introduced API layer for
external applications (enabled with CONFIG_API).

Signed-off-by: Rafal Jaworowski <raj at semihalf.com>
Signed-off-by: Piotr Kruszynski <ppk at semihalf.com>
---
 include/net.h |    3 ++
 net/eth.c     |   58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 net/net.c     |   10 +++++++++
 3 files changed, 71 insertions(+), 0 deletions(-)

diff --git a/include/net.h b/include/net.h
index 603452a..f6decdc 100644
--- a/include/net.h
+++ b/include/net.h
@@ -122,6 +122,9 @@ extern void eth_set_enetaddr(int num, char* a);	/* Set new MAC address		*/
 
 extern int eth_init(bd_t *bis);			/* Initialize the device	*/
 extern int eth_send(volatile void *packet, int length);	   /* Send a packet	*/
+#ifdef CONFIG_API
+extern int eth_receive(volatile void *packet, int length); /* Receive a packet	*/
+#endif
 extern int eth_rx(void);			/* Check for received packets	*/
 extern void eth_halt(void);			/* stop SCC			*/
 extern char *eth_get_name(void);		/* get name of current device	*/
diff --git a/net/eth.c b/net/eth.c
index 1b56a35..4657f79 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -62,6 +62,17 @@ extern int bfin_EMAC_initialize(bd_t *);
 extern int atstk1000_eth_initialize(bd_t *);
 extern int mcffec_initialize(bd_t*);
 
+#ifdef CONFIG_API
+extern void (*push_packet)(volatile void *, int);
+
+static struct {
+	uchar data[PKTSIZE];
+	int length;
+} eth_rcv_bufs[PKTBUFSRX];
+
+static unsigned int eth_rcv_current = 0, eth_rcv_last = 0;
+#endif
+
 static struct eth_device *eth_devices, *eth_current;
 
 struct eth_device *eth_get_dev(void)
@@ -457,6 +468,53 @@ int eth_rx(void)
 	return eth_current->recv(eth_current);
 }
 
+#ifdef CONFIG_API
+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;
+}
+#endif /* CONFIG_API */
+
 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 c719bc4..cac3e09 100644
--- a/net/net.c
+++ b/net/net.c
@@ -137,6 +137,9 @@ uchar		NetBcastAddr[6] =	/* Ethernet bcast address		*/
 			{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 uchar		NetEtherNullAddr[6] =
 			{ 0, 0, 0, 0, 0, 0 };
+#ifdef CONFIG_API
+void		(*push_packet)(volatile void *, int len) = 0;
+#endif
 #if defined(CONFIG_CMD_CDP)
 uchar		NetCDPAddr[6] =		/* Ethernet bcast address		*/
 			{ 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc };
@@ -1161,6 +1164,13 @@ NetReceive(volatile uchar * inpkt, int len)
 	if (len < ETHER_HDR_SIZE)
 		return;
 
+#ifdef CONFIG_API
+	if (push_packet) {
+		(*push_packet)(inpkt, len);
+		return;
+	}
+#endif
+
 #if defined(CONFIG_CMD_CDP)
 	/* keep track if packet is CDP */
 	iscdp = memcmp(et->et_dest, NetCDPAddr, 6) == 0;
-- 
1.5.2.2





More information about the U-Boot mailing list