aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/virtio_net.c68
-rw-r--r--include/linux/virtio_net.h18
2 files changed, 83 insertions, 3 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index fe576e75a538..67bb583b7fc9 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -37,10 +37,12 @@ module_param(gso, bool, 0444);
37#define MAX_PACKET_LEN (ETH_HLEN + VLAN_HLEN + ETH_DATA_LEN) 37#define MAX_PACKET_LEN (ETH_HLEN + VLAN_HLEN + ETH_DATA_LEN)
38#define GOOD_COPY_LEN 128 38#define GOOD_COPY_LEN 128
39 39
40#define VIRTNET_SEND_COMMAND_SG_MAX 0
41
40struct virtnet_info 42struct virtnet_info
41{ 43{
42 struct virtio_device *vdev; 44 struct virtio_device *vdev;
43 struct virtqueue *rvq, *svq; 45 struct virtqueue *rvq, *svq, *cvq;
44 struct net_device *dev; 46 struct net_device *dev;
45 struct napi_struct napi; 47 struct napi_struct napi;
46 unsigned int status; 48 unsigned int status;
@@ -589,6 +591,53 @@ static int virtnet_open(struct net_device *dev)
589 return 0; 591 return 0;
590} 592}
591 593
594/*
595 * Send command via the control virtqueue and check status. Commands
596 * supported by the hypervisor, as indicated by feature bits, should
597 * never fail unless improperly formated.
598 */
599static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
600 struct scatterlist *data, int out, int in)
601{
602 struct scatterlist sg[VIRTNET_SEND_COMMAND_SG_MAX + 2];
603 struct virtio_net_ctrl_hdr ctrl;
604 virtio_net_ctrl_ack status = ~0;
605 unsigned int tmp;
606
607 if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)) {
608 BUG(); /* Caller should know better */
609 return false;
610 }
611
612 BUG_ON(out + in > VIRTNET_SEND_COMMAND_SG_MAX);
613
614 out++; /* Add header */
615 in++; /* Add return status */
616
617 ctrl.class = class;
618 ctrl.cmd = cmd;
619
620 sg_init_table(sg, out + in);
621
622 sg_set_buf(&sg[0], &ctrl, sizeof(ctrl));
623 memcpy(&sg[1], data, sizeof(struct scatterlist) * (out + in - 2));
624 sg_set_buf(&sg[out + in - 1], &status, sizeof(status));
625
626 if (vi->cvq->vq_ops->add_buf(vi->cvq, sg, out, in, vi) != 0)
627 BUG();
628
629 vi->cvq->vq_ops->kick(vi->cvq);
630
631 /*
632 * Spin for a response, the kick causes an ioport write, trapping
633 * into the hypervisor, so the request should be handled immediately.
634 */
635 while (!vi->cvq->vq_ops->get_buf(vi->cvq, &tmp))
636 cpu_relax();
637
638 return status == VIRTIO_NET_OK;
639}
640
592static int virtnet_close(struct net_device *dev) 641static int virtnet_close(struct net_device *dev)
593{ 642{
594 struct virtnet_info *vi = netdev_priv(dev); 643 struct virtnet_info *vi = netdev_priv(dev);
@@ -752,6 +801,14 @@ static int virtnet_probe(struct virtio_device *vdev)
752 goto free_recv; 801 goto free_recv;
753 } 802 }
754 803
804 if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)) {
805 vi->cvq = vdev->config->find_vq(vdev, 2, NULL);
806 if (IS_ERR(vi->cvq)) {
807 err = PTR_ERR(vi->svq);
808 goto free_send;
809 }
810 }
811
755 /* Initialize our empty receive and send queues. */ 812 /* Initialize our empty receive and send queues. */
756 skb_queue_head_init(&vi->recv); 813 skb_queue_head_init(&vi->recv);
757 skb_queue_head_init(&vi->send); 814 skb_queue_head_init(&vi->send);
@@ -764,7 +821,7 @@ static int virtnet_probe(struct virtio_device *vdev)
764 err = register_netdev(dev); 821 err = register_netdev(dev);
765 if (err) { 822 if (err) {
766 pr_debug("virtio_net: registering device failed\n"); 823 pr_debug("virtio_net: registering device failed\n");
767 goto free_send; 824 goto free_ctrl;
768 } 825 }
769 826
770 /* Last of all, set up some receive buffers. */ 827 /* Last of all, set up some receive buffers. */
@@ -784,6 +841,9 @@ static int virtnet_probe(struct virtio_device *vdev)
784 841
785unregister: 842unregister:
786 unregister_netdev(dev); 843 unregister_netdev(dev);
844free_ctrl:
845 if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ))
846 vdev->config->del_vq(vi->cvq);
787free_send: 847free_send:
788 vdev->config->del_vq(vi->svq); 848 vdev->config->del_vq(vi->svq);
789free_recv: 849free_recv:
@@ -815,6 +875,8 @@ static void virtnet_remove(struct virtio_device *vdev)
815 875
816 vdev->config->del_vq(vi->svq); 876 vdev->config->del_vq(vi->svq);
817 vdev->config->del_vq(vi->rvq); 877 vdev->config->del_vq(vi->rvq);
878 if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ))
879 vdev->config->del_vq(vi->cvq);
818 unregister_netdev(vi->dev); 880 unregister_netdev(vi->dev);
819 881
820 while (vi->pages) 882 while (vi->pages)
@@ -834,7 +896,7 @@ static unsigned int features[] = {
834 VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6, 896 VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6,
835 VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6, 897 VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6,
836 VIRTIO_NET_F_GUEST_ECN, /* We don't yet handle UFO input. */ 898 VIRTIO_NET_F_GUEST_ECN, /* We don't yet handle UFO input. */
837 VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, 899 VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ,
838 VIRTIO_F_NOTIFY_ON_EMPTY, 900 VIRTIO_F_NOTIFY_ON_EMPTY,
839}; 901};
840 902
diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
index d8e362d52fd8..245eda829aa8 100644
--- a/include/linux/virtio_net.h
+++ b/include/linux/virtio_net.h
@@ -23,6 +23,7 @@
23#define VIRTIO_NET_F_HOST_UFO 14 /* Host can handle UFO in. */ 23#define VIRTIO_NET_F_HOST_UFO 14 /* Host can handle UFO in. */
24#define VIRTIO_NET_F_MRG_RXBUF 15 /* Host can merge receive buffers. */ 24#define VIRTIO_NET_F_MRG_RXBUF 15 /* Host can merge receive buffers. */
25#define VIRTIO_NET_F_STATUS 16 /* virtio_net_config.status available */ 25#define VIRTIO_NET_F_STATUS 16 /* virtio_net_config.status available */
26#define VIRTIO_NET_F_CTRL_VQ 17 /* Control channel available */
26 27
27#define VIRTIO_NET_S_LINK_UP 1 /* Link is up */ 28#define VIRTIO_NET_S_LINK_UP 1 /* Link is up */
28 29
@@ -59,4 +60,21 @@ struct virtio_net_hdr_mrg_rxbuf {
59 __u16 num_buffers; /* Number of merged rx buffers */ 60 __u16 num_buffers; /* Number of merged rx buffers */
60}; 61};
61 62
63/*
64 * Control virtqueue data structures
65 *
66 * The control virtqueue expects a header in the first sg entry
67 * and an ack/status response in the last entry. Data for the
68 * command goes in between.
69 */
70struct virtio_net_ctrl_hdr {
71 __u8 class;
72 __u8 cmd;
73} __attribute__((packed));
74
75typedef __u8 virtio_net_ctrl_ack;
76
77#define VIRTIO_NET_OK 0
78#define VIRTIO_NET_ERR 1
79
62#endif /* _LINUX_VIRTIO_NET_H */ 80#endif /* _LINUX_VIRTIO_NET_H */