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.c45
1 files changed, 18 insertions, 27 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index f0bb1a4c8323..52198f6797a4 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -843,6 +843,10 @@ static int virtnet_probe(struct virtio_device *vdev)
843 int err; 843 int err;
844 struct net_device *dev; 844 struct net_device *dev;
845 struct virtnet_info *vi; 845 struct virtnet_info *vi;
846 struct virtqueue *vqs[3];
847 vq_callback_t *callbacks[] = { skb_recv_done, skb_xmit_done, NULL};
848 const char *names[] = { "input", "output", "control" };
849 int nvqs;
846 850
847 /* Allocate ourselves a network device with room for our info */ 851 /* Allocate ourselves a network device with room for our info */
848 dev = alloc_etherdev(sizeof(struct virtnet_info)); 852 dev = alloc_etherdev(sizeof(struct virtnet_info));
@@ -903,25 +907,19 @@ static int virtnet_probe(struct virtio_device *vdev)
903 if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF)) 907 if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF))
904 vi->mergeable_rx_bufs = true; 908 vi->mergeable_rx_bufs = true;
905 909
906 /* We expect two virtqueues, receive then send. */ 910 /* We expect two virtqueues, receive then send,
907 vi->rvq = vdev->config->find_vq(vdev, 0, skb_recv_done); 911 * and optionally control. */
908 if (IS_ERR(vi->rvq)) { 912 nvqs = virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ) ? 3 : 2;
909 err = PTR_ERR(vi->rvq); 913
914 err = vdev->config->find_vqs(vdev, nvqs, vqs, callbacks, names);
915 if (err)
910 goto free; 916 goto free;
911 }
912 917
913 vi->svq = vdev->config->find_vq(vdev, 1, skb_xmit_done); 918 vi->rvq = vqs[0];
914 if (IS_ERR(vi->svq)) { 919 vi->svq = vqs[1];
915 err = PTR_ERR(vi->svq);
916 goto free_recv;
917 }
918 920
919 if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)) { 921 if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)) {
920 vi->cvq = vdev->config->find_vq(vdev, 2, NULL); 922 vi->cvq = vqs[2];
921 if (IS_ERR(vi->cvq)) {
922 err = PTR_ERR(vi->svq);
923 goto free_send;
924 }
925 923
926 if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VLAN)) 924 if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VLAN))
927 dev->features |= NETIF_F_HW_VLAN_FILTER; 925 dev->features |= NETIF_F_HW_VLAN_FILTER;
@@ -939,7 +937,7 @@ static int virtnet_probe(struct virtio_device *vdev)
939 err = register_netdev(dev); 937 err = register_netdev(dev);
940 if (err) { 938 if (err) {
941 pr_debug("virtio_net: registering device failed\n"); 939 pr_debug("virtio_net: registering device failed\n");
942 goto free_ctrl; 940 goto free_vqs;
943 } 941 }
944 942
945 /* Last of all, set up some receive buffers. */ 943 /* Last of all, set up some receive buffers. */
@@ -960,13 +958,8 @@ static int virtnet_probe(struct virtio_device *vdev)
960 958
961unregister: 959unregister:
962 unregister_netdev(dev); 960 unregister_netdev(dev);
963free_ctrl: 961free_vqs:
964 if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)) 962 vdev->config->del_vqs(vdev);
965 vdev->config->del_vq(vi->cvq);
966free_send:
967 vdev->config->del_vq(vi->svq);
968free_recv:
969 vdev->config->del_vq(vi->rvq);
970free: 963free:
971 free_netdev(dev); 964 free_netdev(dev);
972 return err; 965 return err;
@@ -992,12 +985,10 @@ static void virtnet_remove(struct virtio_device *vdev)
992 985
993 BUG_ON(vi->num != 0); 986 BUG_ON(vi->num != 0);
994 987
995 vdev->config->del_vq(vi->svq);
996 vdev->config->del_vq(vi->rvq);
997 if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ))
998 vdev->config->del_vq(vi->cvq);
999 unregister_netdev(vi->dev); 988 unregister_netdev(vi->dev);
1000 989
990 vdev->config->del_vqs(vi->vdev);
991
1001 while (vi->pages) 992 while (vi->pages)
1002 __free_pages(get_a_page(vi, GFP_KERNEL), 0); 993 __free_pages(get_a_page(vi, GFP_KERNEL), 0);
1003 994