aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Vivier <laurent@vivier.eu>2019-11-06 12:23:41 +0100
committerLaurent Vivier <laurent@vivier.eu>2019-11-08 21:32:31 +0100
commitc744cf78791e7ddc903a46d6506f1a0cbcbb3387 (patch)
treeeac78d23322b7f8267e7ffe4d6775a49e62e700f
parentaf9f0be36cd412442a801d25bd5dd9459d691d0b (diff)
downloadqemu-c744cf78791e7ddc903a46d6506f1a0cbcbb3387.tar.gz
dp8393x: fix dp8393x_receive()
RXpkt.in_use is always 16 bit wide, but when the bus access mode is 32bit and the endianness is big, we must access the second word and not the first. This patch adjusts the offset according to the size and endianness. This fixes DHCP for Q800 guest. Fixes: be9208419865 ("dp8393x: manage big endian bus") Signed-off-by: Laurent Vivier <laurent@vivier.eu> Tested-by: Hervé Poussineau <hpoussin@reactos.org> Message-Id: <20191106112341.23735-3-laurent@vivier.eu>
-rw-r--r--hw/net/dp8393x.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
index 85d3f3788e3..3d991af163f 100644
--- a/hw/net/dp8393x.c
+++ b/hw/net/dp8393x.c
@@ -831,9 +831,15 @@ static ssize_t dp8393x_receive(NetClientState *nc, const uint8_t * buf,
/* EOL detected */
s->regs[SONIC_ISR] |= SONIC_ISR_RDE;
} else {
- dp8393x_put(s, width, 0, 0); /* in_use */
- address_space_rw(&s->as, dp8393x_crda(s) + sizeof(uint16_t) * 6 * width,
- MEMTXATTRS_UNSPECIFIED, (uint8_t *)s->data, sizeof(uint16_t), 1);
+ /* Clear in_use, but it is always 16bit wide */
+ int offset = dp8393x_crda(s) + sizeof(uint16_t) * 6 * width;
+ if (s->big_endian && width == 2) {
+ /* we need to adjust the offset of the 16bit field */
+ offset += sizeof(uint16_t);
+ }
+ s->data[0] = 0;
+ address_space_rw(&s->as, offset, MEMTXATTRS_UNSPECIFIED,
+ (uint8_t *)s->data, sizeof(uint16_t), 1);
s->regs[SONIC_CRDA] = s->regs[SONIC_LLFA];
s->regs[SONIC_ISR] |= SONIC_ISR_PKTRX;
s->regs[SONIC_RSC] = (s->regs[SONIC_RSC] & 0xff00) | (((s->regs[SONIC_RSC] & 0x00ff) + 1) & 0x00ff);