diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-02 23:53:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-02 23:53:45 -0400 |
commit | cd6362befe4cc7bf589a5236d2a780af2d47bcc9 (patch) | |
tree | 3bd4e13ec3f92a00dc4f6c3d65e820b54dbfe46e /drivers/net/hyperv/netvsc.c | |
parent | 0f1b1e6d73cb989ce2c071edc57deade3b084dfe (diff) | |
parent | b1586f099ba897542ece36e8a23c1a62907261ef (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.c | 93 |
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 | ||
363 | cleanup: | 375 | cleanup: |
@@ -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 | ||
435 | static void netvsc_send_completion(struct hv_device *device, | 447 | static 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 | ||
563 | static void netvsc_send_recv_completion(struct hv_device *device, | 572 | static 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 | ||
660 | static void netvsc_receive(struct hv_device *device, | 670 | static 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 | ||
875 | out: | 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); |