This is a note to let you know that I've just added the patch titled r8169: fix offloaded tx checksum for small packets. to the 3.9-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: r8169-fix-offloaded-tx-checksum-for-small-packets.patch and it can be found in the queue-3.9 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From 0a1f685d4b458666b1f979cd46ec0a26da37b6fc Mon Sep 17 00:00:00 2001 From: Francois Romieu <romieu@xxxxxxxxxxxxx> Date: Sat, 18 May 2013 01:24:46 +0000 Subject: r8169: fix offloaded tx checksum for small packets. From: Francois Romieu <romieu@xxxxxxxxxxxxx> [ Upstream commit b423e9ae49d78ea3f53b131c8d5a6087aed16fd6 ] 8168evl offloaded checksums are wrong since commit e5195c1f31f399289347e043d6abf3ffa80f0005 ("r8169: fix 8168evl frame padding.") pads small packets to 60 bytes (without ethernet checksum). Typical symptoms appear as UDP checksums which are wrong by the count of added bytes. It isn't worth compensating. Let the driver checksum. Due to the skb length changes, TSO code is moved before the Tx descriptor gets written. Signed-off-by: Francois Romieu <romieu@xxxxxxxxxxxxx> Tested-by: Holger Hoffstätte <holger.hoffstaette@xxxxxxxxxxxxxx> Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/net/ethernet/realtek/r8169.c | 41 +++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 14 deletions(-) --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -5747,7 +5747,20 @@ err_out: return -EIO; } -static inline void rtl8169_tso_csum(struct rtl8169_private *tp, +static bool rtl_skb_pad(struct sk_buff *skb) +{ + if (skb_padto(skb, ETH_ZLEN)) + return false; + skb_put(skb, ETH_ZLEN - skb->len); + return true; +} + +static bool rtl_test_hw_pad_bug(struct rtl8169_private *tp, struct sk_buff *skb) +{ + return skb->len < ETH_ZLEN && tp->mac_version == RTL_GIGA_MAC_VER_34; +} + +static inline bool rtl8169_tso_csum(struct rtl8169_private *tp, struct sk_buff *skb, u32 *opts) { const struct rtl_tx_desc_info *info = tx_desc_info + tp->txd_version; @@ -5760,13 +5773,20 @@ static inline void rtl8169_tso_csum(stru } else if (skb->ip_summed == CHECKSUM_PARTIAL) { const struct iphdr *ip = ip_hdr(skb); + if (unlikely(rtl_test_hw_pad_bug(tp, skb))) + return skb_checksum_help(skb) == 0 && rtl_skb_pad(skb); + if (ip->protocol == IPPROTO_TCP) opts[offset] |= info->checksum.tcp; else if (ip->protocol == IPPROTO_UDP) opts[offset] |= info->checksum.udp; else WARN_ON_ONCE(1); + } else { + if (unlikely(rtl_test_hw_pad_bug(tp, skb))) + return rtl_skb_pad(skb); } + return true; } static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, @@ -5787,17 +5807,15 @@ static netdev_tx_t rtl8169_start_xmit(st goto err_stop_0; } - /* 8168evl does not automatically pad to minimum length. */ - if (unlikely(tp->mac_version == RTL_GIGA_MAC_VER_34 && - skb->len < ETH_ZLEN)) { - if (skb_padto(skb, ETH_ZLEN)) - goto err_update_stats; - skb_put(skb, ETH_ZLEN - skb->len); - } - if (unlikely(le32_to_cpu(txd->opts1) & DescOwn)) goto err_stop_0; + opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(skb)); + opts[0] = DescOwn; + + if (!rtl8169_tso_csum(tp, skb, opts)) + goto err_update_stats; + len = skb_headlen(skb); mapping = dma_map_single(d, skb->data, len, DMA_TO_DEVICE); if (unlikely(dma_mapping_error(d, mapping))) { @@ -5809,11 +5827,6 @@ static netdev_tx_t rtl8169_start_xmit(st tp->tx_skb[entry].len = len; txd->addr = cpu_to_le64(mapping); - opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(skb)); - opts[0] = DescOwn; - - rtl8169_tso_csum(tp, skb, opts); - frags = rtl8169_xmit_frags(tp, skb, opts); if (frags < 0) goto err_dma_1; Patches currently in stable-queue which might be from romieu@xxxxxxxxxxxxx are queue-3.9/r8169-fix-offloaded-tx-checksum-for-small-packets.patch -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html