summaryrefslogtreecommitdiffstats
path: root/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0030-net-sh_eth-Fix-RX-error-handling.patch
blob: a93ce61771928b59a3a547b567587ff766088e1c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
From d71076d2f04dace4483f184899e365a27a74d07d Mon Sep 17 00:00:00 2001
From: Valentine Barshak <valentine.barshak@cogentembedded.com>
Date: Mon, 2 Dec 2019 01:20:34 +0300
Subject: [PATCH 4/4] net: sh_eth: Fix RX error handling

In case RX error occurs, and the RD_RFE bit is set, the descriptor
is never returned back to the queue. Make sh_eth_recv_start return
zero length in this case so that the descriptor can be released
and pushed back to the list. Also return the more appropriate
-EAGAIN instead of -EINVAL if the descriptor is not ready yet.

Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
---
 drivers/net/sh_eth.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 5df078d..eeb1d32 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -125,11 +125,11 @@ static int sh_eth_recv_start(struct sh_eth_dev *eth)
 	/* Check if the rx descriptor is ready */
 	invalidate_cache(port_info->rx_desc_cur, sizeof(struct rx_desc_s));
 	if (port_info->rx_desc_cur->rd0 & RD_RACT)
-		return -EINVAL;
+		return -EAGAIN;
 
 	/* Check for errors */
 	if (port_info->rx_desc_cur->rd0 & RD_RFE)
-		return -EINVAL;
+		return 0;
 
 	return port_info->rx_desc_cur->rd1 & 0xffff;
 }
@@ -553,9 +553,11 @@ static int sh_eth_recv_common(struct sh_eth_dev *eth)
 	uchar *packet = (uchar *)ADDR_TO_P2(port_info->rx_desc_cur->rd2);
 
 	len = sh_eth_recv_start(eth);
-	if (len > 0) {
-		invalidate_cache(packet, len);
-		net_process_received_packet(packet, len);
+	if (len >= 0) {
+		if (len > 0) {
+			invalidate_cache(packet, len);
+			net_process_received_packet(packet, len);
+		}
 		sh_eth_recv_finish(eth);
 	} else
 		len = 0;
@@ -710,15 +712,13 @@ static int sh_ether_recv(struct udevice *dev, int flags, uchar **packetp)
 		*packetp = packet;
 
 		return len;
-	} else {
-		len = 0;
+	}
 
-		/* Restart the receiver if disabled */
-		if (!(sh_eth_read(port_info, EDRRR) & EDRRR_R))
-			sh_eth_write(port_info, EDRRR_R, EDRRR);
+	/* Restart the receiver if disabled */
+	if (!(sh_eth_read(port_info, EDRRR) & EDRRR_R))
+		sh_eth_write(port_info, EDRRR_R, EDRRR);
 
-		return -EAGAIN;
-	}
+	return len;
 }
 
 static int sh_ether_free_pkt(struct udevice *dev, uchar *packet, int length)
-- 
2.7.4