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