diff options
author | Jesse Brandeburg <jesse.brandeburg@intel.com> | 2007-01-18 09:25:21 -0800 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-02-05 16:58:41 -0500 |
commit | b5fc8f0c43d388d76ebbb5650b20f4ce4420a5ad (patch) | |
tree | 918c5acec2c262da60f16570053edb86bb850618 /drivers/net | |
parent | bf3cea4d8a1a8deb21d247a0622f1aa54270e0f9 (diff) | |
download | op-kernel-dev-b5fc8f0c43d388d76ebbb5650b20f4ce4420a5ad.zip op-kernel-dev-b5fc8f0c43d388d76ebbb5650b20f4ce4420a5ad.tar.gz |
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 f091042..8e7acb0 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h @@ -257,7 +257,6 @@ struct e1000_adapter { spinlock_t tx_queue_lock; #endif atomic_t irq_sem; - unsigned int detect_link; unsigned int total_tx_bytes; unsigned int total_tx_packets; unsigned int total_rx_bytes; diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index c6259c7..d408949 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) * @data: pointer to a network interface device structure **/ -static -irqreturn_t e1000_intr_msi(int irq, void *data) +static irqreturn_t +e1000_intr_msi(int irq, void *data) { struct net_device *netdev = data; struct e1000_adapter *adapter = netdev_priv(netdev); @@ -3774,49 +3774,27 @@ irqreturn_t e1000_intr_msi(int irq, void *data) #ifndef CONFIG_E1000_NAPI int i; #endif + uint32_t icr = E1000_READ_REG(hw, ICR); - /* this code avoids the read of ICR but has to get 1000 interrupts - * at every link change event before it will notice the change */ - if (++adapter->detect_link >= 1000) { - uint32_t icr = E1000_READ_REG(hw, ICR); #ifdef CONFIG_E1000_NAPI - /* read ICR disables interrupts using IAM, so keep up with our - * enable/disable accounting */ - atomic_inc(&adapter->irq_sem); + /* read ICR disables interrupts using IAM, so keep up with our + * enable/disable accounting */ + atomic_inc(&adapter->irq_sem); #endif - adapter->detect_link = 0; - if ((icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) && - (icr & E1000_ICR_INT_ASSERTED)) { - hw->get_link_status = 1; - /* 80003ES2LAN workaround-- - * For packet buffer work-around on link down event; - * disable receives here in the ISR and - * reset adapter in watchdog - */ - if (netif_carrier_ok(netdev) && - (adapter->hw.mac_type == e1000_80003es2lan)) { - /* disable receives */ - uint32_t rctl = E1000_READ_REG(hw, RCTL); - E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN); - } - /* guard against interrupt when we're going down */ - if (!test_bit(__E1000_DOWN, &adapter->flags)) - mod_timer(&adapter->watchdog_timer, - jiffies + 1); + if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { + hw->get_link_status = 1; + /* 80003ES2LAN workaround-- For packet buffer work-around on + * link down event; disable receives here in the ISR and reset + * adapter in watchdog */ + if (netif_carrier_ok(netdev) && + (adapter->hw.mac_type == e1000_80003es2lan)) { + /* disable receives */ + uint32_t rctl = E1000_READ_REG(hw, RCTL); + E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN); } - } else { - E1000_WRITE_REG(hw, ICR, (0xffffffff & ~(E1000_ICR_RXSEQ | - E1000_ICR_LSC))); - /* bummer we have to flush here, but things break otherwise as - * some event appears to be lost or delayed and throughput - * drops. In almost all tests this flush is un-necessary */ - E1000_WRITE_FLUSH(hw); -#ifdef CONFIG_E1000_NAPI - /* Interrupt Auto-Mask (IAM)...upon writing ICR, interrupts are - * masked. No need for the IMC write, but it does mean we - * should account for it ASAP. */ - atomic_inc(&adapter->irq_sem); -#endif + /* guard against interrupt when we're going down */ + if (!test_bit(__E1000_DOWN, &adapter->flags)) + mod_timer(&adapter->watchdog_timer, jiffies + 1); } #ifdef CONFIG_E1000_NAPI |