From patchwork Mon Feb 14 04:27:41 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guo-Fu Tseng X-Patchwork-Id: 83038 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 4C85EB7120 for ; Mon, 14 Feb 2011 15:28:49 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755491Ab1BNE2q (ORCPT ); Sun, 13 Feb 2011 23:28:46 -0500 Received: from cooldavid.org ([114.33.45.68]:48737 "EHLO cooldavid.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755481Ab1BNE2o (ORCPT ); Sun, 13 Feb 2011 23:28:44 -0500 Received: from kh (cooldavid-1-pt.tunnel.tserv3.fmt2.ipv6.he.net [IPv6:2001:470:1f04:16bf::2]) by cooldavid.org (Postfix) with SMTP id E4EE5247C72; Mon, 14 Feb 2011 12:28:44 +0800 (CST) Received: by kh (sSMTP sendmail emulation); Mon, 14 Feb 2011 12:28:30 +0800 From: "Guo-Fu Tseng" To: "David Miller" Cc: Guo-Fu Tseng , "linux-netdev" , "Aries Lee" , "Devinchiu" , "Ethan Hsiao" Subject: [PATCH net-next-2.6 8/9] jme: Don't show UDP Checksum error if HW misjudged Date: Mon, 14 Feb 2011 12:27:41 +0800 Message-Id: <1297657662-30289-8-git-send-email-cooldavid@cooldavid.org> X-Mailer: git-send-email 1.7.2.2 In-Reply-To: <1297657662-30289-1-git-send-email-cooldavid@cooldavid.org> References: <1297657662-30289-1-git-send-email-cooldavid@cooldavid.org> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Guo-Fu Tseng Some JMicron Chip treat 0 as error checksum for UDP packets. Which should be "No checksum needed". Reported-by: Adam Swift Confirmed-by: "Aries Lee" Signed-off-by: Guo-Fu Tseng --- drivers/net/jme.c | 25 ++++++++++++++++++++++--- 1 files changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/net/jme.c b/drivers/net/jme.c index ed35e17..5ced990 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -956,8 +956,27 @@ jme_disable_rx_engine(struct jme_adapter *jme) jme_mac_rxclk_off(jme); } +static u16 +jme_udpsum(struct sk_buff *skb) +{ + u16 csum = 0xFFFFu; + + if (skb->protocol != htons(ETH_P_IP)) + return csum; + skb_set_network_header(skb, ETH_HLEN); + if (ip_hdr(skb)->protocol != IPPROTO_UDP) + return csum; + skb_set_transport_header(skb, + ETH_HLEN + (ip_hdr(skb)->ihl << 2)); + csum = udp_hdr(skb)->check; + skb_reset_transport_header(skb); + skb_reset_network_header(skb); + + return csum; +} + static int -jme_rxsum_ok(struct jme_adapter *jme, u16 flags) +jme_rxsum_ok(struct jme_adapter *jme, u16 flags, struct sk_buff *skb) { if (!(flags & (RXWBFLAG_TCPON | RXWBFLAG_UDPON | RXWBFLAG_IPV4))) return false; @@ -970,7 +989,7 @@ jme_rxsum_ok(struct jme_adapter *jme, u16 flags) } if (unlikely((flags & (RXWBFLAG_MF | RXWBFLAG_UDPON | RXWBFLAG_UDPCS)) - == RXWBFLAG_UDPON)) { + == RXWBFLAG_UDPON) && jme_udpsum(skb)) { if (flags & RXWBFLAG_IPV4) netif_err(jme, rx_err, jme->dev, "UDP Checksum error\n"); return false; @@ -1018,7 +1037,7 @@ jme_alloc_and_feed_skb(struct jme_adapter *jme, int idx) skb_put(skb, framesize); skb->protocol = eth_type_trans(skb, jme->dev); - if (jme_rxsum_ok(jme, le16_to_cpu(rxdesc->descwb.flags))) + if (jme_rxsum_ok(jme, le16_to_cpu(rxdesc->descwb.flags), skb)) skb->ip_summed = CHECKSUM_UNNECESSARY; else skb_checksum_none_assert(skb);