Commit 554c97dd43e021b626c78ed5bd72bca33d5cb99c

Authored by aliguori
1 parent 99ed7e30

Implement virtio_net link status (Mark McLoughlin)

Implement the VIRTIO_NET_F_STATUS feature by exposing the link status
through virtio_net_config::status.

Signed-off-by: Mark McLoughlin <markmc@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6250 c046a42c-6fe2-441c-8c8c-71466251a162
hw/virtio-net.c
... ... @@ -20,6 +20,7 @@ typedef struct VirtIONet
20 20 {
21 21 VirtIODevice vdev;
22 22 uint8_t mac[6];
  23 + uint16_t status;
23 24 VirtQueue *rx_vq;
24 25 VirtQueue *tx_vq;
25 26 VLANClientState *vc;
... ... @@ -42,13 +43,28 @@ static void virtio_net_update_config(VirtIODevice *vdev, uint8_t *config)
42 43 VirtIONet *n = to_virtio_net(vdev);
43 44 struct virtio_net_config netcfg;
44 45  
  46 + netcfg.status = n->status;
45 47 memcpy(netcfg.mac, n->mac, 6);
46 48 memcpy(config, &netcfg, sizeof(netcfg));
47 49 }
48 50  
  51 +static void virtio_net_set_link_status(VLANClientState *vc)
  52 +{
  53 + VirtIONet *n = vc->opaque;
  54 + uint16_t old_status = n->status;
  55 +
  56 + if (vc->link_down)
  57 + n->status &= ~VIRTIO_NET_S_LINK_UP;
  58 + else
  59 + n->status |= VIRTIO_NET_S_LINK_UP;
  60 +
  61 + if (n->status != old_status)
  62 + virtio_notify_config(&n->vdev);
  63 +}
  64 +
49 65 static uint32_t virtio_net_get_features(VirtIODevice *vdev)
50 66 {
51   - uint32_t features = (1 << VIRTIO_NET_F_MAC);
  67 + uint32_t features = (1 << VIRTIO_NET_F_MAC) | (1 << VIRTIO_NET_F_STATUS);
52 68  
53 69 return features;
54 70 }
... ... @@ -307,7 +323,8 @@ PCIDevice *virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn)
307 323 n = (VirtIONet *)virtio_init_pci(bus, "virtio-net", 6900, 0x1000,
308 324 0, VIRTIO_ID_NET,
309 325 0x02, 0x00, 0x00,
310   - 6, sizeof(VirtIONet));
  326 + sizeof(struct virtio_net_config),
  327 + sizeof(VirtIONet));
311 328 if (!n)
312 329 return NULL;
313 330  
... ... @@ -317,8 +334,10 @@ PCIDevice *virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn)
317 334 n->rx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_rx);
318 335 n->tx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_tx);
319 336 memcpy(n->mac, nd->macaddr, 6);
  337 + n->status = VIRTIO_NET_S_LINK_UP;
320 338 n->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
321 339 virtio_net_receive, virtio_net_can_receive, n);
  340 + n->vc->link_status_changed = virtio_net_set_link_status;
322 341  
323 342 qemu_format_nic_info_str(n->vc, n->mac);
324 343  
... ...
hw/virtio-net.h
... ... @@ -37,16 +37,21 @@
37 37 #define VIRTIO_NET_F_HOST_ECN 13 /* Host can handle TSO[6] w/ ECN in. */
38 38 #define VIRTIO_NET_F_HOST_UFO 14 /* Host can handle UFO in. */
39 39 #define VIRTIO_NET_F_MRG_RXBUF 15 /* Host can merge receive buffers. */
  40 +#define VIRTIO_NET_F_STATUS 16 /* virtio_net_config.status available */
  41 +
  42 +#define VIRTIO_NET_S_LINK_UP 1 /* Link is up */
40 43  
41 44 #define TX_TIMER_INTERVAL 150000 /* 150 us */
42 45  
43 46 /* Maximum packet size we can receive from tap device: header + 64k */
44 47 #define VIRTIO_NET_MAX_BUFSIZE (sizeof(struct virtio_net_hdr) + (64 << 10))
45 48  
46   -/* The config defining mac address (6 bytes) */
47 49 struct virtio_net_config
48 50 {
  51 + /* The config defining mac address (6 bytes) */
49 52 uint8_t mac[6];
  53 + /* See VIRTIO_NET_F_STATUS and VIRTIO_NET_S_* above */
  54 + uint16_t status;
50 55 } __attribute__((packed));
51 56  
52 57 /* This is the first element of the scatter-gather list. If you don't
... ...