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 |