Skip to content

Commit

Permalink
dp8393x: fix dp8393x_receive()
Browse files Browse the repository at this point in the history
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: be92084 ("dp8393x: manage big endian bus")
Signed-off-by: Laurent Vivier <[email protected]>
Tested-by: Hervé Poussineau <[email protected]>
Message-Id: <[email protected]>
  • Loading branch information
vivier committed Nov 8, 2019
1 parent af9f0be commit c744cf7
Showing 1 changed file with 9 additions and 3 deletions.
12 changes: 9 additions & 3 deletions hw/net/dp8393x.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit c744cf7

Please sign in to comment.