diff options
author | Prashant Sreedharan <prashant@broadcom.com> | 2014-08-05 19:02:02 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-08-05 19:48:14 -0400 |
commit | 4d8fdc95c60e90d84c8257a0067ff4b1729a3757 (patch) | |
tree | 17f60ec7471b3cf024188042f88375b78fe6a669 /drivers/net/ethernet/broadcom/tg3.c | |
parent | 2670cc699a66c4cf268cb3e3f6dfc325ec14f224 (diff) |
tg3: Modify tg3_tso_bug() to handle multiple TX rings
tg3_tso_bug() was originally designed to handle only HW TX ring 0, Commit
d3f6f3a1d818410c17445bce4f4caab52eb102f1 ("tg3: Prevent page allocation failure
during TSO workaround") changed the driver logic to use tg3_tso_bug() for all
HW TX rings that are enabled. This patch fixes the regression by modifying
tg3_tso_bug() to handle multiple HW TX rings.
Signed-off-by: Prashant Sreedharan <prashant@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/broadcom/tg3.c')
-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 |