From 1ef4a6069f8b4c09c3383cd4b8e27b6ff25b2d41 Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Wed, 15 Jul 2015 18:19:11 +0800 Subject: [PATCH] stellaris_enet: Flush queued packets when read done If s->np reaches 31, the queue will be disabled by peer when it sees stellaris_enet_can_receive() returns false, until we explicitly flushes it which notifies the peer. Do this when guest is done reading all existing data. Move the semantics to stellaris_enet_receive, by returning 0 when the buffer is full, so that new packets will be queued. In stellaris_enet_read, flush and restart the queue when guest has done reading. Signed-off-by: Fam Zheng Reviewed-by: Stefan Hajnoczi Reviewed-by: Jason Wang Message-id: 1436955553-22791-11-git-send-email-famz@redhat.com Signed-off-by: Stefan Hajnoczi --- hw/net/stellaris_enet.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/hw/net/stellaris_enet.c b/hw/net/stellaris_enet.c index 278a6545c3..21a47735d2 100644 --- a/hw/net/stellaris_enet.c +++ b/hw/net/stellaris_enet.c @@ -228,8 +228,7 @@ static ssize_t stellaris_enet_receive(NetClientState *nc, const uint8_t *buf, si if ((s->rctl & SE_RCTL_RXEN) == 0) return -1; if (s->np >= 31) { - DPRINTF("Packet dropped\n"); - return -1; + return 0; } DPRINTF("Received packet len=%zu\n", size); @@ -260,13 +259,8 @@ static ssize_t stellaris_enet_receive(NetClientState *nc, const uint8_t *buf, si return size; } -static int stellaris_enet_can_receive(NetClientState *nc) +static int stellaris_enet_can_receive(stellaris_enet_state *s) { - stellaris_enet_state *s = qemu_get_nic_opaque(nc); - - if ((s->rctl & SE_RCTL_RXEN) == 0) - return 1; - return (s->np < 31); } @@ -307,6 +301,9 @@ static uint64_t stellaris_enet_read(void *opaque, hwaddr offset, s->next_packet = 0; s->np--; DPRINTF("RX done np=%d\n", s->np); + if (!s->np && stellaris_enet_can_receive(s)) { + qemu_flush_queued_packets(qemu_get_queue(s->nic)); + } } return val; } @@ -454,7 +451,6 @@ static void stellaris_enet_reset(stellaris_enet_state *s) static NetClientInfo net_stellaris_enet_info = { .type = NET_CLIENT_OPTIONS_KIND_NIC, .size = sizeof(NICState), - .can_receive = stellaris_enet_can_receive, .receive = stellaris_enet_receive, };