aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/hyperv/hyperv_net.h1
-rw-r--r--drivers/net/hyperv/netvsc_drv.c26
-rw-r--r--drivers/net/hyperv/rndis_filter.c12
3 files changed, 37 insertions, 2 deletions
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 13010b4dae5b..d18f711d0b0c 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -747,6 +747,7 @@ struct ndis_oject_header {
747#define NDIS_TCP_LARGE_SEND_OFFLOAD_IPV4 0 747#define NDIS_TCP_LARGE_SEND_OFFLOAD_IPV4 0
748#define NDIS_TCP_LARGE_SEND_OFFLOAD_IPV6 1 748#define NDIS_TCP_LARGE_SEND_OFFLOAD_IPV6 1
749 749
750#define VERSION_4_OFFLOAD_SIZE 22
750/* 751/*
751 * New offload OIDs for NDIS 6 752 * New offload OIDs for NDIS 6
752 */ 753 */
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 6f39baa67a5f..31e55fba7cad 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -398,7 +398,30 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
398 csum_info->transmit.tcp_checksum = 1; 398 csum_info->transmit.tcp_checksum = 1;
399 csum_info->transmit.tcp_header_offset = hdr_offset; 399 csum_info->transmit.tcp_header_offset = hdr_offset;
400 } else if (net_trans_info & INFO_UDP) { 400 } else if (net_trans_info & INFO_UDP) {
401 csum_info->transmit.udp_checksum = 1; 401 /* UDP checksum offload is not supported on ws2008r2.
402 * Furthermore, on ws2012 and ws2012r2, there are some
403 * issues with udp checksum offload from Linux guests.
404 * (these are host issues).
405 * For now compute the checksum here.
406 */
407 struct udphdr *uh;
408 u16 udp_len;
409
410 ret = skb_cow_head(skb, 0);
411 if (ret)
412 goto drop;
413
414 uh = udp_hdr(skb);
415 udp_len = ntohs(uh->len);
416 uh->check = 0;
417 uh->check = csum_tcpudp_magic(ip_hdr(skb)->saddr,
418 ip_hdr(skb)->daddr,
419 udp_len, IPPROTO_UDP,
420 csum_partial(uh, udp_len, 0));
421 if (uh->check == 0)
422 uh->check = CSUM_MANGLED_0;
423
424 csum_info->transmit.udp_checksum = 0;
402 } 425 }
403 goto do_send; 426 goto do_send;
404 427
@@ -438,6 +461,7 @@ do_send:
438 461
439 ret = netvsc_send(net_device_ctx->device_ctx, packet); 462 ret = netvsc_send(net_device_ctx->device_ctx, packet);
440 463
464drop:
441 if (ret == 0) { 465 if (ret == 0) {
442 net->stats.tx_bytes += skb->len; 466 net->stats.tx_bytes += skb->len;
443 net->stats.tx_packets++; 467 net->stats.tx_packets++;
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index 4a37e3db9e32..143a98caf618 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -641,6 +641,16 @@ int rndis_filter_set_offload_params(struct hv_device *hdev,
641 struct rndis_set_complete *set_complete; 641 struct rndis_set_complete *set_complete;
642 u32 extlen = sizeof(struct ndis_offload_params); 642 u32 extlen = sizeof(struct ndis_offload_params);
643 int ret, t; 643 int ret, t;
644 u32 vsp_version = nvdev->nvsp_version;
645
646 if (vsp_version <= NVSP_PROTOCOL_VERSION_4) {
647 extlen = VERSION_4_OFFLOAD_SIZE;
648 /* On NVSP_PROTOCOL_VERSION_4 and below, we do not support
649 * UDP checksum offload.
650 */
651 req_offloads->udp_ip_v4_csum = 0;
652 req_offloads->udp_ip_v6_csum = 0;
653 }
644 654
645 request = get_rndis_request(rdev, RNDIS_MSG_SET, 655 request = get_rndis_request(rdev, RNDIS_MSG_SET,
646 RNDIS_MESSAGE_SIZE(struct rndis_set_request) + extlen); 656 RNDIS_MESSAGE_SIZE(struct rndis_set_request) + extlen);
@@ -674,7 +684,7 @@ int rndis_filter_set_offload_params(struct hv_device *hdev,
674 } else { 684 } else {
675 set_complete = &request->response_msg.msg.set_complete; 685 set_complete = &request->response_msg.msg.set_complete;
676 if (set_complete->status != RNDIS_STATUS_SUCCESS) { 686 if (set_complete->status != RNDIS_STATUS_SUCCESS) {
677 netdev_err(ndev, "Fail to set MAC on host side:0x%x\n", 687 netdev_err(ndev, "Fail to set offload on host side:0x%x\n",
678 set_complete->status); 688 set_complete->status);
679 ret = -EINVAL; 689 ret = -EINVAL;
680 } 690 }