aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom/tg3.c
diff options
context:
space:
mode:
authorPrashant Sreedharan <prashant@broadcom.com>2014-08-05 19:02:02 -0400
committerDavid S. Miller <davem@davemloft.net>2014-08-05 19:48:14 -0400
commit4d8fdc95c60e90d84c8257a0067ff4b1729a3757 (patch)
tree17f60ec7471b3cf024188042f88375b78fe6a669 /drivers/net/ethernet/broadcom/tg3.c
parent2670cc699a66c4cf268cb3e3f6dfc325ec14f224 (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.c22
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
7831static netdev_tx_t tg3_start_xmit(struct sk_buff *, struct net_device *); 7831static 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 */
7836static int tg3_tso_bug(struct tg3 *tp, struct sk_buff *skb) 7836static 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