diff options
author | David S. Miller <davem@davemloft.net> | 2014-05-13 18:39:01 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-05-13 18:39:01 -0400 |
commit | 1e1c77bfded1ee718eb14deac7ab474f6f1f3016 (patch) | |
tree | 2ad2a0d8d8a4f6fa769a12266fdda4a1f061039a | |
parent | b6bd26c4de0141d0736a51487e4ca37390fcae03 (diff) | |
parent | de750e4c4bf36b8a14401527e6541e8620ea6267 (diff) |
Merge branch 'tg3-next'
Michael Chan says:
====================
tg3: TSO related enhancements to prevent memory allocation failure
Michael Chan (3):
tg3: Don't modify ip header fields when doing GSO
tg3: Prevent page allocation failure during TSO workaround
tg3: Update copyright and version to 3.137
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/broadcom/tg3.c | 51 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/tg3.h | 2 |
2 files changed, 35 insertions, 18 deletions
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index e5d95c5ce1ad..ccd90156aebc 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com) | 4 | * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com) |
5 | * Copyright (C) 2001, 2002, 2003 Jeff Garzik (jgarzik@pobox.com) | 5 | * Copyright (C) 2001, 2002, 2003 Jeff Garzik (jgarzik@pobox.com) |
6 | * Copyright (C) 2004 Sun Microsystems Inc. | 6 | * Copyright (C) 2004 Sun Microsystems Inc. |
7 | * Copyright (C) 2005-2013 Broadcom Corporation. | 7 | * Copyright (C) 2005-2014 Broadcom Corporation. |
8 | * | 8 | * |
9 | * Firmware is: | 9 | * Firmware is: |
10 | * Derived from proprietary unpublished source code, | 10 | * Derived from proprietary unpublished source code, |
@@ -94,10 +94,10 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits) | |||
94 | 94 | ||
95 | #define DRV_MODULE_NAME "tg3" | 95 | #define DRV_MODULE_NAME "tg3" |
96 | #define TG3_MAJ_NUM 3 | 96 | #define TG3_MAJ_NUM 3 |
97 | #define TG3_MIN_NUM 136 | 97 | #define TG3_MIN_NUM 137 |
98 | #define DRV_MODULE_VERSION \ | 98 | #define DRV_MODULE_VERSION \ |
99 | __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM) | 99 | __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM) |
100 | #define DRV_MODULE_RELDATE "Jan 03, 2014" | 100 | #define DRV_MODULE_RELDATE "May 11, 2014" |
101 | 101 | ||
102 | #define RESET_KIND_SHUTDOWN 0 | 102 | #define RESET_KIND_SHUTDOWN 0 |
103 | #define RESET_KIND_INIT 1 | 103 | #define RESET_KIND_INIT 1 |
@@ -7871,9 +7871,7 @@ tg3_tso_bug_end: | |||
7871 | return NETDEV_TX_OK; | 7871 | return NETDEV_TX_OK; |
7872 | } | 7872 | } |
7873 | 7873 | ||
7874 | /* hard_start_xmit for devices that have the 4G bug and/or 40-bit bug and | 7874 | /* hard_start_xmit for all devices */ |
7875 | * support TG3_FLAG_HW_TSO_1 or firmware TSO only. | ||
7876 | */ | ||
7877 | static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | 7875 | static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) |
7878 | { | 7876 | { |
7879 | struct tg3 *tp = netdev_priv(dev); | 7877 | struct tg3 *tp = netdev_priv(dev); |
@@ -7884,6 +7882,10 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
7884 | struct tg3_napi *tnapi; | 7882 | struct tg3_napi *tnapi; |
7885 | struct netdev_queue *txq; | 7883 | struct netdev_queue *txq; |
7886 | unsigned int last; | 7884 | unsigned int last; |
7885 | struct iphdr *iph = NULL; | ||
7886 | struct tcphdr *tcph = NULL; | ||
7887 | __sum16 tcp_csum = 0, ip_csum = 0; | ||
7888 | __be16 ip_tot_len = 0; | ||
7887 | 7889 | ||
7888 | txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb)); | 7890 | txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb)); |
7889 | tnapi = &tp->napi[skb_get_queue_mapping(skb)]; | 7891 | tnapi = &tp->napi[skb_get_queue_mapping(skb)]; |
@@ -7915,7 +7917,6 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
7915 | 7917 | ||
7916 | mss = skb_shinfo(skb)->gso_size; | 7918 | mss = skb_shinfo(skb)->gso_size; |
7917 | if (mss) { | 7919 | if (mss) { |
7918 | struct iphdr *iph; | ||
7919 | u32 tcp_opt_len, hdr_len; | 7920 | u32 tcp_opt_len, hdr_len; |
7920 | 7921 | ||
7921 | if (skb_cow_head(skb, 0)) | 7922 | if (skb_cow_head(skb, 0)) |
@@ -7927,27 +7928,31 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
7927 | hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb) - ETH_HLEN; | 7928 | hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb) - ETH_HLEN; |
7928 | 7929 | ||
7929 | if (!skb_is_gso_v6(skb)) { | 7930 | if (!skb_is_gso_v6(skb)) { |
7931 | if (unlikely((ETH_HLEN + hdr_len) > 80) && | ||
7932 | tg3_flag(tp, TSO_BUG)) | ||
7933 | return tg3_tso_bug(tp, skb); | ||
7934 | |||
7935 | ip_csum = iph->check; | ||
7936 | ip_tot_len = iph->tot_len; | ||
7930 | iph->check = 0; | 7937 | iph->check = 0; |
7931 | iph->tot_len = htons(mss + hdr_len); | 7938 | iph->tot_len = htons(mss + hdr_len); |
7932 | } | 7939 | } |
7933 | 7940 | ||
7934 | if (unlikely((ETH_HLEN + hdr_len) > 80) && | ||
7935 | tg3_flag(tp, TSO_BUG)) | ||
7936 | return tg3_tso_bug(tp, skb); | ||
7937 | |||
7938 | base_flags |= (TXD_FLAG_CPU_PRE_DMA | | 7941 | base_flags |= (TXD_FLAG_CPU_PRE_DMA | |
7939 | TXD_FLAG_CPU_POST_DMA); | 7942 | TXD_FLAG_CPU_POST_DMA); |
7940 | 7943 | ||
7944 | tcph = tcp_hdr(skb); | ||
7945 | tcp_csum = tcph->check; | ||
7946 | |||
7941 | if (tg3_flag(tp, HW_TSO_1) || | 7947 | if (tg3_flag(tp, HW_TSO_1) || |
7942 | tg3_flag(tp, HW_TSO_2) || | 7948 | tg3_flag(tp, HW_TSO_2) || |
7943 | tg3_flag(tp, HW_TSO_3)) { | 7949 | tg3_flag(tp, HW_TSO_3)) { |
7944 | tcp_hdr(skb)->check = 0; | 7950 | tcph->check = 0; |
7945 | base_flags &= ~TXD_FLAG_TCPUDP_CSUM; | 7951 | base_flags &= ~TXD_FLAG_TCPUDP_CSUM; |
7946 | } else | 7952 | } else { |
7947 | tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr, | 7953 | tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, |
7948 | iph->daddr, 0, | 7954 | 0, IPPROTO_TCP, 0); |
7949 | IPPROTO_TCP, | 7955 | } |
7950 | 0); | ||
7951 | 7956 | ||
7952 | if (tg3_flag(tp, HW_TSO_3)) { | 7957 | if (tg3_flag(tp, HW_TSO_3)) { |
7953 | mss |= (hdr_len & 0xc) << 12; | 7958 | mss |= (hdr_len & 0xc) << 12; |
@@ -8047,6 +8052,18 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
8047 | if (would_hit_hwbug) { | 8052 | if (would_hit_hwbug) { |
8048 | tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, i); | 8053 | tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, i); |
8049 | 8054 | ||
8055 | if (mss) { | ||
8056 | /* If it's a TSO packet, do GSO instead of | ||
8057 | * allocating and copying to a large linear SKB | ||
8058 | */ | ||
8059 | if (ip_tot_len) { | ||
8060 | iph->check = ip_csum; | ||
8061 | iph->tot_len = ip_tot_len; | ||
8062 | } | ||
8063 | tcph->check = tcp_csum; | ||
8064 | return tg3_tso_bug(tp, skb); | ||
8065 | } | ||
8066 | |||
8050 | /* If the workaround fails due to memory/mapping | 8067 | /* If the workaround fails due to memory/mapping |
8051 | * failure, silently drop this packet. | 8068 | * failure, silently drop this packet. |
8052 | */ | 8069 | */ |
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index 04321e5a356e..461accaf0aa4 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h | |||
@@ -4,7 +4,7 @@ | |||
4 | * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com) | 4 | * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com) |
5 | * Copyright (C) 2001 Jeff Garzik (jgarzik@pobox.com) | 5 | * Copyright (C) 2001 Jeff Garzik (jgarzik@pobox.com) |
6 | * Copyright (C) 2004 Sun Microsystems Inc. | 6 | * Copyright (C) 2004 Sun Microsystems Inc. |
7 | * Copyright (C) 2007-2013 Broadcom Corporation. | 7 | * Copyright (C) 2007-2014 Broadcom Corporation. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #ifndef _T3_H | 10 | #ifndef _T3_H |