Patchwork [3/7] net: create the VLANClientState for NICs early

login
register
mail settings
Submitter Mark McLoughlin
Date Nov. 12, 2009, 8:28 p.m.
Message ID <1258057742-18699-4-git-send-email-markmc@redhat.com>
Download mbox | patch
Permalink /patch/38277/
State New
Headers show

Comments

Mark McLoughlin - Nov. 12, 2009, 8:28 p.m.
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
 hw/dp8393x.c        |   10 +++++-----
 hw/e1000.c          |   10 +++++-----
 hw/eepro100.c       |   10 +++++-----
 hw/etraxfs_eth.c    |   11 +++++------
 hw/mcf_fec.c        |   10 +++++-----
 hw/mipsnet.c        |   15 ++++++---------
 hw/musicpal.c       |   10 +++++-----
 hw/ne2000-isa.c     |   10 ++++++----
 hw/ne2000.c         |   11 +++++++----
 hw/pcnet.c          |   10 +++++-----
 hw/qdev.c           |    3 +++
 hw/rtl8139.c        |   11 ++++++-----
 hw/smc91c111.c      |   11 ++++++-----
 hw/stellaris_enet.c |   12 ++++++------
 hw/usb-net.c        |   12 +++++-------
 hw/virtio-net.c     |   11 ++++++-----
 hw/xilinx_ethlite.c |   10 +++++-----
 net.c               |    5 +++++
 net.h               |    1 +
 19 files changed, 97 insertions(+), 86 deletions(-)
Gerd Hoffmann - Nov. 16, 2009, 9:26 a.m.
Hi,

> diff --git a/hw/e1000.c b/hw/e1000.c
> index 00f6a57..d9c9f79 100644
> --- a/hw/e1000.c
> +++ b/hw/e1000.c
> @@ -1107,11 +1107,11 @@ static int pci_e1000_init(PCIDevice *pci_dev)
>       checksum = (uint16_t) EEPROM_SUM - checksum;
>       d->eeprom_data[EEPROM_CHECKSUM_REG] = checksum;
>
> -    d->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
> -                                 d->conf.vlan, d->conf.peer,
> -                                 d->dev.qdev.info->name, d->dev.qdev.id,
> -                                 e1000_can_receive, e1000_receive, NULL,
> -                                 NULL, e1000_cleanup, d);
> +    d->vc = d->conf.client;
> +    d->vc->opaque = d;
> +    d->vc->can_receive = e1000_can_receive;
> +    d->vc->receive = e1000_receive;
> +    d->vc->cleanup = e1000_cleanup;
>       d->vc->link_status_changed = e1000_set_link_status;
>
>       qemu_format_nic_info_str(d->vc, macaddr);

... and now -device $nic,args is completely broken.

There are netdev, vlan and net-client properties but none of them will work.


If you want to have net.c prepare vlanclientstate (there might be good 
reasons for it), then it must be properly:

   * Create a named vlanclientstate.
   * Have drivers lookup the vlanclientstate by name.  Pretty much like
     the netdev peer lookup works today, only with the difference that
     it is used directly instead of being passed as peer on vlanclient
     creation.

i.e. something like

   -netdev client,id=foo,<moreargs>
   -device e1000,client=foo,mac=11:22:33:44:55:66

It is probably a good idea to zap the vlan and netdev properties then, 
so we don't have tons of different ways to setup a nic.  Fortunaly we 
had no release with the vlan+netdev properties yet, so this shouldn't be 
a backward compatibility issue IMHO.

Also take care that the creation and destruction is symmetric.  If net.c 
creates the vlanclient it should also net.c's job to clean it up, i.e. 
all the qemu_del_vlan_client() calls in the nic drivers should go away, 
otherwise hotplug will have some unpleasant surprises for you.

cheers,
   Gerd

Patch

