Commit 554c97dd43e021b626c78ed5bd72bca33d5cb99c
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
Showing
2 changed files
with
27 additions
and
3 deletions
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 | ... | ... |