summaryrefslogtreecommitdiffstats
path: root/hw/net/virtio-net.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/net/virtio-net.c')
-rw-r--r--hw/net/virtio-net.c81
1 files changed, 29 insertions, 52 deletions
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 3af6faf..012ab7f 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -435,7 +435,7 @@ static void virtio_net_set_queues(VirtIONet *n)
static void virtio_net_set_multiqueue(VirtIONet *n, int multiqueue);
-static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features)
+static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features)
{
VirtIONet *n = VIRTIO_NET(vdev);
NetClientState *nc = qemu_get_queue(n->nic);
@@ -468,9 +468,9 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features)
return vhost_net_get_features(get_vhost_net(nc->peer), features);
}
-static uint32_t virtio_net_bad_features(VirtIODevice *vdev)
+static uint64_t virtio_net_bad_features(VirtIODevice *vdev)
{
- uint32_t features = 0;
+ uint64_t features = 0;
/* Linux kernel 2.6.25. It understood MAC (as everyone must),
* but also these: */
@@ -1032,10 +1032,12 @@ static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t
if (i == 0)
return -1;
error_report("virtio-net unexpected empty queue: "
- "i %zd mergeable %d offset %zd, size %zd, "
- "guest hdr len %zd, host hdr len %zd guest features 0x%x",
- i, n->mergeable_rx_bufs, offset, size,
- n->guest_hdr_len, n->host_hdr_len, vdev->guest_features);
+ "i %zd mergeable %d offset %zd, size %zd, "
+ "guest hdr len %zd, host hdr len %zd "
+ "guest features 0x%" PRIx64,
+ i, n->mergeable_rx_bufs, offset, size,
+ n->guest_hdr_len, n->host_hdr_len,
+ vdev->guest_features);
exit(1);
}
@@ -1301,39 +1303,8 @@ static void virtio_net_tx_bh(void *opaque)
static void virtio_net_set_multiqueue(VirtIONet *n, int multiqueue)
{
- VirtIODevice *vdev = VIRTIO_DEVICE(n);
- int i, max = multiqueue ? n->max_queues : 1;
-
n->multiqueue = multiqueue;
- for (i = 2; i < n->max_queues * 2 + 1; i++) {
- virtio_del_queue(vdev, i);
- }
-
- for (i = 1; i < max; i++) {
- n->vqs[i].rx_vq = virtio_add_queue(vdev, 256, virtio_net_handle_rx);
- if (n->vqs[i].tx_timer) {
- n->vqs[i].tx_vq =
- virtio_add_queue(vdev, 256, virtio_net_handle_tx_timer);
- n->vqs[i].tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
- virtio_net_tx_timer,
- &n->vqs[i]);
- } else {
- n->vqs[i].tx_vq =
- virtio_add_queue(vdev, 256, virtio_net_handle_tx_bh);
- n->vqs[i].tx_bh = qemu_bh_new(virtio_net_tx_bh, &n->vqs[i]);
- }
-
- n->vqs[i].tx_waiting = 0;
- n->vqs[i].n = n;
- }
-
- /* Note: Minux Guests (version 3.2.1) use ctrl vq but don't ack
- * VIRTIO_NET_F_CTRL_VQ. Create ctrl vq unconditionally to avoid
- * breaking them.
- */
- n->ctrl_vq = virtio_add_queue(vdev, 64, virtio_net_handle_ctrl);
-
virtio_net_set_queues(n);
}
@@ -1549,7 +1520,7 @@ static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx,
vdev, idx, mask);
}
-static void virtio_net_set_config_size(VirtIONet *n, uint32_t host_features)
+static void virtio_net_set_config_size(VirtIONet *n, uint64_t host_features)
{
int i, config_size = 0;
virtio_add_feature(&host_features, VIRTIO_NET_F_MAC);
@@ -1586,17 +1557,15 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
virtio_init(vdev, "virtio-net", VIRTIO_ID_NET, n->config_size);
n->max_queues = MAX(n->nic_conf.peers.queues, 1);
- if (n->max_queues * 2 + 1 > VIRTIO_PCI_QUEUE_MAX) {
+ if (n->max_queues * 2 + 1 > VIRTIO_QUEUE_MAX) {
error_setg(errp, "Invalid number of queues (= %" PRIu32 "), "
"must be a positive integer less than %d.",
- n->max_queues, (VIRTIO_PCI_QUEUE_MAX - 1) / 2);
+ n->max_queues, (VIRTIO_QUEUE_MAX - 1) / 2);
virtio_cleanup(vdev);
return;
}
n->vqs = g_malloc0(sizeof(VirtIONetQueue) * n->max_queues);
- n->vqs[0].rx_vq = virtio_add_queue(vdev, 256, virtio_net_handle_rx);
n->curr_queues = 1;
- n->vqs[0].n = n;
n->tx_timeout = n->net_conf.txtimer;
if (n->net_conf.tx && strcmp(n->net_conf.tx, "timer")
@@ -1607,16 +1576,24 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
error_report("Defaulting to \"bh\"");
}
- if (n->net_conf.tx && !strcmp(n->net_conf.tx, "timer")) {
- n->vqs[0].tx_vq = virtio_add_queue(vdev, 256,
- virtio_net_handle_tx_timer);
- n->vqs[0].tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, virtio_net_tx_timer,
- &n->vqs[0]);
- } else {
- n->vqs[0].tx_vq = virtio_add_queue(vdev, 256,
- virtio_net_handle_tx_bh);
- n->vqs[0].tx_bh = qemu_bh_new(virtio_net_tx_bh, &n->vqs[0]);
+ for (i = 0; i < n->max_queues; i++) {
+ n->vqs[i].rx_vq = virtio_add_queue(vdev, 256, virtio_net_handle_rx);
+ if (n->net_conf.tx && !strcmp(n->net_conf.tx, "timer")) {
+ n->vqs[i].tx_vq =
+ virtio_add_queue(vdev, 256, virtio_net_handle_tx_timer);
+ n->vqs[i].tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
+ virtio_net_tx_timer,
+ &n->vqs[i]);
+ } else {
+ n->vqs[i].tx_vq =
+ virtio_add_queue(vdev, 256, virtio_net_handle_tx_bh);
+ n->vqs[i].tx_bh = qemu_bh_new(virtio_net_tx_bh, &n->vqs[i]);
+ }
+
+ n->vqs[i].tx_waiting = 0;
+ n->vqs[i].n = n;
}
+
n->ctrl_vq = virtio_add_queue(vdev, 64, virtio_net_handle_ctrl);
qemu_macaddr_default_if_unset(&n->nic_conf.macaddr);
memcpy(&n->mac[0], &n->nic_conf.macaddr, sizeof(n->mac));
OpenPOWER on IntegriCloud