Skip to content

Commit

Permalink
dp8393x: fix receiving buffer exhaustion
Browse files Browse the repository at this point in the history
The card is not able to exit from exhaustion state, because
while the drive consumes the buffers, the RRP is incremented
(when the driver clears the ISR RBE bit), so it stays equal
to RWP, and while RRP == RWP, the card thinks it is always
in exhaustion state. So the driver consumes all the buffers,
but the card cannot receive new ones.

This patch fixes the problem by not incrementing RRP when
the driver clears the ISR RBE bit.

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
  • Loading branch information
vivier committed Nov 28, 2019
1 parent b5a8355 commit 0a45280
Showing 1 changed file with 16 additions and 15 deletions.
31 changes: 16 additions & 15 deletions hw/net/dp8393x.c
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ static void dp8393x_do_load_cam(dp8393xState *s)
dp8393x_update_irq(s);
}

static void dp8393x_do_read_rra(dp8393xState *s)
static void dp8393x_do_read_rra(dp8393xState *s, int next)
{
int width, size;

Expand All @@ -323,19 +323,20 @@ static void dp8393x_do_read_rra(dp8393xState *s)
s->regs[SONIC_CRBA0], s->regs[SONIC_CRBA1],
s->regs[SONIC_RBWC0], s->regs[SONIC_RBWC1]);

/* Go to next entry */
s->regs[SONIC_RRP] += size;
if (next) {
/* Go to next entry */
s->regs[SONIC_RRP] += size;

/* Handle wrap */
if (s->regs[SONIC_RRP] == s->regs[SONIC_REA]) {
s->regs[SONIC_RRP] = s->regs[SONIC_RSA];
}
/* Handle wrap */
if (s->regs[SONIC_RRP] == s->regs[SONIC_REA]) {
s->regs[SONIC_RRP] = s->regs[SONIC_RSA];
}

/* Check resource exhaustion */
if (s->regs[SONIC_RRP] == s->regs[SONIC_RWP])
{
s->regs[SONIC_ISR] |= SONIC_ISR_RBE;
dp8393x_update_irq(s);
/* Check resource exhaustion */
if (s->regs[SONIC_RRP] == s->regs[SONIC_RWP]) {
s->regs[SONIC_ISR] |= SONIC_ISR_RBE;
dp8393x_update_irq(s);
}
}

/* Done */
Expand Down Expand Up @@ -549,7 +550,7 @@ static void dp8393x_do_command(dp8393xState *s, uint16_t command)
if (command & SONIC_CR_RST)
dp8393x_do_software_reset(s);
if (command & SONIC_CR_RRRA)
dp8393x_do_read_rra(s);
dp8393x_do_read_rra(s, 1);
if (command & SONIC_CR_LCAM)
dp8393x_do_load_cam(s);
}
Expand Down Expand Up @@ -640,7 +641,7 @@ static void dp8393x_write(void *opaque, hwaddr addr, uint64_t data,
data &= s->regs[reg];
s->regs[reg] &= ~data;
if (data & SONIC_ISR_RBE) {
dp8393x_do_read_rra(s);
dp8393x_do_read_rra(s, 0);
}
dp8393x_update_irq(s);
if (dp8393x_can_receive(s->nic->ncs)) {
Expand Down Expand Up @@ -846,7 +847,7 @@ static ssize_t dp8393x_receive(NetClientState *nc, const uint8_t * buf,

if (s->regs[SONIC_RCR] & SONIC_RCR_LPKT) {
/* Read next RRA */
dp8393x_do_read_rra(s);
dp8393x_do_read_rra(s, 1);
}
}

Expand Down

0 comments on commit 0a45280

Please sign in to comment.