virtio: use qdev properties for configuration.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
254111ecc8
commit
97b156213e
@ -390,6 +390,10 @@ void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
|
|||||||
qdev_prop_set_vlan(dev, "vlan", nd->vlan);
|
qdev_prop_set_vlan(dev, "vlan", nd->vlan);
|
||||||
if (nd->netdev)
|
if (nd->netdev)
|
||||||
qdev_prop_set_netdev(dev, "netdev", nd->netdev);
|
qdev_prop_set_netdev(dev, "netdev", nd->netdev);
|
||||||
|
if (nd->nvectors != NIC_NVECTORS_UNSPECIFIED &&
|
||||||
|
qdev_prop_exists(dev, "vectors")) {
|
||||||
|
qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int next_block_unit[IF_COUNT];
|
static int next_block_unit[IF_COUNT];
|
||||||
|
@ -77,13 +77,13 @@ static void syborg_init(ram_addr_t ram_size,
|
|||||||
sysbus_create_simple("syborg,serial", 0xC0008000, pic[7]);
|
sysbus_create_simple("syborg,serial", 0xC0008000, pic[7]);
|
||||||
sysbus_create_simple("syborg,serial", 0xC0009000, pic[8]);
|
sysbus_create_simple("syborg,serial", 0xC0009000, pic[8]);
|
||||||
|
|
||||||
if (nd_table[0].vlan) {
|
if (nd_table[0].vlan || nd_table[0].netdev) {
|
||||||
DeviceState *dev;
|
DeviceState *dev;
|
||||||
SysBusDevice *s;
|
SysBusDevice *s;
|
||||||
|
|
||||||
qemu_check_nic_model(&nd_table[0], "virtio");
|
qemu_check_nic_model(&nd_table[0], "virtio");
|
||||||
dev = qdev_create(NULL, "syborg,virtio-net");
|
dev = qdev_create(NULL, "syborg,virtio-net");
|
||||||
dev->nd = &nd_table[0];
|
qdev_set_nic_properties(dev, &nd_table[0]);
|
||||||
qdev_init_nofail(dev);
|
qdev_init_nofail(dev);
|
||||||
s = sysbus_from_qdev(dev);
|
s = sysbus_from_qdev(dev);
|
||||||
sysbus_mmio_map(s, 0, 0xc000c000);
|
sysbus_mmio_map(s, 0, 0xc000c000);
|
||||||
|
@ -65,6 +65,7 @@ typedef struct {
|
|||||||
qemu_irq irq;
|
qemu_irq irq;
|
||||||
uint32_t int_enable;
|
uint32_t int_enable;
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
|
NICConf nic;
|
||||||
} SyborgVirtIOProxy;
|
} SyborgVirtIOProxy;
|
||||||
|
|
||||||
static uint32_t syborg_virtio_readl(void *opaque, target_phys_addr_t offset)
|
static uint32_t syborg_virtio_readl(void *opaque, target_phys_addr_t offset)
|
||||||
@ -273,14 +274,23 @@ static int syborg_virtio_net_init(SysBusDevice *dev)
|
|||||||
VirtIODevice *vdev;
|
VirtIODevice *vdev;
|
||||||
SyborgVirtIOProxy *proxy = FROM_SYSBUS(SyborgVirtIOProxy, dev);
|
SyborgVirtIOProxy *proxy = FROM_SYSBUS(SyborgVirtIOProxy, dev);
|
||||||
|
|
||||||
vdev = virtio_net_init(&dev->qdev);
|
vdev = virtio_net_init(&dev->qdev, &proxy->nic);
|
||||||
return syborg_virtio_init(proxy, vdev);
|
return syborg_virtio_init(proxy, vdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SysBusDeviceInfo syborg_virtio_net_info = {
|
||||||
|
.init = syborg_virtio_net_init,
|
||||||
|
.qdev.name = "syborg,virtio-net",
|
||||||
|
.qdev.size = sizeof(SyborgVirtIOProxy),
|
||||||
|
.qdev.props = (Property[]) {
|
||||||
|
DEFINE_NIC_PROPERTIES(SyborgVirtIOProxy, nic),
|
||||||
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static void syborg_virtio_register_devices(void)
|
static void syborg_virtio_register_devices(void)
|
||||||
{
|
{
|
||||||
sysbus_register_dev("syborg,virtio-net", sizeof(SyborgVirtIOProxy),
|
sysbus_register_withprop(&syborg_virtio_net_info);
|
||||||
syborg_virtio_net_init);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
device_init(syborg_virtio_register_devices)
|
device_init(syborg_virtio_register_devices)
|
||||||
|
@ -700,20 +700,10 @@ static void virtio_net_cleanup(VLANClientState *vc)
|
|||||||
{
|
{
|
||||||
VirtIONet *n = vc->opaque;
|
VirtIONet *n = vc->opaque;
|
||||||
|
|
||||||
qemu_purge_queued_packets(vc);
|
n->vc = NULL;
|
||||||
|
|
||||||
unregister_savevm("virtio-net", n);
|
|
||||||
|
|
||||||
qemu_free(n->mac_table.macs);
|
|
||||||
qemu_free(n->vlans);
|
|
||||||
|
|
||||||
qemu_del_timer(n->tx_timer);
|
|
||||||
qemu_free_timer(n->tx_timer);
|
|
||||||
|
|
||||||
virtio_cleanup(&n->vdev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtIODevice *virtio_net_init(DeviceState *dev)
|
VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf)
|
||||||
{
|
{
|
||||||
VirtIONet *n;
|
VirtIONet *n;
|
||||||
static int virtio_net_id;
|
static int virtio_net_id;
|
||||||
@ -731,15 +721,16 @@ VirtIODevice *virtio_net_init(DeviceState *dev)
|
|||||||
n->rx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_rx);
|
n->rx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_rx);
|
||||||
n->tx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_tx);
|
n->tx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_tx);
|
||||||
n->ctrl_vq = virtio_add_queue(&n->vdev, 64, virtio_net_handle_ctrl);
|
n->ctrl_vq = virtio_add_queue(&n->vdev, 64, virtio_net_handle_ctrl);
|
||||||
qdev_get_macaddr(dev, n->mac);
|
qemu_macaddr_default_if_unset(&conf->macaddr);
|
||||||
n->status = VIRTIO_NET_S_LINK_UP;
|
n->status = VIRTIO_NET_S_LINK_UP;
|
||||||
n->vc = qdev_get_vlan_client(dev,
|
n->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC, conf->vlan, conf->peer,
|
||||||
|
dev->info->name, dev->id,
|
||||||
virtio_net_can_receive,
|
virtio_net_can_receive,
|
||||||
virtio_net_receive, NULL,
|
virtio_net_receive, NULL, NULL,
|
||||||
virtio_net_cleanup, n);
|
virtio_net_cleanup, n);
|
||||||
n->vc->link_status_changed = virtio_net_set_link_status;
|
n->vc->link_status_changed = virtio_net_set_link_status;
|
||||||
|
|
||||||
qemu_format_nic_info_str(n->vc, n->mac);
|
qemu_format_nic_info_str(n->vc, conf->macaddr.a);
|
||||||
|
|
||||||
n->tx_timer = qemu_new_timer(vm_clock, virtio_net_tx_timer, n);
|
n->tx_timer = qemu_new_timer(vm_clock, virtio_net_tx_timer, n);
|
||||||
n->tx_timer_active = 0;
|
n->tx_timer_active = 0;
|
||||||
@ -749,13 +740,27 @@ VirtIODevice *virtio_net_init(DeviceState *dev)
|
|||||||
n->mac_table.macs = qemu_mallocz(MAC_TABLE_ENTRIES * ETH_ALEN);
|
n->mac_table.macs = qemu_mallocz(MAC_TABLE_ENTRIES * ETH_ALEN);
|
||||||
|
|
||||||
n->vlans = qemu_mallocz(MAX_VLAN >> 3);
|
n->vlans = qemu_mallocz(MAX_VLAN >> 3);
|
||||||
if (dev->nd->nvectors == NIC_NVECTORS_UNSPECIFIED)
|
|
||||||
n->vdev.nvectors = 3;
|
|
||||||
else
|
|
||||||
n->vdev.nvectors = dev->nd->nvectors;
|
|
||||||
|
|
||||||
register_savevm("virtio-net", virtio_net_id++, VIRTIO_NET_VM_VERSION,
|
register_savevm("virtio-net", virtio_net_id++, VIRTIO_NET_VM_VERSION,
|
||||||
virtio_net_save, virtio_net_load, n);
|
virtio_net_save, virtio_net_load, n);
|
||||||
|
|
||||||
return &n->vdev;
|
return &n->vdev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void virtio_net_exit(VirtIODevice *vdev)
|
||||||
|
{
|
||||||
|
VirtIONet *n = DO_UPCAST(VirtIONet, vdev, vdev);
|
||||||
|
|
||||||
|
qemu_purge_queued_packets(n->vc);
|
||||||
|
|
||||||
|
unregister_savevm("virtio-net", n);
|
||||||
|
|
||||||
|
qemu_free(n->mac_table.macs);
|
||||||
|
qemu_free(n->vlans);
|
||||||
|
|
||||||
|
qemu_del_timer(n->tx_timer);
|
||||||
|
qemu_free_timer(n->tx_timer);
|
||||||
|
|
||||||
|
virtio_cleanup(&n->vdev);
|
||||||
|
qemu_del_vlan_client(n->vc);
|
||||||
|
}
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "sysemu.h"
|
#include "sysemu.h"
|
||||||
#include "msix.h"
|
#include "msix.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
|
#include "loader.h"
|
||||||
|
|
||||||
/* from Linux's linux/virtio_pci.h */
|
/* from Linux's linux/virtio_pci.h */
|
||||||
|
|
||||||
@ -90,6 +91,7 @@ typedef struct {
|
|||||||
uint32_t class_code;
|
uint32_t class_code;
|
||||||
uint32_t nvectors;
|
uint32_t nvectors;
|
||||||
DriveInfo *dinfo;
|
DriveInfo *dinfo;
|
||||||
|
NICConf nic;
|
||||||
} VirtIOPCIProxy;
|
} VirtIOPCIProxy;
|
||||||
|
|
||||||
/* virtio device */
|
/* virtio device */
|
||||||
@ -493,14 +495,9 @@ static int virtio_net_init_pci(PCIDevice *pci_dev)
|
|||||||
VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
|
VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
|
||||||
VirtIODevice *vdev;
|
VirtIODevice *vdev;
|
||||||
|
|
||||||
vdev = virtio_net_init(&pci_dev->qdev);
|
vdev = virtio_net_init(&pci_dev->qdev, &proxy->nic);
|
||||||
|
|
||||||
/* set nvectors from property, unless the user specified something
|
|
||||||
* via -net nic,model=virtio,vectors=n command line option */
|
|
||||||
if (pci_dev->qdev.nd->nvectors == NIC_NVECTORS_UNSPECIFIED)
|
|
||||||
if (proxy->nvectors != NIC_NVECTORS_UNSPECIFIED)
|
|
||||||
vdev->nvectors = proxy->nvectors;
|
|
||||||
|
|
||||||
|
vdev->nvectors = proxy->nvectors;
|
||||||
virtio_init_pci(proxy, vdev,
|
virtio_init_pci(proxy, vdev,
|
||||||
PCI_VENDOR_ID_REDHAT_QUMRANET,
|
PCI_VENDOR_ID_REDHAT_QUMRANET,
|
||||||
PCI_DEVICE_ID_VIRTIO_NET,
|
PCI_DEVICE_ID_VIRTIO_NET,
|
||||||
@ -509,9 +506,25 @@ static int virtio_net_init_pci(PCIDevice *pci_dev)
|
|||||||
|
|
||||||
/* make the actual value visible */
|
/* make the actual value visible */
|
||||||
proxy->nvectors = vdev->nvectors;
|
proxy->nvectors = vdev->nvectors;
|
||||||
|
|
||||||
|
if (!pci_dev->qdev.hotplugged) {
|
||||||
|
static int loaded = 0;
|
||||||
|
if (!loaded) {
|
||||||
|
rom_add_option("pxe-virtio.bin");
|
||||||
|
loaded = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int virtio_net_exit_pci(PCIDevice *pci_dev)
|
||||||
|
{
|
||||||
|
VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
|
||||||
|
|
||||||
|
virtio_net_exit(proxy->vdev);
|
||||||
|
return virtio_exit_pci(pci_dev);
|
||||||
|
}
|
||||||
|
|
||||||
static int virtio_balloon_init_pci(PCIDevice *pci_dev)
|
static int virtio_balloon_init_pci(PCIDevice *pci_dev)
|
||||||
{
|
{
|
||||||
VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
|
VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
|
||||||
@ -543,10 +556,10 @@ static PCIDeviceInfo virtio_info[] = {
|
|||||||
.qdev.name = "virtio-net-pci",
|
.qdev.name = "virtio-net-pci",
|
||||||
.qdev.size = sizeof(VirtIOPCIProxy),
|
.qdev.size = sizeof(VirtIOPCIProxy),
|
||||||
.init = virtio_net_init_pci,
|
.init = virtio_net_init_pci,
|
||||||
.exit = virtio_exit_pci,
|
.exit = virtio_net_exit_pci,
|
||||||
.qdev.props = (Property[]) {
|
.qdev.props = (Property[]) {
|
||||||
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors,
|
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
|
||||||
NIC_NVECTORS_UNSPECIFIED),
|
DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
},
|
},
|
||||||
.qdev.reset = virtio_pci_reset,
|
.qdev.reset = virtio_pci_reset,
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#define _QEMU_VIRTIO_H
|
#define _QEMU_VIRTIO_H
|
||||||
|
|
||||||
#include "hw.h"
|
#include "hw.h"
|
||||||
|
#include "net.h"
|
||||||
#include "qdev.h"
|
#include "qdev.h"
|
||||||
#include "sysemu.h"
|
#include "sysemu.h"
|
||||||
|
|
||||||
@ -163,8 +164,10 @@ void virtio_bind_device(VirtIODevice *vdev, const VirtIOBindings *binding,
|
|||||||
|
|
||||||
/* Base devices. */
|
/* Base devices. */
|
||||||
VirtIODevice *virtio_blk_init(DeviceState *dev, DriveInfo *dinfo);
|
VirtIODevice *virtio_blk_init(DeviceState *dev, DriveInfo *dinfo);
|
||||||
VirtIODevice *virtio_net_init(DeviceState *dev);
|
VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf);
|
||||||
VirtIODevice *virtio_console_init(DeviceState *dev);
|
VirtIODevice *virtio_console_init(DeviceState *dev);
|
||||||
VirtIODevice *virtio_balloon_init(DeviceState *dev);
|
VirtIODevice *virtio_balloon_init(DeviceState *dev);
|
||||||
|
|
||||||
|
void virtio_net_exit(VirtIODevice *vdev);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user