diff options
author | Michael Chan <mchan@broadcom.com> | 2005-06-24 23:20:04 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2005-06-24 23:20:04 -0400 |
commit | bbe832c09233738c100145fd535b6b8fc97640f6 (patch) | |
tree | a4c9b8ec06c768a5808018d1b9a1b919c223199c /drivers/net | |
parent | f47c11eeccc8820010992eb32dbe7370a08f8bd3 (diff) |
[TG3]: Refinements to new locking strategy.
1. Move tp->irq_sync = 0 to before the interrupt mailbox IO in
tg3_enable_ints() so that the interrupt handler will always see
irq_sync == 0 when interrupts are enabled.
2. Remove the tg3_enable_ints() call in tg3_reset_hw(). Interrupts are
always enabled explicitly or through tg3_netif_start(). This is to
prevent interrupts being enabled while poll is disabled.
3. Update trans_start with jiffies in tg3_netif_stop() to prevent false
NETDEV WATCHDOG.
4. Pass in the proper irq_sync parameter to tg3_full_lock() depending on
netif_running() in some of the ethtool set calls.
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/tg3.c | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 8b8aa2ad578b..04e747aa1a86 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -430,12 +430,14 @@ static inline void tg3_cond_int(struct tg3 *tp) | |||
430 | 430 | ||
431 | static void tg3_enable_ints(struct tg3 *tp) | 431 | static void tg3_enable_ints(struct tg3 *tp) |
432 | { | 432 | { |
433 | tp->irq_sync = 0; | ||
434 | wmb(); | ||
435 | |||
433 | tw32(TG3PCI_MISC_HOST_CTRL, | 436 | tw32(TG3PCI_MISC_HOST_CTRL, |
434 | (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT)); | 437 | (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT)); |
435 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, | 438 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, |
436 | (tp->last_tag << 24)); | 439 | (tp->last_tag << 24)); |
437 | tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); | 440 | tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); |
438 | tp->irq_sync = 0; | ||
439 | tg3_cond_int(tp); | 441 | tg3_cond_int(tp); |
440 | } | 442 | } |
441 | 443 | ||
@@ -484,6 +486,7 @@ static void tg3_restart_ints(struct tg3 *tp) | |||
484 | 486 | ||
485 | static inline void tg3_netif_stop(struct tg3 *tp) | 487 | static inline void tg3_netif_stop(struct tg3 *tp) |
486 | { | 488 | { |
489 | tp->dev->trans_start = jiffies; /* prevent tx timeout */ | ||
487 | netif_poll_disable(tp->dev); | 490 | netif_poll_disable(tp->dev); |
488 | netif_tx_disable(tp->dev); | 491 | netif_tx_disable(tp->dev); |
489 | } | 492 | } |
@@ -5724,9 +5727,6 @@ static int tg3_reset_hw(struct tg3 *tp) | |||
5724 | 5727 | ||
5725 | tg3_write_sig_post_reset(tp, RESET_KIND_INIT); | 5728 | tg3_write_sig_post_reset(tp, RESET_KIND_INIT); |
5726 | 5729 | ||
5727 | if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) | ||
5728 | tg3_enable_ints(tp); | ||
5729 | |||
5730 | return 0; | 5730 | return 0; |
5731 | } | 5731 | } |
5732 | 5732 | ||
@@ -7076,16 +7076,19 @@ static void tg3_get_ringparam(struct net_device *dev, struct ethtool_ringparam * | |||
7076 | static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) | 7076 | static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) |
7077 | { | 7077 | { |
7078 | struct tg3 *tp = netdev_priv(dev); | 7078 | struct tg3 *tp = netdev_priv(dev); |
7079 | int irq_sync = 0; | ||
7079 | 7080 | ||
7080 | if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) || | 7081 | if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) || |
7081 | (ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) || | 7082 | (ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) || |
7082 | (ering->tx_pending > TG3_TX_RING_SIZE - 1)) | 7083 | (ering->tx_pending > TG3_TX_RING_SIZE - 1)) |
7083 | return -EINVAL; | 7084 | return -EINVAL; |
7084 | 7085 | ||
7085 | if (netif_running(dev)) | 7086 | if (netif_running(dev)) { |
7086 | tg3_netif_stop(tp); | 7087 | tg3_netif_stop(tp); |
7088 | irq_sync = 1; | ||
7089 | } | ||
7087 | 7090 | ||
7088 | tg3_full_lock(tp, 0); | 7091 | tg3_full_lock(tp, irq_sync); |
7089 | 7092 | ||
7090 | tp->rx_pending = ering->rx_pending; | 7093 | tp->rx_pending = ering->rx_pending; |
7091 | 7094 | ||
@@ -7118,11 +7121,14 @@ static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam | |||
7118 | static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) | 7121 | static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) |
7119 | { | 7122 | { |
7120 | struct tg3 *tp = netdev_priv(dev); | 7123 | struct tg3 *tp = netdev_priv(dev); |
7124 | int irq_sync = 0; | ||
7121 | 7125 | ||
7122 | if (netif_running(dev)) | 7126 | if (netif_running(dev)) { |
7123 | tg3_netif_stop(tp); | 7127 | tg3_netif_stop(tp); |
7128 | irq_sync = 1; | ||
7129 | } | ||
7124 | 7130 | ||
7125 | tg3_full_lock(tp, 1); | 7131 | tg3_full_lock(tp, irq_sync); |
7126 | 7132 | ||
7127 | if (epause->autoneg) | 7133 | if (epause->autoneg) |
7128 | tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG; | 7134 | tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG; |
@@ -7578,8 +7584,6 @@ static int tg3_test_loopback(struct tg3 *tp) | |||
7578 | 7584 | ||
7579 | tg3_abort_hw(tp, 1); | 7585 | tg3_abort_hw(tp, 1); |
7580 | 7586 | ||
7581 | /* Clearing this flag to keep interrupts disabled */ | ||
7582 | tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE; | ||
7583 | tg3_reset_hw(tp); | 7587 | tg3_reset_hw(tp); |
7584 | 7588 | ||
7585 | mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | | 7589 | mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | |
@@ -7688,10 +7692,14 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, | |||
7688 | data[1] = 1; | 7692 | data[1] = 1; |
7689 | } | 7693 | } |
7690 | if (etest->flags & ETH_TEST_FL_OFFLINE) { | 7694 | if (etest->flags & ETH_TEST_FL_OFFLINE) { |
7691 | if (netif_running(dev)) | 7695 | int irq_sync = 0; |
7696 | |||
7697 | if (netif_running(dev)) { | ||
7692 | tg3_netif_stop(tp); | 7698 | tg3_netif_stop(tp); |
7699 | irq_sync = 1; | ||
7700 | } | ||
7693 | 7701 | ||
7694 | tg3_full_lock(tp, 1); | 7702 | tg3_full_lock(tp, irq_sync); |
7695 | 7703 | ||
7696 | tg3_halt(tp, RESET_KIND_SUSPEND, 1); | 7704 | tg3_halt(tp, RESET_KIND_SUSPEND, 1); |
7697 | tg3_nvram_lock(tp); | 7705 | tg3_nvram_lock(tp); |
@@ -10184,8 +10192,6 @@ static int tg3_resume(struct pci_dev *pdev) | |||
10184 | tp->timer.expires = jiffies + tp->timer_offset; | 10192 | tp->timer.expires = jiffies + tp->timer_offset; |
10185 | add_timer(&tp->timer); | 10193 | add_timer(&tp->timer); |
10186 | 10194 | ||
10187 | tg3_enable_ints(tp); | ||
10188 | |||
10189 | tg3_netif_start(tp); | 10195 | tg3_netif_start(tp); |
10190 | 10196 | ||
10191 | tg3_full_unlock(tp); | 10197 | tg3_full_unlock(tp); |