diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2009-10-27 23:49:59 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-10-28 03:25:52 -0700 |
commit | 25568a531a1bc76fdf968382a4eb65a979186c67 (patch) | |
tree | 165236fed52a368906e21734a0e6ae9422607aa5 | |
parent | ee1b9f06dca9c406b159904e9b13ea2dfa5ed037 (diff) |
igb: cleanup interrupt enablement in regards to msix_other
This patch changes a few things so that instead of firing a link status
interrupt directly the get_link_status bit is set and the watchdog is
scheduled. In addition the mailbox bit is now only enabled if VFs are
enabled.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/igb/igb_main.c | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 52c43021c13..5b0f93911f3 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -919,6 +919,11 @@ static void igb_irq_disable(struct igb_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; + /* + * we need to be careful when disabling interrupts. The VFs are also + * mapped into these registers and so clearing the bits can cause + * issues on the VF drivers so we only need to clear what we set + */ if (adapter->msix_entries) { u32 regval = rd32(E1000_EIAM); wr32(E1000_EIAM, regval & ~adapter->eims_enable_mask); @@ -942,15 +947,17 @@ static void igb_irq_enable(struct igb_adapter *adapter) struct e1000_hw *hw = &adapter->hw; if (adapter->msix_entries) { + u32 ims = E1000_IMS_LSC | E1000_IMS_DOUTSYNC; u32 regval = rd32(E1000_EIAC); wr32(E1000_EIAC, regval | adapter->eims_enable_mask); regval = rd32(E1000_EIAM); wr32(E1000_EIAM, regval | adapter->eims_enable_mask); wr32(E1000_EIMS, adapter->eims_enable_mask); - if (adapter->vfs_allocated_count) + if (adapter->vfs_allocated_count) { wr32(E1000_MBVFIMR, 0xFF); - wr32(E1000_IMS, (E1000_IMS_LSC | E1000_IMS_VMMB | - E1000_IMS_DOUTSYNC)); + ims |= E1000_IMS_VMMB; + } + wr32(E1000_IMS, ims); } else { wr32(E1000_IMS, IMS_ENABLE_MASK); wr32(E1000_IAM, IMS_ENABLE_MASK); @@ -1091,8 +1098,10 @@ int igb_up(struct igb_adapter *adapter) netif_tx_start_all_queues(adapter->netdev); - /* Fire a link change interrupt to start the watchdog. */ - wr32(E1000_ICS, E1000_ICS_LSC); + /* start the watchdog. */ + hw->mac.get_link_status = 1; + schedule_work(&adapter->watchdog_task); + return 0; } @@ -1889,8 +1898,9 @@ static int igb_open(struct net_device *netdev) netif_tx_start_all_queues(netdev); - /* Fire a link status change interrupt to start the watchdog. */ - wr32(E1000_ICS, E1000_ICS_LSC); + /* start the watchdog. */ + hw->mac.get_link_status = 1; + schedule_work(&adapter->watchdog_task); return 0; @@ -3952,7 +3962,12 @@ static irqreturn_t igb_msix_other(int irq, void *data) mod_timer(&adapter->watchdog_timer, jiffies + 1); } - wr32(E1000_IMS, E1000_IMS_LSC | E1000_IMS_DOUTSYNC | E1000_IMS_VMMB); + if (adapter->vfs_allocated_count) + wr32(E1000_IMS, E1000_IMS_LSC | + E1000_IMS_VMMB | + E1000_IMS_DOUTSYNC); + else + wr32(E1000_IMS, E1000_IMS_LSC | E1000_IMS_DOUTSYNC); wr32(E1000_EIMS, adapter->eims_other); return IRQ_HANDLED; |