|
@@ -7830,17 +7830,18 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
|
|
|
|
|
|
static netdev_tx_t tg3_start_xmit(struct sk_buff *, struct net_device *);
|
|
|
|
|
|
-/* Use GSO to workaround a rare TSO bug that may be triggered when the
|
|
|
- * TSO header is greater than 80 bytes.
|
|
|
+/* Use GSO to workaround all TSO packets that meet HW bug conditions
|
|
|
+ * indicated in tg3_tx_frag_set()
|
|
|
*/
|
|
|
-static int tg3_tso_bug(struct tg3 *tp, struct sk_buff *skb)
|
|
|
+static int tg3_tso_bug(struct tg3 *tp, struct tg3_napi *tnapi,
|
|
|
+ struct netdev_queue *txq, struct sk_buff *skb)
|
|
|
{
|
|
|
struct sk_buff *segs, *nskb;
|
|
|
u32 frag_cnt_est = skb_shinfo(skb)->gso_segs * 3;
|
|
|
|
|
|
/* Estimate the number of fragments in the worst case */
|
|
|
- if (unlikely(tg3_tx_avail(&tp->napi[0]) <= frag_cnt_est)) {
|
|
|
- netif_stop_queue(tp->dev);
|
|
|
+ if (unlikely(tg3_tx_avail(tnapi) <= frag_cnt_est)) {
|
|
|
+ netif_tx_stop_queue(txq);
|
|
|
|
|
|
/* netif_tx_stop_queue() must be done before checking
|
|
|
* 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)
|
|
|
* netif_tx_queue_stopped().
|
|
|
*/
|
|
|
smp_mb();
|
|
|
- if (tg3_tx_avail(&tp->napi[0]) <= frag_cnt_est)
|
|
|
+ if (tg3_tx_avail(tnapi) <= frag_cnt_est)
|
|
|
return NETDEV_TX_BUSY;
|
|
|
|
|
|
- netif_wake_queue(tp->dev);
|
|
|
+ netif_tx_wake_queue(txq);
|
|
|
}
|
|
|
|
|
|
- segs = skb_gso_segment(skb, tp->dev->features & ~(NETIF_F_TSO | NETIF_F_TSO6));
|
|
|
+ segs = skb_gso_segment(skb, tp->dev->features &
|
|
|
+ ~(NETIF_F_TSO | NETIF_F_TSO6));
|
|
|
if (IS_ERR(segs) || !segs)
|
|
|
goto tg3_tso_bug_end;
|
|
|
|
|
@@ -7930,7 +7932,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|
|
if (!skb_is_gso_v6(skb)) {
|
|
|
if (unlikely((ETH_HLEN + hdr_len) > 80) &&
|
|
|
tg3_flag(tp, TSO_BUG))
|
|
|
- return tg3_tso_bug(tp, skb);
|
|
|
+ return tg3_tso_bug(tp, tnapi, txq, skb);
|
|
|
|
|
|
ip_csum = iph->check;
|
|
|
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)
|
|
|
iph->tot_len = ip_tot_len;
|
|
|
}
|
|
|
tcph->check = tcp_csum;
|
|
|
- return tg3_tso_bug(tp, skb);
|
|
|
+ return tg3_tso_bug(tp, tnapi, txq, skb);
|
|
|
}
|
|
|
|
|
|
/* If the workaround fails due to memory/mapping
|