Commit f4bec17b authored by David S. Miller's avatar David S. Miller

TIGON3: Finish up NAPI implementation.

- Split out TX processing to seperate spinlock so we
do not deadlock inside of netif_receive_skb.  Also improves
performance a bit.
- Bump version to 1.0, what the heck.
parent 8d5b76d7
...@@ -52,8 +52,8 @@ ...@@ -52,8 +52,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 "0.99-NAPI" #define DRV_MODULE_VERSION "1.0"
#define DRV_MODULE_RELDATE "Jun 20, 2002" #define DRV_MODULE_RELDATE "Jul 19, 2002"
#define TG3_DEF_MAC_MODE 0 #define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0 #define TG3_DEF_RX_MODE 0
...@@ -1922,8 +1922,11 @@ static int tg3_poll(struct net_device *netdev, int *budget) ...@@ -1922,8 +1922,11 @@ static int tg3_poll(struct net_device *netdev, int *budget)
} }
} }
if (sblk->idx[0].tx_consumer != tp->tx_cons) if (sblk->idx[0].tx_consumer != tp->tx_cons) {
spin_lock(&tp->tx_lock);
tg3_tx(tp); tg3_tx(tp);
spin_unlock(&tp->tx_lock);
}
done = 1; done = 1;
if (sblk->idx[0].rx_producer != tp->rx_rcb_ptr) { if (sblk->idx[0].rx_producer != tp->rx_rcb_ptr) {
...@@ -2014,11 +2017,13 @@ static void tg3_tx_timeout(struct net_device *dev) ...@@ -2014,11 +2017,13 @@ static void tg3_tx_timeout(struct net_device *dev)
dev->name); dev->name);
spin_lock_irq(&tp->lock); spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock);
tg3_halt(tp); tg3_halt(tp);
tg3_init_rings(tp); tg3_init_rings(tp);
tg3_init_hw(tp); tg3_init_hw(tp);
spin_unlock(&tp->tx_lock);
spin_unlock_irq(&tp->lock); spin_unlock_irq(&tp->lock);
netif_wake_queue(dev); netif_wake_queue(dev);
...@@ -2203,12 +2208,16 @@ static int tg3_start_xmit_4gbug(struct sk_buff *skb, struct net_device *dev) ...@@ -2203,12 +2208,16 @@ static int tg3_start_xmit_4gbug(struct sk_buff *skb, struct net_device *dev)
len = (skb->len - skb->data_len); len = (skb->len - skb->data_len);
spin_lock_irq(&tp->lock); /* No BH disabling for tx_lock here. We are running in BH disabled
* context and TX reclaim runs via tp->poll inside of a software
* interrupt. Rejoice!
*/
spin_lock(&tp->tx_lock);
/* This is a hard error, log it. */ /* This is a hard error, log it. */
if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) { if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) {
netif_stop_queue(dev); netif_stop_queue(dev);
spin_unlock_irq(&tp->lock); spin_unlock(&tp->tx_lock);
printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n", printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
dev->name); dev->name);
return 1; return 1;
...@@ -2327,7 +2336,7 @@ static int tg3_start_xmit_4gbug(struct sk_buff *skb, struct net_device *dev) ...@@ -2327,7 +2336,7 @@ static int tg3_start_xmit_4gbug(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue(dev); netif_stop_queue(dev);
out_unlock: out_unlock:
spin_unlock_irq(&tp->lock); spin_unlock(&tp->tx_lock);
dev->trans_start = jiffies; dev->trans_start = jiffies;
...@@ -2342,12 +2351,16 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -2342,12 +2351,16 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
len = (skb->len - skb->data_len); len = (skb->len - skb->data_len);
spin_lock_irq(&tp->lock); /* No BH disabling for tx_lock here. We are running in BH disabled
* context and TX reclaim runs via tp->poll inside of a software
* interrupt. Rejoice!
*/
spin_lock(&tp->tx_lock);
/* This is a hard error, log it. */ /* This is a hard error, log it. */
if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) { if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) {
netif_stop_queue(dev); netif_stop_queue(dev);
spin_unlock_irq(&tp->lock); spin_unlock(&tp->tx_lock);
printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n", printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
dev->name); dev->name);
return 1; return 1;
...@@ -2416,7 +2429,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -2416,7 +2429,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (TX_BUFFS_AVAIL(tp) <= (MAX_SKB_FRAGS + 1)) if (TX_BUFFS_AVAIL(tp) <= (MAX_SKB_FRAGS + 1))
netif_stop_queue(dev); netif_stop_queue(dev);
spin_unlock_irq(&tp->lock); spin_unlock(&tp->tx_lock);
dev->trans_start = jiffies; dev->trans_start = jiffies;
...@@ -2439,6 +2452,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) ...@@ -2439,6 +2452,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
} }
spin_lock_irq(&tp->lock); spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock);
tg3_halt(tp); tg3_halt(tp);
...@@ -2452,6 +2466,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) ...@@ -2452,6 +2466,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
tg3_init_rings(tp); tg3_init_rings(tp);
tg3_init_hw(tp); tg3_init_hw(tp);
spin_unlock(&tp->tx_lock);
spin_unlock_irq(&tp->lock); spin_unlock_irq(&tp->lock);
return 0; return 0;
...@@ -2461,7 +2476,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) ...@@ -2461,7 +2476,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
* *
* The chip has been shut down and the driver detached from * The chip has been shut down and the driver detached from
* the networking, so no interrupts or new tx packets will * the networking, so no interrupts or new tx packets will
* end up in the driver. tp->lock is not held and we are not * end up in the driver. tp->{tx,}lock is not held and we are not
* in an interrupt context and thus may sleep. * in an interrupt context and thus may sleep.
*/ */
static void tg3_free_rings(struct tg3 *tp) static void tg3_free_rings(struct tg3 *tp)
...@@ -2546,7 +2561,7 @@ static void tg3_free_rings(struct tg3 *tp) ...@@ -2546,7 +2561,7 @@ static void tg3_free_rings(struct tg3 *tp)
* *
* The chip has been shut down and the driver detached from * The chip has been shut down and the driver detached from
* the networking, so no interrupts or new tx packets will * the networking, so no interrupts or new tx packets will
* end up in the driver. tp->lock is not held and we are not * end up in the driver. tp->{tx,}lock is not held and we are not
* in an interrupt context and thus may sleep. * in an interrupt context and thus may sleep.
*/ */
static void tg3_init_rings(struct tg3 *tp) static void tg3_init_rings(struct tg3 *tp)
...@@ -3711,6 +3726,7 @@ static void tg3_timer(unsigned long __opaque) ...@@ -3711,6 +3726,7 @@ static void tg3_timer(unsigned long __opaque)
struct tg3 *tp = (struct tg3 *) __opaque; struct tg3 *tp = (struct tg3 *) __opaque;
spin_lock_irq(&tp->lock); spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock);
/* All of this garbage is because when using non-tagged /* All of this garbage is because when using non-tagged
* IRQ status the mailbox/status_block protocol the chip * IRQ status the mailbox/status_block protocol the chip
...@@ -3772,6 +3788,7 @@ static void tg3_timer(unsigned long __opaque) ...@@ -3772,6 +3788,7 @@ static void tg3_timer(unsigned long __opaque)
tp->timer_counter = tp->timer_multiplier; tp->timer_counter = tp->timer_multiplier;
} }
spin_unlock(&tp->tx_lock);
spin_unlock_irq(&tp->lock); spin_unlock_irq(&tp->lock);
tp->timer.expires = jiffies + tp->timer_offset; tp->timer.expires = jiffies + tp->timer_offset;
...@@ -3784,10 +3801,12 @@ static int tg3_open(struct net_device *dev) ...@@ -3784,10 +3801,12 @@ static int tg3_open(struct net_device *dev)
int err; int err;
spin_lock_irq(&tp->lock); spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock);
tg3_disable_ints(tp); tg3_disable_ints(tp);
tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE; tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
spin_unlock(&tp->tx_lock);
spin_unlock_irq(&tp->lock); spin_unlock_irq(&tp->lock);
/* If you move this call, make sure TG3_FLAG_HOST_TXDS in /* If you move this call, make sure TG3_FLAG_HOST_TXDS in
...@@ -3806,6 +3825,7 @@ static int tg3_open(struct net_device *dev) ...@@ -3806,6 +3825,7 @@ static int tg3_open(struct net_device *dev)
} }
spin_lock_irq(&tp->lock); spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock);
tg3_init_rings(tp); tg3_init_rings(tp);
...@@ -3823,13 +3843,10 @@ static int tg3_open(struct net_device *dev) ...@@ -3823,13 +3843,10 @@ static int tg3_open(struct net_device *dev)
tp->timer.function = tg3_timer; tp->timer.function = tg3_timer;
add_timer(&tp->timer); add_timer(&tp->timer);
tp->last_rate_sample = jiffies;
tp->last_rx_count = 0;
tp->last_tx_count = 0;
tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
} }
spin_unlock(&tp->tx_lock);
spin_unlock_irq(&tp->lock); spin_unlock_irq(&tp->lock);
if (err) { if (err) {
...@@ -3841,9 +3858,11 @@ static int tg3_open(struct net_device *dev) ...@@ -3841,9 +3858,11 @@ static int tg3_open(struct net_device *dev)
netif_start_queue(dev); netif_start_queue(dev);
spin_lock_irq(&tp->lock); spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock);
tg3_enable_ints(tp); tg3_enable_ints(tp);
spin_unlock(&tp->tx_lock);
spin_unlock_irq(&tp->lock); spin_unlock_irq(&tp->lock);
return 0; return 0;
...@@ -4105,6 +4124,7 @@ static int tg3_close(struct net_device *dev) ...@@ -4105,6 +4124,7 @@ static int tg3_close(struct net_device *dev)
del_timer_sync(&tp->timer); del_timer_sync(&tp->timer);
spin_lock_irq(&tp->lock); spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock);
#if 0 #if 0
tg3_dump_state(tp); tg3_dump_state(tp);
#endif #endif
...@@ -4118,6 +4138,7 @@ static int tg3_close(struct net_device *dev) ...@@ -4118,6 +4138,7 @@ static int tg3_close(struct net_device *dev)
TG3_FLAG_GOT_SERDES_FLOWCTL); TG3_FLAG_GOT_SERDES_FLOWCTL);
netif_carrier_off(tp->dev); netif_carrier_off(tp->dev);
spin_unlock(&tp->tx_lock);
spin_unlock_irq(&tp->lock); spin_unlock_irq(&tp->lock);
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
...@@ -4325,6 +4346,7 @@ static u8 *tg3_get_regs(struct tg3 *tp) ...@@ -4325,6 +4346,7 @@ static u8 *tg3_get_regs(struct tg3 *tp)
memset(orig_p, 0, TG3_REGDUMP_LEN); memset(orig_p, 0, TG3_REGDUMP_LEN);
spin_lock_irq(&tp->lock); spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock);
#define __GET_REG32(reg) (*((u32 *)(p))++ = tr32(reg)) #define __GET_REG32(reg) (*((u32 *)(p))++ = tr32(reg))
#define GET_REG32_LOOP(base,len) \ #define GET_REG32_LOOP(base,len) \
...@@ -4373,6 +4395,7 @@ do { p = orig_p + (reg); \ ...@@ -4373,6 +4395,7 @@ do { p = orig_p + (reg); \
#undef GET_REG32_LOOP #undef GET_REG32_LOOP
#undef GET_REG32_1 #undef GET_REG32_1
spin_unlock(&tp->tx_lock);
spin_unlock_irq(&tp->lock); spin_unlock_irq(&tp->lock);
return orig_p; return orig_p;
...@@ -4471,6 +4494,7 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr) ...@@ -4471,6 +4494,7 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr)
} }
spin_lock_irq(&tp->lock); spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock);
tp->link_config.autoneg = cmd.autoneg; tp->link_config.autoneg = cmd.autoneg;
if (cmd.autoneg == AUTONEG_ENABLE) { if (cmd.autoneg == AUTONEG_ENABLE) {
...@@ -4483,6 +4507,7 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr) ...@@ -4483,6 +4507,7 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr)
} }
tg3_setup_phy(tp); tg3_setup_phy(tp);
spin_unlock(&tp->tx_lock);
spin_unlock_irq(&tp->lock); spin_unlock_irq(&tp->lock);
return 0; return 0;
...@@ -4617,6 +4642,7 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr) ...@@ -4617,6 +4642,7 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr)
return -EINVAL; return -EINVAL;
spin_lock_irq(&tp->lock); spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock);
tp->rx_pending = ering.rx_pending; tp->rx_pending = ering.rx_pending;
#if TG3_MINI_RING_WORKS #if TG3_MINI_RING_WORKS
...@@ -4629,6 +4655,7 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr) ...@@ -4629,6 +4655,7 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr)
tg3_init_rings(tp); tg3_init_rings(tp);
tg3_init_hw(tp); tg3_init_hw(tp);
netif_wake_queue(tp->dev); netif_wake_queue(tp->dev);
spin_unlock(&tp->tx_lock);
spin_unlock_irq(&tp->lock); spin_unlock_irq(&tp->lock);
return 0; return 0;
...@@ -4653,6 +4680,7 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr) ...@@ -4653,6 +4680,7 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr)
return -EFAULT; return -EFAULT;
spin_lock_irq(&tp->lock); spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock);
if (epause.autoneg) if (epause.autoneg)
tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG; tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
else else
...@@ -4668,6 +4696,7 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr) ...@@ -4668,6 +4696,7 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr)
tg3_halt(tp); tg3_halt(tp);
tg3_init_rings(tp); tg3_init_rings(tp);
tg3_init_hw(tp); tg3_init_hw(tp);
spin_unlock(&tp->tx_lock);
spin_unlock_irq(&tp->lock); spin_unlock_irq(&tp->lock);
return 0; return 0;
...@@ -4805,7 +4834,9 @@ static void tg3_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) ...@@ -4805,7 +4834,9 @@ static void tg3_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
struct tg3 *tp = dev->priv; struct tg3 *tp = dev->priv;
spin_lock_irq(&tp->lock); spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock);
tp->vlgrp = grp; tp->vlgrp = grp;
spin_unlock(&tp->tx_lock);
spin_unlock_irq(&tp->lock); spin_unlock_irq(&tp->lock);
} }
...@@ -4814,8 +4845,10 @@ static void tg3_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) ...@@ -4814,8 +4845,10 @@ static void tg3_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
struct tg3 *tp = dev->priv; struct tg3 *tp = dev->priv;
spin_lock_irq(&tp->lock); spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock);
if (tp->vlgrp) if (tp->vlgrp)
tp->vlgrp->vlan_devices[vid] = NULL; tp->vlgrp->vlan_devices[vid] = NULL;
spin_unlock(&tp->tx_lock);
spin_unlock_irq(&tp->lock); spin_unlock_irq(&tp->lock);
} }
#endif #endif
...@@ -5926,6 +5959,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, ...@@ -5926,6 +5959,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
tp->grc_mode |= GRC_MODE_BSWAP_NONFRM_DATA; tp->grc_mode |= GRC_MODE_BSWAP_NONFRM_DATA;
#endif #endif
spin_lock_init(&tp->lock); spin_lock_init(&tp->lock);
spin_lock_init(&tp->tx_lock);
spin_lock_init(&tp->indirect_lock); spin_lock_init(&tp->indirect_lock);
tp->regs = (unsigned long) ioremap(tg3reg_base, tg3reg_len); tp->regs = (unsigned long) ioremap(tg3reg_base, tg3reg_len);
...@@ -6061,22 +6095,28 @@ static int tg3_suspend(struct pci_dev *pdev, u32 state) ...@@ -6061,22 +6095,28 @@ static int tg3_suspend(struct pci_dev *pdev, u32 state)
return 0; return 0;
spin_lock_irq(&tp->lock); spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock);
tg3_disable_ints(tp); tg3_disable_ints(tp);
spin_unlock(&tp->tx_lock);
spin_unlock_irq(&tp->lock); spin_unlock_irq(&tp->lock);
netif_device_detach(dev); netif_device_detach(dev);
spin_lock_irq(&tp->lock); spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock);
tg3_halt(tp); tg3_halt(tp);
spin_unlock(&tp->tx_lock);
spin_unlock_irq(&tp->lock); spin_unlock_irq(&tp->lock);
err = tg3_set_power_state(tp, state); err = tg3_set_power_state(tp, state);
if (err) { if (err) {
spin_lock_irq(&tp->lock); spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock);
tg3_init_rings(tp); tg3_init_rings(tp);
tg3_init_hw(tp); tg3_init_hw(tp);
spin_unlock(&tp->tx_lock);
spin_unlock_irq(&tp->lock); spin_unlock_irq(&tp->lock);
netif_device_attach(dev); netif_device_attach(dev);
...@@ -6101,11 +6141,13 @@ static int tg3_resume(struct pci_dev *pdev) ...@@ -6101,11 +6141,13 @@ static int tg3_resume(struct pci_dev *pdev)
netif_device_attach(dev); netif_device_attach(dev);
spin_lock_irq(&tp->lock); spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock);
tg3_init_rings(tp); tg3_init_rings(tp);
tg3_init_hw(tp); tg3_init_hw(tp);
tg3_enable_ints(tp); tg3_enable_ints(tp);
spin_unlock(&tp->tx_lock);
spin_unlock_irq(&tp->lock); spin_unlock_irq(&tp->lock);
return 0; return 0;
......
...@@ -1701,7 +1701,21 @@ struct tg3_bufmgr_config { ...@@ -1701,7 +1701,21 @@ struct tg3_bufmgr_config {
}; };
struct tg3 { struct tg3 {
/* SMP locking strategy:
*
* lock: Held during all operations except TX packet
* processing.
*
* tx_lock: Held during tg3_start_xmit{,_4gbug} and tg3_tx
*
* If you want to shut up all asynchronous processing you must
* acquire both locks, 'lock' taken before 'tx_lock'. IRQs must
* be disabled to take 'lock' but only softirq disabling is
* necessary for acquisition of 'tx_lock'.
*/
spinlock_t lock; spinlock_t lock;
spinlock_t tx_lock;
u32 tx_prod; u32 tx_prod;
u32 tx_cons; u32 tx_cons;
u32 rx_rcb_ptr; u32 rx_rcb_ptr;
...@@ -1716,11 +1730,6 @@ struct tg3 { ...@@ -1716,11 +1730,6 @@ struct tg3 {
struct net_device_stats net_stats_prev; struct net_device_stats net_stats_prev;
unsigned long phy_crc_errors; unsigned long phy_crc_errors;
/* Adaptive coalescing engine. */
unsigned long last_rate_sample;
u32 last_rx_count;
u32 last_tx_count;
u32 rx_offset; u32 rx_offset;
u32 tg3_flags; u32 tg3_flags;
#define TG3_FLAG_HOST_TXDS 0x00000001 #define TG3_FLAG_HOST_TXDS 0x00000001
...@@ -1728,8 +1737,6 @@ struct tg3 { ...@@ -1728,8 +1737,6 @@ struct tg3 {
#define TG3_FLAG_RX_CHECKSUMS 0x00000004 #define TG3_FLAG_RX_CHECKSUMS 0x00000004
#define TG3_FLAG_USE_LINKCHG_REG 0x00000008 #define TG3_FLAG_USE_LINKCHG_REG 0x00000008
#define TG3_FLAG_USE_MI_INTERRUPT 0x00000010 #define TG3_FLAG_USE_MI_INTERRUPT 0x00000010
#define TG3_FLAG_ADAPTIVE_RX 0x00000020
#define TG3_FLAG_ADAPTIVE_TX 0x00000040
#define TG3_FLAG_POLL_SERDES 0x00000080 #define TG3_FLAG_POLL_SERDES 0x00000080
#define TG3_FLAG_PHY_RESET_ON_INIT 0x00000100 #define TG3_FLAG_PHY_RESET_ON_INIT 0x00000100
#define TG3_FLAG_PCIX_TARGET_HWBUG 0x00000200 #define TG3_FLAG_PCIX_TARGET_HWBUG 0x00000200
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment