aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/virtio_net.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/virtio_net.c')
-rw-r--r--drivers/net/virtio_net.c68
1 files changed, 65 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