Commit f85b60710571b37293d2233933b76e2aa3db5635

Authored by Rafal Jaworowski
Committed by Ben Warren
1 parent 5c740711f0

Introduce new 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@semihalf.com>
Signed-off-by: Piotr Kruszynski <ppk@semihalf.com>
Signed-off-by: Ben Warren <biggerbadderben@gmail.com>

Showing 3 changed files with 71 additions and 0 deletions Side-by-side Diff

... ... @@ -122,6 +122,9 @@
122 122  
123 123 extern int eth_init(bd_t *bis); /* Initialize the device */
124 124 extern int eth_send(volatile void *packet, int length); /* Send a packet */
  125 +#ifdef CONFIG_API
  126 +extern int eth_receive(volatile void *packet, int length); /* Receive a packet */
  127 +#endif
125 128 extern int eth_rx(void); /* Check for received packets */
126 129 extern void eth_halt(void); /* stop SCC */
127 130 extern char *eth_get_name(void); /* get name of current device */
... ... @@ -62,6 +62,17 @@
62 62 extern int atstk1000_eth_initialize(bd_t *);
63 63 extern int mcffec_initialize(bd_t*);
64 64  
  65 +#ifdef CONFIG_API
  66 +extern void (*push_packet)(volatile void *, int);
  67 +
  68 +static struct {
  69 + uchar data[PKTSIZE];
  70 + int length;
  71 +} eth_rcv_bufs[PKTBUFSRX];
  72 +
  73 +static unsigned int eth_rcv_current = 0, eth_rcv_last = 0;
  74 +#endif
  75 +
65 76 static struct eth_device *eth_devices, *eth_current;
66 77  
67 78 struct eth_device *eth_get_dev(void)
... ... @@ -456,6 +467,53 @@
456 467  
457 468 return eth_current->recv(eth_current);
458 469 }
  470 +
  471 +#ifdef CONFIG_API
  472 +static void eth_save_packet(volatile void *packet, int length)
  473 +{
  474 + volatile char *p = packet;
  475 + int i;
  476 +
  477 + if ((eth_rcv_last+1) % PKTBUFSRX == eth_rcv_current)
  478 + return;
  479 +
  480 + if (PKTSIZE < length)
  481 + return;
  482 +
  483 + for (i = 0; i < length; i++)
  484 + eth_rcv_bufs[eth_rcv_last].data[i] = p[i];
  485 +
  486 + eth_rcv_bufs[eth_rcv_last].length = length;
  487 + eth_rcv_last = (eth_rcv_last + 1) % PKTBUFSRX;
  488 +}
  489 +
  490 +int eth_receive(volatile void *packet, int length)
  491 +{
  492 + volatile char *p = packet;
  493 + void *pp = push_packet;
  494 + int i;
  495 +
  496 + if (eth_rcv_current == eth_rcv_last) {
  497 + push_packet = eth_save_packet;
  498 + eth_rx();
  499 + push_packet = pp;
  500 +
  501 + if (eth_rcv_current == eth_rcv_last)
  502 + return -1;
  503 + }
  504 +
  505 + if (length < eth_rcv_bufs[eth_rcv_current].length)
  506 + return -1;
  507 +
  508 + length = eth_rcv_bufs[eth_rcv_current].length;
  509 +
  510 + for (i = 0; i < length; i++)
  511 + p[i] = eth_rcv_bufs[eth_rcv_current].data[i];
  512 +
  513 + eth_rcv_current = (eth_rcv_current + 1) % PKTBUFSRX;
  514 + return length;
  515 +}
  516 +#endif /* CONFIG_API */
459 517  
460 518 void eth_try_another(int first_restart)
461 519 {
... ... @@ -137,6 +137,9 @@
137 137 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
138 138 uchar NetEtherNullAddr[6] =
139 139 { 0, 0, 0, 0, 0, 0 };
  140 +#ifdef CONFIG_API
  141 +void (*push_packet)(volatile void *, int len) = 0;
  142 +#endif
140 143 #if defined(CONFIG_CMD_CDP)
141 144 uchar NetCDPAddr[6] = /* Ethernet bcast address */
142 145 { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc };
... ... @@ -1160,6 +1163,13 @@
1160 1163 /* too small packet? */
1161 1164 if (len < ETHER_HDR_SIZE)
1162 1165 return;
  1166 +
  1167 +#ifdef CONFIG_API
  1168 + if (push_packet) {
  1169 + (*push_packet)(inpkt, len);
  1170 + return;
  1171 + }
  1172 +#endif
1163 1173  
1164 1174 #if defined(CONFIG_CMD_CDP)
1165 1175 /* keep track if packet is CDP */