diff options
Diffstat (limited to 'drivers/net/ethernet/intel/e1000e/ich8lan.c')
-rw-r--r-- | drivers/net/ethernet/intel/e1000e/ich8lan.c | 433 |
1 files changed, 207 insertions, 226 deletions
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index e2a80a283fd..64c76443a7a 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. + Copyright(c) 1999 - 2012 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -145,6 +145,8 @@ #define I82579_EMI_ADDR 0x10 #define I82579_EMI_DATA 0x11 #define I82579_LPI_UPDATE_TIMER 0x4805 /* in 40ns units + 40 ns base value */ +#define I82579_MSE_THRESHOLD 0x084F /* Mean Square Error Threshold */ +#define I82579_MSE_LINK_DOWN 0x2411 /* MSE count before dropping link */ /* Strapping Option Register - RO */ #define E1000_STRAP 0x0000C @@ -278,8 +280,8 @@ static inline void __ew32flash(struct e1000_hw *hw, unsigned long reg, u32 val) #define er16flash(reg) __er16flash(hw, (reg)) #define er32flash(reg) __er32flash(hw, (reg)) -#define ew16flash(reg,val) __ew16flash(hw, (reg), (val)) -#define ew32flash(reg,val) __ew32flash(hw, (reg), (val)) +#define ew16flash(reg, val) __ew16flash(hw, (reg), (val)) +#define ew32flash(reg, val) __ew32flash(hw, (reg), (val)) static void e1000_toggle_lanphypc_value_ich8lan(struct e1000_hw *hw) { @@ -304,7 +306,6 @@ static void e1000_toggle_lanphypc_value_ich8lan(struct e1000_hw *hw) static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; - u32 fwsm; s32 ret_val = 0; phy->addr = 1; @@ -323,14 +324,14 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) phy->ops.power_down = e1000_power_down_phy_copper_ich8lan; phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; - /* - * The MAC-PHY interconnect may still be in SMBus mode - * after Sx->S0. If the manageability engine (ME) is - * disabled, then toggle the LANPHYPC Value bit to force - * the interconnect to PCIe mode. - */ - fwsm = er32(FWSM); - if (!(fwsm & E1000_ICH_FWSM_FW_VALID) && !e1000_check_reset_block(hw)) { + if (!hw->phy.ops.check_reset_block(hw)) { + u32 fwsm = er32(FWSM); + + /* + * The MAC-PHY interconnect may still be in SMBus mode after + * Sx->S0. If resetting the PHY is not blocked, toggle the + * LANPHYPC Value bit to force the interconnect to PCIe mode. + */ e1000_toggle_lanphypc_value_ich8lan(hw); msleep(50); @@ -338,25 +339,26 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) * Gate automatic PHY configuration by hardware on * non-managed 82579 */ - if (hw->mac.type == e1000_pch2lan) + if ((hw->mac.type == e1000_pch2lan) && + !(fwsm & E1000_ICH_FWSM_FW_VALID)) e1000_gate_hw_phy_config_ich8lan(hw, true); - } - /* - * Reset the PHY before any access to it. Doing so, ensures that - * the PHY is in a known good state before we read/write PHY registers. - * The generic reset is sufficient here, because we haven't determined - * the PHY type yet. - */ - ret_val = e1000e_phy_hw_reset_generic(hw); - if (ret_val) - goto out; + /* + * Reset the PHY before any access to it. Doing so, ensures + * that the PHY is in a known good state before we read/write + * PHY registers. The generic reset is sufficient here, + * because we haven't determined the PHY type yet. + */ + ret_val = e1000e_phy_hw_reset_generic(hw); + if (ret_val) + return ret_val; - /* Ungate automatic PHY configuration on non-managed 82579 */ - if ((hw->mac.type == e1000_pch2lan) && - !(fwsm & E1000_ICH_FWSM_FW_VALID)) { - usleep_range(10000, 20000); - e1000_gate_hw_phy_config_ich8lan(hw, false); + /* Ungate automatic PHY configuration on non-managed 82579 */ + if ((hw->mac.type == e1000_pch2lan) && + !(fwsm & E1000_ICH_FWSM_FW_VALID)) { + usleep_range(10000, 20000); + e1000_gate_hw_phy_config_ich8lan(hw, false); + } } phy->id = e1000_phy_unknown; @@ -364,7 +366,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) default: ret_val = e1000e_get_phy_id(hw); if (ret_val) - goto out; + return ret_val; if ((phy->id != 0) && (phy->id != PHY_REVISION_MASK)) break; /* fall-through */ @@ -375,10 +377,10 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) */ ret_val = e1000_set_mdio_slow_mode_hv(hw); if (ret_val) - goto out; + return ret_val; ret_val = e1000e_get_phy_id(hw); if (ret_val) - goto out; + return ret_val; break; } phy->type = e1000e_get_phy_type_from_id(phy->id); @@ -404,7 +406,6 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) break; } -out: return ret_val; } @@ -551,9 +552,8 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw) * Initialize family-specific MAC parameters and function * pointers. **/ -static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter) +static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw) { - struct e1000_hw *hw = &adapter->hw; struct e1000_mac_info *mac = &hw->mac; /* Set media type function pointer */ @@ -580,7 +580,7 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter) /* check management mode */ mac->ops.check_mng_mode = e1000_check_mng_mode_ich8lan; /* ID LED init */ - mac->ops.id_led_init = e1000e_id_led_init; + mac->ops.id_led_init = e1000e_id_led_init_generic; /* blink LED */ mac->ops.blink_led = e1000e_blink_led_generic; /* setup LED */ @@ -634,20 +634,18 @@ static s32 e1000_set_eee_pchlan(struct e1000_hw *hw) u16 phy_reg; if (hw->phy.type != e1000_phy_82579) - goto out; + return 0; ret_val = e1e_rphy(hw, I82579_LPI_CTRL, &phy_reg); if (ret_val) - goto out; + return ret_val; if (hw->dev_spec.ich8lan.eee_disable) phy_reg &= ~I82579_LPI_CTRL_ENABLE_MASK; else phy_reg |= I82579_LPI_CTRL_ENABLE_MASK; - ret_val = e1e_wphy(hw, I82579_LPI_CTRL, phy_reg); -out: - return ret_val; + return e1e_wphy(hw, I82579_LPI_CTRL, phy_reg); } /** @@ -671,10 +669,8 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) * get_link_status flag is set upon receiving a Link Status * Change or Rx Sequence Error interrupt. */ - if (!mac->get_link_status) { - ret_val = 0; - goto out; - } + if (!mac->get_link_status) + return 0; /* * First we want to see if the MII Status Register reports @@ -683,16 +679,16 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) */ ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link); if (ret_val) - goto out; + return ret_val; if (hw->mac.type == e1000_pchlan) { ret_val = e1000_k1_gig_workaround_hv(hw, link); if (ret_val) - goto out; + return ret_val; } if (!link) - goto out; /* No link detected */ + return 0; /* No link detected */ mac->get_link_status = false; @@ -700,13 +696,13 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) case e1000_pch2lan: ret_val = e1000_k1_workaround_lv(hw); if (ret_val) - goto out; + return ret_val; /* fall-thru */ case e1000_pchlan: if (hw->phy.type == e1000_phy_82578) { ret_val = e1000_link_stall_workaround_hv(hw); if (ret_val) - goto out; + return ret_val; } /* @@ -736,23 +732,21 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) /* Enable/Disable EEE after link up */ ret_val = e1000_set_eee_pchlan(hw); if (ret_val) - goto out; + return ret_val; /* * If we are forcing speed/duplex, then we simply return since * we have already determined whether we have link or not. */ - if (!mac->autoneg) { - ret_val = -E1000_ERR_CONFIG; - goto out; - } + if (!mac->autoneg) + return -E1000_ERR_CONFIG; /* * Auto-Neg is enabled. Auto Speed Detection takes care * of MAC speed/duplex configuration. So we only need to * configure Collision Distance in the MAC. */ - e1000e_config_collision_dist(hw); + mac->ops.config_collision_dist(hw); /* * Configure Flow Control now that Auto-Neg has completed. @@ -764,7 +758,6 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) if (ret_val) e_dbg("Error configuring flow control\n"); -out: return ret_val; } @@ -773,7 +766,7 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter) struct e1000_hw *hw = &adapter->hw; s32 rc; - rc = e1000_init_mac_params_ich8lan(adapter); + rc = e1000_init_mac_params_ich8lan(hw); if (rc) return rc; @@ -900,8 +893,7 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) } if (!timeout) { - e_dbg("Failed to acquire the semaphore, FW or HW has it: " - "FWSM=0x%8.8x EXTCNF_CTRL=0x%8.8x)\n", + e_dbg("Failed to acquire the semaphore, FW or HW has it: FWSM=0x%8.8x EXTCNF_CTRL=0x%8.8x)\n", er32(FWSM), extcnf_ctrl); extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; ew32(EXTCNF_CTRL, extcnf_ctrl); @@ -1008,15 +1000,13 @@ static s32 e1000_write_smbus_addr(struct e1000_hw *hw) ret_val = e1000_read_phy_reg_hv_locked(hw, HV_SMB_ADDR, &phy_data); if (ret_val) - goto out; + return ret_val; phy_data &= ~HV_SMB_ADDR_MASK; phy_data |= (strap >> E1000_STRAP_SMBUS_ADDRESS_SHIFT); phy_data |= HV_SMB_ADDR_PEC_EN | HV_SMB_ADDR_VALID; - ret_val = e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR, phy_data); -out: - return ret_val; + return e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR, phy_data); } /** @@ -1065,7 +1055,7 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) data = er32(FEXTNVM); if (!(data & sw_cfg_mask)) - goto out; + goto release; /* * Make sure HW does not configure LCD from PHY @@ -1074,14 +1064,14 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) data = er32(EXTCNF_CTRL); if (!(hw->mac.type == e1000_pch2lan)) { if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE) - goto out; + goto release; } cnf_size = er32(EXTCNF_SIZE); cnf_size &= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK; cnf_size >>= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT; if (!cnf_size) - goto out; + goto release; cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK; cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT; @@ -1097,13 +1087,13 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) */ ret_val = e1000_write_smbus_addr(hw); if (ret_val) - goto out; + goto release; data = er32(LEDCTL); ret_val = e1000_write_phy_reg_hv_locked(hw, HV_LED_CONFIG, (u16)data); if (ret_val) - goto out; + goto release; } /* Configure LCD from extended configuration region. */ @@ -1115,12 +1105,12 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) ret_val = e1000_read_nvm(hw, (word_addr + i * 2), 1, ®_data); if (ret_val) - goto out; + goto release; ret_val = e1000_read_nvm(hw, (word_addr + i * 2 + 1), 1, ®_addr); if (ret_val) - goto out; + goto release; /* Save off the PHY page for future writes. */ if (reg_addr == IGP01E1000_PHY_PAGE_SELECT) { @@ -1134,10 +1124,10 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) ret_val = phy->ops.write_reg_locked(hw, (u32)reg_addr, reg_data); if (ret_val) - goto out; + goto release; } -out: +release: hw->phy.ops.release(hw); return ret_val; } @@ -1159,12 +1149,12 @@ static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link) bool k1_enable = hw->dev_spec.ich8lan.nvm_k1_enabled; if (hw->mac.type != e1000_pchlan) - goto out; + return 0; /* Wrap the whole flow with the sw flag */ ret_val = hw->phy.ops.acquire(hw); if (ret_val) - goto out; + return ret_val; /* Disable K1 when link is 1Gbps, otherwise use the NVM setting */ if (link) { @@ -1218,7 +1208,7 @@ static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link) release: hw->phy.ops.release(hw); -out: + return ret_val; } @@ -1240,22 +1230,20 @@ s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable) u32 reg = 0; u16 kmrn_reg = 0; - ret_val = e1000e_read_kmrn_reg_locked(hw, - E1000_KMRNCTRLSTA_K1_CONFIG, - &kmrn_reg); + ret_val = e1000e_read_kmrn_reg_locked(hw, E1000_KMRNCTRLSTA_K1_CONFIG, + &kmrn_reg); if (ret_val) - goto out; + return ret_val; if (k1_enable) kmrn_reg |= E1000_KMRNCTRLSTA_K1_ENABLE; else kmrn_reg &= ~E1000_KMRNCTRLSTA_K1_ENABLE; - ret_val = e1000e_write_kmrn_reg_locked(hw, - E1000_KMRNCTRLSTA_K1_CONFIG, - kmrn_reg); + ret_val = e1000e_write_kmrn_reg_locked(hw, E1000_KMRNCTRLSTA_K1_CONFIG, + kmrn_reg); if (ret_val) - goto out; + return ret_val; udelay(20); ctrl_ext = er32(CTRL_EXT); @@ -1273,8 +1261,7 @@ s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable) e1e_flush(); udelay(20); -out: - return ret_val; + return 0; } /** @@ -1302,18 +1289,18 @@ static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state) if (!(hw->mac.type == e1000_pch2lan)) { mac_reg = er32(EXTCNF_CTRL); if (mac_reg & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) - goto out; + goto release; } mac_reg = er32(FEXTNVM); if (!(mac_reg & E1000_FEXTNVM_SW_CONFIG_ICH8M)) - goto out; + goto release; mac_reg = er32(PHY_CTRL); ret_val = hw->phy.ops.read_reg_locked(hw, HV_OEM_BITS, &oem_reg); if (ret_val) - goto out; + goto release; oem_reg &= ~(HV_OEM_BITS_GBE_DIS | HV_OEM_BITS_LPLU); @@ -1325,7 +1312,7 @@ static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state) oem_reg |= HV_OEM_BITS_LPLU; /* Set Restart auto-neg to activate the bits */ - if (!e1000_check_reset_block(hw)) + if (!hw->phy.ops.check_reset_block(hw)) oem_reg |= HV_OEM_BITS_RESTART_AN; } else { if (mac_reg & (E1000_PHY_CTRL_GBE_DISABLE | @@ -1339,7 +1326,7 @@ static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state) ret_val = hw->phy.ops.write_reg_locked(hw, HV_OEM_BITS, oem_reg); -out: +release: hw->phy.ops.release(hw); return ret_val; @@ -1376,13 +1363,13 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) u16 phy_data; if (hw->mac.type != e1000_pchlan) - return ret_val; + return 0; /* Set MDIO slow mode before any other MDIO access */ if (hw->phy.type == e1000_phy_82577) { ret_val = e1000_set_mdio_slow_mode_hv(hw); if (ret_val) - goto out; + return ret_val; } if (((hw->phy.type == e1000_phy_82577) && @@ -1419,7 +1406,7 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0); hw->phy.ops.release(hw); if (ret_val) - goto out; + return ret_val; /* * Configure the K1 Si workaround during phy reset assuming there is @@ -1427,12 +1414,12 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) */ ret_val = e1000_k1_gig_workaround_hv(hw, true); if (ret_val) - goto out; + return ret_val; /* Workaround for link disconnects on a busy hub in half duplex */ ret_val = hw->phy.ops.acquire(hw); if (ret_val) - goto out; + return ret_val; ret_val = hw->phy.ops.read_reg_locked(hw, BM_PORT_GEN_CFG, &phy_data); if (ret_val) goto release; @@ -1440,7 +1427,7 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) phy_data & 0x00FF); release: hw->phy.ops.release(hw); -out: + return ret_val; } @@ -1497,13 +1484,13 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable) u16 i; if (hw->mac.type != e1000_pch2lan) - goto out; + return 0; /* disable Rx path while enabling/disabling workaround */ e1e_rphy(hw, PHY_REG(769, 20), &phy_reg); ret_val = e1e_wphy(hw, PHY_REG(769, 20), phy_reg | (1 << 14)); if (ret_val) - goto out; + return ret_val; if (enable) { /* @@ -1545,24 +1532,24 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable) E1000_KMRNCTRLSTA_CTRL_OFFSET, &data); if (ret_val) - goto out; + return ret_val; ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_CTRL_OFFSET, data | (1 << 0)); if (ret_val) - goto out; + return ret_val; ret_val = e1000e_read_kmrn_reg(hw, E1000_KMRNCTRLSTA_HD_CTRL, &data); if (ret_val) - goto out; + return ret_val; data &= ~(0xF << 8); data |= (0xB << 8); ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_HD_CTRL, data); if (ret_val) - goto out; + return ret_val; /* Enable jumbo frame workaround in the PHY */ e1e_rphy(hw, PHY_REG(769, 23), &data); @@ -1570,25 +1557,25 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable) data |= (0x37 << 5); ret_val = e1e_wphy(hw, PHY_REG(769, 23), data); if (ret_val) - goto out; + return ret_val; e1e_rphy(hw, PHY_REG(769, 16), &data); data &= ~(1 << 13); ret_val = e1e_wphy(hw, PHY_REG(769, 16), data); if (ret_val) - goto out; + return ret_val; e1e_rphy(hw, PHY_REG(776, 20), &data); data &= ~(0x3FF << 2); data |= (0x1A << 2); ret_val = e1e_wphy(hw, PHY_REG(776, 20), data); if (ret_val) - goto out; + return ret_val; ret_val = e1e_wphy(hw, PHY_REG(776, 23), 0xF100); if (ret_val) - goto out; + return ret_val; e1e_rphy(hw, HV_PM_CTRL, &data); ret_val = e1e_wphy(hw, HV_PM_CTRL, data | (1 << 10)); if (ret_val) - goto out; + return ret_val; } else { /* Write MAC register values back to h/w defaults */ mac_reg = er32(FFLT_DBG); @@ -1603,56 +1590,53 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable) E1000_KMRNCTRLSTA_CTRL_OFFSET, &data); if (ret_val) - goto out; + return ret_val; ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_CTRL_OFFSET, data & ~(1 << 0)); if (ret_val) - goto out; + return ret_val; ret_val = e1000e_read_kmrn_reg(hw, E1000_KMRNCTRLSTA_HD_CTRL, &data); if (ret_val) - goto out; + return ret_val; data &= ~(0xF << 8); data |= (0xB << 8); ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_HD_CTRL, data); if (ret_val) - goto out; + return ret_val; /* Write PHY register values back to h/w defaults */ e1e_rphy(hw, PHY_REG(769, 23), &data); data &= ~(0x7F << 5); ret_val = e1e_wphy(hw, PHY_REG(769, 23), data); if (ret_val) - goto out; + return ret_val; e1e_rphy(hw, PHY_REG(769, 16), &data); data |= (1 << 13); ret_val = e1e_wphy(hw, PHY_REG(769, 16), data); if (ret_val) - goto out; + return ret_val; e1e_rphy(hw, PHY_REG(776, 20), &data); data &= ~(0x3FF << 2); data |= (0x8 << 2); ret_val = e1e_wphy(hw, PHY_REG(776, 20), data); if (ret_val) - goto out; + return ret_val; ret_val = e1e_wphy(hw, PHY_REG(776, 23), 0x7E00); if (ret_val) - goto out; + return ret_val; e1e_rphy(hw, HV_PM_CTRL, &data); ret_val = e1e_wphy(hw, HV_PM_CTRL, data & ~(1 << 10)); if (ret_val) - goto out; + return ret_val; } /* re-enable Rx path after enabling/disabling workaround */ - ret_val = e1e_wphy(hw, PHY_REG(769, 20), phy_reg & ~(1 << 14)); - -out: - return ret_val; + return e1e_wphy(hw, PHY_REG(769, 20), phy_reg & ~(1 << 14)); } /** @@ -1664,12 +1648,31 @@ static s32 e1000_lv_phy_workarounds_ich8lan(struct e1000_hw *hw) s32 ret_val = 0; if (hw->mac.type != e1000_pch2lan) - goto out; + return 0; /* Set MDIO slow mode before any other MDIO access */ ret_val = e1000_set_mdio_slow_mode_hv(hw); -out: + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + return ret_val; + ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_ADDR, + I82579_MSE_THRESHOLD); + if (ret_val) + goto release; + /* set MSE higher to enable link to stay up when noise is high */ + ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_DATA, 0x0034); + if (ret_val) + goto release; + ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_ADDR, + I82579_MSE_LINK_DOWN); + if (ret_val) + goto release; + /* drop link after 5 times MSE threshold was reached */ + ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_DATA, 0x0005); +release: + hw->phy.ops.release(hw); + return ret_val; } @@ -1687,12 +1690,12 @@ static s32 e1000_k1_workaround_lv(struct e1000_hw *hw) u16 phy_reg; if (hw->mac.type != e1000_pch2lan) - goto out; + return 0; /* Set K1 beacon duration based on 1Gbps speed or otherwise */ ret_val = e1e_rphy(hw, HV_M_STATUS, &status_reg); if (ret_val) - goto out; + return ret_val; if ((status_reg & (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE)) == (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE)) { @@ -1701,7 +1704,7 @@ static s32 e1000_k1_workaround_lv(struct e1000_hw *hw) ret_val = e1e_rphy(hw, I82579_LPI_CTRL, &phy_reg); if (ret_val) - goto out; + return ret_val; if (status_reg & HV_M_STATUS_SPEED_1000) { mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_8USEC; @@ -1714,7 +1717,6 @@ static s32 e1000_k1_workaround_lv(struct e1000_hw *hw) ret_val = e1e_wphy(hw, I82579_LPI_CTRL, phy_reg); } -out: return ret_val; } @@ -1741,7 +1743,6 @@ static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate) extcnf_ctrl &= ~E1000_EXTCNF_CTRL_GATE_PHY_CFG; ew32(EXTCNF_CTRL, extcnf_ctrl); - return; } /** @@ -1785,8 +1786,8 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw) s32 ret_val = 0; u16 reg; - if (e1000_check_reset_block(hw)) - goto out; + if (hw->phy.ops.check_reset_block(hw)) + return 0; /* Allow time for h/w to get to quiescent state after reset */ usleep_range(10000, 20000); @@ -1796,12 +1797,12 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw) case e1000_pchlan: ret_val = e1000_hv_phy_workarounds_ich8lan(hw); if (ret_val) - goto out; + return ret_val; break; case e1000_pch2lan: ret_val = e1000_lv_phy_workarounds_ich8lan(hw); if (ret_val) - goto out; + return ret_val; break; default: break; @@ -1817,7 +1818,7 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw) /* Configure the LCD with the extended configuration region in NVM */ ret_val = e1000_sw_lcd_config_ich8lan(hw); if (ret_val) - goto out; + return ret_val; /* Configure the LCD with the OEM bits in NVM */ ret_val = e1000_oem_bits_config_ich8lan(hw, true); @@ -1832,18 +1833,16 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw) /* Set EEE LPI Update Timer to 200usec */ ret_val = hw->phy.ops.acquire(hw); if (ret_val) - goto out; + return ret_val; ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_ADDR, I82579_LPI_UPDATE_TIMER); - if (ret_val) - goto release; - ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_DATA, - 0x1387); -release: + if (!ret_val) + ret_val = hw->phy.ops.write_reg_locked(hw, + I82579_EMI_DATA, + 0x1387); hw->phy.ops.release(hw); } -out: return ret_val; } @@ -1866,12 +1865,9 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) ret_val = e1000e_phy_hw_reset_generic(hw); if (ret_val) - goto out; - - ret_val = e1000_post_phy_reset_ich8lan(hw); + return ret_val; -out: - return ret_val; + return e1000_post_phy_reset_ich8lan(hw); } /** @@ -1892,18 +1888,17 @@ static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active) ret_val = e1e_rphy(hw, HV_OEM_BITS, &oem_reg); if (ret_val) - goto out; + return ret_val; if (active) oem_reg |= HV_OEM_BITS_LPLU; else oem_reg &= ~HV_OEM_BITS_LPLU; - oem_reg |= HV_OEM_BITS_RESTART_AN; - ret_val = e1e_wphy(hw, HV_OEM_BITS, oem_reg); + if (!hw->phy.ops.check_reset_block(hw)) + oem_reg |= HV_OEM_BITS_RESTART_AN; -out: - return ret_val; + return e1e_wphy(hw, HV_OEM_BITS, oem_reg); } /** @@ -1927,7 +1922,7 @@ static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, bool active) u16 data; if (phy->type == e1000_phy_ife) - return ret_val; + return 0; phy_ctrl = er32(PHY_CTRL); @@ -2009,7 +2004,7 @@ static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, bool active) { struct e1000_phy_info *phy = &hw->phy; u32 phy_ctrl; - s32 ret_val; + s32 ret_val = 0; u16 data; phy_ctrl = er32(PHY_CTRL); @@ -2075,7 +2070,7 @@ static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, bool active) ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG, data); } - return 0; + return ret_val; } /** @@ -2093,7 +2088,7 @@ static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank) u32 bank1_offset = nvm->flash_bank_size * sizeof(u16); u32 act_offset = E1000_ICH_NVM_SIG_WORD * 2 + 1; u8 sig_byte = 0; - s32 ret_val = 0; + s32 ret_val; switch (hw->mac.type) { case e1000_ich8lan: @@ -2108,8 +2103,7 @@ static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank) return 0; } - e_dbg("Unable to determine valid NVM bank via EEC - " - "reading flash signature\n"); + e_dbg("Unable to determine valid NVM bank via EEC - reading flash signature\n"); /* fall-thru */ default: /* set bank to 0 in case flash read fails */ @@ -2141,8 +2135,6 @@ static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank) e_dbg("ERROR: No valid NVM bank present\n"); return -E1000_ERR_NVM; } - - return 0; } /** @@ -2221,8 +2213,7 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw) /* Check if the flash descriptor is valid */ if (hsfsts.hsf_status.fldesvalid == 0) { - e_dbg("Flash descriptor invalid. " - "SW Sequencing must be used.\n"); + e_dbg("Flash descriptor invalid. SW Sequencing must be used.\n"); return -E1000_ERR_NVM; } @@ -2251,21 +2242,21 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw) ew16flash(ICH_FLASH_HSFSTS, hsfsts.regval); ret_val = 0; } else { - s32 i = 0; + s32 i; /* * Otherwise poll for sometime so the current * cycle has a chance to end before giving up. */ for (i = 0; i < ICH_FLASH_READ_COMMAND_TIMEOUT; i++) { - hsfsts.regval = __er16flash(hw, ICH_FLASH_HSFSTS); + hsfsts.regval = er16flash(ICH_FLASH_HSFSTS); if (hsfsts.hsf_status.flcinprog == 0) { ret_val = 0; break; } udelay(1); } - if (ret_val == 0) { + if (!ret_val) { /* * Successful in waiting for previous cycle to timeout, * now set the Flash Cycle Done. @@ -2291,7 +2282,6 @@ static s32 e1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout) { union ich8_hws_flash_ctrl hsflctl; union ich8_hws_flash_status hsfsts; - s32 ret_val = -E1000_ERR_NVM; u32 i = 0; /* Start a cycle by writing 1 in Flash Cycle Go in Hw Flash Control */ @@ -2310,7 +2300,7 @@ static s32 e1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout) if (hsfsts.hsf_status.flcdone == 1 && hsfsts.hsf_status.flcerr == 0) return 0; - return ret_val; + return -E1000_ERR_NVM; } /** @@ -2383,7 +2373,7 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, udelay(1); /* Steps */ ret_val = e1000_flash_cycle_init_ich8lan(hw); - if (ret_val != 0) + if (ret_val) break; hsflctl.regval = er16flash(ICH_FLASH_HSFCTL); @@ -2403,7 +2393,7 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, * read in (shift in) the Flash Data0, the order is * least significant byte first msb to lsb */ - if (ret_val == 0) { + if (!ret_val) { flash_data = er32flash(ICH_FLASH_FDATA0); if (size == 1) *data = (u8)(flash_data & 0x000000FF); @@ -2422,8 +2412,7 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, /* Repeat for some time before giving up. */ continue; } else if (hsfsts.hsf_status.flcdone == 0) { - e_dbg("Timeout error - flash cycle " - "did not complete.\n"); + e_dbg("Timeout error - flash cycle did not complete.\n"); break; } } @@ -2618,7 +2607,7 @@ release: * until after the next adapter reset. */ if (!ret_val) { - e1000e_reload_nvm(hw); + nvm->ops.reload(hw); usleep_range(10000, 20000); } @@ -2774,8 +2763,7 @@ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, /* Repeat for some time before giving up. */ continue; if (hsfsts.hsf_status.flcdone == 0) { - e_dbg("Timeout error - flash cycle " - "did not complete."); + e_dbg("Timeout error - flash cycle did not complete.\n"); break; } } while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT); @@ -2917,7 +2905,7 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank) ret_val = e1000_flash_cycle_ich8lan(hw, ICH_FLASH_ERASE_COMMAND_TIMEOUT); - if (ret_val == 0) + if (!ret_val) break; /* @@ -2972,7 +2960,7 @@ static s32 e1000_valid_led_default_ich8lan(struct e1000_hw *hw, u16 *data) * * PCH also does not have an "always on" or "always off" mode which * complicates the ID feature. Instead of using the "on" mode to indicate - * in ledctl_mode2 the LEDs to use for ID (see e1000e_id_led_init()), + * in ledctl_mode2 the LEDs to use for ID (see e1000e_id_led_init_generic()), * use "link_up" mode. The LEDs will still ID on request if there is no * link based on logic in e1000_led_[on|off]_pchlan(). **/ @@ -2987,7 +2975,7 @@ static s32 e1000_id_led_init_pchlan(struct e1000_hw *hw) /* Get default ID LED modes */ ret_val = hw->nvm.ops.valid_led_default(hw, &data); if (ret_val) - goto out; + return ret_val; mac->ledctl_default = er32(LEDCTL); mac->ledctl_mode1 = mac->ledctl_default; @@ -3032,8 +3020,7 @@ static s32 e1000_id_led_init_pchlan(struct e1000_hw *hw) } } -out: - return ret_val; + return 0; } /** @@ -3120,7 +3107,7 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) ctrl = er32(CTRL); - if (!e1000_check_reset_block(hw)) { + if (!hw->phy.ops.check_reset_block(hw)) { /* * Full-chip reset requires MAC and PHY reset at the same * time to make sure the interface between MAC and the @@ -3148,11 +3135,11 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) if (ctrl & E1000_CTRL_PHY_RST) { ret_val = hw->phy.ops.get_cfg_done(hw); if (ret_val) - goto out; + return ret_val; ret_val = e1000_post_phy_reset_ich8lan(hw); if (ret_val) - goto out; + return ret_val; } /* @@ -3170,8 +3157,7 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) kab |= E1000_KABGTXD_BGSQLBIAS; ew32(KABGTXD, kab); -out: - return ret_val; + return 0; } /** @@ -3224,7 +3210,7 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw) } /* Setup link and flow control */ - ret_val = e1000_setup_link_ich8lan(hw); + ret_val = mac->ops.setup_link(hw); /* Set the transmit descriptor write-back policy for both queues */ txdctl = er32(TXDCTL(0)); @@ -3262,7 +3248,7 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw) */ e1000_clear_hw_cntrs_ich8lan(hw); - return 0; + return ret_val; } /** * e1000_initialize_hw_bits_ich8lan - Initialize required hardware bits @@ -3339,7 +3325,7 @@ static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw) { s32 ret_val; - if (e1000_check_reset_block(hw)) + if (hw->phy.ops.check_reset_block(hw)) return 0; /* @@ -3365,7 +3351,7 @@ static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw) hw->fc.current_mode); /* Continue to configure the copper link. */ - ret_val = e1000_setup_copper_link_ich8lan(hw); + ret_val = hw->mac.ops.setup_physical_interface(hw); if (ret_val) return ret_val; @@ -3465,6 +3451,7 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw) default: break; } + return e1000e_setup_copper_link(hw); } @@ -3566,7 +3553,7 @@ static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw) } /** - * e1000_set_kmrn_lock_loss_workaround_ich8lan - Set Kumeran workaround state + * e1000e_set_kmrn_lock_loss_workaround_ich8lan - Set Kumeran workaround state * @hw: pointer to the HW structure * @state: boolean value used to set the current Kumeran workaround state * @@ -3676,9 +3663,10 @@ void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw) * * During S0 to Sx transition, it is possible the link remains at gig * instead of negotiating to a lower speed. Before going to Sx, set - * 'LPLU Enabled' and 'Gig Disable' to force link speed negotiation - * to a lower speed. For PCH and newer parts, the OEM bits PHY register - * (LED, GbE disable and LPLU configurations) also needs to be written. + * 'Gig Disable' to force link speed negotiation to a lower speed based on + * the LPLU setting in the NVM or custom setting. For PCH and newer parts, + * the OEM bits PHY register (LED, GbE disable and LPLU configurations) also + * needs to be written. **/ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw) { @@ -3686,7 +3674,7 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw) s32 ret_val; phy_ctrl = er32(PHY_CTRL); - phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU | E1000_PHY_CTRL_GBE_DISABLE; + phy_ctrl |= E1000_PHY_CTRL_GBE_DISABLE; ew32(PHY_CTRL, phy_ctrl); if (hw->mac.type == e1000_ich8lan) @@ -3714,47 +3702,41 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw) **/ void e1000_resume_workarounds_pchlan(struct e1000_hw *hw) { - u32 fwsm; + u16 phy_id1, phy_id2; + s32 ret_val; - if (hw->mac.type != e1000_pch2lan) + if ((hw->mac.type != e1000_pch2lan) || + hw->phy.ops.check_reset_block(hw)) return; - fwsm = er32(FWSM); - if (!(fwsm & E1000_ICH_FWSM_FW_VALID) || !e1000_check_reset_block(hw)) { - u16 phy_id1, phy_id2; - s32 ret_val; - - ret_val = hw->phy.ops.acquire(hw); - if (ret_val) { - e_dbg("Failed to acquire PHY semaphore in resume\n"); - return; - } + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) { + e_dbg("Failed to acquire PHY semaphore in resume\n"); + return; + } - /* Test access to the PHY registers by reading the ID regs */ - ret_val = hw->phy.ops.read_reg_locked(hw, PHY_ID1, &phy_id1); - if (ret_val) - goto release; - ret_val = hw->phy.ops.read_reg_locked(hw, PHY_ID2, &phy_id2); - if (ret_val) - goto release; + /* Test access to the PHY registers by reading the ID regs */ + ret_val = hw->phy.ops.read_reg_locked(hw, PHY_ID1, &phy_id1); + if (ret_val) + goto release; + ret_val = hw->phy.ops.read_reg_locked(hw, PHY_ID2, &phy_id2); + if (ret_val) + goto release; - if (hw->phy.id == ((u32)(phy_id1 << 16) | - (u32)(phy_id2 & PHY_REVISION_MASK))) - goto release; + if (hw->phy.id == ((u32)(phy_id1 << 16) | + (u32)(phy_id2 & PHY_REVISION_MASK))) + goto release; - e1000_toggle_lanphypc_value_ich8lan(hw); + e1000_toggle_lanphypc_value_ich8lan(hw); - hw->phy.ops.release(hw); - msleep(50); - e1000_phy_hw_reset(hw); - msleep(50); - return; - } + hw->phy.ops.release(hw); + msleep(50); + e1000_phy_hw_reset(hw); + msleep(50); + return; release: hw->phy.ops.release(hw); - - return; } /** @@ -4023,7 +4005,6 @@ release: } static const struct e1000_mac_operations ich8_mac_ops = { - .id_led_init = e1000e_id_led_init, /* check_mng_mode dependent on mac type */ .check_for_link = e1000_check_for_copper_link_ich8lan, /* cleanup_led dependent on mac type */ @@ -4039,6 +4020,7 @@ static const struct e1000_mac_operations ich8_mac_ops = { .setup_link = e1000_setup_link_ich8lan, .setup_physical_interface= e1000_setup_copper_link_ich8lan, /* id_led_init dependent on mac type */ + .config_collision_dist = e1000e_config_collision_dist_generic, }; static const struct e1000_phy_operations ich8_phy_ops = { @@ -4059,6 +4041,7 @@ static const struct e1000_nvm_operations ich8_nvm_ops = { .acquire = e1000_acquire_nvm_ich8lan, .read = e1000_read_nvm_ich8lan, .release = e1000_release_nvm_ich8lan, + .reload = e1000e_reload_nvm_generic, .update = e1000_update_nvm_checksum_ich8lan, .valid_led_default = e1000_valid_led_default_ich8lan, .validate = e1000_validate_nvm_checksum_ich8lan, @@ -4088,10 +4071,9 @@ const struct e1000_info e1000_ich9_info = { | FLAG_HAS_WOL | FLAG_HAS_CTRLEXT_ON_LOAD | FLAG_HAS_AMT - | FLAG_HAS_ERT | FLAG_HAS_FLASH | FLAG_APME_IN_WUC, - .pba = 10, + .pba = 18, .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_ich8lan, .mac_ops = &ich8_mac_ops, @@ -4106,10 +4088,9 @@ const struct e1000_info e1000_ich10_info = { | FLAG_HAS_WOL | FLAG_HAS_CTRLEXT_ON_LOAD | FLAG_HAS_AMT - | FLAG_HAS_ERT | FLAG_HAS_FLASH | FLAG_APME_IN_WUC, - .pba = 10, + .pba = 18, .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_ich8lan, .mac_ops = &ich8_mac_ops, |