From patchwork Tue Dec 2 20:31:22 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David L Stevens X-Patchwork-Id: 417137 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id B07B8140185 for ; Wed, 3 Dec 2014 07:31:35 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933376AbaLBUba (ORCPT ); Tue, 2 Dec 2014 15:31:30 -0500 Received: from aserp1040.oracle.com ([141.146.126.69]:31305 "EHLO aserp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933360AbaLBUb1 (ORCPT ); Tue, 2 Dec 2014 15:31:27 -0500 Received: from acsinet21.oracle.com (acsinet21.oracle.com [141.146.126.237]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id sB2KVPwJ002809 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 2 Dec 2014 20:31:26 GMT Received: from userz7022.oracle.com (userz7022.oracle.com [156.151.31.86]) by acsinet21.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id sB2KVO7R002092 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 2 Dec 2014 20:31:25 GMT Received: from abhmp0006.oracle.com (abhmp0006.oracle.com [141.146.116.12]) by userz7022.oracle.com (8.14.5+Sun/8.14.4) with ESMTP id sB2KVNp9021965; Tue, 2 Dec 2014 20:31:24 GMT Received: from [10.154.108.160] (/10.154.108.160) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 02 Dec 2014 12:31:23 -0800 Message-ID: <547E219A.7010706@oracle.com> Date: Tue, 02 Dec 2014 15:31:22 -0500 From: David L Stevens Organization: Oracle Corporation User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.7.0 MIME-Version: 1.0 To: David Miller CC: netdev@vger.kernel.org, Sowmini Varadhan Subject: [PATCH net-next 4/6] sunvnet: add checksum offload support X-Source-IP: acsinet21.oracle.com [141.146.126.237] Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This patch adds support for sender-side checksum offloading. Signed-off-by: David L Stevens --- drivers/net/ethernet/sun/sunvnet.c | 37 +++++++++++++++++++++++++++++++++-- 1 files changed, 34 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index b6a5336..b172eda 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c @@ -375,6 +375,8 @@ static int vnet_rx_one(struct vnet_port *port, struct vio_net_desc *desc) } } + skb->ip_summed = port->switch_port ? CHECKSUM_NONE : CHECKSUM_PARTIAL; + dev->stats.rx_packets++; dev->stats.rx_bytes += len; napi_gro_receive(&port->napi, skb); @@ -1047,7 +1049,8 @@ static inline struct sk_buff *vnet_skb_shape(struct sk_buff *skb, int ncookies) if (((unsigned long)skb->data & 7) != VNET_PACKET_SKIP || skb_tailroom(skb) < pad || skb_headroom(skb) < VNET_PACKET_SKIP || docopy) { - int offset; + int start = 0, offset; + __wsum csum; len = skb->len > ETH_ZLEN ? skb->len : ETH_ZLEN; nskb = alloc_and_align_skb(skb->dev, len); @@ -1065,10 +1068,35 @@ static inline struct sk_buff *vnet_skb_shape(struct sk_buff *skb, int ncookies) offset = skb_transport_header(skb) - skb->data; skb_set_transport_header(nskb, offset); + offset = 0; nskb->csum_offset = skb->csum_offset; nskb->ip_summed = skb->ip_summed; - if (skb_copy_bits(skb, 0, nskb->data, skb->len)) { + if (skb->ip_summed == CHECKSUM_PARTIAL) + start = skb_checksum_start_offset(skb); + if (start) { + struct iphdr *iph = ip_hdr(nskb); + int offset = start + nskb->csum_offset; + + if (skb_copy_bits(skb, 0, nskb->data, start)) { + dev_kfree_skb(nskb); + dev_kfree_skb(skb); + return NULL; + } + *(__sum16 *)(skb->data + offset) = 0; + csum = skb_copy_and_csum_bits(skb, start, + nskb->data + start, + skb->len - start, 0); + if (iph->protocol == IPPROTO_TCP || + iph->protocol == IPPROTO_UDP) { + csum = csum_tcpudp_magic(iph->saddr, iph->daddr, + skb->len - start, + iph->protocol, csum); + } + *(__sum16 *)(nskb->data + offset) = csum; + + nskb->ip_summed = CHECKSUM_NONE; + } else if (skb_copy_bits(skb, 0, nskb->data, skb->len)) { dev_kfree_skb(nskb); dev_kfree_skb(skb); return NULL; @@ -1150,6 +1178,9 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev) goto out_dropped; } + if (skb->ip_summed == CHECKSUM_PARTIAL) + vnet_fullcsum(skb); + dr = &port->vio.drings[VIO_DRIVER_TX_RING]; i = skb_get_queue_mapping(skb); txq = netdev_get_tx_queue(dev, i); @@ -1611,7 +1642,7 @@ static struct vnet *vnet_new(const u64 *local_mac) dev->ethtool_ops = &vnet_ethtool_ops; dev->watchdog_timeo = VNET_TX_TIMEOUT; - dev->hw_features = NETIF_F_SG; + dev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG; dev->features = dev->hw_features; err = register_netdev(dev);