diff options
-rw-r--r-- | drivers/net/ethernet/broadcom/tg3.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 49eea8981332..3010080cfeee 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
@@ -7831,6 +7831,14 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi, | |||
7831 | return ret; | 7831 | return ret; |
7832 | } | 7832 | } |
7833 | 7833 | ||
7834 | static bool tg3_tso_bug_gso_check(struct tg3_napi *tnapi, struct sk_buff *skb) | ||
7835 | { | ||
7836 | /* Check if we will never have enough descriptors, | ||
7837 | * as gso_segs can be more than current ring size | ||
7838 | */ | ||
7839 | return skb_shinfo(skb)->gso_segs < tnapi->tx_pending / 3; | ||
7840 | } | ||
7841 | |||
7834 | static netdev_tx_t tg3_start_xmit(struct sk_buff *, struct net_device *); | 7842 | static netdev_tx_t tg3_start_xmit(struct sk_buff *, struct net_device *); |
7835 | 7843 | ||
7836 | /* Use GSO to workaround all TSO packets that meet HW bug conditions | 7844 | /* Use GSO to workaround all TSO packets that meet HW bug conditions |
@@ -7934,14 +7942,19 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
7934 | * vlan encapsulated. | 7942 | * vlan encapsulated. |
7935 | */ | 7943 | */ |
7936 | if (skb->protocol == htons(ETH_P_8021Q) || | 7944 | if (skb->protocol == htons(ETH_P_8021Q) || |
7937 | skb->protocol == htons(ETH_P_8021AD)) | 7945 | skb->protocol == htons(ETH_P_8021AD)) { |
7938 | return tg3_tso_bug(tp, tnapi, txq, skb); | 7946 | if (tg3_tso_bug_gso_check(tnapi, skb)) |
7947 | return tg3_tso_bug(tp, tnapi, txq, skb); | ||
7948 | goto drop; | ||
7949 | } | ||
7939 | 7950 | ||
7940 | if (!skb_is_gso_v6(skb)) { | 7951 | if (!skb_is_gso_v6(skb)) { |
7941 | if (unlikely((ETH_HLEN + hdr_len) > 80) && | 7952 | if (unlikely((ETH_HLEN + hdr_len) > 80) && |
7942 | tg3_flag(tp, TSO_BUG)) | 7953 | tg3_flag(tp, TSO_BUG)) { |
7943 | return tg3_tso_bug(tp, tnapi, txq, skb); | 7954 | if (tg3_tso_bug_gso_check(tnapi, skb)) |
7944 | 7955 | return tg3_tso_bug(tp, tnapi, txq, skb); | |
7956 | goto drop; | ||
7957 | } | ||
7945 | ip_csum = iph->check; | 7958 | ip_csum = iph->check; |
7946 | ip_tot_len = iph->tot_len; | 7959 | ip_tot_len = iph->tot_len; |
7947 | iph->check = 0; | 7960 | iph->check = 0; |
@@ -8073,7 +8086,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
8073 | if (would_hit_hwbug) { | 8086 | if (would_hit_hwbug) { |
8074 | tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, i); | 8087 | tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, i); |
8075 | 8088 | ||
8076 | if (mss) { | 8089 | if (mss && tg3_tso_bug_gso_check(tnapi, skb)) { |
8077 | /* If it's a TSO packet, do GSO instead of | 8090 | /* If it's a TSO packet, do GSO instead of |
8078 | * allocating and copying to a large linear SKB | 8091 | * allocating and copying to a large linear SKB |
8079 | */ | 8092 | */ |