diff --git a/hw/dp8393x.c b/hw/dp8393x.c
index 5143cc8..7145ad5 100644
--- a/hw/dp8393x.c
+++ b/hw/dp8393x.c
@@ -889,11 +889,11 @@  void dp83932_init(NICInfo *nd, target_phys_addr_t base, int it_shift,
     s->watchdog = qemu_new_timer(vm_clock, dp8393x_watchdog, s);
     s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux */
 
-    s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
-                                 nd->vlan, nd->netdev,
-                                 nd->model, nd->name,
-                                 nic_can_receive, nic_receive, NULL, NULL,
-                                 nic_cleanup, s);
+    s->vc = nd->vc;
+    s->vc->opaque = s;
+    s->vc->receive = nic_receive;
+    s->vc->can_receive = nic_can_receive;
+    s->vc->cleanup = nic_cleanup;
 
     qemu_format_nic_info_str(s->vc, nd->macaddr);
     qemu_register_reset(nic_reset, s);
diff --git a/hw/e1000.c b/hw/e1000.c
index 00f6a57..d9c9f79 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1107,11 +1107,11 @@  static int pci_e1000_init(PCIDevice *pci_dev)
     checksum = (uint16_t) EEPROM_SUM - checksum;
     d->eeprom_data[EEPROM_CHECKSUM_REG] = checksum;
 
-    d->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
-                                 d->conf.vlan, d->conf.peer,
-                                 d->dev.qdev.info->name, d->dev.qdev.id,
-                                 e1000_can_receive, e1000_receive, NULL,
-                                 NULL, e1000_cleanup, d);
+    d->vc = d->conf.client;
+    d->vc->opaque = d;
+    d->vc->can_receive = e1000_can_receive;
+    d->vc->receive = e1000_receive;
+    d->vc->cleanup = e1000_cleanup;
     d->vc->link_status_changed = e1000_set_link_status;
 
     qemu_format_nic_info_str(d->vc, macaddr);
diff --git a/hw/eepro100.c b/hw/eepro100.c
index 8734907..2608f31 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -1829,11 +1829,11 @@  static int nic_init(PCIDevice *pci_dev, uint32_t device)
 
     nic_reset(s);
 
-    s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
-                                 s->conf.vlan, s->conf.peer,
-                                 pci_dev->qdev.info->name, pci_dev->qdev.id,
-                                 nic_can_receive, nic_receive, NULL, NULL,
-                                 nic_cleanup, s);
+    s->vc = s->conf.client;
+    s->vc->opaque = s;
+    s->vc->can_receive = nic_can_receive;
+    s->vc->receive = nic_receive;
+    s->vc->cleanup = nic_cleanup;
 
     qemu_format_nic_info_str(s->vc, s->conf.macaddr.a);
     TRACE(OTHER, logout("%s\n", s->vc->info_str));
diff --git a/hw/etraxfs_eth.c b/hw/etraxfs_eth.c
index 2cc2332..f958d62 100644
--- a/hw/etraxfs_eth.c
+++ b/hw/etraxfs_eth.c
@@ -590,12 +590,11 @@  void *etraxfs_eth_init(NICInfo *nd, target_phys_addr_t base, int phyaddr)
 	eth->ethregs = cpu_register_io_memory(eth_read, eth_write, eth);
 	cpu_register_physical_memory (base, 0x5c, eth->ethregs);
 
-	eth->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
-                                       nd->vlan, nd->netdev,
-                                       nd->model, nd->name,
-                                       eth_can_receive, eth_receive,
-                                       NULL, NULL, eth_cleanup, eth);
-	eth->vc->opaque = eth;
+        eth->vc = nd->vc;
+        eth->vc->opaque = eth;
+        eth->vc->receive = eth_receive;
+        eth->vc->can_receive = eth_can_receive;
+        eth->vc->cleanup = eth_cleanup;
 	eth->vc->link_status_changed = eth_set_link;
 
 	return dma;
diff --git a/hw/mcf_fec.c b/hw/mcf_fec.c
index 8242c8a..d1e57c8 100644
--- a/hw/mcf_fec.c
+++ b/hw/mcf_fec.c
@@ -462,11 +462,11 @@  void mcf_fec_init(NICInfo *nd, target_phys_addr_t base, qemu_irq *irq)
                                            mcf_fec_writefn, s);
     cpu_register_physical_memory(base, 0x400, s->mmio_index);
 
