|
@@ -985,15 +985,38 @@ static void virtnet_config_changed(struct virtio_device *vdev)
|
|
|
virtnet_update_status(vi);
|
|
|
}
|
|
|
|
|
|
+static int init_vqs(struct virtnet_info *vi)
|
|
|
+{
|
|
|
+ struct virtqueue *vqs[3];
|
|
|
+ vq_callback_t *callbacks[] = { skb_recv_done, skb_xmit_done, NULL};
|
|
|
+ const char *names[] = { "input", "output", "control" };
|
|
|
+ int nvqs, err;
|
|
|
+
|
|
|
+ /* We expect two virtqueues, receive then send,
|
|
|
+ * and optionally control. */
|
|
|
+ nvqs = virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ) ? 3 : 2;
|
|
|
+
|
|
|
+ err = vi->vdev->config->find_vqs(vi->vdev, nvqs, vqs, callbacks, names);
|
|
|
+ if (err)
|
|
|
+ return err;
|
|
|
+
|
|
|
+ vi->rvq = vqs[0];
|
|
|
+ vi->svq = vqs[1];
|
|
|
+
|
|
|
+ if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)) {
|
|
|
+ vi->cvq = vqs[2];
|
|
|
+
|
|
|
+ if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VLAN))
|
|
|
+ vi->dev->features |= NETIF_F_HW_VLAN_FILTER;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static int virtnet_probe(struct virtio_device *vdev)
|
|
|
{
|
|
|
int err;
|
|
|
struct net_device *dev;
|
|
|
struct virtnet_info *vi;
|
|
|
- struct virtqueue *vqs[3];
|
|
|
- vq_callback_t *callbacks[] = { skb_recv_done, skb_xmit_done, NULL};
|
|
|
- const char *names[] = { "input", "output", "control" };
|
|
|
- int nvqs;
|
|
|
|
|
|
/* Allocate ourselves a network device with room for our info */
|
|
|
dev = alloc_etherdev(sizeof(struct virtnet_info));
|
|
@@ -1065,24 +1088,10 @@ static int virtnet_probe(struct virtio_device *vdev)
|
|
|
if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF))
|
|
|
vi->mergeable_rx_bufs = true;
|
|
|
|
|
|
- /* We expect two virtqueues, receive then send,
|
|
|
- * and optionally control. */
|
|
|
- nvqs = virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ) ? 3 : 2;
|
|
|
-
|
|
|
- err = vdev->config->find_vqs(vdev, nvqs, vqs, callbacks, names);
|
|
|
+ err = init_vqs(vi);
|
|
|
if (err)
|
|
|
goto free_stats;
|
|
|
|
|
|
- vi->rvq = vqs[0];
|
|
|
- vi->svq = vqs[1];
|
|
|
-
|
|
|
- if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)) {
|
|
|
- vi->cvq = vqs[2];
|
|
|
-
|
|
|
- if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VLAN))
|
|
|
- dev->features |= NETIF_F_HW_VLAN_FILTER;
|
|
|
- }
|
|
|
-
|
|
|
err = register_netdev(dev);
|
|
|
if (err) {
|
|
|
pr_debug("virtio_net: registering device failed\n");
|