From 73e3dd6b45c4c870fc2641eb04c24e3f12dab1e0 Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Tue, 23 Apr 2013 01:56:34 +0000 Subject: e1000e: fix numeric overflow in phc settime method The PTP Hardware Clock settime function in the e1000e driver computes nanoseconds from a struct timespec. The code converts the seconds field .tv_sec by multiplying it with NSEC_PER_SEC. However, both operands are of type long, resulting in an unintended overflow. The patch fixes the issue by using the helper function from time.h. CC: stable Signed-off-by: Richard Cochran Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher diff --git a/drivers/net/ethernet/intel/e1000e/ptp.c b/drivers/net/ethernet/intel/e1000e/ptp.c index b477fa5..065f8c8 100644 --- a/drivers/net/ethernet/intel/e1000e/ptp.c +++ b/drivers/net/ethernet/intel/e1000e/ptp.c @@ -145,8 +145,7 @@ static int e1000e_phc_settime(struct ptp_clock_info *ptp, unsigned long flags; u64 ns; - ns = ts->tv_sec * NSEC_PER_SEC; - ns += ts->tv_nsec; + ns = timespec_to_ns(ts); /* reset the timecounter */ spin_lock_irqsave(&adapter->systim_lock, flags); -- cgit v0.10.2 From a3b87a4c69619f5366b7225aafbf7983eed31a9a Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Sat, 20 Apr 2013 05:37:29 +0000 Subject: e1000e: panic caused by Rx traffic arriving while interface going down An "unable to handle kernel paging request" panic can occur when receiving traffic while the interface is going down. Wait for NAPI to be done with current context after disabling interrupts and then disable NAPI. See https://bugzilla.vyatta.com/show_bug.cgi?id=8837. Reported-by: Stephen Hemminger Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index da7f2fa..a27e3bc 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -4016,6 +4016,8 @@ void e1000e_down(struct e1000_adapter *adapter) e1000_irq_disable(adapter); + napi_synchronize(&adapter->napi); + del_timer_sync(&adapter->watchdog_timer); del_timer_sync(&adapter->phy_info_timer); @@ -4372,12 +4374,13 @@ static int e1000_close(struct net_device *netdev) pm_runtime_get_sync(&pdev->dev); - napi_disable(&adapter->napi); - if (!test_bit(__E1000_DOWN, &adapter->state)) { e1000e_down(adapter); e1000_free_irq(adapter); } + + napi_disable(&adapter->napi); + e1000_power_down_phy(adapter); e1000e_free_tx_resources(adapter->tx_ring); -- cgit v0.10.2 From dc3d226f3366f98af73caffc46b5c0a57fe32a51 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 22 Apr 2013 07:46:40 +0000 Subject: igb: limit udelay for phy changes to 10000us If you really want 100000us you should really use mdelay or so. Found by the LTO kernel build Signed-off-by: Andi Kleen Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher diff --git a/drivers/net/ethernet/intel/igb/e1000_phy.c b/drivers/net/ethernet/intel/igb/e1000_phy.c index fd46add..115b0da 100644 --- a/drivers/net/ethernet/intel/igb/e1000_phy.c +++ b/drivers/net/ethernet/intel/igb/e1000_phy.c @@ -1130,7 +1130,7 @@ s32 igb_phy_force_speed_duplex_igp(struct e1000_hw *hw) if (phy->autoneg_wait_to_complete) { hw_dbg("Waiting for forced speed/duplex link on IGP phy.\n"); - ret_val = igb_phy_has_link(hw, PHY_FORCE_LIMIT, 100000, &link); + ret_val = igb_phy_has_link(hw, PHY_FORCE_LIMIT, 10000, &link); if (ret_val) goto out; @@ -1138,7 +1138,7 @@ s32 igb_phy_force_speed_duplex_igp(struct e1000_hw *hw) hw_dbg("Link taking longer than expected.\n"); /* Try once more */ - ret_val = igb_phy_has_link(hw, PHY_FORCE_LIMIT, 100000, &link); + ret_val = igb_phy_has_link(hw, PHY_FORCE_LIMIT, 10000, &link); if (ret_val) goto out; } @@ -1590,7 +1590,7 @@ s32 igb_phy_has_link(struct e1000_hw *hw, u32 iterations, * it across the board. */ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status); - if (ret_val) { + if (ret_val && usec_interval > 0) { /* If the first read fails, another entity may have * ownership of the resources, wait and try again to * see if they have relinquished the resources yet. -- cgit v0.10.2 From d87d830720a1446403ed38bfc2da268be0d356d1 Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Sat, 2 Mar 2013 07:51:42 +0000 Subject: ixgbe: fix EICR write in ixgbe_msix_other Previously, the ixgbe_msix_other was writing the full 32bits of the set interrupts, instead of only the ones which the ixgbe_msix_other is handling. This resulted in a loss of performance when the X540's PPS feature is enabled due to sometimes clearing queue interrupts which resulted in the driver not getting the interrupt for cleaning the q_vector rings often enough. The fix is to simply mask the lower 16bits off so that this handler does not write them in the EICR, which causes them to remain high and be properly handled by the clean_rings interrupt routine as normal. Signed-off-by: Jacob Keller Cc: stable Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 88f6737..d30fbdd 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -2454,6 +2454,16 @@ static irqreturn_t ixgbe_msix_other(int irq, void *data) * with the write to EICR. */ eicr = IXGBE_READ_REG(hw, IXGBE_EICS); + + /* The lower 16bits of the EICR register are for the queue interrupts + * which should be masked here in order to not accidently clear them if + * the bits are high when ixgbe_msix_other is called. There is a race + * condition otherwise which results in possible performance loss + * especially if the ixgbe_msix_other interrupt is triggering + * consistently (as it would when PPS is turned on for the X540 device) + */ + eicr &= 0xFFFF0000; + IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr); if (eicr & IXGBE_EICR_LSC) -- cgit v0.10.2 From 26b4742beaf18456195eeda1b8f59547f5569ac7 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Fri, 12 Apr 2013 02:10:25 +0000 Subject: ixgbe: fix register access during ethtool loopback test This patch cleans up the logic in ixgbe_setup_loopback_test() to only access registers applicable to the MAC type. AUTOC is only valid on MACs older than X540. MACC is used for X540. In addition it removes a read of AUTOC and uses the stored value to force the link up. Signed-off-by: Emil Tantilov Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index bbe00bc..509d3ae 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c @@ -1609,16 +1609,9 @@ static int ixgbe_setup_loopback_test(struct ixgbe_adapter *adapter) struct ixgbe_hw *hw = &adapter->hw; u32 reg_data; - /* X540 needs to set the MACC.FLU bit to force link up */ - if (adapter->hw.mac.type == ixgbe_mac_X540) { - reg_data = IXGBE_READ_REG(hw, IXGBE_MACC); - reg_data |= IXGBE_MACC_FLU; - IXGBE_WRITE_REG(hw, IXGBE_MACC, reg_data); - } - /* right now we only support MAC loopback in the driver */ - reg_data = IXGBE_READ_REG(hw, IXGBE_HLREG0); /* Setup MAC loopback */ + reg_data = IXGBE_READ_REG(hw, IXGBE_HLREG0); reg_data |= IXGBE_HLREG0_LPBK; IXGBE_WRITE_REG(hw, IXGBE_HLREG0, reg_data); @@ -1626,10 +1619,19 @@ static int ixgbe_setup_loopback_test(struct ixgbe_adapter *adapter) reg_data |= IXGBE_FCTRL_BAM | IXGBE_FCTRL_SBP | IXGBE_FCTRL_MPE; IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg_data); - reg_data = IXGBE_READ_REG(hw, IXGBE_AUTOC); - reg_data &= ~IXGBE_AUTOC_LMS_MASK; - reg_data |= IXGBE_AUTOC_LMS_10G_LINK_NO_AN | IXGBE_AUTOC_FLU; - IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_data); + /* X540 needs to set the MACC.FLU bit to force link up */ + if (adapter->hw.mac.type == ixgbe_mac_X540) { + reg_data = IXGBE_READ_REG(hw, IXGBE_MACC); + reg_data |= IXGBE_MACC_FLU; + IXGBE_WRITE_REG(hw, IXGBE_MACC, reg_data); + } else { + if (hw->mac.orig_autoc) { + reg_data = hw->mac.orig_autoc | IXGBE_AUTOC_FLU; + IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_data); + } else { + return 10; + } + } IXGBE_WRITE_FLUSH(hw); usleep_range(10000, 20000); -- cgit v0.10.2 From 5e82f2f07645ef2d8db837ebe907dfbb33d18a1e Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Fri, 12 Apr 2013 08:36:42 +0000 Subject: ixgbe: cache AUTOC reads This patch removes majority of the AUTOC register reads by using a cached value instead. The reason for this change is to avoid writing corrupted values to AUTOC due to bad FW. Signed-off-by: Emil Tantilov Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c index 3f79242..c4c5e87 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c @@ -167,9 +167,9 @@ static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw) } /* Restart DSP and set SFI mode */ - IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (IXGBE_READ_REG(hw, - IXGBE_AUTOC) | IXGBE_AUTOC_LMS_10G_SERIAL)); - + IXGBE_WRITE_REG(hw, IXGBE_AUTOC, ((hw->mac.orig_autoc) | + IXGBE_AUTOC_LMS_10G_SERIAL)); + hw->mac.cached_autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); ret_val = ixgbe_reset_pipeline_82599(hw); if (got_lock) { @@ -803,12 +803,9 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, bool autoneg_wait_to_complete) { s32 status = 0; - u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); + u32 autoc, pma_pmd_1g, link_mode, start_autoc; u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2); - u32 start_autoc = autoc; u32 orig_autoc = 0; - u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK; - u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK; u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK; u32 links_reg; u32 i; @@ -831,9 +828,14 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, /* Use stored value (EEPROM defaults) of AUTOC to find KR/KX4 support*/ if (hw->mac.orig_link_settings_stored) - orig_autoc = hw->mac.orig_autoc; + autoc = hw->mac.orig_autoc; else - orig_autoc = autoc; + autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); + + orig_autoc = autoc; + start_autoc = hw->mac.cached_autoc; + link_mode = autoc & IXGBE_AUTOC_LMS_MASK; + pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK; if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR || link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN || @@ -887,6 +889,7 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, /* Restart link */ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc); + hw->mac.cached_autoc = autoc; ixgbe_reset_pipeline_82599(hw); if (got_lock) @@ -958,7 +961,7 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw) { ixgbe_link_speed link_speed; s32 status; - u32 ctrl, i, autoc, autoc2; + u32 ctrl, i, autoc2; u32 curr_lms; bool link_up = false; @@ -991,8 +994,12 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw) if (hw->phy.reset_disable == false && hw->phy.ops.reset != NULL) hw->phy.ops.reset(hw); - /* remember AUTOC LMS from before we reset */ - curr_lms = IXGBE_READ_REG(hw, IXGBE_AUTOC) & IXGBE_AUTOC_LMS_MASK; + /* remember AUTOC from before we reset */ + if (hw->mac.cached_autoc) + curr_lms = hw->mac.cached_autoc & IXGBE_AUTOC_LMS_MASK; + else + curr_lms = IXGBE_READ_REG(hw, IXGBE_AUTOC) & + IXGBE_AUTOC_LMS_MASK; mac_reset_top: /* @@ -1042,10 +1049,10 @@ mac_reset_top: * stored off yet. Otherwise restore the stored original * values since the reset operation sets back to defaults. */ - autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); + hw->mac.cached_autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2); if (hw->mac.orig_link_settings_stored == false) { - hw->mac.orig_autoc = autoc; + hw->mac.orig_autoc = hw->mac.cached_autoc; hw->mac.orig_autoc2 = autoc2; hw->mac.orig_link_settings_stored = true; } else { @@ -1062,7 +1069,7 @@ mac_reset_top: (hw->mac.orig_autoc & ~IXGBE_AUTOC_LMS_MASK) | curr_lms; - if (autoc != hw->mac.orig_autoc) { + if (hw->mac.cached_autoc != hw->mac.orig_autoc) { /* Need SW/FW semaphore around AUTOC writes if LESM is * on, likewise reset_pipeline requires us to hold * this lock as it also writes to AUTOC. @@ -1078,6 +1085,7 @@ mac_reset_top: } IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc); + hw->mac.cached_autoc = hw->mac.orig_autoc; ixgbe_reset_pipeline_82599(hw); if (got_lock) @@ -2181,7 +2189,7 @@ s32 ixgbe_reset_pipeline_82599(struct ixgbe_hw *hw) s32 i, autoc_reg, ret_val; s32 anlp1_reg = 0; - autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); + autoc_reg = hw->mac.cached_autoc; autoc_reg |= IXGBE_AUTOC_AN_RESTART; /* Write AUTOC register with toggled LMS[2] bit and Restart_AN */ diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h index 6d70665..7480f7b 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h @@ -2928,6 +2928,7 @@ struct ixgbe_mac_info { u32 max_tx_queues; u32 max_rx_queues; u32 orig_autoc; + u32 cached_autoc; u32 orig_autoc2; bool orig_link_settings_stored; bool autotry_restart; -- cgit v0.10.2 From 46d5ceddd282262267abecd70c5ed6f5bdce0f92 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Fri, 12 Apr 2013 08:36:47 +0000 Subject: ixgbe: add support for disabling link at boot time on 82599 This patch adds support for disabling link during boot time. This feature was requested by customers and is configurable through the EEPROM. Signed-off-by: Emil Tantilov Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c index c4c5e87..0b82d38 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c @@ -1051,6 +1051,14 @@ mac_reset_top: */ hw->mac.cached_autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2); + + /* Enable link if disabled in NVM */ + if (autoc2 & IXGBE_AUTOC2_LINK_DISABLE_MASK) { + autoc2 &= ~IXGBE_AUTOC2_LINK_DISABLE_MASK; + IXGBE_WRITE_REG(hw, IXGBE_AUTOC2, autoc2); + IXGBE_WRITE_FLUSH(hw); + } + if (hw->mac.orig_link_settings_stored == false) { hw->mac.orig_autoc = hw->mac.cached_autoc; hw->mac.orig_autoc2 = autoc2; @@ -2186,8 +2194,17 @@ static s32 ixgbe_read_eeprom_82599(struct ixgbe_hw *hw, **/ s32 ixgbe_reset_pipeline_82599(struct ixgbe_hw *hw) { - s32 i, autoc_reg, ret_val; - s32 anlp1_reg = 0; + s32 ret_val; + u32 anlp1_reg = 0; + u32 i, autoc_reg, autoc2_reg; + + /* Enable link if disabled in NVM */ + autoc2_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC2); + if (autoc2_reg & IXGBE_AUTOC2_LINK_DISABLE_MASK) { + autoc2_reg &= ~IXGBE_AUTOC2_LINK_DISABLE_MASK; + IXGBE_WRITE_REG(hw, IXGBE_AUTOC2, autoc2_reg); + IXGBE_WRITE_FLUSH(hw); + } autoc_reg = hw->mac.cached_autoc; autoc_reg |= IXGBE_AUTOC_AN_RESTART; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h index 7480f7b..70c6aa3 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h @@ -1593,6 +1593,7 @@ enum { #define IXGBE_AUTOC2_10G_KR (0x0 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT) #define IXGBE_AUTOC2_10G_XFI (0x1 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT) #define IXGBE_AUTOC2_10G_SFI (0x2 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT) +#define IXGBE_AUTOC2_LINK_DISABLE_MASK 0x70000000 #define IXGBE_MACC_FLU 0x00000001 #define IXGBE_MACC_FSV_10G 0x00030000 -- cgit v0.10.2 From c4a56de88c6cd9996fb5dc7576d6c4934b5e6465 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Fri, 19 Apr 2013 09:31:17 +0000 Subject: ixgbe: add mac type to the version in ethtool_regs This patch adds the mac type to the version in ethtool_regs. This will make it easier to check the mac type when dumping registers with ethtool. The drawback of this is that older versions of ethtool will only be able to dump in hex format for 82599 and above when used with the updated driver. Signed-off-by: Emil Tantilov Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index 509d3ae..d375472 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c @@ -440,7 +440,8 @@ static void ixgbe_get_regs(struct net_device *netdev, memset(p, 0, IXGBE_REGS_LEN * sizeof(u32)); - regs->version = (1 << 24) | hw->revision_id << 16 | hw->device_id; + regs->version = hw->mac.type << 24 | hw->revision_id << 16 | + hw->device_id; /* General Registers */ regs_buff[0] = IXGBE_READ_REG(hw, IXGBE_CTRL); -- cgit v0.10.2