]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/net/hyperv/rndis_filter.c
Merge tag 'for-linus-20170812' of git://git.infradead.org/linux-mtd
[karo-tx-linux.git] / drivers / net / hyperv / rndis_filter.c
index 85c00e1c52b6aa9309e782df639e03f444ffc1be..d6308ffda53ec797acf5f9e6038bf0a230008b55 100644 (file)
@@ -1048,8 +1048,8 @@ static void netvsc_sc_open(struct vmbus_channel *new_sc)
        else
                netif_napi_del(&nvchan->napi);
 
-       if (refcount_dec_and_test(&nvscdev->sc_offered))
-               complete(&nvscdev->channel_init_wait);
+       atomic_inc(&nvscdev->open_chn);
+       wake_up(&nvscdev->subchan_open);
 }
 
 int rndis_filter_device_add(struct hv_device *dev,
@@ -1090,8 +1090,6 @@ int rndis_filter_device_add(struct hv_device *dev,
        net_device->max_chn = 1;
        net_device->num_chn = 1;
 
-       refcount_set(&net_device->sc_offered, 0);
-
        net_device->extension = rndis_device;
        rndis_device->ndev = net;
 
@@ -1221,11 +1219,11 @@ int rndis_filter_device_add(struct hv_device *dev,
                rndis_device->ind_table[i] = ethtool_rxfh_indir_default(i,
                                                        net_device->num_chn);
 
+       atomic_set(&net_device->open_chn, 1);
        num_rss_qs = net_device->num_chn - 1;
        if (num_rss_qs == 0)
                return 0;
 
-       refcount_set(&net_device->sc_offered, num_rss_qs);
        vmbus_set_sc_create_callback(dev->channel, netvsc_sc_open);
 
        init_packet = &net_device->channel_init_pkt;
@@ -1242,15 +1240,19 @@ int rndis_filter_device_add(struct hv_device *dev,
        if (ret)
                goto out;
 
+       wait_for_completion(&net_device->channel_init_wait);
        if (init_packet->msg.v5_msg.subchn_comp.status != NVSP_STAT_SUCCESS) {
                ret = -ENODEV;
                goto out;
        }
-       wait_for_completion(&net_device->channel_init_wait);
 
        net_device->num_chn = 1 +
                init_packet->msg.v5_msg.subchn_comp.num_subchannels;
 
+       /* wait for all sub channels to open */
+       wait_event(net_device->subchan_open,
+                  atomic_read(&net_device->open_chn) == net_device->num_chn);
+
        /* ignore failues from setting rss parameters, still have channels */
        rndis_filter_set_rss_param(rndis_device, netvsc_hash_key,
                                   net_device->num_chn);