aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/hyperv/netvsc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-04-02 23:53:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-02 23:53:45 -0400
commitcd6362befe4cc7bf589a5236d2a780af2d47bcc9 (patch)
tree3bd4e13ec3f92a00dc4f6c3d65e820b54dbfe46e /drivers/net/hyperv/netvsc.c
parent0f1b1e6d73cb989ce2c071edc57deade3b084dfe (diff)
parentb1586f099ba897542ece36e8a23c1a62907261ef (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller: "Here is my initial pull request for the networking subsystem during this merge window: 1) Support for ESN in AH (RFC 4302) from Fan Du. 2) Add full kernel doc for ethtool command structures, from Ben Hutchings. 3) Add BCM7xxx PHY driver, from Florian Fainelli. 4) Export computed TCP rate information in netlink socket dumps, from Eric Dumazet. 5) Allow IPSEC SA to be dumped partially using a filter, from Nicolas Dichtel. 6) Convert many drivers to pci_enable_msix_range(), from Alexander Gordeev. 7) Record SKB timestamps more efficiently, from Eric Dumazet. 8) Switch to microsecond resolution for TCP round trip times, also from Eric Dumazet. 9) Clean up and fix 6lowpan fragmentation handling by making use of the existing inet_frag api for it's implementation. 10) Add TX grant mapping to xen-netback driver, from Zoltan Kiss. 11) Auto size SKB lengths when composing netlink messages based upon past message sizes used, from Eric Dumazet. 12) qdisc dumps can take a long time, add a cond_resched(), From Eric Dumazet. 13) Sanitize netpoll core and drivers wrt. SKB handling semantics. Get rid of never-used-in-tree netpoll RX handling. From Eric W Biederman. 14) Support inter-address-family and namespace changing in VTI tunnel driver(s). From Steffen Klassert. 15) Add Altera TSE driver, from Vince Bridgers. 16) Optimizing csum_replace2() so that it doesn't adjust the checksum by checksumming the entire header, from Eric Dumazet. 17) Expand BPF internal implementation for faster interpreting, more direct translations into JIT'd code, and much cleaner uses of BPF filtering in non-socket ocntexts. From Daniel Borkmann and Alexei Starovoitov" * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1976 commits) netpoll: Use skb_irq_freeable to make zap_completion_queue safe. net: Add a test to see if a skb is freeable in irq context qlcnic: Fix build failure due to undefined reference to `vxlan_get_rx_port' net: ptp: move PTP classifier in its own file net: sxgbe: make "core_ops" static net: sxgbe: fix logical vs bitwise operation net: sxgbe: sxgbe_mdio_register() frees the bus Call efx_set_channels() before efx->type->dimension_resources() xen-netback: disable rogue vif in kthread context net/mlx4: Set proper build dependancy with vxlan be2net: fix build dependency on VxLAN mac802154: make csma/cca parameters per-wpan mac802154: allow only one WPAN to be up at any given time net: filter: minor: fix kdoc in __sk_run_filter netlink: don't compare the nul-termination in nla_strcmp can: c_can: Avoid led toggling for every packet. can: c_can: Simplify TX interrupt cleanup can: c_can: Store dlc private can: c_can: Reduce register access can: c_can: Make the code readable ...
Diffstat (limited to 'drivers/net/hyperv/netvsc.c')
-rw-r--r--drivers/net/hyperv/netvsc.c93
1 files changed, 44 insertions, 49 deletions
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 03a2c6e17158..daddea2654ce 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -290,7 +290,7 @@ static int negotiate_nvsp_ver(struct hv_device *device,
290 NVSP_STAT_SUCCESS) 290 NVSP_STAT_SUCCESS)
291 return -EINVAL; 291 return -EINVAL;
292 292
293 if (nvsp_ver != NVSP_PROTOCOL_VERSION_2) 293 if (nvsp_ver == NVSP_PROTOCOL_VERSION_1)
294 return 0; 294 return 0;
295 295
296 /* NVSPv2 only: Send NDIS config */ 296 /* NVSPv2 only: Send NDIS config */
@@ -314,6 +314,9 @@ static int netvsc_connect_vsp(struct hv_device *device)
314 struct nvsp_message *init_packet; 314 struct nvsp_message *init_packet;
315 int ndis_version; 315 int ndis_version;
316 struct net_device *ndev; 316 struct net_device *ndev;
317 u32 ver_list[] = { NVSP_PROTOCOL_VERSION_1, NVSP_PROTOCOL_VERSION_2,
318 NVSP_PROTOCOL_VERSION_4, NVSP_PROTOCOL_VERSION_5 };
319 int i, num_ver = 4; /* number of different NVSP versions */
317 320
318 net_device = get_outbound_net_device(device); 321 net_device = get_outbound_net_device(device);
319 if (!net_device) 322 if (!net_device)
@@ -323,13 +326,14 @@ static int netvsc_connect_vsp(struct hv_device *device)
323 init_packet = &net_device->channel_init_pkt; 326 init_packet = &net_device->channel_init_pkt;
324 327
325 /* Negotiate the latest NVSP protocol supported */ 328 /* Negotiate the latest NVSP protocol supported */
326 if (negotiate_nvsp_ver(device, net_device, init_packet, 329 for (i = num_ver - 1; i >= 0; i--)
327 NVSP_PROTOCOL_VERSION_2) == 0) { 330 if (negotiate_nvsp_ver(device, net_device, init_packet,
328 net_device->nvsp_version = NVSP_PROTOCOL_VERSION_2; 331 ver_list[i]) == 0) {
329 } else if (negotiate_nvsp_ver(device, net_device, init_packet, 332 net_device->nvsp_version = ver_list[i];
330 NVSP_PROTOCOL_VERSION_1) == 0) { 333 break;
331 net_device->nvsp_version = NVSP_PROTOCOL_VERSION_1; 334 }
332 } else { 335
336 if (i < 0) {
333 ret = -EPROTO; 337 ret = -EPROTO;
334 goto cleanup; 338 goto cleanup;
335 } 339 }
@@ -339,7 +343,10 @@ static int netvsc_connect_vsp(struct hv_device *device)
339 /* Send the ndis version */ 343 /* Send the ndis version */
340 memset(init_packet, 0, sizeof(struct nvsp_message)); 344 memset(init_packet, 0, sizeof(struct nvsp_message));
341 345
342 ndis_version = 0x00050001; 346 if (net_device->nvsp_version <= NVSP_PROTOCOL_VERSION_4)
347 ndis_version = 0x00050001;
348 else
349 ndis_version = 0x0006001e;
343 350
344 init_packet->hdr.msg_type = NVSP_MSG1_TYPE_SEND_NDIS_VER; 351 init_packet->hdr.msg_type = NVSP_MSG1_TYPE_SEND_NDIS_VER;
345 init_packet->msg.v1_msg. 352 init_packet->msg.v1_msg.
@@ -358,6 +365,11 @@ static int netvsc_connect_vsp(struct hv_device *device)
358 goto cleanup; 365 goto cleanup;
359 366
360 /* Post the big receive buffer to NetVSP */ 367 /* Post the big receive buffer to NetVSP */
368 if (net_device->nvsp_version <= NVSP_PROTOCOL_VERSION_2)
369 net_device->recv_buf_size = NETVSC_RECEIVE_BUFFER_SIZE_LEGACY;
370 else
371 net_device->recv_buf_size = NETVSC_RECEIVE_BUFFER_SIZE;
372
361 ret = netvsc_init_recv_buf(device); 373 ret = netvsc_init_recv_buf(device);
362 374
363cleanup: 375cleanup:
@@ -432,17 +444,14 @@ static inline u32 hv_ringbuf_avail_percent(
432 return avail_write * 100 / ring_info->ring_datasize; 444 return avail_write * 100 / ring_info->ring_datasize;
433} 445}
434 446
435static void netvsc_send_completion(struct hv_device *device, 447static void netvsc_send_completion(struct netvsc_device *net_device,
448 struct hv_device *device,
436 struct vmpacket_descriptor *packet) 449 struct vmpacket_descriptor *packet)
437{ 450{
438 struct netvsc_device *net_device;
439 struct nvsp_message *nvsp_packet; 451 struct nvsp_message *nvsp_packet;
440 struct hv_netvsc_packet *nvsc_packet; 452 struct hv_netvsc_packet *nvsc_packet;
441 struct net_device *ndev; 453 struct net_device *ndev;
442 454
443 net_device = get_inbound_net_device(device);
444 if (!net_device)
445 return;
446 ndev = net_device->ndev; 455 ndev = net_device->ndev;
447 456
448 nvsp_packet = (struct nvsp_message *)((unsigned long)packet + 457 nvsp_packet = (struct nvsp_message *)((unsigned long)packet +
@@ -561,13 +570,13 @@ int netvsc_send(struct hv_device *device,
561} 570}
562 571
563static void netvsc_send_recv_completion(struct hv_device *device, 572static void netvsc_send_recv_completion(struct hv_device *device,
573 struct netvsc_device *net_device,
564 u64 transaction_id, u32 status) 574 u64 transaction_id, u32 status)
565{ 575{
566 struct nvsp_message recvcompMessage; 576 struct nvsp_message recvcompMessage;
567 int retries = 0; 577 int retries = 0;
568 int ret; 578 int ret;
569 struct net_device *ndev; 579 struct net_device *ndev;
570 struct netvsc_device *net_device = hv_get_drvdata(device);
571 580
572 ndev = net_device->ndev; 581 ndev = net_device->ndev;
573 582
@@ -653,14 +662,15 @@ static void netvsc_receive_completion(void *context)
653 662
654 /* Send a receive completion for the xfer page packet */ 663 /* Send a receive completion for the xfer page packet */
655 if (fsend_receive_comp) 664 if (fsend_receive_comp)
656 netvsc_send_recv_completion(device, transaction_id, status); 665 netvsc_send_recv_completion(device, net_device, transaction_id,
666 status);
657 667
658} 668}
659 669
660static void netvsc_receive(struct hv_device *device, 670static void netvsc_receive(struct netvsc_device *net_device,
661 struct vmpacket_descriptor *packet) 671 struct hv_device *device,
672 struct vmpacket_descriptor *packet)
662{ 673{
663 struct netvsc_device *net_device;
664 struct vmtransfer_page_packet_header *vmxferpage_packet; 674 struct vmtransfer_page_packet_header *vmxferpage_packet;
665 struct nvsp_message *nvsp_packet; 675 struct nvsp_message *nvsp_packet;
666 struct hv_netvsc_packet *netvsc_packet = NULL; 676 struct hv_netvsc_packet *netvsc_packet = NULL;
@@ -673,9 +683,6 @@ static void netvsc_receive(struct hv_device *device,
673 683
674 LIST_HEAD(listHead); 684 LIST_HEAD(listHead);
675 685
676 net_device = get_inbound_net_device(device);
677 if (!net_device)
678 return;
679 ndev = net_device->ndev; 686 ndev = net_device->ndev;
680 687
681 /* 688 /*
@@ -741,7 +748,7 @@ static void netvsc_receive(struct hv_device *device,
741 spin_unlock_irqrestore(&net_device->recv_pkt_list_lock, 748 spin_unlock_irqrestore(&net_device->recv_pkt_list_lock,
742 flags); 749 flags);
743 750
744 netvsc_send_recv_completion(device, 751 netvsc_send_recv_completion(device, net_device,
745 vmxferpage_packet->d.trans_id, 752 vmxferpage_packet->d.trans_id,
746 NVSP_STAT_FAIL); 753 NVSP_STAT_FAIL);
747 754
@@ -800,22 +807,16 @@ static void netvsc_channel_cb(void *context)
800 struct netvsc_device *net_device; 807 struct netvsc_device *net_device;
801 u32 bytes_recvd; 808 u32 bytes_recvd;
802 u64 request_id; 809 u64 request_id;
803 unsigned char *packet;
804 struct vmpacket_descriptor *desc; 810 struct vmpacket_descriptor *desc;
805 unsigned char *buffer; 811 unsigned char *buffer;
806 int bufferlen = NETVSC_PACKET_SIZE; 812 int bufferlen = NETVSC_PACKET_SIZE;
807 struct net_device *ndev; 813 struct net_device *ndev;
808 814
809 packet = kzalloc(NETVSC_PACKET_SIZE * sizeof(unsigned char),
810 GFP_ATOMIC);
811 if (!packet)
812 return;
813 buffer = packet;
814
815 net_device = get_inbound_net_device(device); 815 net_device = get_inbound_net_device(device);
816 if (!net_device) 816 if (!net_device)
817 goto out; 817 return;
818 ndev = net_device->ndev; 818 ndev = net_device->ndev;
819 buffer = net_device->cb_buffer;
819 820
820 do { 821 do {
821 ret = vmbus_recvpacket_raw(device->channel, buffer, bufferlen, 822 ret = vmbus_recvpacket_raw(device->channel, buffer, bufferlen,
@@ -825,11 +826,13 @@ static void netvsc_channel_cb(void *context)
825 desc = (struct vmpacket_descriptor *)buffer; 826 desc = (struct vmpacket_descriptor *)buffer;
826 switch (desc->type) { 827 switch (desc->type) {
827 case VM_PKT_COMP: 828 case VM_PKT_COMP:
828 netvsc_send_completion(device, desc); 829 netvsc_send_completion(net_device,
830 device, desc);
829 break; 831 break;
830 832
831 case VM_PKT_DATA_USING_XFER_PAGES: 833 case VM_PKT_DATA_USING_XFER_PAGES:
832 netvsc_receive(device, desc); 834 netvsc_receive(net_device,
835 device, desc);
833 break; 836 break;
834 837
835 default: 838 default:
@@ -841,23 +844,16 @@ static void netvsc_channel_cb(void *context)
841 break; 844 break;
842 } 845 }
843 846
844 /* reset */
845 if (bufferlen > NETVSC_PACKET_SIZE) {
846 kfree(buffer);
847 buffer = packet;
848 bufferlen = NETVSC_PACKET_SIZE;
849 }
850 } else { 847 } else {
851 /* reset */ 848 /*
852 if (bufferlen > NETVSC_PACKET_SIZE) { 849 * We are done for this pass.
853 kfree(buffer); 850 */
854 buffer = packet;
855 bufferlen = NETVSC_PACKET_SIZE;
856 }
857
858 break; 851 break;
859 } 852 }
853
860 } else if (ret == -ENOBUFS) { 854 } else if (ret == -ENOBUFS) {
855 if (bufferlen > NETVSC_PACKET_SIZE)
856 kfree(buffer);
861 /* Handle large packet */ 857 /* Handle large packet */
862 buffer = kmalloc(bytes_recvd, GFP_ATOMIC); 858 buffer = kmalloc(bytes_recvd, GFP_ATOMIC);
863 if (buffer == NULL) { 859 if (buffer == NULL) {
@@ -872,8 +868,8 @@ static void netvsc_channel_cb(void *context)
872 } 868 }
873 } while (1); 869 } while (1);
874 870
875out: 871 if (bufferlen > NETVSC_PACKET_SIZE)
876 kfree(buffer); 872 kfree(buffer);
877 return; 873 return;
878} 874}
879 875
@@ -907,7 +903,6 @@ int netvsc_device_add(struct hv_device *device, void *additional_info)
907 ndev = net_device->ndev; 903 ndev = net_device->ndev;
908 904
909 /* Initialize the NetVSC channel extension */ 905 /* Initialize the NetVSC channel extension */
910 net_device->recv_buf_size = NETVSC_RECEIVE_BUFFER_SIZE;
911 spin_lock_init(&net_device->recv_pkt_list_lock); 906 spin_lock_init(&net_device->recv_pkt_list_lock);
912 907
913 INIT_LIST_HEAD(&net_device->recv_pkt_list); 908 INIT_LIST_HEAD(&net_device->recv_pkt_list);