diff options
-rwxr-xr-x | configure | 19 | ||||
-rw-r--r-- | hw/audio/hda-codec.c | 60 | ||||
-rw-r--r-- | hw/display/qxl.c | 8 | ||||
-rw-r--r-- | hw/microblaze/petalogix_ml605_mmu.c | 55 | ||||
-rw-r--r-- | hw/microblaze/petalogix_s3adsp1800_mmu.c | 35 | ||||
-rw-r--r-- | hw/net/vhost_net.c | 6 | ||||
-rw-r--r-- | hw/net/virtio-net.c | 16 | ||||
-rw-r--r-- | hw/net/vmxnet3.c | 22 | ||||
-rw-r--r-- | hw/ppc/virtex_ml507.c | 29 | ||||
-rw-r--r-- | include/hw/xilinx.h | 90 | ||||
-rw-r--r-- | include/net/net.h | 19 | ||||
-rw-r--r-- | include/net/tap.h | 6 | ||||
-rw-r--r-- | net/net.c | 55 | ||||
-rw-r--r-- | net/netmap.c | 123 | ||||
-rw-r--r-- | net/tap-win32.c | 92 | ||||
-rw-r--r-- | net/tap.c | 20 | ||||
-rw-r--r-- | util/module.c | 2 |
17 files changed, 388 insertions, 269 deletions
@@ -1424,6 +1424,9 @@ if compile_prog "-Werror -fno-gcse" "" ; then fi if test "$static" = "yes" ; then + if test "$modules" = "yes" ; then + error_exit "static and modules are mutually incompatible" + fi if test "$pie" = "yes" ; then error_exit "static and pie are mutually incompatible" else @@ -2246,13 +2249,21 @@ EOF fi ########################################## -# netmap headers probe +# netmap support probe +# Apart from looking for netmap headers, we make sure that the host API version +# supports the netmap backend (>=11). The upper bound (15) is meant to simulate +# a minor/major version number. Minor new features will be marked with values up +# to 15, and if something happens that requires a change to the backend we will +# move above 15, submit the backend fixes and modify this two bounds. if test "$netmap" != "no" ; then cat > $TMPC << EOF #include <inttypes.h> #include <net/if.h> #include <net/netmap.h> #include <net/netmap_user.h> +#if (NETMAP_API < 11) || (NETMAP_API > 15) +#error +#endif int main(void) { return 0; } EOF if compile_prog "" "" ; then @@ -2483,8 +2494,12 @@ if test "$mingw32" = yes; then else glib_req_ver=2.12 fi +glib_modules=gthread-2.0 +if test "$modules" = yes; then + glib_modules="$glib_modules gmodule-2.0" +fi -for i in gthread-2.0 gmodule-2.0; do +for i in $glib_modules; do if $pkg_config --atleast-version=$glib_req_ver $i; then glib_cflags=`$pkg_config --cflags $i` glib_libs=`$pkg_config --libs $i` diff --git a/hw/audio/hda-codec.c b/hw/audio/hda-codec.c index 986f2a9..a67ca91 100644 --- a/hw/audio/hda-codec.c +++ b/hw/audio/hda-codec.c @@ -157,6 +157,9 @@ struct HDAAudioStream { uint32_t bpos; }; +#define TYPE_HDA_AUDIO "hda-audio" +#define HDA_AUDIO(obj) OBJECT_CHECK(HDAAudioState, (obj), TYPE_HDA_AUDIO) + struct HDAAudioState { HDACodecDevice hda; const char *name; @@ -288,7 +291,7 @@ static void hda_audio_setup(HDAAudioStream *st) static void hda_audio_command(HDACodecDevice *hda, uint32_t nid, uint32_t data) { - HDAAudioState *a = DO_UPCAST(HDAAudioState, hda, hda); + HDAAudioState *a = HDA_AUDIO(hda); HDAAudioStream *st; const desc_node *node = NULL; const desc_param *param; @@ -448,7 +451,7 @@ fail: static void hda_audio_stream(HDACodecDevice *hda, uint32_t stnr, bool running, bool output) { - HDAAudioState *a = DO_UPCAST(HDAAudioState, hda, hda); + HDAAudioState *a = HDA_AUDIO(hda); int s; a->running_compat[stnr] = running; @@ -469,7 +472,7 @@ static void hda_audio_stream(HDACodecDevice *hda, uint32_t stnr, bool running, b static int hda_audio_init(HDACodecDevice *hda, const struct desc_codec *desc) { - HDAAudioState *a = DO_UPCAST(HDAAudioState, hda, hda); + HDAAudioState *a = HDA_AUDIO(hda); HDAAudioStream *st; const desc_node *node; const desc_param *param; @@ -514,7 +517,7 @@ static int hda_audio_init(HDACodecDevice *hda, const struct desc_codec *desc) static int hda_audio_exit(HDACodecDevice *hda) { - HDAAudioState *a = DO_UPCAST(HDAAudioState, hda, hda); + HDAAudioState *a = HDA_AUDIO(hda); HDAAudioStream *st; int i; @@ -561,7 +564,7 @@ static int hda_audio_post_load(void *opaque, int version) static void hda_audio_reset(DeviceState *dev) { - HDAAudioState *a = DO_UPCAST(HDAAudioState, hda.qdev, dev); + HDAAudioState *a = HDA_AUDIO(dev); HDAAudioStream *st; int i; @@ -613,7 +616,7 @@ static Property hda_audio_properties[] = { static int hda_audio_init_output(HDACodecDevice *hda) { - HDAAudioState *a = DO_UPCAST(HDAAudioState, hda, hda); + HDAAudioState *a = HDA_AUDIO(hda); if (!a->mixer) { return hda_audio_init(hda, &output_nomixemu); @@ -624,7 +627,7 @@ static int hda_audio_init_output(HDACodecDevice *hda) static int hda_audio_init_duplex(HDACodecDevice *hda) { - HDAAudioState *a = DO_UPCAST(HDAAudioState, hda, hda); + HDAAudioState *a = HDA_AUDIO(hda); if (!a->mixer) { return hda_audio_init(hda, &duplex_nomixemu); @@ -635,7 +638,7 @@ static int hda_audio_init_duplex(HDACodecDevice *hda) static int hda_audio_init_micro(HDACodecDevice *hda) { - HDAAudioState *a = DO_UPCAST(HDAAudioState, hda, hda); + HDAAudioState *a = HDA_AUDIO(hda); if (!a->mixer) { return hda_audio_init(hda, µ_nomixemu); @@ -644,25 +647,39 @@ static int hda_audio_init_micro(HDACodecDevice *hda) } } -static void hda_audio_output_class_init(ObjectClass *klass, void *data) +static void hda_audio_base_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass); - k->init = hda_audio_init_output; k->exit = hda_audio_exit; k->command = hda_audio_command; k->stream = hda_audio_stream; set_bit(DEVICE_CATEGORY_SOUND, dc->categories); - dc->desc = "HDA Audio Codec, output-only (line-out)"; dc->reset = hda_audio_reset; dc->vmsd = &vmstate_hda_audio; dc->props = hda_audio_properties; } +static const TypeInfo hda_audio_info = { + .name = TYPE_HDA_AUDIO, + .parent = TYPE_HDA_CODEC_DEVICE, + .class_init = hda_audio_base_class_init, + .abstract = true, +}; + +static void hda_audio_output_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass); + + k->init = hda_audio_init_output; + dc->desc = "HDA Audio Codec, output-only (line-out)"; +} + static const TypeInfo hda_audio_output_info = { .name = "hda-output", - .parent = TYPE_HDA_CODEC_DEVICE, + .parent = TYPE_HDA_AUDIO, .instance_size = sizeof(HDAAudioState), .class_init = hda_audio_output_class_init, }; @@ -673,19 +690,12 @@ static void hda_audio_duplex_class_init(ObjectClass *klass, void *data) HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass); k->init = hda_audio_init_duplex; - k->exit = hda_audio_exit; - k->command = hda_audio_command; - k->stream = hda_audio_stream; - set_bit(DEVICE_CATEGORY_SOUND, dc->categories); dc->desc = "HDA Audio Codec, duplex (line-out, line-in)"; - dc->reset = hda_audio_reset; - dc->vmsd = &vmstate_hda_audio; - dc->props = hda_audio_properties; } static const TypeInfo hda_audio_duplex_info = { .name = "hda-duplex", - .parent = TYPE_HDA_CODEC_DEVICE, + .parent = TYPE_HDA_AUDIO, .instance_size = sizeof(HDAAudioState), .class_init = hda_audio_duplex_class_init, }; @@ -696,25 +706,19 @@ static void hda_audio_micro_class_init(ObjectClass *klass, void *data) HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass); k->init = hda_audio_init_micro; - k->exit = hda_audio_exit; - k->command = hda_audio_command; - k->stream = hda_audio_stream; - set_bit(DEVICE_CATEGORY_SOUND, dc->categories); dc->desc = "HDA Audio Codec, duplex (speaker, microphone)"; - dc->reset = hda_audio_reset; - dc->vmsd = &vmstate_hda_audio; - dc->props = hda_audio_properties; } static const TypeInfo hda_audio_micro_info = { .name = "hda-micro", - .parent = TYPE_HDA_CODEC_DEVICE, + .parent = TYPE_HDA_AUDIO, .instance_size = sizeof(HDAAudioState), .class_init = hda_audio_micro_class_init, }; static void hda_audio_register_types(void) { + type_register_static(&hda_audio_info); type_register_static(&hda_audio_output_info); type_register_static(&hda_audio_duplex_info); type_register_static(&hda_audio_micro_info); diff --git a/hw/display/qxl.c b/hw/display/qxl.c index 1471cc0..2a559eb 100644 --- a/hw/display/qxl.c +++ b/hw/display/qxl.c @@ -1429,7 +1429,7 @@ static int qxl_destroy_primary(PCIQXLDevice *d, qxl_async_io async) return 1; } -static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm) +static void qxl_set_mode(PCIQXLDevice *d, unsigned int modenr, int loadvm) { pcibus_t start = d->pci.io_regions[QXL_RAM_RANGE_INDEX].addr; pcibus_t end = d->pci.io_regions[QXL_RAM_RANGE_INDEX].size + start; @@ -1439,6 +1439,12 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm) .mem_start = start, .mem_end = end }; + + if (modenr >= d->modes->n_modes) { + qxl_set_guest_bug(d, "mode number out of range"); + return; + } + QXLSurfaceCreate surface = { .width = mode->x_res, .height = mode->y_res, diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c index 37cbbfd..40a9f5c 100644 --- a/hw/microblaze/petalogix_ml605_mmu.c +++ b/hw/microblaze/petalogix_ml605_mmu.c @@ -32,7 +32,6 @@ #include "sysemu/sysemu.h" #include "hw/devices.h" #include "hw/boards.h" -#include "hw/xilinx.h" #include "sysemu/blockdev.h" #include "hw/char/serial.h" #include "exec/address-spaces.h" @@ -49,6 +48,7 @@ #define NUM_SPI_FLASHES 4 +#define SPI_BASEADDR 0x40a00000 #define MEMORY_BASEADDR 0x50000000 #define FLASH_BASEADDR 0x86000000 #define INTC_BASEADDR 0x81800000 @@ -57,6 +57,13 @@ #define AXIENET_BASEADDR 0x82780000 #define AXIDMA_BASEADDR 0x84600000 +#define AXIDMA_IRQ1 0 +#define AXIDMA_IRQ0 1 +#define TIMER_IRQ 2 +#define AXIENET_IRQ 3 +#define SPI_IRQ 4 +#define UART16550_IRQ 5 + static void machine_cpu_reset(MicroBlazeCPU *cpu) { CPUMBState *env = &cpu->env; @@ -111,17 +118,27 @@ petalogix_ml605_init(QEMUMachineInitArgs *args) 2, 0x89, 0x18, 0x0000, 0x0, 0); - dev = xilinx_intc_create(INTC_BASEADDR, qdev_get_gpio_in(DEVICE(cpu), - MB_CPU_IRQ), 4); + dev = qdev_create(NULL, "xlnx.xps-intc"); + qdev_prop_set_uint32(dev, "kind-of-intr", 1 << TIMER_IRQ); + qdev_init_nofail(dev); + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, INTC_BASEADDR); + sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, + qdev_get_gpio_in(DEVICE(cpu), MB_CPU_IRQ)); for (i = 0; i < 32; i++) { irq[i] = qdev_get_gpio_in(dev, i); } serial_mm_init(address_space_mem, UART16550_BASEADDR + 0x1000, 2, - irq[5], 115200, serial_hds[0], DEVICE_LITTLE_ENDIAN); + irq[UART16550_IRQ], 115200, serial_hds[0], + DEVICE_LITTLE_ENDIAN); /* 2 timers at irq 2 @ 100 Mhz. */ - xilinx_timer_create(TIMER_BASEADDR, irq[2], 0, 100 * 1000000); + dev = qdev_create(NULL, "xlnx.xps-timer"); + qdev_prop_set_uint32(dev, "one-timer-only", 0); + qdev_prop_set_uint32(dev, "clock-frequency", 100 * 1000000); + qdev_init_nofail(dev); + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, TIMER_BASEADDR); + sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[TIMER_IRQ]); /* axi ethernet and dma initialization. */ qemu_check_nic_model(&nd_table[0], "xlnx.axi-ethernet"); @@ -138,16 +155,30 @@ petalogix_ml605_init(QEMUMachineInitArgs *args) "axistream-connected-target", NULL); cs = object_property_get_link(OBJECT(dma), "axistream-control-connected-target", NULL); - xilinx_axiethernet_init(eth0, &nd_table[0], STREAM_SLAVE(ds), - STREAM_SLAVE(cs), 0x82780000, irq[3], 0x1000, - 0x1000); + qdev_set_nic_properties(eth0, &nd_table[0]); + qdev_prop_set_uint32(eth0, "rxmem", 0x1000); + qdev_prop_set_uint32(eth0, "txmem", 0x1000); + object_property_set_link(OBJECT(eth0), OBJECT(ds), + "axistream-connected", &error_abort); + object_property_set_link(OBJECT(eth0), OBJECT(cs), + "axistream-control-connected", &error_abort); + qdev_init_nofail(eth0); + sysbus_mmio_map(SYS_BUS_DEVICE(eth0), 0, AXIENET_BASEADDR); + sysbus_connect_irq(SYS_BUS_DEVICE(eth0), 0, irq[AXIENET_IRQ]); ds = object_property_get_link(OBJECT(eth0), "axistream-connected-target", NULL); cs = object_property_get_link(OBJECT(eth0), "axistream-control-connected-target", NULL); - xilinx_axidma_init(dma, STREAM_SLAVE(ds), STREAM_SLAVE(cs), 0x84600000, - irq[1], irq[0], 100 * 1000000); + qdev_prop_set_uint32(dma, "freqhz", 100 * 1000000); + object_property_set_link(OBJECT(dma), OBJECT(ds), + "axistream-connected", &error_abort); + object_property_set_link(OBJECT(dma), OBJECT(cs), + "axistream-control-connected", &error_abort); + qdev_init_nofail(dma); + sysbus_mmio_map(SYS_BUS_DEVICE(dma), 0, AXIDMA_BASEADDR); + sysbus_connect_irq(SYS_BUS_DEVICE(dma), 0, irq[AXIDMA_IRQ0]); + sysbus_connect_irq(SYS_BUS_DEVICE(dma), 1, irq[AXIDMA_IRQ1]); { SSIBus *spi; @@ -156,8 +187,8 @@ petalogix_ml605_init(QEMUMachineInitArgs *args) qdev_prop_set_uint8(dev, "num-ss-bits", NUM_SPI_FLASHES); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); - sysbus_mmio_map(busdev, 0, 0x40a00000); - sysbus_connect_irq(busdev, 0, irq[4]); + sysbus_mmio_map(busdev, 0, SPI_BASEADDR); + sysbus_connect_irq(busdev, 0, irq[SPI_IRQ]); spi = (SSIBus *)qdev_get_child_bus(dev, "spi"); diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c index f500215..6c45e20 100644 --- a/hw/microblaze/petalogix_s3adsp1800_mmu.c +++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c @@ -30,7 +30,6 @@ #include "sysemu/sysemu.h" #include "hw/devices.h" #include "hw/boards.h" -#include "hw/xilinx.h" #include "sysemu/blockdev.h" #include "exec/address-spaces.h" @@ -48,6 +47,10 @@ #define UARTLITE_BASEADDR 0x84000000 #define ETHLITE_BASEADDR 0x81000000 +#define TIMER_IRQ 0 +#define ETHLITE_IRQ 1 +#define UARTLITE_IRQ 3 + static void machine_cpu_reset(MicroBlazeCPU *cpu) { CPUMBState *env = &cpu->env; @@ -93,16 +96,36 @@ petalogix_s3adsp1800_init(QEMUMachineInitArgs *args) FLASH_SIZE >> 16, 1, 0x89, 0x18, 0x0000, 0x0, 1); - dev = xilinx_intc_create(INTC_BASEADDR, qdev_get_gpio_in(DEVICE(cpu), - MB_CPU_IRQ), 0xA); + dev = qdev_create(NULL, "xlnx.xps-intc"); + qdev_prop_set_uint32(dev, "kind-of-intr", + 1 << ETHLITE_IRQ | 1 << UARTLITE_IRQ); + qdev_init_nofail(dev); + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, INTC_BASEADDR); + sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, + qdev_get_gpio_in(DEVICE(cpu), MB_CPU_IRQ)); for (i = 0; i < 32; i++) { irq[i] = qdev_get_gpio_in(dev, i); } - sysbus_create_simple("xlnx.xps-uartlite", UARTLITE_BASEADDR, irq[3]); + sysbus_create_simple("xlnx.xps-uartlite", UARTLITE_BASEADDR, + irq[UARTLITE_IRQ]); + /* 2 timers at irq 2 @ 62 Mhz. */ - xilinx_timer_create(TIMER_BASEADDR, irq[0], 0, 62 * 1000000); - xilinx_ethlite_create(&nd_table[0], ETHLITE_BASEADDR, irq[1], 0, 0); + dev = qdev_create(NULL, "xlnx.xps-timer"); + qdev_prop_set_uint32(dev, "one-timer-only", 0); + qdev_prop_set_uint32(dev, "clock-frequency", 62 * 1000000); + qdev_init_nofail(dev); + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, TIMER_BASEADDR); + sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[TIMER_IRQ]); + + qemu_check_nic_model(&nd_table[0], "xlnx.xps-ethernetlite"); + dev = qdev_create(NULL, "xlnx.xps-ethernetlite"); + qdev_set_nic_properties(dev, &nd_table[0]); + qdev_prop_set_uint32(dev, "tx-ping-pong", 0); + qdev_prop_set_uint32(dev, "rx-ping-pong", 0); + qdev_init_nofail(dev); + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, ETHLITE_BASEADDR); + sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[ETHLITE_IRQ]); microblaze_load_kernel(cpu, ddr_base, ram_size, args->initrd_filename, diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index 854997d..a1de2f4 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -106,7 +106,7 @@ struct vhost_net *vhost_net_init(NetClientState *backend, int devfd, goto fail; } net->nc = backend; - net->dev.backend_features = tap_has_vnet_hdr(backend) ? 0 : + net->dev.backend_features = qemu_has_vnet_hdr(backend) ? 0 : (1 << VHOST_NET_F_VIRTIO_NET_HDR); net->backend = r; @@ -117,8 +117,8 @@ struct vhost_net *vhost_net_init(NetClientState *backend, int devfd, if (r < 0) { goto fail; } - if (!tap_has_vnet_hdr_len(backend, - sizeof(struct virtio_net_hdr_mrg_rxbuf))) { + if (!qemu_has_vnet_hdr_len(backend, + sizeof(struct virtio_net_hdr_mrg_rxbuf))) { net->dev.features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF); } if (~net->dev.features & net->dev.backend_features) { diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 3626608..3c0342e 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -325,11 +325,7 @@ static void peer_test_vnet_hdr(VirtIONet *n) return; } - if (nc->peer->info->type != NET_CLIENT_OPTIONS_KIND_TAP) { - return; - } - - n->has_vnet_hdr = tap_has_vnet_hdr(nc->peer); + n->has_vnet_hdr = qemu_has_vnet_hdr(nc->peer); } static int peer_has_vnet_hdr(VirtIONet *n) @@ -342,7 +338,7 @@ static int peer_has_ufo(VirtIONet *n) if (!peer_has_vnet_hdr(n)) return 0; - n->has_ufo = tap_has_ufo(qemu_get_queue(n->nic)->peer); + n->has_ufo = qemu_has_ufo(qemu_get_queue(n->nic)->peer); return n->has_ufo; } @@ -361,8 +357,8 @@ static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs) nc = qemu_get_subqueue(n->nic, i); if (peer_has_vnet_hdr(n) && - tap_has_vnet_hdr_len(nc->peer, n->guest_hdr_len)) { - tap_set_vnet_hdr_len(nc->peer, n->guest_hdr_len); + qemu_has_vnet_hdr_len(nc->peer, n->guest_hdr_len)) { + qemu_set_vnet_hdr_len(nc->peer, n->guest_hdr_len); n->host_hdr_len = n->guest_hdr_len; } } @@ -463,7 +459,7 @@ static uint32_t virtio_net_bad_features(VirtIODevice *vdev) static void virtio_net_apply_guest_offloads(VirtIONet *n) { - tap_set_offload(qemu_get_subqueue(n->nic, 0)->peer, + qemu_set_offload(qemu_get_queue(n->nic)->peer, !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_CSUM)), !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO4)), !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO6)), @@ -1544,7 +1540,7 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp) peer_test_vnet_hdr(n); if (peer_has_vnet_hdr(n)) { for (i = 0; i < n->max_queues; i++) { - tap_using_vnet_hdr(qemu_get_subqueue(n->nic, i)->peer, true); + qemu_using_vnet_hdr(qemu_get_subqueue(n->nic, i)->peer, true); } n->host_hdr_len = sizeof(struct virtio_net_hdr); } else { diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 19687aa..5be807c 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -1290,12 +1290,12 @@ static void vmxnet3_update_features(VMXNET3State *s) s->lro_supported, rxcso_supported, s->rx_vlan_stripping); if (s->peer_has_vhdr) { - tap_set_offload(qemu_get_queue(s->nic)->peer, - rxcso_supported, - s->lro_supported, - s->lro_supported, - 0, - 0); + qemu_set_offload(qemu_get_queue(s->nic)->peer, + rxcso_supported, + s->lro_supported, + s->lro_supported, + 0, + 0); } } @@ -1883,11 +1883,9 @@ static NetClientInfo net_vmxnet3_info = { static bool vmxnet3_peer_has_vnet_hdr(VMXNET3State *s) { - NetClientState *peer = qemu_get_queue(s->nic)->peer; + NetClientState *nc = qemu_get_queue(s->nic); - if ((NULL != peer) && - (peer->info->type == NET_CLIENT_OPTIONS_KIND_TAP) && - tap_has_vnet_hdr(peer)) { + if (qemu_has_vnet_hdr(nc->peer)) { return true; } @@ -1935,10 +1933,10 @@ static void vmxnet3_net_init(VMXNET3State *s) s->lro_supported = false; if (s->peer_has_vhdr) { - tap_set_vnet_hdr_len(qemu_get_queue(s->nic)->peer, + qemu_set_vnet_hdr_len(qemu_get_queue(s->nic)->peer, sizeof(struct virtio_net_hdr)); - tap_using_vnet_hdr(qemu_get_queue(s->nic)->peer, 1); + qemu_using_vnet_hdr(qemu_get_queue(s->nic)->peer, 1); } qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c index bdb057e..85a0e53 100644 --- a/hw/ppc/virtex_ml507.c +++ b/hw/ppc/virtex_ml507.c @@ -40,11 +40,19 @@ #include "ppc405.h" #include "sysemu/blockdev.h" -#include "hw/xilinx.h" +#include "qapi/qmp/qerror.h" #define EPAPR_MAGIC (0x45504150) #define FLASH_SIZE (16 * 1024 * 1024) +#define INTC_BASEADDR 0x81800000 +#define UART16550_BASEADDR 0x83e01003 +#define TIMER_BASEADDR 0x83c00000 +#define PFLASH_BASEADDR 0xfc000000 + +#define TIMER_IRQ 3 +#define UART16550_IRQ 9 + static struct boot_info { uint32_t bootstrap_pc; @@ -204,22 +212,31 @@ static void virtex_init(QEMUMachineInitArgs *args) memory_region_add_subregion(address_space_mem, ram_base, phys_ram); dinfo = drive_get(IF_PFLASH, 0, 0); - pflash_cfi01_register(0xfc000000, NULL, "virtex.flash", FLASH_SIZE, + pflash_cfi01_register(PFLASH_BASEADDR, NULL, "virtex.flash", FLASH_SIZE, dinfo ? dinfo->bdrv : NULL, (64 * 1024), FLASH_SIZE >> 16, 1, 0x89, 0x18, 0x0000, 0x0, 1); cpu_irq = (qemu_irq *) &env->irq_inputs[PPC40x_INPUT_INT]; - dev = xilinx_intc_create(0x81800000, cpu_irq[0], 0); + dev = qdev_create(NULL, "xlnx.xps-intc"); + qdev_prop_set_uint32(dev, "kind-of-intr", 0); + qdev_init_nofail(dev); + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, INTC_BASEADDR); + sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, cpu_irq[0]); for (i = 0; i < 32; i++) { irq[i] = qdev_get_gpio_in(dev, i); } - serial_mm_init(address_space_mem, 0x83e01003ULL, 2, irq[9], 115200, - serial_hds[0], DEVICE_LITTLE_ENDIAN); + serial_mm_init(address_space_mem, UART16550_BASEADDR, 2, irq[UART16550_IRQ], + 115200, serial_hds[0], DEVICE_LITTLE_ENDIAN); /* 2 timers at irq 2 @ 62 Mhz. */ - xilinx_timer_create(0x83c00000, irq[3], 0, 62 * 1000000); + dev = qdev_create(NULL, "xlnx.xps-timer"); + qdev_prop_set_uint32(dev, "one-timer-only", 0); + qdev_prop_set_uint32(dev, "clock-frequency", 62 * 1000000); + qdev_init_nofail(dev); + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, TIMER_BASEADDR); + sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[TIMER_IRQ]); if (kernel_filename) { uint64_t entry, low, high; diff --git a/include/hw/xilinx.h b/include/hw/xilinx.h deleted file mode 100644 index 9d6debe..0000000 --- a/include/hw/xilinx.h +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef HW_XILINX_H -#define HW_XILINX_H 1 - - -#include "qemu-common.h" -#include "qapi/qmp/qerror.h" -#include "hw/stream.h" -#include "net/net.h" - -static inline DeviceState * -xilinx_intc_create(hwaddr base, qemu_irq irq, int kind_of_intr) -{ - DeviceState *dev; - - dev = qdev_create(NULL, "xlnx.xps-intc"); - qdev_prop_set_uint32(dev, "kind-of-intr", kind_of_intr); - qdev_init_nofail(dev); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq); - return dev; -} - -/* OPB Timer/Counter. */ -static inline DeviceState * -xilinx_timer_create(hwaddr base, qemu_irq irq, int oto, int freq) -{ - DeviceState *dev; - - dev = qdev_create(NULL, "xlnx.xps-timer"); - qdev_prop_set_uint32(dev, "one-timer-only", oto); - qdev_prop_set_uint32(dev, "clock-frequency", freq); - qdev_init_nofail(dev); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq); - return dev; -} - -/* XPS Ethernet Lite MAC. */ -static inline DeviceState * -xilinx_ethlite_create(NICInfo *nd, hwaddr base, qemu_irq irq, - int txpingpong, int rxpingpong) -{ - DeviceState *dev; - - qemu_check_nic_model(nd, "xlnx.xps-ethernetlite"); - - dev = qdev_create(NULL, "xlnx.xps-ethernetlite"); - qdev_set_nic_properties(dev, nd); - qdev_prop_set_uint32(dev, "tx-ping-pong", txpingpong); - qdev_prop_set_uint32(dev, "rx-ping-pong", rxpingpong); - qdev_init_nofail(dev); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq); - return dev; -} - -static inline void -xilinx_axiethernet_init(DeviceState *dev, NICInfo *nd, StreamSlave *ds, - StreamSlave *cs, hwaddr base, qemu_irq irq, int txmem, - int rxmem) -{ - qdev_set_nic_properties(dev, nd); - qdev_prop_set_uint32(dev, "rxmem", rxmem); - qdev_prop_set_uint32(dev, "txmem", txmem); - object_property_set_link(OBJECT(dev), OBJECT(ds), - "axistream-connected", &error_abort); - object_property_set_link(OBJECT(dev), OBJECT(cs), - "axistream-control-connected", &error_abort); - qdev_init_nofail(dev); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq); -} - -static inline void -xilinx_axidma_init(DeviceState *dev, StreamSlave *ds, StreamSlave *cs, - hwaddr base, qemu_irq irq, qemu_irq irq2, int freqhz) -{ - qdev_prop_set_uint32(dev, "freqhz", freqhz); - object_property_set_link(OBJECT(dev), OBJECT(ds), - "axistream-connected", &error_abort); - object_property_set_link(OBJECT(dev), OBJECT(cs), - "axistream-control-connected", &error_abort); - qdev_init_nofail(dev); - - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, irq2); -} - -#endif diff --git a/include/net/net.h b/include/net/net.h index 11e1468..8166345 100644 --- a/include/net/net.h +++ b/include/net/net.h @@ -50,6 +50,12 @@ typedef void (NetCleanup) (NetClientState *); typedef void (LinkStatusChanged)(NetClientState *); typedef void (NetClientDestructor)(NetClientState *); typedef RxFilterInfo *(QueryRxFilter)(NetClientState *); +typedef bool (HasUfo)(NetClientState *); +typedef bool (HasVnetHdr)(NetClientState *); +typedef bool (HasVnetHdrLen)(NetClientState *, int); +typedef void (UsingVnetHdr)(NetClientState *, bool); +typedef void (SetOffload)(NetClientState *, int, int, int, int, int); +typedef void (SetVnetHdrLen)(NetClientState *, int); typedef struct NetClientInfo { NetClientOptionsKind type; @@ -62,6 +68,12 @@ typedef struct NetClientInfo { LinkStatusChanged *link_status_changed; QueryRxFilter *query_rx_filter; NetPoll *poll; + HasUfo *has_ufo; + HasVnetHdr *has_vnet_hdr; + HasVnetHdrLen *has_vnet_hdr_len; + UsingVnetHdr *using_vnet_hdr; + SetOffload *set_offload; + SetVnetHdrLen *set_vnet_hdr_len; } NetClientInfo; struct NetClientState { @@ -120,6 +132,13 @@ ssize_t qemu_send_packet_async(NetClientState *nc, const uint8_t *buf, void qemu_purge_queued_packets(NetClientState *nc); void qemu_flush_queued_packets(NetClientState *nc); void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6]); +bool qemu_has_ufo(NetClientState *nc); +bool qemu_has_vnet_hdr(NetClientState *nc); +bool qemu_has_vnet_hdr_len(NetClientState *nc, int len); +void qemu_using_vnet_hdr(NetClientState *nc, bool enable); +void qemu_set_offload(NetClientState *nc, int csum, int tso4, int tso6, + int ecn, int ufo); +void qemu_set_vnet_hdr_len(NetClientState *nc, int len); void qemu_macaddr_default_if_unset(MACAddr *macaddr); int qemu_show_nic_models(const char *arg, const char *const *models); void qemu_check_nic_model(NICInfo *nd, const char *model); diff --git a/include/net/tap.h b/include/net/tap.h index a994f20..6daeb42 100644 --- a/include/net/tap.h +++ b/include/net/tap.h @@ -29,12 +29,6 @@ #include "qemu-common.h" #include "qapi-types.h" -bool tap_has_ufo(NetClientState *nc); -int tap_has_vnet_hdr(NetClientState *nc); -int tap_has_vnet_hdr_len(NetClientState *nc, int len); -void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr); -void tap_set_offload(NetClientState *nc, int csum, int tso4, int tso6, int ecn, int ufo); -void tap_set_vnet_hdr_len(NetClientState *nc, int len); int tap_enable(NetClientState *nc); int tap_disable(NetClientState *nc); @@ -378,6 +378,61 @@ void qemu_foreach_nic(qemu_nic_foreach func, void *opaque) } } +bool qemu_has_ufo(NetClientState *nc) +{ + if (!nc || !nc->info->has_ufo) { + return false; + } + + return nc->info->has_ufo(nc); +} + +bool qemu_has_vnet_hdr(NetClientState *nc) +{ + if (!nc || !nc->info->has_vnet_hdr) { + return false; + } + + return nc->info->has_vnet_hdr(nc); +} + +bool qemu_has_vnet_hdr_len(NetClientState *nc, int len) +{ + if (!nc || !nc->info->has_vnet_hdr_len) { + return false; + } + + return nc->info->has_vnet_hdr_len(nc, len); +} + +void qemu_using_vnet_hdr(NetClientState *nc, bool enable) +{ + if (!nc || !nc->info->using_vnet_hdr) { + return; + } + + nc->info->using_vnet_hdr(nc, enable); +} + +void qemu_set_offload(NetClientState *nc, int csum, int tso4, int tso6, + int ecn, int ufo) +{ + if (!nc || !nc->info->set_offload) { + return; + } + + nc->info->set_offload(nc, csum, tso4, tso6, ecn, ufo); +} + +void qemu_set_vnet_hdr_len(NetClientState *nc, int len) +{ + if (!nc || !nc->info->set_vnet_hdr_len) { + return; + } + + nc->info->set_vnet_hdr_len(nc, len); +} + int qemu_can_send_packet(NetClientState *sender) { if (!sender->peer) { diff --git a/net/netmap.c b/net/netmap.c index 0ccc497..8213304 100644 --- a/net/netmap.c +++ b/net/netmap.c @@ -27,10 +27,13 @@ #include <net/if.h> #include <sys/mman.h> #include <stdint.h> +#include <stdio.h> +#define NETMAP_WITH_LIBS #include <net/netmap.h> #include <net/netmap_user.h> #include "net/net.h" +#include "net/tap.h" #include "clients.h" #include "sysemu/sysemu.h" #include "qemu/error-report.h" @@ -54,33 +57,9 @@ typedef struct NetmapState { bool read_poll; bool write_poll; struct iovec iov[IOV_MAX]; + int vnet_hdr_len; /* Current virtio-net header length. */ } NetmapState; -#define D(format, ...) \ - do { \ - struct timeval __xxts; \ - gettimeofday(&__xxts, NULL); \ - printf("%03d.%06d %s [%d] " format "\n", \ - (int)__xxts.tv_sec % 1000, (int)__xxts.tv_usec, \ - __func__, __LINE__, ##__VA_ARGS__); \ - } while (0) - -/* Rate limited version of "D", lps indicates how many per second */ -#define RD(lps, format, ...) \ - do { \ - static int t0, __cnt; \ - struct timeval __xxts; \ - gettimeofday(&__xxts, NULL); \ - if (t0 != __xxts.tv_sec) { \ - t0 = __xxts.tv_sec; \ - __cnt = 0; \ - } \ - if (__cnt++ < lps) { \ - D(format, ##__VA_ARGS__); \ - } \ - } while (0) - - #ifndef __FreeBSD__ #define pkt_copy bcopy #else @@ -237,7 +216,7 @@ static ssize_t netmap_receive(NetClientState *nc, return size; } - if (ring->avail == 0) { + if (nm_ring_empty(ring)) { /* No available slots in the netmap TX ring. */ netmap_write_poll(s, true); return 0; @@ -250,8 +229,7 @@ static ssize_t netmap_receive(NetClientState *nc, ring->slot[i].len = size; ring->slot[i].flags = 0; pkt_copy(buf, dst, size); - ring->cur = NETMAP_RING_NEXT(ring, i); - ring->avail--; + ring->cur = ring->head = nm_ring_next(ring, i); ioctl(s->me.fd, NIOCTXSYNC, NULL); return size; @@ -267,17 +245,15 @@ static ssize_t netmap_receive_iov(NetClientState *nc, uint8_t *dst; int j; uint32_t i; - uint32_t avail; if (unlikely(!ring)) { /* Drop the packet. */ return iov_size(iov, iovcnt); } - i = ring->cur; - avail = ring->avail; + last = i = ring->cur; - if (avail < iovcnt) { + if (nm_ring_space(ring) < iovcnt) { /* Not enough netmap slots. */ netmap_write_poll(s, true); return 0; @@ -293,7 +269,7 @@ static ssize_t netmap_receive_iov(NetClientState *nc, while (iov_frag_size) { nm_frag_size = MIN(iov_frag_size, ring->nr_buf_size); - if (unlikely(avail == 0)) { + if (unlikely(nm_ring_empty(ring))) { /* We run out of netmap slots while splitting the iovec fragments. */ netmap_write_poll(s, true); @@ -308,8 +284,7 @@ static ssize_t netmap_receive_iov(NetClientState *nc, pkt_copy(iov[j].iov_base + offset, dst, nm_frag_size); last = i; - i = NETMAP_RING_NEXT(ring, i); - avail--; + i = nm_ring_next(ring, i); offset += nm_frag_size; iov_frag_size -= nm_frag_size; @@ -318,9 +293,8 @@ static ssize_t netmap_receive_iov(NetClientState *nc, /* The last slot must not have NS_MOREFRAG set. */ ring->slot[last].flags &= ~NS_MOREFRAG; - /* Now update ring->cur and ring->avail. */ - ring->cur = i; - ring->avail = avail; + /* Now update ring->cur and ring->head. */ + ring->cur = ring->head = i; ioctl(s->me.fd, NIOCTXSYNC, NULL); @@ -343,7 +317,7 @@ static void netmap_send(void *opaque) /* Keep sending while there are available packets into the netmap RX ring and the forwarding path towards the peer is open. */ - while (ring->avail > 0 && qemu_can_send_packet(&s->nc)) { + while (!nm_ring_empty(ring) && qemu_can_send_packet(&s->nc)) { uint32_t i; uint32_t idx; bool morefrag; @@ -358,11 +332,10 @@ static void netmap_send(void *opaque) s->iov[iovcnt].iov_len = ring->slot[i].len; iovcnt++; - ring->cur = NETMAP_RING_NEXT(ring, i); - ring->avail--; - } while (ring->avail && morefrag); + ring->cur = ring->head = nm_ring_next(ring, i); + } while (!nm_ring_empty(ring) && morefrag); - if (unlikely(!ring->avail && morefrag)) { + if (unlikely(nm_ring_empty(ring) && morefrag)) { RD(5, "[netmap_send] ran out of slots, with a pending" "incomplete packet\n"); } @@ -394,6 +367,63 @@ static void netmap_cleanup(NetClientState *nc) s->me.fd = -1; } +/* Offloading manipulation support callbacks. */ +static bool netmap_has_ufo(NetClientState *nc) +{ + return true; +} + +static bool netmap_has_vnet_hdr(NetClientState *nc) +{ + return true; +} + +static bool netmap_has_vnet_hdr_len(NetClientState *nc, int len) +{ + return len == 0 || len == sizeof(struct virtio_net_hdr) || + len == sizeof(struct virtio_net_hdr_mrg_rxbuf); +} + +static void netmap_using_vnet_hdr(NetClientState *nc, bool enable) +{ +} + +static void netmap_set_vnet_hdr_len(NetClientState *nc, int len) +{ + NetmapState *s = DO_UPCAST(NetmapState, nc, nc); + int err; + struct nmreq req; + + /* Issue a NETMAP_BDG_VNET_HDR command to change the virtio-net header + * length for the netmap adapter associated to 'me->ifname'. + */ + memset(&req, 0, sizeof(req)); + pstrcpy(req.nr_name, sizeof(req.nr_name), s->me.ifname); + req.nr_version = NETMAP_API; + req.nr_cmd = NETMAP_BDG_VNET_HDR; + req.nr_arg1 = len; + err = ioctl(s->me.fd, NIOCREGIF, &req); + if (err) { + error_report("Unable to execute NETMAP_BDG_VNET_HDR on %s: %s", + s->me.ifname, strerror(errno)); + } else { + /* Keep track of the current length. */ + s->vnet_hdr_len = len; + } +} + +static void netmap_set_offload(NetClientState *nc, int csum, int tso4, int tso6, + int ecn, int ufo) +{ + NetmapState *s = DO_UPCAST(NetmapState, nc, nc); + + /* Setting a virtio-net header length greater than zero automatically + * enables the offloadings. + */ + if (!s->vnet_hdr_len) { + netmap_set_vnet_hdr_len(nc, sizeof(struct virtio_net_hdr)); + } +} /* NetClientInfo methods */ static NetClientInfo net_netmap_info = { @@ -403,6 +433,12 @@ static NetClientInfo net_netmap_info = { .receive_iov = netmap_receive_iov, .poll = netmap_poll, .cleanup = netmap_cleanup, + .has_ufo = netmap_has_ufo, + .has_vnet_hdr = netmap_has_vnet_hdr, + .has_vnet_hdr_len = netmap_has_vnet_hdr_len, + .using_vnet_hdr = netmap_using_vnet_hdr, + .set_offload = netmap_set_offload, + .set_vnet_hdr_len = netmap_set_vnet_hdr_len, }; /* The exported init function @@ -428,6 +464,7 @@ int net_init_netmap(const NetClientOptions *opts, nc = qemu_new_net_client(&net_netmap_info, peer, "netmap", name); s = DO_UPCAST(NetmapState, nc, nc); s->me = me; + s->vnet_hdr_len = 0; netmap_read_poll(s, true); /* Initially only poll for reads. */ return 0; diff --git a/net/tap-win32.c b/net/tap-win32.c index 91e9e84..8aee611 100644 --- a/net/tap-win32.c +++ b/net/tap-win32.c @@ -669,11 +669,60 @@ static void tap_win32_send(void *opaque) } } +static bool tap_has_ufo(NetClientState *nc) +{ + return false; +} + +static bool tap_has_vnet_hdr(NetClientState *nc) +{ + return false; +} + +int tap_probe_vnet_hdr_len(int fd, int len) +{ + return 0; +} + +void tap_fd_set_vnet_hdr_len(int fd, int len) +{ +} + +static void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr) +{ +} + +static void tap_set_offload(NetClientState *nc, int csum, int tso4, + int tso6, int ecn, int ufo) +{ +} + +struct vhost_net *tap_get_vhost_net(NetClientState *nc) +{ + return NULL; +} + +static bool tap_has_vnet_hdr_len(NetClientState *nc, int len) +{ + return false; +} + +static void tap_set_vnet_hdr_len(NetClientState *nc, int len) +{ + abort(); +} + static NetClientInfo net_tap_win32_info = { .type = NET_CLIENT_OPTIONS_KIND_TAP, .size = sizeof(TAPState), .receive = tap_receive, .cleanup = tap_cleanup, + .has_ufo = tap_has_ufo, + .has_vnet_hdr = tap_has_vnet_hdr, + .has_vnet_hdr_len = tap_has_vnet_hdr_len, + .using_vnet_hdr = tap_using_vnet_hdr, + .set_offload = tap_set_offload, + .set_vnet_hdr_len = tap_set_vnet_hdr_len, }; static int tap_win32_init(NetClientState *peer, const char *model, @@ -722,49 +771,6 @@ int net_init_tap(const NetClientOptions *opts, const char *name, return 0; } -bool tap_has_ufo(NetClientState *nc) -{ - return false; -} - -int tap_has_vnet_hdr(NetClientState *nc) -{ - return 0; -} - -int tap_probe_vnet_hdr_len(int fd, int len) -{ - return 0; -} - -void tap_fd_set_vnet_hdr_len(int fd, int len) -{ -} - -void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr) -{ -} - -void tap_set_offload(NetClientState *nc, int csum, int tso4, - int tso6, int ecn, int ufo) -{ -} - -struct vhost_net *tap_get_vhost_net(NetClientState *nc) -{ - return NULL; -} - -int tap_has_vnet_hdr_len(NetClientState *nc, int len) -{ - return 0; -} - -void tap_set_vnet_hdr_len(NetClientState *nc, int len) -{ - abort(); -} - int tap_enable(NetClientState *nc) { abort(); @@ -210,7 +210,7 @@ static void tap_send(void *opaque) } while (size > 0 && qemu_can_send_packet(&s->nc)); } -bool tap_has_ufo(NetClientState *nc) +static bool tap_has_ufo(NetClientState *nc) { TAPState *s = DO_UPCAST(TAPState, nc, nc); @@ -219,7 +219,7 @@ bool tap_has_ufo(NetClientState *nc) return s->has_ufo; } -int tap_has_vnet_hdr(NetClientState *nc) +static bool tap_has_vnet_hdr(NetClientState *nc) { TAPState *s = DO_UPCAST(TAPState, nc, nc); @@ -228,16 +228,16 @@ int tap_has_vnet_hdr(NetClientState *nc) return !!s->host_vnet_hdr_len; } -int tap_has_vnet_hdr_len(NetClientState *nc, int len) +static bool tap_has_vnet_hdr_len(NetClientState *nc, int len) { TAPState *s = DO_UPCAST(TAPState, nc, nc); assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP); - return tap_probe_vnet_hdr_len(s->fd, len); + return !!tap_probe_vnet_hdr_len(s->fd, len); } -void tap_set_vnet_hdr_len(NetClientState *nc, int len) +static void tap_set_vnet_hdr_len(NetClientState *nc, int len) { TAPState *s = DO_UPCAST(TAPState, nc, nc); @@ -249,7 +249,7 @@ void tap_set_vnet_hdr_len(NetClientState *nc, int len) s->host_vnet_hdr_len = len; } -void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr) +static void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr) { TAPState *s = DO_UPCAST(TAPState, nc, nc); @@ -259,7 +259,7 @@ void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr) s->using_vnet_hdr = using_vnet_hdr; } -void tap_set_offload(NetClientState *nc, int csum, int tso4, +static void tap_set_offload(NetClientState *nc, int csum, int tso4, int tso6, int ecn, int ufo) { TAPState *s = DO_UPCAST(TAPState, nc, nc); @@ -314,6 +314,12 @@ static NetClientInfo net_tap_info = { .receive_iov = tap_receive_iov, .poll = tap_poll, .cleanup = tap_cleanup, + .has_ufo = tap_has_ufo, + .has_vnet_hdr = tap_has_vnet_hdr, + .has_vnet_hdr_len = tap_has_vnet_hdr_len, + .using_vnet_hdr = tap_using_vnet_hdr, + .set_offload = tap_set_offload, + .set_vnet_hdr_len = tap_set_vnet_hdr_len, }; static TAPState *net_tap_fd_init(NetClientState *peer, diff --git a/util/module.c b/util/module.c index 42bc373..dc08c16 100644 --- a/util/module.c +++ b/util/module.c @@ -14,7 +14,9 @@ */ #include <stdlib.h> +#ifdef CONFIG_MODULES #include <gmodule.h> +#endif #include "qemu-common.h" #include "qemu/queue.h" #include "qemu/module.h" |