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