aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000
diff options
context:
space:
mode:
authorJesse Brandeburg <jesse.brandeburg@intel.com>2007-01-18 12:25:21 -0500
committerJeff Garzik <jeff@garzik.org>2007-02-05 16:58:41 -0500
commitb5fc8f0c43d388d76ebbb5650b20f4ce4420a5ad (patch)
tree918c5acec2c262da60f16570053edb86bb850618 /drivers/net/e1000
parentbf3cea4d8a1a8deb21d247a0622f1aa54270e0f9 (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/e1000')
-rw-r--r--drivers/net/e1000/e1000.h1
-rw-r--r--drivers/net/e1000/e1000_main.c60
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
3768static 3768static irqreturn_t
3769irqreturn_t e1000_intr_msi(int irq, void *data) 3769e1000_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