-    s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
-                                 nd->vlan, nd->netdev,
-                                 nd->model, nd->name,
-                                 mcf_fec_can_receive, mcf_fec_receive,
-                                 NULL, NULL, mcf_fec_cleanup, s);
+    s->vc = nd->vc;
+    s->vc->opaque = s;
+    s->vc->receive = mcf_fec_receive;
+    s->vc->can_receive = mcf_fec_can_receive;
+    s->vc->cleanup = mcf_fec_cleanup;
     memcpy(s->macaddr, nd->macaddr, 6);
     qemu_format_nic_info_str(s->vc, s->macaddr);
 }
diff --git a/hw/mipsnet.c b/hw/mipsnet.c
index 67160a4..c630890 100644
--- a/hw/mipsnet.c
+++ b/hw/mipsnet.c
@@ -262,15 +262,12 @@  void mipsnet_init (int base, qemu_irq irq, NICInfo *nd)
 
     s->io_base = base;
     s->irq = irq;
-    if (nd) {
-        s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
-                                     nd->vlan, nd->netdev,
-                                     nd->model, nd->name,
-                                     mipsnet_can_receive, mipsnet_receive,
-                                     NULL, NULL, mipsnet_cleanup, s);
-    } else {
-        s->vc = NULL;
-    }
+
+    s->vc = nd->vc;
+    s->vc->opaque = s;
+    s->vc->receive = mipsnet_receive;
+    s->vc->can_receive = mipsnet_can_receive;
+    s->vc->cleanup = mipsnet_cleanup;
 
     qemu_format_nic_info_str(s->vc, nd->macaddr);
 
diff --git a/hw/musicpal.c b/hw/musicpal.c
index 0d21f17..a32eed6 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -377,11 +377,11 @@  static int mv88w8618_eth_init(SysBusDevice *dev)
     mv88w8618_eth_state *s = FROM_SYSBUS(mv88w8618_eth_state, dev);
 
     sysbus_init_irq(dev, &s->irq);
-    s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
-                                 s->conf.vlan, s->conf.peer,
-                                 dev->qdev.info->name, dev->qdev.id,
-                                 eth_can_receive, eth_receive, NULL,
-                                 NULL, eth_cleanup, s);
+    s->vc = s->conf.client;
+    s->vc->opaque = s;
+    s->vc->receive = eth_receive;
+    s->vc->can_receive = eth_can_receive;
+    s->vc->cleanup = eth_cleanup;
     s->mmio_index = cpu_register_io_memory(mv88w8618_eth_readfn,
                                            mv88w8618_eth_writefn, s);
     sysbus_init_mmio(dev, MP_ETH_SIZE, s->mmio_index);
diff --git a/hw/ne2000-isa.c b/hw/ne2000-isa.c
index 729e8e2..6ea80c2 100644
--- a/hw/ne2000-isa.c
+++ b/hw/ne2000-isa.c
@@ -63,10 +63,12 @@  static int isa_ne2000_initfn(ISADevice *dev)
     qemu_macaddr_default_if_unset(&s->c.macaddr);
     ne2000_reset(s);
 
-    s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC, s->c.vlan, s->c.peer,
-                                 dev->qdev.info->name, dev->qdev.id,
-                                 ne2000_can_receive, ne2000_receive, NULL,
-                                 NULL, isa_ne2000_cleanup, s);
+    s->vc = s->c.client;
+    s->vc->opaque = s;
+    s->vc->receive = ne2000_receive;
+    s->vc->can_receive = ne2000_can_receive;
+    s->vc->cleanup = isa_ne2000_cleanup;
+
     qemu_format_nic_info_str(s->vc, s->c.macaddr.a);
 
     vmstate_register(-1, &vmstate_ne2000, s);
diff --git a/hw/ne2000.c b/hw/ne2000.c
index 63efc3a..19f52ad 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -725,10 +725,13 @@  static int pci_ne2000_init(PCIDevice *pci_dev)
 
     qemu_macaddr_default_if_unset(&s->c.macaddr);
     ne2000_reset(s);
