diff options
Diffstat (limited to 'drivers/net/hyperv/rndis_filter.c')
-rw-r--r-- | drivers/net/hyperv/rndis_filter.c | 88 |
1 files changed, 49 insertions, 39 deletions
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index c4e1e04..97c292b 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c @@ -126,11 +126,7 @@ static void put_rndis_request(struct rndis_device *dev, 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: @@ -211,6 +207,7 @@ static int rndis_filter_send_request(struct rndis_device *dev, 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; @@ -236,7 +233,7 @@ static int rndis_filter_send_request(struct rndis_device *dev, 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; } @@ -262,9 +259,7 @@ static void rndis_filter_receive_response(struct rndis_device *dev, 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) { @@ -355,6 +350,7 @@ static int rndis_filter_receive_data(struct rndis_device *dev, 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; @@ -368,7 +364,7 @@ static int rndis_filter_receive_data(struct rndis_device *dev, * 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); @@ -390,7 +386,7 @@ static int rndis_filter_receive_data(struct rndis_device *dev, } 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); } @@ -399,10 +395,11 @@ int rndis_filter_receive(struct hv_device *dev, 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) { @@ -410,8 +407,6 @@ int rndis_filter_receive(struct hv_device *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 - " @@ -430,7 +425,7 @@ int rndis_filter_receive(struct hv_device *dev, 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) { @@ -550,9 +545,10 @@ static int rndis_filter_query_device_mac(struct rndis_device *dev) 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; @@ -629,9 +625,10 @@ static int 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; @@ -703,7 +700,7 @@ u8 netvsc_hash_key[HASH_KEYLEN] = { 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; @@ -799,9 +796,7 @@ int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter) 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) + @@ -856,7 +851,8 @@ static int rndis_filter_init_device(struct rndis_device *dev) 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)); @@ -879,7 +875,6 @@ static int rndis_filter_init_device(struct rndis_device *dev) goto cleanup; } - t = wait_for_completion_timeout(&request->wait_event, 5*HZ); if (t == 0) { @@ -910,8 +905,9 @@ static void rndis_filter_halt_device(struct rndis_device *dev) { 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 */ @@ -979,13 +975,14 @@ static int rndis_filter_close_device(struct rndis_device *dev) 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; @@ -1010,6 +1007,8 @@ int rndis_filter_device_add(struct hv_device *dev, 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; @@ -1040,16 +1039,15 @@ int rndis_filter_device_add(struct hv_device *dev, 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); @@ -1063,8 +1061,8 @@ int rndis_filter_device_add(struct hv_device *dev, ret = rndis_filter_query_device(rndis_device, RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE, &mtu, &size); - if (ret == 0 && size == sizeof(u32) && mtu < net_device->ndev->mtu) - net_device->ndev->mtu = mtu; + if (ret == 0 && size == sizeof(u32) && mtu < net->mtu) + net->mtu = mtu; /* Get the mac address */ ret = rndis_filter_query_device_mac(rndis_device); @@ -1198,7 +1196,9 @@ err_dev_remv: 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; @@ -1224,20 +1224,30 @@ void rndis_filter_device_remove(struct hv_device *dev) 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; + if (atomic_inc_return(&net_device->open_cnt) != 1) + return 0; + return rndis_filter_open_device(net_device->extension); } 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; + if (atomic_dec_return(&nvdev->open_cnt) != 0) + return 0; + return rndis_filter_close_device(nvdev->extension); } |