Merge tag 'omap-fixes-against-v3.18-rc4' of git://git.kernel.org/pub/scm/linux/kernel...
[cascardo/linux.git] / drivers / net / virtio_net.c
index 3d0ce44..ec2a8b4 100644 (file)
@@ -123,9 +123,6 @@ struct virtnet_info {
        /* Host can handle any s/g split between our header and packet data */
        bool any_header_sg;
 
-       /* enable config space updates */
-       bool config_enable;
-
        /* Active statistics */
        struct virtnet_stats __percpu *stats;
 
@@ -135,9 +132,6 @@ struct virtnet_info {
        /* Work struct for config space updates */
        struct work_struct config_work;
 
-       /* Lock for config space updates */
-       struct mutex config_lock;
-
        /* Does the affinity hint is set for virtqueues? */
        bool affinity_hint_set;
 
@@ -497,8 +491,17 @@ static void receive_buf(struct receive_queue *rq, void *buf, unsigned int len)
                        skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
                        break;
                case VIRTIO_NET_HDR_GSO_UDP:
+               {
+                       static bool warned;
+
+                       if (!warned) {
+                               warned = true;
+                               netdev_warn(dev,
+                                           "host using disabled UFO feature; please fix it\n");
+                       }
                        skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
                        break;
+               }
                case VIRTIO_NET_HDR_GSO_TCPV6:
                        skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
                        break;
@@ -887,8 +890,6 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb)
                        hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
                else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
                        hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
-               else if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP)
-                       hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_UDP;
                else
                        BUG();
                if (skb_shinfo(skb)->gso_type & SKB_GSO_TCP_ECN)
@@ -920,6 +921,8 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
        int qnum = skb_get_queue_mapping(skb);
        struct send_queue *sq = &vi->sq[qnum];
        int err;
+       struct netdev_queue *txq = netdev_get_tx_queue(dev, qnum);
+       bool kick = !skb->xmit_more;
 
        /* Free up any pending old buffers before queueing new ones. */
        free_old_xmit_skbs(sq);
@@ -956,7 +959,7 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
                }
        }
 
-       if (__netif_subqueue_stopped(dev, qnum) || !skb->xmit_more)
+       if (kick || netif_xmit_stopped(txq))
                virtqueue_kick(sq->vq);
 
        return NETDEV_TX_OK;
@@ -1412,13 +1415,9 @@ static void virtnet_config_changed_work(struct work_struct *work)
                container_of(work, struct virtnet_info, config_work);
        u16 v;
 
-       mutex_lock(&vi->config_lock);
-       if (!vi->config_enable)
-               goto done;
-
        if (virtio_cread_feature(vi->vdev, VIRTIO_NET_F_STATUS,
                                 struct virtio_net_config, status, &v) < 0)
-               goto done;
+               return;
 
        if (v & VIRTIO_NET_S_ANNOUNCE) {
                netdev_notify_peers(vi->dev);
@@ -1429,7 +1428,7 @@ static void virtnet_config_changed_work(struct work_struct *work)
        v &= VIRTIO_NET_S_LINK_UP;
 
        if (vi->status == v)
-               goto done;
+               return;
 
        vi->status = v;
 
@@ -1440,8 +1439,6 @@ static void virtnet_config_changed_work(struct work_struct *work)
                netif_carrier_off(vi->dev);
                netif_tx_stop_all_queues(vi->dev);
        }
-done:
-       mutex_unlock(&vi->config_lock);
 }
 
 static void virtnet_config_changed(struct virtio_device *vdev)
@@ -1715,7 +1712,7 @@ static int virtnet_probe(struct virtio_device *vdev)
                        dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
 
                if (virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) {
-                       dev->hw_features |= NETIF_F_TSO | NETIF_F_UFO
+                       dev->hw_features |= NETIF_F_TSO
                                | NETIF_F_TSO_ECN | NETIF_F_TSO6;
                }
                /* Individual feature bits: what can host handle? */
@@ -1725,11 +1722,9 @@ static int virtnet_probe(struct virtio_device *vdev)
                        dev->hw_features |= NETIF_F_TSO6;
                if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN))
                        dev->hw_features |= NETIF_F_TSO_ECN;
-               if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UFO))
-                       dev->hw_features |= NETIF_F_UFO;
 
                if (gso)
