@@ -784,12 +784,13 @@ static ssize_t dp8393x_receive(NetClientState *nc, const uint8_t * buf,
address = dp8393x_crda(s) + sizeof(uint16_t) * 5 * width;
address_space_rw(&s->as, address, MEMTXATTRS_UNSPECIFIED,
(uint8_t *)s->data, size, 0);
- if (dp8393x_get(s, width, 0) & SONIC_DESC_EOL) {
+ s->regs[SONIC_LLFA] = dp8393x_get(s, width, 0);
+ if (s->regs[SONIC_LLFA] & SONIC_DESC_EOL) {
/* Still EOL ; stop reception */
return -1;
- } else {
- s->regs[SONIC_CRDA] = s->regs[SONIC_LLFA];
}
+ /* Link has been updated by host */
+ s->regs[SONIC_CRDA] = s->regs[SONIC_LLFA];
}
/* Save current position */
@@ -837,7 +838,7 @@ static ssize_t dp8393x_receive(NetClientState *nc, const uint8_t * buf,
address_space_rw(&s->as, dp8393x_crda(s),
MEMTXATTRS_UNSPECIFIED, (uint8_t *)s->data, size, 1);
- /* Move to next descriptor */
+ /* Check link field */
size = sizeof(uint16_t) * width;
address_space_rw(&s->as, dp8393x_crda(s) + sizeof(uint16_t) * 5 * width,
MEMTXATTRS_UNSPECIFIED, (uint8_t *)s->data, size, 0);
@@ -852,6 +853,8 @@ static ssize_t dp8393x_receive(NetClientState *nc, const uint8_t * buf,
dp8393x_put(s, width, 0, 0);
address_space_rw(&s->as, address, MEMTXATTRS_UNSPECIFIED,
(uint8_t *)s->data, size, 1);
+
+ /* Move to next descriptor */
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);