aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/broadcom/tg3.c25
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
7834static 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
7834static netdev_tx_t tg3_start_xmit(struct sk_buff *, struct net_device *); 7842static 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 */