diff options
Diffstat (limited to 'drivers/net/hyperv/netvsc.c')
-rw-r--r-- | drivers/net/hyperv/netvsc.c | 51 |
1 files changed, 17 insertions, 34 deletions
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index 652453d9fb08..0a9167dd72fb 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c @@ -57,6 +57,8 @@ void netvsc_switch_datapath(struct net_device *ndev, bool vf) sizeof(struct nvsp_message), (unsigned long)init_pkt, VM_PKT_DATA_INBAND, 0); + + net_device_ctx->datapath = vf; } static struct netvsc_device *alloc_net_device(void) @@ -97,16 +99,6 @@ static void free_netvsc_device_rcu(struct netvsc_device *nvdev) call_rcu(&nvdev->rcu, free_netvsc_device); } -static struct netvsc_device *get_outbound_net_device(struct hv_device *device) -{ - struct netvsc_device *net_device = hv_device_to_netvsc_device(device); - - if (net_device && net_device->destroy) - net_device = NULL; - - return net_device; -} - static void netvsc_destroy_buf(struct hv_device *device) { struct nvsp_message *revoke_packet; @@ -243,18 +235,15 @@ static void netvsc_destroy_buf(struct hv_device *device) kfree(net_device->send_section_map); } -static int netvsc_init_buf(struct hv_device *device) +static int netvsc_init_buf(struct hv_device *device, + struct netvsc_device *net_device) { int ret = 0; - struct netvsc_device *net_device; struct nvsp_message *init_packet; struct net_device *ndev; size_t map_words; int node; - net_device = get_outbound_net_device(device); - if (!net_device) - return -ENODEV; ndev = hv_get_drvdata(device); node = cpu_to_node(device->channel->target_cpu); @@ -285,9 +274,7 @@ static int netvsc_init_buf(struct hv_device *device) /* Notify the NetVsp of the gpadl handle */ init_packet = &net_device->channel_init_pkt; - memset(init_packet, 0, sizeof(struct nvsp_message)); - init_packet->hdr.msg_type = NVSP_MSG1_TYPE_SEND_RECV_BUF; init_packet->msg.v1_msg.send_recv_buf. gpadl_handle = net_device->recv_buf_gpadl_handle; @@ -486,20 +473,15 @@ static int negotiate_nvsp_ver(struct hv_device *device, return ret; } -static int netvsc_connect_vsp(struct hv_device *device) +static int netvsc_connect_vsp(struct hv_device *device, + struct netvsc_device *net_device) { - int ret; - struct netvsc_device *net_device; - struct nvsp_message *init_packet; - int ndis_version; const u32 ver_list[] = { NVSP_PROTOCOL_VERSION_1, NVSP_PROTOCOL_VERSION_2, - NVSP_PROTOCOL_VERSION_4, NVSP_PROTOCOL_VERSION_5 }; - int i; - - net_device = get_outbound_net_device(device); - if (!net_device) - return -ENODEV; + NVSP_PROTOCOL_VERSION_4, NVSP_PROTOCOL_VERSION_5 + }; + struct nvsp_message *init_packet; + int ndis_version, i, ret; init_packet = &net_device->channel_init_pkt; @@ -549,7 +531,7 @@ static int netvsc_connect_vsp(struct hv_device *device) net_device->recv_buf_size = NETVSC_RECEIVE_BUFFER_SIZE; net_device->send_buf_size = NETVSC_SEND_BUFFER_SIZE; - ret = netvsc_init_buf(device); + ret = netvsc_init_buf(device, net_device); cleanup: return ret; @@ -843,7 +825,7 @@ int netvsc_send(struct hv_device *device, struct hv_page_buffer **pb, struct sk_buff *skb) { - struct netvsc_device *net_device; + struct netvsc_device *net_device = hv_device_to_netvsc_device(device); int ret = 0; struct netvsc_channel *nvchan; u32 pktlen = packet->total_data_buflen, msd_len = 0; @@ -854,15 +836,15 @@ int netvsc_send(struct hv_device *device, bool try_batch; bool xmit_more = (skb != NULL) ? skb->xmit_more : false; - net_device = get_outbound_net_device(device); - if (!net_device) + /* If device is rescinded, return error and packet will get dropped. */ + if (unlikely(net_device->destroy)) return -ENODEV; /* We may race with netvsc_connect_vsp()/netvsc_init_buf() and get * here before the negotiation with the host is finished and * send_section_map may not be allocated yet. */ - if (!net_device->send_section_map) + if (unlikely(!net_device->send_section_map)) return -EAGAIN; nvchan = &net_device->chan_table[packet->q_idx]; @@ -1349,7 +1331,7 @@ int netvsc_device_add(struct hv_device *device, rcu_assign_pointer(net_device_ctx->nvdev, net_device); /* Connect with the NetVsp */ - ret = netvsc_connect_vsp(device); + ret = netvsc_connect_vsp(device, net_device); if (ret != 0) { netdev_err(ndev, "unable to connect to NetVSP - %d\n", ret); @@ -1368,4 +1350,5 @@ cleanup: free_netvsc_device(&net_device->rcu); return ret; + } |