summaryrefslogtreecommitdiff
path: root/net/eth.c
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2015-07-06 16:47:49 -0600
committerSimon Glass <sjg@chromium.org>2015-07-21 17:39:40 -0600
commita1ca92eaaf0cac2a11c16b93f0cd0cd6f6256f02 (patch)
tree31b3e4ebdb988f061df1424df9f59da239093775 /net/eth.c
parent69559093f6173dcfcb041df0995063bdbd07d49b (diff)
downloadu-boot-a1ca92eaaf0cac2a11c16b93f0cd0cd6f6256f02.tar.gz
u-boot-a1ca92eaaf0cac2a11c16b93f0cd0cd6f6256f02.tar.bz2
u-boot-a1ca92eaaf0cac2a11c16b93f0cd0cd6f6256f02.zip
dm: eth: Avoid blocking on packet reception
Some devices can take a long time to work out whether they have a new packet or now. For example the ASIX USB Ethernet dongle can take 5 seconds to do this, since it waits until it gets a new packet on the wire before allowing the USB bulk read packet to be submitted. At present with driver mode the Ethernet receive code reads 32 packets. This can take a very long time if we must wait for all 32 packets. The old code (before driver model) worked by reading a single set of packets from the USB device, then processing all the packets with in. It would be nice to use the same behaviour with driver model. Add a flag to the receive method which indicates that the driver should try to find a packet if available, by consulting the hardware. When the flag is not set, it should just return any packet data it has already received. If there is none, it should return -EAGAIN so that the loop will terminate. Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'net/eth.c')
-rw-r--r--net/eth.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/net/eth.c b/net/eth.c
index 953b7310bd..72ce91c9d0 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -404,6 +404,7 @@ int eth_rx(void)
{
struct udevice *current;
uchar *packet;
+ int flags;
int ret;
int i;
@@ -415,8 +416,10 @@ int eth_rx(void)
return -EINVAL;
/* Process up to 32 packets at one time */
+ flags = ETH_RECV_CHECK_DEVICE;
for (i = 0; i < 32; i++) {
- ret = eth_get_ops(current)->recv(current, &packet);
+ ret = eth_get_ops(current)->recv(current, flags, &packet);
+ flags = 0;
if (ret > 0)
net_process_received_packet(packet, ret);
if (ret >= 0 && eth_get_ops(current)->free_pkt)