-    s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC, s->c.vlan, s->c.peer,
-                                 pci_dev->qdev.info->name, pci_dev->qdev.id,
-                                 ne2000_can_receive, ne2000_receive, NULL,
-                                 NULL, ne2000_cleanup, s);
+
+    s->vc = s->c.client;
+    s->vc->opaque = s;
+    s->vc->receive = ne2000_receive;
+    s->vc->can_receive = ne2000_can_receive;
+    s->vc->cleanup = ne2000_cleanup;
+
     qemu_format_nic_info_str(s->vc, s->c.macaddr.a);
 
     if (!pci_dev->qdev.hotplugged) {
diff --git a/hw/pcnet.c b/hw/pcnet.c
index ee3db09..18da141 100644
--- a/hw/pcnet.c
+++ b/hw/pcnet.c
@@ -1897,11 +1897,11 @@  int pcnet_common_init(DeviceState *dev, PCNetState *s,
     s->poll_timer = qemu_new_timer(vm_clock, pcnet_poll_timer, s);
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
-    s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
-                                 s->conf.vlan, s->conf.peer,
-                                 dev->info->name, dev->id,
-                                 pcnet_can_receive, pcnet_receive, NULL, NULL,
-                                 cleanup, s);
+    s->vc = s->conf.client;
+    s->vc->opaque = s;
+    s->vc->receive = pcnet_receive;
+    s->vc->can_receive = pcnet_can_receive;
+    s->vc->cleanup = cleanup;
     qemu_format_nic_info_str(s->vc, s->conf.macaddr.a);
     return 0;
 }
diff --git a/hw/qdev.c b/hw/qdev.c
index d19d531..757b285 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -366,6 +366,9 @@  void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
 void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
 {
     qdev_prop_set_macaddr(dev, "mac", nd->macaddr);
+    if (nd->vc) {
+        qdev_prop_set_net_client(dev, "net-client", nd->vc);
+    }
     if (nd->vlan)
         qdev_prop_set_vlan(dev, "vlan", nd->vlan);
     if (nd->netdev)
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index c166db0..f2c8adb 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -3332,11 +3332,12 @@  static int pci_rtl8139_init(PCIDevice *dev)
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
 
-    s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
-                                 s->conf.vlan, s->conf.peer,
-                                 dev->qdev.info->name, dev->qdev.id,
-                                 rtl8139_can_receive, rtl8139_receive, NULL,
-                                 NULL, rtl8139_cleanup, s);
+    s->vc = s->conf.client;
+    s->vc->opaque = s;
+    s->vc->receive = rtl8139_receive;
+    s->vc->can_receive = rtl8139_can_receive;
+    s->vc->cleanup = rtl8139_cleanup;
+
     qemu_format_nic_info_str(s->vc, s->conf.macaddr.a);
 
     s->cplus_txbuffer = NULL;
diff --git a/hw/smc91c111.c b/hw/smc91c111.c
index b7398c9..410393c 100644
--- a/hw/smc91c111.c
+++ b/hw/smc91c111.c
@@ -711,11 +711,12 @@  static int smc91c111_init1(SysBusDevice *dev)
 
     smc91c111_reset(s);
 
-    s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
-                                 s->conf.vlan, s->conf.peer,
-                                 dev->qdev.info->name, dev->qdev.id,
-                                 smc91c111_can_receive, smc91c111_receive, NULL,
-                                 NULL, smc91c111_cleanup, s);
+    s->vc = s->conf.client;
+    s->vc->opaque = s;
+    s->vc->receive = smc91c111_receive;
+    s->vc->can_receive = smc91c111_can_receive;
+    s->vc->cleanup = smc91c111_cleanup;
+
     qemu_format_nic_info_str(s->vc, s->conf.macaddr.a);
     /* ??? Save/restore.  */
     return 0;
diff --git a/hw/stellaris_enet.c b/hw/stellaris_enet.c
index 2252f1a..432c4ed 100644
--- a/hw/stellaris_enet.c
+++ b/hw/stellaris_enet.c
@@ -406,12 +406,12 @@  static int stellaris_enet_init(SysBusDevice *dev)
     sysbus_init_irq(dev, &s->irq);
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
 
