qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 07/10] dp8393x: Implement TBWC0 and TBWC1 registers to restore bu


From: Finn Thain
Subject: [PATCH 07/10] dp8393x: Implement TBWC0 and TBWC1 registers to restore buffer state
Date: Sat, 14 Dec 2019 12:25:57 +1100

Restore the receive buffer state when the SONIC runs out of receive
descriptors. Otherwise it may write the next packet past the end of the
buffer and corrupt guest memory. This implements behaviour described
in section 3.4.6.2 in the datasheet.

Signed-off-by: Finn Thain <address@hidden>
---
 hw/net/dp8393x.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
index 3fdc6cc6f9..5e4494a945 100644
--- a/hw/net/dp8393x.c
+++ b/hw/net/dp8393x.c
@@ -39,7 +39,7 @@ static const char* reg_names[] = {
     "CR", "DCR", "RCR", "TCR", "IMR", "ISR", "UTDA", "CTDA",
     "TPS", "TFC", "TSA0", "TSA1", "TFS", "URDA", "CRDA", "CRBA0",
     "CRBA1", "RBWC0", "RBWC1", "EOBC", "URRA", "RSA", "REA", "RRP",
-    "RWP", "TRBA0", "TRBA1", "0x1b", "0x1c", "0x1d", "0x1e", "LLFA",
+    "RWP", "TRBA0", "TRBA1", "TBWC0", "TBWC1", "0x1d", "0x1e", "LLFA",
     "TTDA", "CEP", "CAP2", "CAP1", "CAP0", "CE", "CDP", "CDC",
     "SR", "WT0", "WT1", "RSC", "CRCT", "FAET", "MPT", "MDT",
     "0x30", "0x31", "0x32", "0x33", "0x34", "0x35", "0x36", "0x37",
@@ -78,6 +78,8 @@ do { printf("sonic ERROR: %s: " fmt, __func__ , ## 
__VA_ARGS__); } while (0)
 #define SONIC_RWP    0x18
 #define SONIC_TRBA0  0x19
 #define SONIC_TRBA1  0x1a
+#define SONIC_TBWC0  0x1b
+#define SONIC_TBWC1  0x1c
 #define SONIC_LLFA   0x1f
 #define SONIC_TTDA   0x20
 #define SONIC_CEP    0x21
@@ -777,6 +779,8 @@ static ssize_t dp8393x_receive(NetClientState *nc, const 
uint8_t * buf,
     /* Save current position */
     s->regs[SONIC_TRBA1] = s->regs[SONIC_CRBA1];
     s->regs[SONIC_TRBA0] = s->regs[SONIC_CRBA0];
+    s->regs[SONIC_TBWC1] = s->regs[SONIC_RBWC1];
+    s->regs[SONIC_TBWC0] = s->regs[SONIC_RBWC0];
 
     /* Calculate the ethernet checksum */
     checksum = cpu_to_le32(crc32(0, buf, rx_len));
@@ -827,6 +831,12 @@ static ssize_t dp8393x_receive(NetClientState *nc, const 
uint8_t * buf,
     if (s->regs[SONIC_LLFA] & 0x1) {
         /* EOL detected */
         s->regs[SONIC_ISR] |= SONIC_ISR_RDE;
+
+        /* Restore buffer state */
+        s->regs[SONIC_CRBA1] = s->regs[SONIC_TRBA1];
+        s->regs[SONIC_CRBA0] = s->regs[SONIC_TRBA0];
+        s->regs[SONIC_RBWC1] = s->regs[SONIC_TBWC1];
+        s->regs[SONIC_RBWC0] = s->regs[SONIC_TBWC0];
     } else {
         /* Clear in_use */
         int offset = dp8393x_crda(s) + sizeof(uint16_t) * 6 * width;
-- 
2.23.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]