[TG3]: TSO workaround fixes.
1. Add race condition check after netif_stop_queue(). tg3_tx() runs without netif_tx_lock and can race with tg3_start_xmit_dma_bug() -> tg3_tso_bug(). 2. Firmware TSO in 5703/5704/5705 also have the same TSO limitation, i.e. they cannot handle TSO headers bigger than 80 bytes. Rename TG3_FL2_HW_TSO_1_BUG to TG3_FL2_TSO_BUG and set this flag on these chips as well. 3. Update version to 3.74. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
ad930650c0
commit
7f62ad5d37
|
@ -64,8 +64,8 @@
|
||||||
|
|
||||||
#define DRV_MODULE_NAME "tg3"
|
#define DRV_MODULE_NAME "tg3"
|
||||||
#define PFX DRV_MODULE_NAME ": "
|
#define PFX DRV_MODULE_NAME ": "
|
||||||
#define DRV_MODULE_VERSION "3.73"
|
#define DRV_MODULE_VERSION "3.74"
|
||||||
#define DRV_MODULE_RELDATE "February 12, 2007"
|
#define DRV_MODULE_RELDATE "February 20, 2007"
|
||||||
|
|
||||||
#define TG3_DEF_MAC_MODE 0
|
#define TG3_DEF_MAC_MODE 0
|
||||||
#define TG3_DEF_RX_MODE 0
|
#define TG3_DEF_RX_MODE 0
|
||||||
|
@ -3993,7 +3993,10 @@ static int tg3_tso_bug(struct tg3 *tp, struct sk_buff *skb)
|
||||||
/* Estimate the number of fragments in the worst case */
|
/* Estimate the number of fragments in the worst case */
|
||||||
if (unlikely(tg3_tx_avail(tp) <= (skb_shinfo(skb)->gso_segs * 3))) {
|
if (unlikely(tg3_tx_avail(tp) <= (skb_shinfo(skb)->gso_segs * 3))) {
|
||||||
netif_stop_queue(tp->dev);
|
netif_stop_queue(tp->dev);
|
||||||
return NETDEV_TX_BUSY;
|
if (tg3_tx_avail(tp) <= (skb_shinfo(skb)->gso_segs * 3))
|
||||||
|
return NETDEV_TX_BUSY;
|
||||||
|
|
||||||
|
netif_wake_queue(tp->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
segs = skb_gso_segment(skb, tp->dev->features & ~NETIF_F_TSO);
|
segs = skb_gso_segment(skb, tp->dev->features & ~NETIF_F_TSO);
|
||||||
|
@ -4061,7 +4064,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
|
||||||
|
|
||||||
hdr_len = ip_tcp_len + tcp_opt_len;
|
hdr_len = ip_tcp_len + tcp_opt_len;
|
||||||
if (unlikely((ETH_HLEN + hdr_len) > 80) &&
|
if (unlikely((ETH_HLEN + hdr_len) > 80) &&
|
||||||
(tp->tg3_flags2 & TG3_FLG2_HW_TSO_1_BUG))
|
(tp->tg3_flags2 & TG3_FLG2_TSO_BUG))
|
||||||
return (tg3_tso_bug(tp, skb));
|
return (tg3_tso_bug(tp, skb));
|
||||||
|
|
||||||
base_flags |= (TXD_FLAG_CPU_PRE_DMA |
|
base_flags |= (TXD_FLAG_CPU_PRE_DMA |
|
||||||
|
@ -8137,7 +8140,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
|
||||||
(ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) ||
|
(ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) ||
|
||||||
(ering->tx_pending > TG3_TX_RING_SIZE - 1) ||
|
(ering->tx_pending > TG3_TX_RING_SIZE - 1) ||
|
||||||
(ering->tx_pending <= MAX_SKB_FRAGS) ||
|
(ering->tx_pending <= MAX_SKB_FRAGS) ||
|
||||||
((tp->tg3_flags2 & TG3_FLG2_HW_TSO_1_BUG) &&
|
((tp->tg3_flags2 & TG3_FLG2_TSO_BUG) &&
|
||||||
(ering->tx_pending <= (MAX_SKB_FRAGS * 3))))
|
(ering->tx_pending <= (MAX_SKB_FRAGS * 3))))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -10557,12 +10560,11 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
|
||||||
tp->tg3_flags2 |= TG3_FLG2_HW_TSO_2;
|
tp->tg3_flags2 |= TG3_FLG2_HW_TSO_2;
|
||||||
tp->tg3_flags2 |= TG3_FLG2_1SHOT_MSI;
|
tp->tg3_flags2 |= TG3_FLG2_1SHOT_MSI;
|
||||||
} else {
|
} else {
|
||||||
tp->tg3_flags2 |= TG3_FLG2_HW_TSO_1 |
|
tp->tg3_flags2 |= TG3_FLG2_HW_TSO_1 | TG3_FLG2_TSO_BUG;
|
||||||
TG3_FLG2_HW_TSO_1_BUG;
|
|
||||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) ==
|
if (GET_ASIC_REV(tp->pci_chip_rev_id) ==
|
||||||
ASIC_REV_5750 &&
|
ASIC_REV_5750 &&
|
||||||
tp->pci_chip_rev_id >= CHIPREV_ID_5750_C2)
|
tp->pci_chip_rev_id >= CHIPREV_ID_5750_C2)
|
||||||
tp->tg3_flags2 &= ~TG3_FLG2_HW_TSO_1_BUG;
|
tp->tg3_flags2 &= ~TG3_FLG2_TSO_BUG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11867,7 +11869,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
|
||||||
(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0) {
|
(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0) {
|
||||||
tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
|
tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
|
||||||
} else {
|
} else {
|
||||||
tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
|
tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE | TG3_FLG2_TSO_BUG;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TSO is on by default on chips that support hardware TSO.
|
/* TSO is on by default on chips that support hardware TSO.
|
||||||
|
|
|
@ -2227,7 +2227,7 @@ struct tg3 {
|
||||||
#define TG3_FLAG_INIT_COMPLETE 0x80000000
|
#define TG3_FLAG_INIT_COMPLETE 0x80000000
|
||||||
u32 tg3_flags2;
|
u32 tg3_flags2;
|
||||||
#define TG3_FLG2_RESTART_TIMER 0x00000001
|
#define TG3_FLG2_RESTART_TIMER 0x00000001
|
||||||
#define TG3_FLG2_HW_TSO_1_BUG 0x00000002
|
#define TG3_FLG2_TSO_BUG 0x00000002
|
||||||
#define TG3_FLG2_NO_ETH_WIRE_SPEED 0x00000004
|
#define TG3_FLG2_NO_ETH_WIRE_SPEED 0x00000004
|
||||||
#define TG3_FLG2_IS_5788 0x00000008
|
#define TG3_FLG2_IS_5788 0x00000008
|
||||||
#define TG3_FLG2_MAX_RXPEND_64 0x00000010
|
#define TG3_FLG2_MAX_RXPEND_64 0x00000010
|
||||||
|
|
Loading…
Reference in New Issue