-    s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
-                                 s->conf.vlan, s->conf.peer,
-                                 dev->qdev.info->name, dev->qdev.id,
-                                 stellaris_enet_can_receive,
-                                 stellaris_enet_receive, NULL, NULL,
-                                 stellaris_enet_cleanup, s);
+    s->vc = s->conf.client;
+    s->vc->opaque = s;
+    s->vc->receive = stellaris_enet_receive;
+    s->vc->can_receive = stellaris_enet_can_receive;
+    s->vc->cleanup = stellaris_enet_cleanup;
+
     qemu_format_nic_info_str(s->vc, s->conf.macaddr.a);
 
     stellaris_enet_reset(s);
diff --git a/hw/usb-net.c b/hw/usb-net.c
index 7b8cc7a..2d8e79f 100644
--- a/hw/usb-net.c
+++ b/hw/usb-net.c
@@ -1460,13 +1460,11 @@  USBDevice *usb_net_init(NICInfo *nd)
 
     memcpy(s->mac, nd->macaddr, 6);
 
-    s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
-                                 nd->vlan, nd->netdev,
-                                 nd->model, nd->name,
-                                 usbnet_can_receive,
-                                 usbnet_receive,
-                                 NULL, NULL,
-                                 usbnet_cleanup, s);
+    s->vc = nd->vc;
+    s->vc->opaque = s;
+    s->vc->receive = usbnet_receive;
+    s->vc->can_receive = usbnet_can_receive;
+    s->vc->cleanup = usbnet_cleanup;
 
     qemu_format_nic_info_str(s->vc, s->mac);
 
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 2f147e5..94f8616 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -839,11 +839,12 @@  VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf)
     qemu_macaddr_default_if_unset(&conf->macaddr);
     memcpy(&n->mac[0], &conf->macaddr, sizeof(n->mac));
     n->status = VIRTIO_NET_S_LINK_UP;
-    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_receive, NULL, NULL,
-                                 virtio_net_cleanup, n);
+
+    n->vc = conf->client;
+    n->vc->opaque = n;
+    n->vc->can_receive = virtio_net_can_receive;
+    n->vc->receive = virtio_net_receive;
+    n->vc->cleanup = virtio_net_cleanup;
     n->vc->link_status_changed = virtio_net_set_link_status;
 
     qemu_format_nic_info_str(n->vc, conf->macaddr.a);
diff --git a/hw/xilinx_ethlite.c b/hw/xilinx_ethlite.c
index b7129d5..af3978d 100644
--- a/hw/xilinx_ethlite.c
+++ b/hw/xilinx_ethlite.c
@@ -220,11 +220,11 @@  static int xilinx_ethlite_init(SysBusDevice *dev)
     sysbus_init_mmio(dev, R_MAX * 4, regs);
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
-    s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
-                                 s->conf.vlan, s->conf.peer,
-                                 dev->qdev.info->name, dev->qdev.id,
-                                 eth_can_rx, eth_rx, NULL,
-                                 NULL, eth_cleanup, s);
+    s->vc = s->conf.client;
+    s->vc->opaque = s;
+    s->vc->receive = eth_rx;
+    s->vc->can_receive = eth_can_rx;
+    s->vc->cleanup = eth_cleanup;
     qemu_format_nic_info_str(s->vc, s->conf.macaddr.a);
     return 0;
 }
diff --git a/net.c b/net.c
index 9ea66e3..e90084d 100644
--- a/net.c
+++ b/net.c
@@ -2107,6 +2107,11 @@  static int net_init_nic(QemuOpts *opts,
         return -1;
     }
 
+    nd->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
+                                  nd->vlan, nd->netdev,
+                                  nd->model, nd->name,
+                                  NULL, NULL, NULL,
+                                  NULL, NULL, NULL);
     nd->used = 1;
     if (vlan) {
         nd->vlan->nb_guest_devs++;
diff --git a/net.h b/net.h
index d7235bb..83e50ab 100644
--- a/net.h
+++ b/net.h
@@ -126,6 +126,7 @@  struct NICInfo {
     char *devaddr;
     VLANState *vlan;
     VLANClientState *netdev;
+    VLANClientState *vc;
     void *private;
     int used;
     int bootable;