-                       dev->features |= dev->hw_features & (NETIF_F_ALL_TSO|NETIF_F_UFO);
+                       dev->features |= dev->hw_features & NETIF_F_ALL_TSO;
                /* (!csum && gso) case will be fixed by register_netdev() */
        }
        if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_CSUM))
@@ -1762,15 +1757,12 @@ static int virtnet_probe(struct virtio_device *vdev)
                u64_stats_init(&virtnet_stats->rx_syncp);
        }
 
-       mutex_init(&vi->config_lock);
-       vi->config_enable = true;
        INIT_WORK(&vi->config_work, virtnet_config_changed_work);
 
        /* If we can receive ANY GSO packets, we must allocate large ones. */
        if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) ||
            virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6) ||
-           virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN) ||
-           virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_UFO))
+           virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN))
                vi->big_packets = true;
 
        if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF))
@@ -1811,6 +1803,8 @@ static int virtnet_probe(struct virtio_device *vdev)
                goto free_vqs;
        }
 
+       virtio_device_ready(vdev);
+
        /* Last of all, set up some receive buffers. */
        for (i = 0; i < vi->curr_queue_pairs; i++) {
                try_fill_recv(&vi->rq[i], GFP_KERNEL);
@@ -1847,6 +1841,8 @@ static int virtnet_probe(struct virtio_device *vdev)
        return 0;
 
 free_recv_bufs:
+       vi->vdev->config->reset(vdev);
+
        free_receive_bufs(vi);
        unregister_netdev(dev);
 free_vqs:
@@ -1880,17 +1876,13 @@ static void virtnet_remove(struct virtio_device *vdev)
 
        unregister_hotcpu_notifier(&vi->nb);
 
-       /* Prevent config work handler from accessing the device. */
-       mutex_lock(&vi->config_lock);
-       vi->config_enable = false;
-       mutex_unlock(&vi->config_lock);
+       /* Make sure no work handler is accessing the device. */
+       flush_work(&vi->config_work);
 
        unregister_netdev(vi->dev);
 
        remove_vq_common(vi);
 
-       flush_work(&vi->config_work);
-
        free_percpu(vi->stats);
        free_netdev(vi->dev);
 }
@@ -1903,10 +1895,8 @@ static int virtnet_freeze(struct virtio_device *vdev)
 
        unregister_hotcpu_notifier(&vi->nb);
 
-       /* Prevent config work handler from accessing the device */
-       mutex_lock(&vi->config_lock);
-       vi->config_enable = false;
-       mutex_unlock(&vi->config_lock);
+       /* Make sure no work handler is accessing the device */
+       flush_work(&vi->config_work);
 
        netif_device_detach(vi->dev);
        cancel_delayed_work_sync(&vi->refill);
@@ -1921,8 +1911,6 @@ static int virtnet_freeze(struct virtio_device *vdev)
 
        remove_vq_common(vi);
 
-       flush_work(&vi->config_work);
-
        return 0;
 }
 
@@ -1935,6 +1923,8 @@ static int virtnet_restore(struct virtio_device *vdev)
        if (err)
                return err;
 
+       virtio_device_ready(vdev);
+
        if (netif_running(vi->dev)) {
                for (i = 0; i < vi->curr_queue_pairs; i++)
                        if (!try_fill_recv(&vi->rq[i], GFP_KERNEL))
@@ -1946,10 +1936,6 @@ static int virtnet_restore(struct virtio_device *vdev)
 
        netif_device_attach(vi->dev);
 
-       mutex_lock(&vi->config_lock);
-       vi->config_enable = true;
-       mutex_unlock(&vi->config_lock);
-
        rtnl_lock();
        virtnet_set_queues(vi, vi->curr_queue_pairs);
        rtnl_unlock();
@@ -1970,9 +1956,9 @@ static struct virtio_device_id id_table[] = {
 static unsigned int features[] = {
        VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GUEST_CSUM,
        VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC,
-       VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6,
+       VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_TSO6,
        VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6,
-       VIRTIO_NET_F_GUEST_ECN, VIRTIO_NET_F_GUEST_UFO,
+       VIRTIO_NET_F_GUEST_ECN,
        VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ,
        VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN,
        VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ,