Le 02/11/2019 à 18:15, Laurent Vivier a écrit : > 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 <laur...@vivier.eu> > --- > hw/net/dp8393x.c | 31 ++++++++++++++++--------------- > 1 file changed, 16 insertions(+), 15 deletions(-)
For reviewers, this patch main changes (without indentation changes) can be simplified to: diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c index b8c4473f99..123d110f16 100644 --- a/hw/net/dp8393x.c +++ b/hw/net/dp8393x.c @@ -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; @@ -323,6 +323,7 @@ static void dp8393x_do_read_rra(dp8393xState *s) s->regs[SONIC_CRBA0], s->regs[SONIC_CRBA1], s->regs[SONIC_RBWC0], s->regs[SONIC_RBWC1]); + if (next) { /* Go to next entry */ s->regs[SONIC_RRP] += size; @@ -337,6 +338,7 @@ static void dp8393x_do_read_rra(dp8393xState *s) s->regs[SONIC_ISR] |= SONIC_ISR_RBE; dp8393x_update_irq(s); } + } /* Done */ s->regs[SONIC_CR] &= ~SONIC_CR_RRRA; @@ -549,7 +551,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); } @@ -640,7 +642,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)) { @@ -840,7 +842,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); } }