};
 
 struct rndis_device {
-       struct netvsc_device *net_dev;
+       struct net_device *ndev;
 
        enum rndis_device_state state;
        bool link_state;
 
 /* Interface */
 struct rndis_message;
+struct netvsc_device;
 int netvsc_device_add(struct hv_device *device, void *additional_info);
 int netvsc_device_remove(struct hv_device *device);
 int netvsc_send(struct hv_device *device,
 struct net_device_context {
        /* point back to our device context */
        struct hv_device *device_ctx;
+       /* netvsc_device */
+       struct netvsc_device *nvdev;
        /* reconfigure work */
        struct delayed_work dwork;
        /* last reconfig time */
 
 /* Per netvsc device */
 struct netvsc_device {
-       struct hv_device *dev;
-
        u32 nvsp_version;
 
        atomic_t num_outstanding_sends;
        u32 max_pkt; /* max number of pkt in one send, e.g. 8 */
        u32 pkt_align; /* alignment bytes, e.g. 8 */
 
-       /* The net device context */
-       struct net_device_context *nd_ctx;
-
        /* 1: allocated, serial number is valid. 0: not allocated */
        u32 vf_alloc;
        /* Serial number of the VF to team with */
 
 void netvsc_switch_datapath(struct netvsc_device *nv_dev, bool vf)
 {
        struct nvsp_message *init_pkt = &nv_dev->channel_init_pkt;
-       struct hv_device *dev = nv_dev->dev;
+       struct net_device *ndev = nv_dev->ndev;
+       struct net_device_context *net_device_ctx = netdev_priv(ndev);
+       struct hv_device *dev = net_device_ctx->device_ctx;
 
        memset(init_pkt, 0, sizeof(struct nvsp_message));
        init_pkt->hdr.msg_type = NVSP_MSG4_TYPE_SWITCH_DATA_PATH;
 {
        struct netvsc_device *net_device;
        struct net_device *ndev = hv_get_drvdata(device);
+       struct net_device_context *net_device_ctx = netdev_priv(ndev);
 
        net_device = kzalloc(sizeof(struct netvsc_device), GFP_KERNEL);
        if (!net_device)
        net_device->destroy = false;
        atomic_set(&net_device->open_cnt, 0);
        atomic_set(&net_device->vf_use_cnt, 0);
-       net_device->dev = device;
        net_device->ndev = ndev;
        net_device->max_pkt = RNDIS_MAX_PKT_DEFAULT;
        net_device->pkt_align = RNDIS_PKT_ALIGN_DEFAULT;
        net_device->vf_netdev = NULL;
        net_device->vf_inject = false;
 
-       hv_set_drvdata(device, net_device);
+       net_device_ctx->nvdev = net_device;
+
        return net_device;
 }
 
 
 static struct netvsc_device *get_outbound_net_device(struct hv_device *device)
 {
-       struct netvsc_device *net_device;
+       struct net_device *ndev = hv_get_drvdata(device);
+       struct net_device_context *net_device_ctx = netdev_priv(ndev);
+       struct netvsc_device *net_device = net_device_ctx->nvdev;
 
-       net_device = hv_get_drvdata(device);
        if (net_device && net_device->destroy)
                net_device = NULL;
 
 
 static struct netvsc_device *get_inbound_net_device(struct hv_device *device)
 {
-       struct netvsc_device *net_device;
-
-       net_device = hv_get_drvdata(device);
+       struct net_device *ndev = hv_get_drvdata(device);
+       struct net_device_context *net_device_ctx = netdev_priv(ndev);
+       struct netvsc_device *net_device = net_device_ctx->nvdev;
 
        if (!net_device)
                goto get_in_err;
 }
 
 
-static int netvsc_destroy_buf(struct netvsc_device *net_device)
+static int netvsc_destroy_buf(struct hv_device *device)
 {
        struct nvsp_message *revoke_packet;
        int ret = 0;
-       struct net_device *ndev = net_device->ndev;
+       struct net_device *ndev = hv_get_drvdata(device);
+       struct net_device_context *net_device_ctx = netdev_priv(ndev);
+       struct netvsc_device *net_device = net_device_ctx->nvdev;
 
        /*
         * If we got a section count, it means we received a
                revoke_packet->msg.v1_msg.
                revoke_recv_buf.id = NETVSC_RECEIVE_BUFFER_ID;
 
-               ret = vmbus_sendpacket(net_device->dev->channel,
+               ret = vmbus_sendpacket(device->channel,
                                       revoke_packet,
                                       sizeof(struct nvsp_message),
                                       (unsigned long)revoke_packet,
 
        /* Teardown the gpadl on the vsp end */
        if (net_device->recv_buf_gpadl_handle) {
-               ret = vmbus_teardown_gpadl(net_device->dev->channel,
-                          net_device->recv_buf_gpadl_handle);
+               ret = vmbus_teardown_gpadl(device->channel,
+                                          net_device->recv_buf_gpadl_handle);
 
                /* If we failed here, we might as well return and have a leak
                 * rather than continue and a bugchk
                revoke_packet->msg.v1_msg.revoke_send_buf.id =
                        NETVSC_SEND_BUFFER_ID;
 
-               ret = vmbus_sendpacket(net_device->dev->channel,
+               ret = vmbus_sendpacket(device->channel,
                                       revoke_packet,
                                       sizeof(struct nvsp_message),
                                       (unsigned long)revoke_packet,
        }
        /* Teardown the gpadl on the vsp end */
        if (net_device->send_buf_gpadl_handle) {
-               ret = vmbus_teardown_gpadl(net_device->dev->channel,
+               ret = vmbus_teardown_gpadl(device->channel,
                                           net_device->send_buf_gpadl_handle);
 
                /* If we failed here, we might as well return and have a leak
        goto exit;
 
 cleanup:
-       netvsc_destroy_buf(net_device);
+       netvsc_destroy_buf(device);
 
 exit:
        return ret;
        return ret;
 }
 
-static void netvsc_disconnect_vsp(struct netvsc_device *net_device)
+static void netvsc_disconnect_vsp(struct hv_device *device)
 {
-       netvsc_destroy_buf(net_device);
+       netvsc_destroy_buf(device);
 }
 
 /*
  */
 int netvsc_device_remove(struct hv_device *device)
 {
-       struct netvsc_device *net_device;
-       unsigned long flags;
-
-       net_device = hv_get_drvdata(device);
-
-       netvsc_disconnect_vsp(net_device);
+       struct net_device *ndev = hv_get_drvdata(device);
+       struct net_device_context *net_device_ctx = netdev_priv(ndev);
+       struct netvsc_device *net_device = net_device_ctx->nvdev;
 
-       /*
-        * Since we have already drained, we don't need to busy wait
-        * as was done in final_release_stor_device()
-        * Note that we cannot set the ext pointer to NULL until
-        * we have drained - to drain the outgoing packets, we need to
-        * allow incoming packets.
-        */
+       netvsc_disconnect_vsp(device);
 
-       spin_lock_irqsave(&device->channel->inbound_lock, flags);
-       hv_set_drvdata(device, NULL);
-       spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
+       net_device_ctx->nvdev = NULL;
 
        /*
         * At this point, no one should be accessing net_device
 {
        struct nvsp_message *nvsp_packet;
        struct hv_netvsc_packet *nvsc_packet;
-       struct net_device *ndev;
+       struct net_device *ndev = hv_get_drvdata(device);
+       struct net_device_context *net_device_ctx = netdev_priv(ndev);
        u32 send_index;
        struct sk_buff *skb;
 
-       ndev = net_device->ndev;
-
        nvsp_packet = (struct nvsp_message *)((unsigned long)packet +
                        (packet->offset8 << 3));
 
                        wake_up(&net_device->wait_drain);
 
                if (netif_tx_queue_stopped(netdev_get_tx_queue(ndev, q_idx)) &&
-                   !net_device->nd_ctx->start_remove &&
+                   !net_device_ctx->start_remove &&
                    (hv_ringbuf_avail_percent(&channel->outbound) >
                     RING_AVAIL_PERCENT_HIWATER || queue_sends < 1))
                                netif_tx_wake_queue(netdev_get_tx_queue(
 
        net_device->ring_size = ring_size;
 
-       /*
-        * Coming into this function, struct net_device * is
-        * registered as the driver private data.
-        * In alloc_net_device(), we register struct netvsc_device *
-        * as the driver private data and stash away struct net_device *
-        * in struct netvsc_device *.
-        */
-       ndev = net_device->ndev;
-
-       /* Add netvsc_device context to netvsc_device */
-       net_device->nd_ctx = netdev_priv(ndev);
+       ndev = hv_get_drvdata(device);
 
        /* Initialize the NetVSC channel extension */
        init_completion(&net_device->channel_init_wait);
 
        struct netvsc_device *nvdev;
        struct rndis_device *rdev;
 
-       nvdev = hv_get_drvdata(ndevctx->device_ctx);
+       nvdev = ndevctx->nvdev;
        if (nvdev == NULL || nvdev->ndev == NULL)
                return;
 
 {
        struct net_device_context *net_device_ctx = netdev_priv(net);
        struct hv_device *device_obj = net_device_ctx->device_ctx;
-       struct netvsc_device *nvdev;
+       struct netvsc_device *nvdev = net_device_ctx->nvdev;
        struct rndis_device *rdev;
        int ret = 0;
 
 
        netif_tx_wake_all_queues(net);
 
-       nvdev = hv_get_drvdata(device_obj);
        rdev = nvdev->extension;
        if (!rdev->link_state)
                netif_carrier_on(net);
 {
        struct net_device_context *net_device_ctx = netdev_priv(net);
        struct hv_device *device_obj = net_device_ctx->device_ctx;
-       struct netvsc_device *nvdev = hv_get_drvdata(device_obj);
+       struct netvsc_device *nvdev = net_device_ctx->nvdev;
        int ret;
        u32 aread, awrite, i, msec = 10, retry = 0, retry_max = 20;
        struct vmbus_channel *chn;
                        void *accel_priv, select_queue_fallback_t fallback)
 {
        struct net_device_context *net_device_ctx = netdev_priv(ndev);
-       struct hv_device *hdev =  net_device_ctx->device_ctx;
-       struct netvsc_device *nvsc_dev = hv_get_drvdata(hdev);
+       struct netvsc_device *nvsc_dev = net_device_ctx->nvdev;
        u32 hash;
        u16 q_idx = 0;
 
        struct rndis_indicate_status *indicate = &resp->msg.indicate_status;
        struct net_device *net;
        struct net_device_context *ndev_ctx;
-       struct netvsc_device *net_device;
        struct netvsc_reconfig *event;
        unsigned long flags;
 
            indicate->status != RNDIS_STATUS_MEDIA_DISCONNECT)
                return;
 
-       net_device = hv_get_drvdata(device_obj);
-       net = net_device->ndev;
+       net = hv_get_drvdata(device_obj);
 
        if (!net || net->reg_state != NETREG_REGISTERED)
                return;
                                struct vmbus_channel *channel,
                                u16 vlan_tci)
 {
-       struct net_device *net;
-       struct net_device_context *net_device_ctx;
+       struct net_device *net = hv_get_drvdata(device_obj);
+       struct net_device_context *net_device_ctx = netdev_priv(net);
        struct sk_buff *skb;
        struct sk_buff *vf_skb;
        struct netvsc_stats *rx_stats;
-       struct netvsc_device *netvsc_dev = hv_get_drvdata(device_obj);
+       struct netvsc_device *netvsc_dev = net_device_ctx->nvdev;
        u32 bytes_recvd = packet->total_data_buflen;
        int ret = 0;
 
-       net = netvsc_dev->ndev;
        if (!net || net->reg_state != NETREG_REGISTERED)
                return NVSP_STAT_FAIL;
 
                                struct ethtool_channels *channel)
 {
        struct net_device_context *net_device_ctx = netdev_priv(net);
-       struct hv_device *dev = net_device_ctx->device_ctx;
-       struct netvsc_device *nvdev = hv_get_drvdata(dev);
+       struct netvsc_device *nvdev = net_device_ctx->nvdev;
 
        if (nvdev) {
                channel->max_combined   = nvdev->max_chn;
 {
        struct net_device_context *net_device_ctx = netdev_priv(net);
        struct hv_device *dev = net_device_ctx->device_ctx;
-       struct netvsc_device *nvdev = hv_get_drvdata(dev);
+       struct netvsc_device *nvdev = net_device_ctx->nvdev;
        struct netvsc_device_info device_info;
        u32 num_chn;
        u32 max_chn;
 
        nvdev->num_chn = channels->combined_count;
 
-       net_device_ctx->device_ctx = dev;
-       hv_set_drvdata(dev, net);
-
        memset(&device_info, 0, sizeof(device_info));
        device_info.num_chn = nvdev->num_chn; /* passed to RNDIS */
        device_info.ring_size = ring_size;
                goto recover;
        }
 
-       nvdev = hv_get_drvdata(dev);
+       nvdev = net_device_ctx->nvdev;
 
        ret = netif_set_real_num_tx_queues(net, nvdev->num_chn);
        if (ret) {
 static int netvsc_change_mtu(struct net_device *ndev, int mtu)
 {
        struct net_device_context *ndevctx = netdev_priv(ndev);
-       struct hv_device *hdev =  ndevctx->device_ctx;
-       struct netvsc_device *nvdev = hv_get_drvdata(hdev);
+       struct netvsc_device *nvdev = ndevctx->nvdev;
+       struct hv_device *hdev = ndevctx->device_ctx;
        struct netvsc_device_info device_info;
        int limit = ETH_DATA_LEN;
        u32 num_chn;
 
        ndev->mtu = mtu;
 
-       ndevctx->device_ctx = hdev;
-       hv_set_drvdata(hdev, ndev);
-
        memset(&device_info, 0, sizeof(device_info));
        device_info.ring_size = ring_size;
        device_info.num_chn = num_chn;
        if (ndev_ctx->start_remove)
                goto out_unlock;
 
-       net_device = hv_get_drvdata(ndev_ctx->device_ctx);
+       net_device = ndev_ctx->nvdev;
        rdev = net_device->extension;
        net = net_device->ndev;
 
        if (netvsc_ctx == NULL)
                return NULL;
 
-       return hv_get_drvdata(netvsc_ctx->device_ctx);
+       return netvsc_ctx->nvdev;
 }
 
 static int netvsc_register_vf(struct net_device *vf_netdev)
        }
        memcpy(net->dev_addr, device_info.mac_adr, ETH_ALEN);
 
-       nvdev = hv_get_drvdata(dev);
+       nvdev = net_device_ctx->nvdev;
        netif_set_real_num_tx_queues(net, nvdev->num_chn);
        netif_set_real_num_rx_queues(net, nvdev->num_chn);
 
        struct net_device_context *ndev_ctx;
        struct netvsc_device *net_device;
 
-       net_device = hv_get_drvdata(dev);
-       net = net_device->ndev;
+       net = hv_get_drvdata(dev);
 
        if (net == NULL) {
                dev_err(&dev->device, "No net device to remove\n");
 
 
        ndev_ctx = netdev_priv(net);
+       net_device = ndev_ctx->nvdev;
+
        ndev_ctx->start_remove = true;
 
        cancel_delayed_work_sync(&ndev_ctx->dwork);
         */
        rndis_filter_device_remove(dev);
 
+       hv_set_drvdata(dev, NULL);
+
        netvsc_free_netdev(net);
        return 0;
 }
 
 static void dump_rndis_message(struct hv_device *hv_dev,
                        struct rndis_message *rndis_msg)
 {
-       struct net_device *netdev;
-       struct netvsc_device *net_device;
-
-       net_device = hv_get_drvdata(hv_dev);
-       netdev = net_device->ndev;
+       struct net_device *netdev = hv_get_drvdata(hv_dev);
 
        switch (rndis_msg->ndis_msg_type) {
        case RNDIS_MSG_PACKET:
        struct hv_netvsc_packet *packet;
        struct hv_page_buffer page_buf[2];
        struct hv_page_buffer *pb = page_buf;
+       struct net_device_context *net_device_ctx = netdev_priv(dev->ndev);
 
        /* Setup the packet to send it */
        packet = &req->pkt;
                        pb[0].len;
        }
 
-       ret = netvsc_send(dev->net_dev->dev, packet, NULL, &pb, NULL);
+       ret = netvsc_send(net_device_ctx->device_ctx, packet, NULL, &pb, NULL);
        return ret;
 }
 
        struct rndis_request *request = NULL;
        bool found = false;
        unsigned long flags;
-       struct net_device *ndev;
-
-       ndev = dev->net_dev->ndev;
+       struct net_device *ndev = dev->ndev;
 
        spin_lock_irqsave(&dev->request_lock, flags);
        list_for_each_entry(request, &dev->req_list, list_ent) {
        struct ndis_pkt_8021q_info *vlan;
        struct ndis_tcp_ip_checksum_info *csum_info;
        u16 vlan_tci = 0;
+       struct net_device_context *net_device_ctx = netdev_priv(dev->ndev);
 
        rndis_pkt = &msg->msg.pkt;
 
         * should be the data packet size plus the trailer padding size
         */
        if (pkt->total_data_buflen < rndis_pkt->data_len) {
-               netdev_err(dev->net_dev->ndev, "rndis message buffer "
+               netdev_err(dev->ndev, "rndis message buffer "
                           "overflow detected (got %u, min %u)"
                           "...dropping this message!\n",
                           pkt->total_data_buflen, rndis_pkt->data_len);
        }
 
        csum_info = rndis_get_ppi(rndis_pkt, TCPIP_CHKSUM_PKTINFO);
-       return netvsc_recv_callback(dev->net_dev->dev, pkt, data,
+       return netvsc_recv_callback(net_device_ctx->device_ctx, pkt, data,
                                    csum_info, channel, vlan_tci);
 }
 
                                void **data,
                                struct vmbus_channel *channel)
 {
-       struct netvsc_device *net_dev = hv_get_drvdata(dev);
+       struct net_device *ndev = hv_get_drvdata(dev);
+       struct net_device_context *net_device_ctx = netdev_priv(ndev);
+       struct netvsc_device *net_dev = net_device_ctx->nvdev;
        struct rndis_device *rndis_dev;
        struct rndis_message *rndis_msg;
-       struct net_device *ndev;
        int ret = 0;
 
        if (!net_dev) {
                goto exit;
        }
 
-       ndev = net_dev->ndev;
-
        /* Make sure the rndis device state is initialized */
        if (!net_dev->extension) {
                netdev_err(ndev, "got rndis message but no rndis device - "
 
        rndis_msg = *data;
 
-       if (netif_msg_rx_err(net_dev->nd_ctx))
+       if (netif_msg_rx_err(net_device_ctx))
                dump_rndis_message(dev, rndis_msg);
 
        switch (rndis_msg->ndis_msg_type) {
 
 int rndis_filter_set_device_mac(struct hv_device *hdev, char *mac)
 {
-       struct netvsc_device *nvdev = hv_get_drvdata(hdev);
+       struct net_device *ndev = hv_get_drvdata(hdev);
+       struct net_device_context *net_device_ctx = netdev_priv(ndev);
+       struct netvsc_device *nvdev = net_device_ctx->nvdev;
        struct rndis_device *rdev = nvdev->extension;
-       struct net_device *ndev = nvdev->ndev;
        struct rndis_request *request;
        struct rndis_set_request *set;
        struct rndis_config_parameter_info *cpi;
 rndis_filter_set_offload_params(struct hv_device *hdev,
                                struct ndis_offload_params *req_offloads)
 {
-       struct netvsc_device *nvdev = hv_get_drvdata(hdev);
+       struct net_device *ndev = hv_get_drvdata(hdev);
+       struct net_device_context *net_device_ctx = netdev_priv(ndev);
+       struct netvsc_device *nvdev = net_device_ctx->nvdev;
        struct rndis_device *rdev = nvdev->extension;
-       struct net_device *ndev = nvdev->ndev;
        struct rndis_request *request;
        struct rndis_set_request *set;
        struct ndis_offload_params *offload_params;
 
 static int rndis_filter_set_rss_param(struct rndis_device *rdev, int num_queue)
 {
-       struct net_device *ndev = rdev->net_dev->ndev;
+       struct net_device *ndev = rdev->ndev;
        struct rndis_request *request;
        struct rndis_set_request *set;
        struct rndis_set_complete *set_complete;
        u32 status;
        int ret;
        unsigned long t;
-       struct net_device *ndev;
-
-       ndev = dev->net_dev->ndev;
+       struct net_device *ndev = dev->ndev;
 
        request = get_rndis_request(dev, RNDIS_MSG_SET,
                        RNDIS_MESSAGE_SIZE(struct rndis_set_request) +
        u32 status;
        int ret;
        unsigned long t;
-       struct netvsc_device *nvdev = dev->net_dev;
+       struct net_device_context *net_device_ctx = netdev_priv(dev->ndev);
+       struct netvsc_device *nvdev = net_device_ctx->nvdev;
 
        request = get_rndis_request(dev, RNDIS_MSG_INIT,
                        RNDIS_MESSAGE_SIZE(struct rndis_initialize_request));
                goto cleanup;
        }
 
-
        t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
 
        if (t == 0) {
 {
        struct rndis_request *request;
        struct rndis_halt_request *halt;
-       struct netvsc_device *nvdev = dev->net_dev;
-       struct hv_device *hdev = nvdev->dev;
+       struct net_device_context *net_device_ctx = netdev_priv(dev->ndev);
+       struct netvsc_device *nvdev = net_device_ctx->nvdev;
+       struct hv_device *hdev = net_device_ctx->device_ctx;
        ulong flags;
 
        /* Attempt to do a rndis device halt */
 
 static void netvsc_sc_open(struct vmbus_channel *new_sc)
 {
-       struct netvsc_device *nvscdev;
+       struct net_device *ndev =
+               hv_get_drvdata(new_sc->primary_channel->device_obj);
+       struct net_device_context *net_device_ctx = netdev_priv(ndev);
+       struct netvsc_device *nvscdev = net_device_ctx->nvdev;
        u16 chn_index = new_sc->offermsg.offer.sub_channel_index;
        int ret;
        unsigned long flags;
 
-       nvscdev = hv_get_drvdata(new_sc->primary_channel->device_obj);
-
        if (chn_index >= nvscdev->num_chn)
                return;
 
                                  void *additional_info)
 {
        int ret;
+       struct net_device *net = hv_get_drvdata(dev);
+       struct net_device_context *net_device_ctx = netdev_priv(net);
        struct netvsc_device *net_device;
        struct rndis_device *rndis_device;
        struct netvsc_device_info *device_info = additional_info;
                return ret;
        }
 
-
        /* Initialize the rndis device */
-       net_device = hv_get_drvdata(dev);
+       net_device = net_device_ctx->nvdev;
        net_device->max_chn = 1;
        net_device->num_chn = 1;
 
        spin_lock_init(&net_device->sc_lock);
 
        net_device->extension = rndis_device;
-       rndis_device->net_dev = net_device;
+       rndis_device->ndev = net;
 
        /* Send the rndis initialization message */
        ret = rndis_filter_init_device(rndis_device);
 
 void rndis_filter_device_remove(struct hv_device *dev)
 {
-       struct netvsc_device *net_dev = hv_get_drvdata(dev);
+       struct net_device *ndev = hv_get_drvdata(dev);
+       struct net_device_context *net_device_ctx = netdev_priv(ndev);
+       struct netvsc_device *net_dev = net_device_ctx->nvdev;
        struct rndis_device *rndis_dev = net_dev->extension;
        unsigned long t;
 
 
 int rndis_filter_open(struct hv_device *dev)
 {
-       struct netvsc_device *net_device = hv_get_drvdata(dev);
+       struct net_device *ndev = hv_get_drvdata(dev);
+       struct net_device_context *net_device_ctx = netdev_priv(ndev);
+       struct netvsc_device *net_device = net_device_ctx->nvdev;
 
        if (!net_device)
                return -EINVAL;
 
 int rndis_filter_close(struct hv_device *dev)
 {
-       struct netvsc_device *nvdev = hv_get_drvdata(dev);
+       struct net_device *ndev = hv_get_drvdata(dev);
+       struct net_device_context *net_device_ctx = netdev_priv(ndev);
+       struct netvsc_device *nvdev = net_device_ctx->nvdev;
 
        if (!nvdev)
                return -EINVAL;