Staging: hv: vmbus: Introduce a utility function to match hv_vmbus_device_id
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / hv / netvsc_drv.c
index 30a0cb2c0fea5e15811b930fdb20fe76d2a181e3..30b9c80e2009db8bbe2cd8a833ec0818b4d4b61d 100644 (file)
@@ -140,12 +140,12 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
                         (num_pages * sizeof(struct hv_page_buffer)) +
                         sizeof(struct rndis_filter_packet), GFP_ATOMIC);
        if (!packet) {
-               /* out of memory, silently drop packet */
+               /* out of memory, drop packet */
                netdev_err(net, "unable to allocate hv_netvsc_packet\n");
 
                dev_kfree_skb(skb);
                net->stats.tx_dropped++;
-               return NETDEV_TX_OK;
+               return NETDEV_TX_BUSY;
        }
 
        packet->extension = (void *)(unsigned long)packet +
@@ -190,10 +190,11 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
        } else {
                /* we are shutting down or bus overloaded, just drop packet */
                net->stats.tx_dropped++;
-               netvsc_xmit_completion(packet);
+               kfree(packet);
+               dev_kfree_skb_any(skb);
        }
 
-       return NETDEV_TX_OK;
+       return ret ? NETDEV_TX_BUSY : NETDEV_TX_OK;
 }
 
 /*
@@ -214,8 +215,8 @@ void netvsc_linkstatus_callback(struct hv_device *device_obj,
        if (status == 1) {
                netif_carrier_on(net);
                netif_wake_queue(net);
-               netif_notify_peers(net);
                ndev_ctx = netdev_priv(net);
+               schedule_delayed_work(&ndev_ctx->dwork, 0);
                schedule_delayed_work(&ndev_ctx->dwork, msecs_to_jiffies(20));
        } else {
                netif_carrier_off(net);
@@ -348,19 +349,6 @@ static int netvsc_probe(struct hv_device *dev)
        dev_set_drvdata(&dev->device, net);
        INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_send_garp);
 
-       /* Notify the netvsc driver of the new device */
-       device_info.ring_size = ring_size;
-       ret = rndis_filter_device_add(dev, &device_info);
-       if (ret != 0) {
-               free_netdev(net);
-               dev_set_drvdata(&dev->device, NULL);
-               return ret;
-       }
-
-       netif_carrier_on(net);
-
-       memcpy(net->dev_addr, device_info.mac_adr, ETH_ALEN);
-
        net->netdev_ops = &device_ops;
 
        /* TODO: Add GSO and Checksum offload */
@@ -372,11 +360,26 @@ static int netvsc_probe(struct hv_device *dev)
 
        ret = register_netdev(net);
        if (ret != 0) {
-               /* Remove the device and release the resource */
-               rndis_filter_device_remove(dev);
+               pr_err("Unable to register netdev.\n");
                free_netdev(net);
+               goto out;
        }
 
+       /* Notify the netvsc driver of the new device */
+       device_info.ring_size = ring_size;
+       ret = rndis_filter_device_add(dev, &device_info);
+       if (ret != 0) {
+               netdev_err(net, "unable to add netvsc device (ret %d)\n", ret);
+               unregister_netdev(net);
+               free_netdev(net);
+               dev_set_drvdata(&dev->device, NULL);
+               return ret;
+       }
+       memcpy(net->dev_addr, device_info.mac_adr, ETH_ALEN);
+
+       netif_carrier_on(net);
+
+out:
        return ret;
 }