aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/virtio-net.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 4bc111422a..4b09a930ef 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -367,12 +367,19 @@ static void virtio_net_handle_rx(VirtIODevice *vdev, VirtQueue *vq)
qemu_notify_event();
}
-static int do_virtio_net_can_receive(VirtIONet *n, int bufsize)
+static int virtio_net_can_receive(VLANClientState *vc)
{
+ VirtIONet *n = vc->opaque;
+
if (!virtio_queue_ready(n->rx_vq) ||
!(n->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK))
return 0;
+ return 1;
+}
+
+static int virtio_net_has_buffers(VirtIONet *n, int bufsize)
+{
if (virtio_queue_empty(n->rx_vq) ||
(n->mergeable_rx_bufs &&
!virtqueue_avail_bytes(n->rx_vq, bufsize, 0))) {
@@ -384,13 +391,6 @@ static int do_virtio_net_can_receive(VirtIONet *n, int bufsize)
return 1;
}
-static int virtio_net_can_receive(VLANClientState *vc)
-{
- VirtIONet *n = vc->opaque;
-
- return do_virtio_net_can_receive(n, VIRTIO_NET_MAX_BUFSIZE);
-}
-
/* dhclient uses AF_PACKET but doesn't pass auxdata to the kernel so
* it never finds out that the packets don't have valid checksums. This
* causes dhclient to get upset. Fedora's carried a patch for ages to
@@ -517,7 +517,10 @@ static ssize_t virtio_net_receive(VLANClientState *vc, const uint8_t *buf, size_
struct virtio_net_hdr_mrg_rxbuf *mhdr = NULL;
size_t hdr_len, offset, i;
- if (!do_virtio_net_can_receive(n, size))
+ if (!virtio_net_can_receive(n->vc))
+ return -1;
+
+ if (!virtio_net_has_buffers(n, size))
return 0;
if (!receive_filter(n, buf, size))