diff options
author | Michael Chan <mchan@broadcom.com> | 2007-02-20 23:25:40 -0800 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-02-26 11:42:47 -0800 |
commit | 7f62ad5d37f4e43c841e92c6f159c93dcf2d2cdd (patch) | |
tree | f8d0e5d2dcc5e7783ace1f966b9e008278357067 | |
parent | ad930650c0e694233971c56e8de8e78b896e2613 (diff) | |
download | talos-op-linux-7f62ad5d37f4e43c841e92c6f159c93dcf2d2cdd.tar.gz talos-op-linux-7f62ad5d37f4e43c841e92c6f159c93dcf2d2cdd.zip |
[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>
-rw-r--r-- | drivers/net/tg3.c | 20 | ||||
-rw-r--r-- | drivers/net/tg3.h | 2 |
2 files changed, 12 insertions, 10 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 81a1c2e1a3f5..26c6ac48288c 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -64,8 +64,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.73" -#define DRV_MODULE_RELDATE "February 12, 2007" +#define DRV_MODULE_VERSION "3.74" +#define DRV_MODULE_RELDATE "February 20, 2007" #define TG3_DEF_MAC_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 */ if (unlikely(tg3_tx_avail(tp) <= (skb_shinfo(skb)->gso_segs * 3))) { 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); @@ -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; 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)); 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->tx_pending > TG3_TX_RING_SIZE - 1) || (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)))) 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_1SHOT_MSI; } else { - tp->tg3_flags2 |= TG3_FLG2_HW_TSO_1 | - TG3_FLG2_HW_TSO_1_BUG; + tp->tg3_flags2 |= TG3_FLG2_HW_TSO_1 | TG3_FLG2_TSO_BUG; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 && 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_flags2 &= ~TG3_FLG2_TSO_CAPABLE; } 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. diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 45d477e8f374..086892d8c1f1 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2227,7 +2227,7 @@ struct tg3 { #define TG3_FLAG_INIT_COMPLETE 0x80000000 u32 tg3_flags2; #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_IS_5788 0x00000008 #define TG3_FLG2_MAX_RXPEND_64 0x00000010 |