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,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 |