aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJesse Brandeburg <jesse.brandeburg@intel.com>2009-03-18 21:24:04 -0400
committerDavid S. Miller <davem@davemloft.net>2009-03-20 04:17:29 -0400
commit22d5a71b50df739abaee83e2fdb191f8aa6b037c (patch)
tree8a04b7033bda976f1fefd3389f77bab1d35034ce /drivers
parente63d9762929d9b86ac87cfb8047e7f7b1f2ed2dd (diff)
ixgbe: Fixup the watchdog interrupt scheduling on 82599
The watchdog will schedule an interrupt to help make sure queues are cleaned in the case when an interrupt is missed, most likely due to very high load. On 82599, there are extra interrupt registers to account for the larger number of MSI-X vectors (64 total for 82599 vs. 18 total for 82598). These must be taken into account when performing this operation in the watchdog. Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com> Signed-off-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c113
1 files changed, 81 insertions, 32 deletions
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 335119a5687a..0956be7c7488 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -1434,27 +1434,6 @@ static void ixgbe_set_itr(struct ixgbe_adapter *adapter)
1434} 1434}
1435 1435
1436/** 1436/**
1437 * ixgbe_irq_disable - Mask off interrupt generation on the NIC
1438 * @adapter: board private structure
1439 **/
1440static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter)
1441{
1442 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0);
1443 if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
1444 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), ~0);
1445 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(2), ~0);
1446 }
1447 IXGBE_WRITE_FLUSH(&adapter->hw);
1448 if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
1449 int i;
1450 for (i = 0; i < adapter->num_msix_vectors; i++)
1451 synchronize_irq(adapter->msix_entries[i].vector);
1452 } else {
1453 synchronize_irq(adapter->pdev->irq);
1454 }
1455}
1456
1457/**
1458 * ixgbe_irq_enable - Enable default interrupt generation settings 1437 * ixgbe_irq_enable - Enable default interrupt generation settings
1459 * @adapter: board private structure 1438 * @adapter: board private structure
1460 **/ 1439 **/
@@ -1597,6 +1576,39 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter)
1597} 1576}
1598 1577
1599/** 1578/**
1579 * ixgbe_irq_disable - Mask off interrupt generation on the NIC
1580 * @adapter: board private structure
1581 **/
1582static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter)
1583{
1584 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0);
1585 if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
1586 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), ~0);
1587 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(2), ~0);
1588 }
1589 IXGBE_WRITE_FLUSH(&adapter->hw);
1590 if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
1591 int i;
1592 for (i = 0; i < adapter->num_msix_vectors; i++)
1593 synchronize_irq(adapter->msix_entries[i].vector);
1594 } else {
1595 synchronize_irq(adapter->pdev->irq);
1596 }
1597}
1598
1599static inline void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter)
1600{
1601 u32 mask = IXGBE_EIMS_RTX_QUEUE;
1602 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);
1603 if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
1604 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(1), mask << 16);
1605 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(2),
1606 (mask << 16 | mask));
1607 }
1608 /* skip the flush */
1609}
1610
1611/**
1600 * ixgbe_configure_msi_and_legacy - Initialize PIN (INTA...) and MSI interrupts 1612 * ixgbe_configure_msi_and_legacy - Initialize PIN (INTA...) and MSI interrupts
1601 * 1613 *
1602 **/ 1614 **/
@@ -2624,7 +2636,7 @@ static int ixgbe_poll(struct napi_struct *napi, int budget)
2624 if (adapter->itr_setting & 1) 2636 if (adapter->itr_setting & 1)
2625 ixgbe_set_itr(adapter); 2637 ixgbe_set_itr(adapter);
2626 if (!test_bit(__IXGBE_DOWN, &adapter->state)) 2638 if (!test_bit(__IXGBE_DOWN, &adapter->state))
2627 ixgbe_irq_enable(adapter); 2639 ixgbe_irq_enable_queues(adapter);
2628 } 2640 }
2629 return work_done; 2641 return work_done;
2630} 2642}
@@ -3806,17 +3818,54 @@ static void ixgbe_watchdog(unsigned long data)
3806 /* Do the watchdog outside of interrupt context due to the lovely 3818 /* Do the watchdog outside of interrupt context due to the lovely
3807 * delays that some of the newer hardware requires */ 3819 * delays that some of the newer hardware requires */
3808 if (!test_bit(__IXGBE_DOWN, &adapter->state)) { 3820 if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
3821 u64 eics = 0;
3822 int i;
3823
3824 for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++)
3825 eics |= (1 << i);
3826
3809 /* Cause software interrupt to ensure rx rings are cleaned */ 3827 /* Cause software interrupt to ensure rx rings are cleaned */
3810 if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { 3828 switch (hw->mac.type) {
3811 u32 eics = 3829 case ixgbe_mac_82598EB:
3812 (1 << (adapter->num_msix_vectors - NON_Q_VECTORS)) - 1; 3830 if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
3813 IXGBE_WRITE_REG(hw, IXGBE_EICS, eics); 3831 IXGBE_WRITE_REG(hw, IXGBE_EICS, (u32)eics);
3814 } else { 3832 } else {
3815 /* For legacy and MSI interrupts don't set any bits that 3833 /*
3816 * are enabled for EIAM, because this operation would 3834 * for legacy and MSI interrupts don't set any
3817 * set *both* EIMS and EICS for any bit in EIAM */ 3835 * bits that are enabled for EIAM, because this
3818 IXGBE_WRITE_REG(hw, IXGBE_EICS, 3836 * operation would set *both* EIMS and EICS for
3819 (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER)); 3837 * any bit in EIAM
3838 */
3839 IXGBE_WRITE_REG(hw, IXGBE_EICS,
3840 (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER));
3841 }
3842 break;
3843 case ixgbe_mac_82599EB:
3844 if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
3845 /*
3846 * EICS(0..15) first 0-15 q vectors
3847 * EICS[1] (16..31) q vectors 16-31
3848 * EICS[2] (0..31) q vectors 32-63
3849 */
3850 IXGBE_WRITE_REG(hw, IXGBE_EICS,
3851 (u32)(eics & 0xFFFF));
3852 IXGBE_WRITE_REG(hw, IXGBE_EICS_EX(1),
3853 (u32)(eics & 0xFFFF0000));
3854 IXGBE_WRITE_REG(hw, IXGBE_EICS_EX(2),
3855 (u32)(eics >> 32));
3856 } else {
3857 /*
3858 * for legacy and MSI interrupts don't set any
3859 * bits that are enabled for EIAM, because this
3860 * operation would set *both* EIMS and EICS for
3861 * any bit in EIAM
3862 */
3863 IXGBE_WRITE_REG(hw, IXGBE_EICS,
3864 (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER));
3865 }
3866 break;
3867 default:
3868 break;
3820 } 3869 }
3821 /* Reset the timer */ 3870 /* Reset the timer */
3822 mod_timer(&adapter->watchdog_timer, 3871 mod_timer(&adapter->watchdog_timer,