diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/net/ethernet/broadcom/tg3.c | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 8afa579e7c40..a3dd5dc64f4c 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
| @@ -7830,17 +7830,18 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi, | |||
| 7830 | 7830 | ||
| 7831 | static netdev_tx_t tg3_start_xmit(struct sk_buff *, struct net_device *); | 7831 | static netdev_tx_t tg3_start_xmit(struct sk_buff *, struct net_device *); |
| 7832 | 7832 | ||
| 7833 | /* Use GSO to workaround a rare TSO bug that may be triggered when the | 7833 | /* Use GSO to workaround all TSO packets that meet HW bug conditions |
| 7834 | * TSO header is greater than 80 bytes. | 7834 | * indicated in tg3_tx_frag_set() |
| 7835 | */ | 7835 | */ |
| 7836 | static int tg3_tso_bug(struct tg3 *tp, struct sk_buff *skb) | 7836 | static int tg3_tso_bug(struct tg3 *tp, struct tg3_napi *tnapi, |
| 7837 | struct netdev_queue *txq, struct sk_buff *skb) | ||
| 7837 | { | 7838 | { |
| 7838 | struct sk_buff *segs, *nskb; | 7839 | struct sk_buff *segs, *nskb; |
| 7839 | u32 frag_cnt_est = skb_shinfo(skb)->gso_segs * 3; | 7840 | u32 frag_cnt_est = skb_shinfo(skb)->gso_segs * 3; |
| 7840 | 7841 | ||
| 7841 | /* Estimate the number of fragments in the worst case */ | 7842 | /* Estimate the number of fragments in the worst case */ |
| 7842 | if (unlikely(tg3_tx_avail(&tp->napi[0]) <= frag_cnt_est)) { | 7843 | if (unlikely(tg3_tx_avail(tnapi) <= frag_cnt_est)) { |
| 7843 | netif_stop_queue(tp->dev); | 7844 | netif_tx_stop_queue(txq); |
| 7844 | 7845 | ||
| 7845 | /* netif_tx_stop_queue() must be done before checking | 7846 | /* netif_tx_stop_queue() must be done before checking |
| 7846 | * checking tx index in tg3_tx_avail() below, because in | 7847 | * checking tx index in tg3_tx_avail() below, because in |
| @@ -7848,13 +7849,14 @@ static int tg3_tso_bug(struct tg3 *tp, struct sk_buff *skb) | |||
| 7848 | * netif_tx_queue_stopped(). | 7849 | * netif_tx_queue_stopped(). |
| 7849 | */ | 7850 | */ |
| 7850 | smp_mb(); | 7851 | smp_mb(); |
| 7851 | if (tg3_tx_avail(&tp->napi[0]) <= frag_cnt_est) | 7852 | if (tg3_tx_avail(tnapi) <= frag_cnt_est) |
| 7852 | return NETDEV_TX_BUSY; | 7853 | return NETDEV_TX_BUSY; |
| 7853 | 7854 | ||
| 7854 | netif_wake_queue(tp->dev); | 7855 | netif_tx_wake_queue(txq); |
| 7855 | } | 7856 | } |
| 7856 | 7857 | ||
| 7857 | segs = skb_gso_segment(skb, tp->dev->features & ~(NETIF_F_TSO | NETIF_F_TSO6)); | 7858 | segs = skb_gso_segment(skb, tp->dev->features & |
| 7859 | ~(NETIF_F_TSO | NETIF_F_TSO6)); | ||
| 7858 | if (IS_ERR(segs) || !segs) | 7860 | if (IS_ERR(segs) || !segs) |
| 7859 | goto tg3_tso_bug_end; | 7861 | goto tg3_tso_bug_end; |
| 7860 | 7862 | ||
| @@ -7930,7 +7932,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 7930 | if (!skb_is_gso_v6(skb)) { | 7932 | if (!skb_is_gso_v6(skb)) { |
| 7931 | if (unlikely((ETH_HLEN + hdr_len) > 80) && | 7933 | if (unlikely((ETH_HLEN + hdr_len) > 80) && |
| 7932 | tg3_flag(tp, TSO_BUG)) | 7934 | tg3_flag(tp, TSO_BUG)) |
| 7933 | return tg3_tso_bug(tp, skb); | 7935 | return tg3_tso_bug(tp, tnapi, txq, skb); |
| 7934 | 7936 | ||
| 7935 | ip_csum = iph->check; | 7937 | ip_csum = iph->check; |
| 7936 | ip_tot_len = iph->tot_len; | 7938 | ip_tot_len = iph->tot_len; |
| @@ -8061,7 +8063,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 8061 | iph->tot_len = ip_tot_len; | 8063 | iph->tot_len = ip_tot_len; |
| 8062 | } | 8064 | } |
| 8063 | tcph->check = tcp_csum; | 8065 | tcph->check = tcp_csum; |
| 8064 | return tg3_tso_bug(tp, skb); | 8066 | return tg3_tso_bug(tp, tnapi, txq, skb); |
| 8065 | } | 8067 | } |
| 8066 | 8068 | ||
| 8067 | /* If the workaround fails due to memory/mapping | 8069 | /* If the workaround fails due to memory/mapping |
