diff options
author | Jesse Brandeburg <jesse.brandeburg@intel.com> | 2007-01-18 12:25:21 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-02-05 16:58:41 -0500 |
commit | b5fc8f0c43d388d76ebbb5650b20f4ce4420a5ad (patch) | |
tree | 918c5acec2c262da60f16570053edb86bb850618 /drivers/net | |
parent | bf3cea4d8a1a8deb21d247a0622f1aa54270e0f9 (diff) |
e1000: Fix MSI only interrupt handler routine
Unfortunately the read-free MSI interrupt handler needs to flush write
the icr register and thus we can't be read-free. Our MSI irq routine
thus becomes a lot more simpler since we don't need to track link state
anymore.
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/e1000/e1000.h | 1 | ||||
-rw-r--r-- | drivers/net/e1000/e1000_main.c | 60 |
2 files changed, 19 insertions, 42 deletions
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index f091042b146e..8e7acb08d9a3 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h | |||
@@ -257,7 +257,6 @@ struct e1000_adapter { | |||
257 | spinlock_t tx_queue_lock; | 257 | spinlock_t tx_queue_lock; |
258 | #endif | 258 | #endif |
259 | atomic_t irq_sem; | 259 | atomic_t irq_sem; |
260 | unsigned int detect_link; | ||
261 | unsigned int total_tx_bytes; | 260 | unsigned int total_tx_bytes; |
262 | unsigned int total_tx_packets; | 261 | unsigned int total_tx_packets; |
263 | unsigned int total_rx_bytes; | 262 | unsigned int total_rx_bytes; |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index c6259c7127f6..d408949d61dd 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -3765,8 +3765,8 @@ e1000_update_stats(struct e1000_adapter *adapter) | |||
3765 | * @data: pointer to a network interface device structure | 3765 | * @data: pointer to a network interface device structure |
3766 | **/ | 3766 | **/ |
3767 | 3767 | ||
3768 | static | 3768 | static irqreturn_t |
3769 | irqreturn_t e1000_intr_msi(int irq, void *data) | 3769 | e1000_intr_msi(int irq, void *data) |
3770 | { | 3770 | { |
3771 | struct net_device *netdev = data; | 3771 | struct net_device *netdev = data; |
3772 | struct e1000_adapter *adapter = netdev_priv(netdev); | 3772 | struct e1000_adapter *adapter = netdev_priv(netdev); |
@@ -3774,49 +3774,27 @@ irqreturn_t e1000_intr_msi(int irq, void *data) | |||
3774 | #ifndef CONFIG_E1000_NAPI | 3774 | #ifndef CONFIG_E1000_NAPI |
3775 | int i; | 3775 | int i; |
3776 | #endif | 3776 | #endif |
3777 | uint32_t icr = E1000_READ_REG(hw, ICR); | ||
3777 | 3778 | ||
3778 | /* this code avoids the read of ICR but has to get 1000 interrupts | ||
3779 | * at every link change event before it will notice the change */ | ||
3780 | if (++adapter->detect_link >= 1000) { | ||
3781 | uint32_t icr = E1000_READ_REG(hw, ICR); | ||
3782 | #ifdef CONFIG_E1000_NAPI | 3779 | #ifdef CONFIG_E1000_NAPI |
3783 | /* read ICR disables interrupts using IAM, so keep up with our | 3780 | /* read ICR disables interrupts using IAM, so keep up with our |
3784 | * enable/disable accounting */ | 3781 | * enable/disable accounting */ |
3785 | atomic_inc(&adapter->irq_sem); | 3782 | atomic_inc(&adapter->irq_sem); |
3786 | #endif | 3783 | #endif |
3787 | adapter->detect_link = 0; | 3784 | if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { |
3788 | if ((icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) && | 3785 | hw->get_link_status = 1; |
3789 | (icr & E1000_ICR_INT_ASSERTED)) { | 3786 | /* 80003ES2LAN workaround-- For packet buffer work-around on |
3790 | hw->get_link_status = 1; | 3787 | * link down event; disable receives here in the ISR and reset |
3791 | /* 80003ES2LAN workaround-- | 3788 | * adapter in watchdog */ |
3792 | * For packet buffer work-around on link down event; | 3789 | if (netif_carrier_ok(netdev) && |
3793 | * disable receives here in the ISR and | 3790 | (adapter->hw.mac_type == e1000_80003es2lan)) { |
3794 | * reset adapter in watchdog | 3791 | /* disable receives */ |
3795 | */ | 3792 | uint32_t rctl = E1000_READ_REG(hw, RCTL); |
3796 | if (netif_carrier_ok(netdev) && | 3793 | E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN); |
3797 | (adapter->hw.mac_type == e1000_80003es2lan)) { | ||
3798 | /* disable receives */ | ||
3799 | uint32_t rctl = E1000_READ_REG(hw, RCTL); | ||
3800 | E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN); | ||
3801 | } | ||
3802 | /* guard against interrupt when we're going down */ | ||
3803 | if (!test_bit(__E1000_DOWN, &adapter->flags)) | ||
3804 | mod_timer(&adapter->watchdog_timer, | ||
3805 | jiffies + 1); | ||
3806 | } | 3794 | } |
3807 | } else { | 3795 | /* guard against interrupt when we're going down */ |
3808 | E1000_WRITE_REG(hw, ICR, (0xffffffff & ~(E1000_ICR_RXSEQ | | 3796 | if (!test_bit(__E1000_DOWN, &adapter->flags)) |
3809 | E1000_ICR_LSC))); | 3797 | mod_timer(&adapter->watchdog_timer, jiffies + 1); |
3810 | /* bummer we have to flush here, but things break otherwise as | ||
3811 | * some event appears to be lost or delayed and throughput | ||
3812 | * drops. In almost all tests this flush is un-necessary */ | ||
3813 | E1000_WRITE_FLUSH(hw); | ||
3814 | #ifdef CONFIG_E1000_NAPI | ||
3815 | /* Interrupt Auto-Mask (IAM)...upon writing ICR, interrupts are | ||
3816 | * masked. No need for the IMC write, but it does mean we | ||
3817 | * should account for it ASAP. */ | ||
3818 | atomic_inc(&adapter->irq_sem); | ||
3819 | #endif | ||
3820 | } | 3798 | } |
3821 | 3799 | ||
3822 | #ifdef CONFIG_E1000_NAPI | 3800 | #ifdef CONFIG_E1000_NAPI |