virtio-net: Add a virtqueue for control commands from the guest
PATCH 2/5 virtio-net: Add a virtqueue for control commands from the guest
This will be used for RX mode, MAC table, VLAN table control, etc...
Signed-off-by Alex Williamson <[email protected]>
---
qemu/hw/virtio-net.c | 32 ++++++++++++++++++++++++++++++++ qemu/hw/virtio-net.h | 3 +++ 2 files changed, 35 insertions(+), 0 deletions(-)
qemu/hw/virtio-net.c +32 -0
@@ -27,6 +27,7 @@ typedef struct VirtIONetuint8_t mac[6 ];VirtQueue *rx_vq;VirtQueue *tx_vq; +VirtQueue *ctrl_vq;VLANClientState *vc;QEMUTimer *tx_timer;int tx_timer_active;
@@ -110,6 +111,36 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)#endif } +static void virtio_net_handle_ctrl (VirtIODevice *vdev,VirtQueue *vq) +{ +struct { +uint8_t class; +uint8_t cmd; + } *ctrl; +uint8_t *status; +VirtQueueElement elem; + +while (virtqueue_pop (vq, &elem)) { +if ((elem.in_num <1 ) | (elem.out_num <1 )) { +fprintf (stderr,"virtio-net ctrl missing headers\n" ); +exit (1 ); + } + +if (elem.out_sg[0 ].iov_len <sizeof (*ctrl) || + elem.out_sg[elem.in_num -1 ].iov_len <sizeof (*status)) { +fprintf (stderr,"virtio-net ctrl header not in correct element\n" ); +exit (1 ); + } + + ctrl = (void *)elem.out_sg[0 ].iov_base; + status = (void *)elem.in_sg[elem.in_num -1 ].iov_base; + *status =VIRTIO_NET_ERR ; + +virtqueue_push (vq, &elem,sizeof (*status)); +virtio_notify (vdev, vq); + } +} +/* RX */ static void virtio_net_handle_rx (VirtIODevice *vdev,VirtQueue *vq)
@@ -424,6 +455,7 @@ PCIDevice *virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn) n->vdev.set_features = virtio_net_set_features; n->rx_vq =virtio_add_queue (&n->vdev,256 , virtio_net_handle_rx); n->tx_vq =virtio_add_queue (&n->vdev,256 , virtio_net_handle_tx); + n->ctrl_vq =virtio_add_queue (&n->vdev,16 , virtio_net_handle_ctrl);memcpy (n->mac, nd->macaddr,6 ); n->vc =qemu_new_vlan_client (nd->vlan, nd->model, nd->name, virtio_net_receive, virtio_net_can_receive, n);
qemu/hw/virtio-net.h +3 -0
@@ -77,4 +77,7 @@ struct virtio_net_hdr_mrg_rxbufPCIDevice *virtio_net_init (PCIBus *bus,NICInfo *nd,int devfn); +#define VIRTIO_NET_OK 0 +#define VIRTIO_NET_ERR 1 +#endif
Quoted 17 lines · Alex Williamson
qemu/hw/virtio-net.c +13
-0@@ -110,6 +111,36 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)#endif } +static void virtio_net_handle_ctrl (VirtIODevice *vdev,VirtQueue *vq) +{ +struct { +uint8_t class; +uint8_t cmd; + } *ctrl; +uint8_t *status; +VirtQueueElement elem; + +while (virtqueue_pop (vq, &elem)) { +if ((elem.in_num <1 ) | (elem.out_num <1 )) { +fprintf (stderr,"virtio-net ctrl missing headers\n" ); +exit (1 );
qemu/hw/virtio-net.c static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features) · line 136
Quoted 10 lines
qemu/hw/virtio-net.c +10
-0+ } + +if (elem.out_sg[0 ].iov_len <sizeof (*ctrl) || + elem.out_sg[elem.in_num -1 ].iov_len <sizeof (*status)) { +fprintf (stderr,"virtio-net ctrl header not in correct element\n" ); +exit (1 ); + } + + ctrl = (void *)elem.out_sg[0 ].iov_base; + status = (void *)elem.in_sg[elem.in_num -1 ].iov_base;
These casts aren't needed - iov_base is a void pointer.
Cheers,
Mark.
Quoted 6 lines · Mark McLoughlin
qemu/hw/virtio-net.c static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features) · line 136
Quoted 3 lines · Alex Williamson
qemu/hw/virtio-net.c +3
-0+ + ctrl = (void *)elem.out_sg[0 ].iov_base; + status = (void *)elem.in_sg[elem.in_num -1 ].iov_base;These casts aren't needed -
iov_baseis a void pointer.
Thanks
Alex
Signature · 1 line
Alex Williamson HP Open Source & Linux Org.