/* In case the PHY needs to be in mdio slow mode, *setslowmodeandtrytogetthePHYidagain.
*/ if (hw->mac.type < e1000_pch_lpt) {
hw->phy.ops.release(hw);
ret_val = e1000_set_mdio_slow_mode_hv(hw); if (!ret_val)
ret_val = e1000e_get_phy_id(hw);
hw->phy.ops.acquire(hw);
}
if (ret_val) returnfalse;
out: if (hw->mac.type >= e1000_pch_lpt) { /* Only unforce SMBus if ME is not active */ if (!(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) { /* Switching PHY interface always returns MDI error *sodisableretrymechanismtoavoidwastingtime
*/
e1000e_disable_phy_retry(hw);
/* Change Kumeran K1 power down state from P0s to P1 */
fextnvm12 = er32(FEXTNVM12);
fextnvm12 &= ~E1000_FEXTNVM12_PHYPD_CTRL_MASK;
fextnvm12 |= E1000_FEXTNVM12_PHYPD_CTRL_P1;
ew32(FEXTNVM12, fextnvm12);
/* Wait for the interface the settle */
usleep_range(1000, 1100);
/* Gate automatic PHY configuration by hardware on managed and *non-managed82579andneweradapters.
*/
e1000_gate_hw_phy_config_ich8lan(hw, true);
/* It is not possible to be certain of the current state of ULP *soforciblydisableit.
*/
hw->dev_spec.ich8lan.ulp_state = e1000_ulp_state_unknown;
ret_val = e1000_disable_ulp_lpt_lp(hw, true); if (ret_val)
e_warn("Failed to disable ULP\n");
ret_val = hw->phy.ops.acquire(hw); if (ret_val) {
e_dbg("Failed to initialize PHY flow\n"); goto out;
}
/* There is no guarantee that the PHY is accessible at this time *sodisableretrymechanismtoavoidwastingtime
*/
e1000e_disable_phy_retry(hw);
/* The MAC-PHY interconnect may be in SMBus mode. If the PHY is *inaccessibleandresettingthePHYisnotblocked,togglethe *LANPHYPCValuebittoforcetheinterconnecttoPCIemode.
*/ switch (hw->mac.type) { case e1000_pch_mtp: case e1000_pch_lnp: case e1000_pch_ptp: case e1000_pch_nvp: /* At this point the PHY might be inaccessible so don't *propagatethefailure
*/ if (e1000_reconfigure_k1_exit_timeout(hw))
e_dbg("Failed to reconfigure K1 exit timeout\n");
fallthrough; case e1000_pch_lpt: case e1000_pch_spt: case e1000_pch_cnp: case e1000_pch_tgp: case e1000_pch_adp: if (e1000_phy_is_accessible_pchlan(hw)) break;
/* Before toggling LANPHYPC, see if PHY is accessible by *forcingMACtoSMBusmodefirst.
*/
mac_reg = er32(CTRL_EXT);
mac_reg |= E1000_CTRL_EXT_FORCE_SMBUS;
ew32(CTRL_EXT, mac_reg);
/* Wait 50 milliseconds for MAC to finish any retries *thatitmightbetryingtoperformfromprevious *attemptstoacknowledgeanyphyreadrequests.
*/
msleep(50);
fallthrough; case e1000_pch2lan: if (e1000_phy_is_accessible_pchlan(hw)) break;
fallthrough; case e1000_pchlan: if ((hw->mac.type == e1000_pchlan) &&
(fwsm & E1000_ICH_FWSM_FW_VALID)) break;
if (hw->phy.ops.check_reset_block(hw)) {
e_dbg("Required LANPHYPC toggle blocked by ME\n");
ret_val = -E1000_ERR_PHY; break;
}
/* Toggle LANPHYPC Value bit */
e1000_toggle_lanphypc_pch_lpt(hw); if (hw->mac.type >= e1000_pch_lpt) { if (e1000_phy_is_accessible_pchlan(hw)) break;
/* Toggling LANPHYPC brings the PHY out of SMBus mode *soensurethattheMACisalsooutofSMBusmode
*/
mac_reg = er32(CTRL_EXT);
mac_reg &= ~E1000_CTRL_EXT_FORCE_SMBUS;
ew32(CTRL_EXT, mac_reg);
/* Check to see if able to reset PHY. Print error if not */ if (hw->phy.ops.check_reset_block(hw)) {
e_err("Reset blocked by ME\n"); goto out;
}
/* Reset the PHY before any access to it. Doing so, ensures *thatthePHYisinaknowngoodstatebeforeweread/write *PHYregisters.Thegenericresetissufficienthere, *becausewehaven'tdeterminedthePHYtypeyet.
*/
ret_val = e1000e_phy_hw_reset_generic(hw); if (ret_val) goto out;
/* On a successful reset, possibly need to wait for the PHY *toquiescetoanaccessiblestatebeforereturningcontrol *tothecallingfunction.IfthePHYdoesnotquiesce,then *returnE1000E_BLK_PHY_RESET,asthisistheconditionthat *thePHYisin.
*/
ret_val = hw->phy.ops.check_reset_block(hw); if (ret_val) {
e_err("ME blocked access to PHY after reset\n"); goto out;
}
if (hw->mac.type >= e1000_pch_mtp) {
ret_val = hw->phy.ops.acquire(hw); if (ret_val) {
e_err("Failed to reconfigure K1 exit timeout\n"); goto out;
}
ret_val = e1000_reconfigure_k1_exit_timeout(hw);
hw->phy.ops.release(hw);
}
}
if (hw->mac.type == e1000_pch_mtp) {
phy->retry_count = 2;
e1000e_enable_phy_retry(hw);
}
ret_val = e1000_init_phy_workarounds_pchlan(hw); if (ret_val) return ret_val;
if (phy->id == e1000_phy_unknown) switch (hw->mac.type) { default:
ret_val = e1000e_get_phy_id(hw); if (ret_val) return ret_val; if ((phy->id != 0) && (phy->id != PHY_REVISION_MASK)) break;
fallthrough; case e1000_pch2lan: case e1000_pch_lpt: case e1000_pch_spt: case e1000_pch_cnp: case e1000_pch_tgp: case e1000_pch_adp: case e1000_pch_mtp: case e1000_pch_lnp: case e1000_pch_ptp: case e1000_pch_nvp: /* In case the PHY needs to be in mdio slow mode, *setslowmodeandtrytogetthePHYidagain.
*/
ret_val = e1000_set_mdio_slow_mode_hv(hw); if (ret_val) return ret_val;
ret_val = e1000e_get_phy_id(hw); if (ret_val) return ret_val; break;
}
phy->type = e1000e_get_phy_type_from_id(phy->id);
/* We may need to do this twice - once for IGP and if that fails, *we'llsetBMfuncpointersandtryagain
*/
ret_val = e1000e_determine_phy_address(hw); if (ret_val) {
phy->ops.write_reg = e1000e_write_phy_reg_bm;
phy->ops.read_reg = e1000e_read_phy_reg_bm;
ret_val = e1000e_determine_phy_address(hw); if (ret_val) {
e_dbg("Cannot determine PHY addr. Erroring out\n"); return ret_val;
}
}
/* flash_base_addr is byte-aligned */
nvm->flash_base_addr = sector_base_addr
<< FLASH_SECTOR_ADDR_SHIFT;
/* find total size of the NVM, then cut in half since the total *sizerepresentstwoseparateNVMbanks.
*/
nvm->flash_bank_size = ((sector_end_addr - sector_base_addr)
<< FLASH_SECTOR_ADDR_SHIFT);
nvm->flash_bank_size /= 2; /* Adjust to word count */
nvm->flash_bank_size /= sizeof(u16);
}
nvm->word_size = E1000_ICH8_SHADOW_RAM_WORDS;
/* Clear shadow ram */ for (i = 0; i < nvm->word_size; i++) {
dev_spec->shadow_ram[i].modified = false;
dev_spec->shadow_ram[i].value = 0xFFFF;
}
/* Set media type function pointer */
hw->phy.media_type = e1000_media_type_copper;
/* Set mta register count */
mac->mta_reg_count = 32; /* Set rar entry count */
mac->rar_entry_count = E1000_ICH_RAR_ENTRIES; if (mac->type == e1000_ich8lan)
mac->rar_entry_count--; /* FWSM register */
mac->has_fwsm = true; /* ARC subsystem not supported */
mac->arc_subsystem_valid = false; /* Adaptive IFS supported */
mac->adaptive_ifs = true;
/* LED and other operations */ switch (mac->type) { case e1000_ich8lan: case e1000_ich9lan: case e1000_ich10lan: /* 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_generic; /* blink LED */
mac->ops.blink_led = e1000e_blink_led_generic; /* setup LED */
mac->ops.setup_led = e1000e_setup_led_generic; /* cleanup LED */
mac->ops.cleanup_led = e1000_cleanup_led_ich8lan; /* turn on/off LED */
mac->ops.led_on = e1000_led_on_ich8lan;
mac->ops.led_off = e1000_led_off_ich8lan; break; case e1000_pch2lan:
mac->rar_entry_count = E1000_PCH2_RAR_ENTRIES;
mac->ops.rar_set = e1000_rar_set_pch2lan;
fallthrough; case e1000_pch_lpt: case e1000_pch_spt: case e1000_pch_cnp: case e1000_pch_tgp: case e1000_pch_adp: case e1000_pch_mtp: case e1000_pch_lnp: case e1000_pch_ptp: case e1000_pch_nvp: case e1000_pchlan: /* check management mode */
mac->ops.check_mng_mode = e1000_check_mng_mode_pchlan; /* ID LED init */
mac->ops.id_led_init = e1000_id_led_init_pchlan; /* setup LED */
mac->ops.setup_led = e1000_setup_led_pchlan; /* cleanup LED */
mac->ops.cleanup_led = e1000_cleanup_led_pchlan; /* turn on/off LED */
mac->ops.led_on = e1000_led_on_pchlan;
mac->ops.led_off = e1000_led_off_pchlan; break; default: break;
}
ret_val = hw->phy.ops.acquire(hw); if (ret_val) return ret_val;
ret_val = e1e_rphy_locked(hw, I82579_LPI_CTRL, &lpi_ctrl); if (ret_val) goto release;
/* Clear bits that enable EEE in various speeds */
lpi_ctrl &= ~I82579_LPI_CTRL_ENABLE_MASK;
/* Enable EEE if not disabled by user */ if (!dev_spec->eee_disable) { /* Save off link partner's EEE ability */
ret_val = e1000_read_emi_reg_locked(hw, lpa,
&dev_spec->eee_lp_ability); if (ret_val) goto release;
/* Enable EEE only for speeds in which the link partner is *EEEcapableandforwhichweadvertiseEEE.
*/ if (adv & dev_spec->eee_lp_ability & I82579_EEE_1000_SUPPORTED)
lpi_ctrl |= I82579_LPI_CTRL_1000_ENABLE;
if (adv & dev_spec->eee_lp_ability & I82579_EEE_100_SUPPORTED) {
e1e_rphy_locked(hw, MII_LPA, &data); if (data & LPA_100FULL)
lpi_ctrl |= I82579_LPI_CTRL_100_ENABLE; else /* EEE is not supported in 100Half, so ignore *partner'sEEEin100abilityiffull-duplex *isnotadvertised.
*/
dev_spec->eee_lp_ability &=
~I82579_EEE_100_SUPPORTED;
}
}
if (hw->phy.type == e1000_phy_82579) {
ret_val = e1000_read_emi_reg_locked(hw, I82579_LPI_PLL_SHUT,
&data); if (ret_val) goto release;
data &= ~I82579_LPI_100_PLL_SHUT;
ret_val = e1000_write_emi_reg_locked(hw, I82579_LPI_PLL_SHUT,
data);
}
ret_val =
e1000e_write_kmrn_reg_locked(hw,
E1000_KMRNCTRLSTA_K1_CONFIG,
reg);
release:
hw->phy.ops.release(hw);
} else { /* clear FEXTNVM6 bit 8 on link down or 10/100 */
fextnvm6 &= ~E1000_FEXTNVM6_REQ_PLL_CLK;
ret_val = e1e_rphy(hw, I217_INBAND_CTRL, ®); if (ret_val) return ret_val;
/* Clear link status transmit timeout */
reg &= ~I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_MASK;
if (status & E1000_STATUS_SPEED_100) { /* Set inband Tx timeout to 5x10us for 100Half */
reg |= 5 << I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_SHIFT;
/* Do not extend the K1 entry latency for 100Half */
fextnvm6 &= ~E1000_FEXTNVM6_ENABLE_K1_ENTRY_CONDITION;
} else { /* Set inband Tx timeout to 50x10us for 10Full/Half */
reg |= 50 <<
I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_SHIFT;
/* Extend the K1 entry latency for 10 Mbps */
fextnvm6 |= E1000_FEXTNVM6_ENABLE_K1_ENTRY_CONDITION;
}
ret_val = e1e_wphy(hw, I217_INBAND_CTRL, reg); if (ret_val) return ret_val;
/* Force SMBus mode in the PHY */
ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &smb_ctrl); if (ret_val) {
e1000e_enable_phy_retry(hw); return ret_val;
}
if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID) { /* Request ME configure ULP mode in the PHY */
mac_reg = er32(H2ME);
mac_reg |= E1000_H2ME_ULP | E1000_H2ME_ENFORCE_SETTINGS;
ew32(H2ME, mac_reg);
goto out;
}
if (!to_sx) { int i = 0;
/* Poll up to 5 seconds for Cable Disconnected indication */ while (!(er32(FEXT) & E1000_FEXT_PHY_CABLE_DISCONNECTED)) { /* Bail if link is re-acquired */ if (er32(STATUS) & E1000_STATUS_LU) return -E1000_ERR_PHY;
if (i++ == 100) break;
msleep(50);
}
e_dbg("CABLE_DISCONNECTED %s set after %dmsec\n",
(er32(FEXT) &
E1000_FEXT_PHY_CABLE_DISCONNECTED) ? "" : "not", i * 50);
}
ret_val = hw->phy.ops.acquire(hw); if (ret_val) goto out;
ret_val = e1000e_force_smbus(hw); if (ret_val) {
e_dbg("Failed to force SMBUS: %d\n", ret_val); goto release;
}
/* Si workaround for ULP entry flow on i127/rev6 h/w. Enable *LPLUanddisableGigspeedwhenenteringULP
*/ if ((hw->phy.type == e1000_phy_i217) && (hw->phy.revision == 6)) {
ret_val = e1000_read_phy_reg_hv_locked(hw, HV_OEM_BITS,
&oem_reg); if (ret_val) goto release;
if (force) { /* Request ME un-configure ULP mode in the PHY */
mac_reg = er32(H2ME);
mac_reg &= ~E1000_H2ME_ULP;
mac_reg |= E1000_H2ME_ENFORCE_SETTINGS;
ew32(H2ME, mac_reg);
}
/* Poll up to 2.5 seconds for ME to clear ULP_CFG_DONE. *Ifthistakesmorethan1second,showawarningindicatinga *firmwarebug
*/ while (er32(FWSM) & E1000_FWSM_ULP_CFG_DONE) { if (i++ == 250) {
ret_val = -E1000_ERR_PHY; goto out;
} if (i > 100 && !firmware_bug)
firmware_bug = true;
usleep_range(10000, 11000);
} if (firmware_bug)
e_warn("ULP_CONFIG_DONE took %d msec. This is a firmware bug\n",
i * 10); else
e_dbg("ULP_CONFIG_DONE cleared after %d msec\n",
i * 10);
/* Unforce SMBus mode in PHY */
ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &phy_reg); if (ret_val) { /* The MAC might be in PCIe mode, so temporarily force to *SMBusmodeinordertoaccessthePHY.
*/
mac_reg = er32(CTRL_EXT);
mac_reg |= E1000_CTRL_EXT_FORCE_SMBUS;
ew32(CTRL_EXT, mac_reg);
/* Unforce SMBus mode in MAC */
mac_reg = er32(CTRL_EXT);
mac_reg &= ~E1000_CTRL_EXT_FORCE_SMBUS;
ew32(CTRL_EXT, mac_reg);
/* When ULP mode was previously entered, K1 was disabled by the *hardware.Re-EnableK1inthePHYwhenexitingULP.
*/
ret_val = e1000_read_phy_reg_hv_locked(hw, HV_PM_CTRL, &phy_reg); if (ret_val) goto release;
phy_reg |= HV_PM_CTRL_K1_ENABLE;
e1000_write_phy_reg_hv_locked(hw, HV_PM_CTRL, phy_reg);
/* We only want to go out to the PHY registers to see if Auto-Neg *hascompletedand/orifourlinkstatushaschanged.The *get_link_statusflagissetuponreceivingaLinkStatus *ChangeorRxSequenceErrorinterrupt.
*/ if (!mac->get_link_status) return0;
mac->get_link_status = false;
/* First we want to see if the MII Status Register reports *link.Ifso,thenwewanttogetthecurrentspeed/duplex *ofthePHY.
*/
ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link); if (ret_val) goto out;
if (hw->mac.type == e1000_pchlan) {
ret_val = e1000_k1_gig_workaround_hv(hw, link); if (ret_val) goto out;
}
/* When connected at 10Mbps half-duplex, some parts are excessively *aggressiveresultinginmanycollisions.Toavoidthis,increase *theIPGandreduceRxlatencyinthePHY.
*/ if ((hw->mac.type >= e1000_pch2lan) && link) {
u16 speed, duplex;
/* Check if there was DownShift, must be checked *immediatelyafterlink-up
*/
e1000e_check_downshift(hw);
/* Enable/Disable EEE after link up */ if (hw->phy.type > e1000_phy_82579) {
ret_val = e1000_set_eee_pchlan(hw); if (ret_val) return ret_val;
}
/* If we are forcing speed/duplex, then we simply return since *wehavealreadydeterminedwhetherwehavelinkornot.
*/ if (!mac->autoneg) return -E1000_ERR_CONFIG;
/* Auto-Neg is enabled. Auto Speed Detection takes care *ofMACspeed/duplexconfiguration.Soweonlyneedto *configureCollisionDistanceintheMAC.
*/
mac->ops.config_collision_dist(hw);
/* Configure Flow Control now that Auto-Neg has completed. *First,weneedtorestorethedesiredflowcontrol *settingsbecausewemayhavehadtore-autonegwitha *differentlinkpartner.
*/
ret_val = e1000e_config_fc_after_link_up(hw); if (ret_val)
e_dbg("Error configuring flow control\n");
rc = e1000_init_mac_params_ich8lan(hw); if (rc) return rc;
rc = e1000_init_nvm_params_ich8lan(hw); if (rc) return rc;
switch (hw->mac.type) { case e1000_ich8lan: case e1000_ich9lan: case e1000_ich10lan:
rc = e1000_init_phy_params_ich8lan(hw); break; case e1000_pchlan: case e1000_pch2lan: case e1000_pch_lpt: case e1000_pch_spt: case e1000_pch_cnp: case e1000_pch_tgp: case e1000_pch_adp: case e1000_pch_mtp: case e1000_pch_lnp: case e1000_pch_ptp: case e1000_pch_nvp:
rc = e1000_init_phy_params_pchlan(hw); break; default: break;
} if (rc) return rc;
/* Disable Jumbo Frame support on parts with Intel 10/100 PHY or *onpartswithMACsecenabledinNVM(reflectedinCTRL_EXT).
*/ if ((adapter->hw.phy.type == e1000_phy_ife) ||
((adapter->hw.mac.type >= e1000_pch2lan) &&
(!(er32(CTRL_EXT) & E1000_CTRL_EXT_LSECCK)))) {
adapter->flags &= ~FLAG_HAS_JUMBO_FRAMES;
adapter->max_hw_frame_size = VLAN_ETH_FRAME_LEN + ETH_FCS_LEN;
/* HW expects these in little endian so we reverse the byte order *fromnetworkorder(bigendian)tolittleendian
*/
rar_low = ((u32)addr[0] |
((u32)addr[1] << 8) |
((u32)addr[2] << 16) | ((u32)addr[3] << 24));
rar_high = ((u32)addr[4] | ((u32)addr[5] << 8));
/* If MAC address zero, no need to set the AV bit */ if (rar_low || rar_high)
rar_high |= E1000_RAH_AV;
/* RAR[1-6] are owned by manageability. Skip those and program the *nextaddressintotheSHRAregisterarray.
*/ if (index < (u32)(hw->mac.rar_entry_count)) {
s32 ret_val;
ret_val = e1000_acquire_swflag_ich8lan(hw); if (ret_val) goto out;
/* HW expects these in little endian so we reverse the byte order *fromnetworkorder(bigendian)tolittleendian
*/
rar_low = ((u32)addr[0] | ((u32)addr[1] << 8) |
((u32)addr[2] << 16) | ((u32)addr[3] << 24));
rar_high = ((u32)addr[4] | ((u32)addr[5] << 8));
/* If MAC address zero, no need to set the AV bit */ if (rar_low || rar_high)
rar_high |= E1000_RAH_AV;
/* Initialize the PHY from the NVM on ICH platforms. This *isneededduetoanissuewheretheNVMconfigurationis *notproperlyautoloadedafterpowertransitions. *Therefore,aftereachPHYreset,wewillloadthe *configurationdataoutoftheNVMmanually.
*/ switch (hw->mac.type) { case e1000_ich8lan: if (phy->type != e1000_phy_igp_3) return ret_val;
if ((hw->adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_AMT) ||
(hw->adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_C)) {
sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG; break;
}
fallthrough; case e1000_pchlan: case e1000_pch2lan: case e1000_pch_lpt: case e1000_pch_spt: case e1000_pch_cnp: case e1000_pch_tgp: case e1000_pch_adp: case e1000_pch_mtp: case e1000_pch_lnp: case e1000_pch_ptp: case e1000_pch_nvp:
sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M; break; default: return ret_val;
}
ret_val = hw->phy.ops.acquire(hw); if (ret_val) return ret_val;
data = er32(FEXTNVM); if (!(data & sw_cfg_mask)) goto release;
/* Make sure HW does not configure LCD from PHY *extendedconfigurationbeforeSWconfiguration
*/
data = er32(EXTCNF_CTRL); if ((hw->mac.type < e1000_pch2lan) &&
(data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE)) goto release;
/* Wrap the whole flow with the sw flag */
ret_val = hw->phy.ops.acquire(hw); if (ret_val) return ret_val;
/* Disable K1 when link is 1Gbps, otherwise use the NVM setting */ if (link) { if (hw->phy.type == e1000_phy_82578) {
ret_val = e1e_rphy_locked(hw, BM_CS_STATUS,
&status_reg); if (ret_val) goto release;
if (d0_state) { if (mac_reg & E1000_PHY_CTRL_GBE_DISABLE)
oem_reg |= HV_OEM_BITS_GBE_DIS;
if (mac_reg & E1000_PHY_CTRL_D0A_LPLU)
oem_reg |= HV_OEM_BITS_LPLU;
} else { if (mac_reg & (E1000_PHY_CTRL_GBE_DISABLE |
E1000_PHY_CTRL_NOND0A_GBE_DISABLE))
oem_reg |= HV_OEM_BITS_GBE_DIS;
if (mac_reg & (E1000_PHY_CTRL_D0A_LPLU |
E1000_PHY_CTRL_NOND0A_LPLU))
oem_reg |= HV_OEM_BITS_LPLU;
}
/* Set Restart auto-neg to activate the bits */ if ((d0_state || (hw->mac.type != e1000_pchlan)) &&
!hw->phy.ops.check_reset_block(hw))
oem_reg |= HV_OEM_BITS_RESTART_AN;
/* 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) return ret_val;
}
if (((hw->phy.type == e1000_phy_82577) &&
((hw->phy.revision == 1) || (hw->phy.revision == 2))) ||
((hw->phy.type == e1000_phy_82578) && (hw->phy.revision == 1))) { /* Disable generation of early preamble */
ret_val = e1e_wphy(hw, PHY_REG(769, 25), 0x4431); if (ret_val) return ret_val;
/* Preamble tuning for SSC */
ret_val = e1e_wphy(hw, HV_KMRN_FIFO_CTRLSTA, 0xA204); if (ret_val) return ret_val;
}
if (hw->phy.type == e1000_phy_82578) { /* Return registers to default by doing a soft reset then *writing0x3140tothecontrolregister.
*/ if (hw->phy.revision < 2) {
e1000e_phy_sw_reset(hw);
ret_val = e1e_wphy(hw, MII_BMCR, 0x3140); if (ret_val) return ret_val;
}
}
/* Configure the K1 Si workaround during phy reset assuming there is *linksothatitdisablesK1iflinkisin1Gbps.
*/
ret_val = e1000_k1_gig_workaround_hv(hw, true); if (ret_val) return ret_val;
/* Workaround for link disconnects on a busy hub in half duplex */
ret_val = hw->phy.ops.acquire(hw); if (ret_val) return ret_val;
ret_val = e1e_rphy_locked(hw, BM_PORT_GEN_CFG, &phy_data); if (ret_val) goto release;
ret_val = e1e_wphy_locked(hw, BM_PORT_GEN_CFG, phy_data & 0x00FF); if (ret_val) goto release;
/* set MSE higher to enable link to stay up when noise is high */
ret_val = e1000_write_emi_reg_locked(hw, I82577_MSE_THRESHOLD, 0x0034);
release:
hw->phy.ops.release(hw);
/* Set MDIO slow mode before any other MDIO access */
ret_val = e1000_set_mdio_slow_mode_hv(hw); if (ret_val) return ret_val;
ret_val = hw->phy.ops.acquire(hw); if (ret_val) return ret_val; /* set MSE higher to enable link to stay up when noise is high */
ret_val = e1000_write_emi_reg_locked(hw, I82579_MSE_THRESHOLD, 0x0034); if (ret_val) goto release; /* drop link after 5 times MSE threshold was reached */
ret_val = e1000_write_emi_reg_locked(hw, I82579_MSE_LINK_DOWN, 0x0005);
release:
hw->phy.ops.release(hw);
/* Wait for basic configuration completes before proceeding */ do {
data = er32(STATUS);
data &= E1000_STATUS_LAN_INIT_DONE;
usleep_range(100, 200);
} while ((!data) && --loop);
/* If basic configuration is incomplete before the above loop *countreaches0,loadingtheconfigurationfromNVMwill *leavethePHYinabadstatepossiblyresultinginnolink.
*/ if (loop == 0)
e_dbg("LAN_INIT_DONE not set, increase timeout\n");
/* Clear the Init Done bit for the next init event */
data = er32(STATUS);
data &= ~E1000_STATUS_LAN_INIT_DONE;
ew32(STATUS, data);
}
if (active) {
phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU;
ew32(PHY_CTRL, phy_ctrl);
if (phy->type != e1000_phy_igp_3) return0;
/* Call gig speed drop workaround on LPLU before accessing *anyPHYregisters
*/ if (hw->mac.type == e1000_ich8lan)
e1000e_gig_downshift_workaround_ich8lan(hw);
/* When LPLU is enabled, we should disable SmartSpeed */
ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG, &data); if (ret_val) return ret_val;
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG, data); if (ret_val) return ret_val;
} else {
phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU;
ew32(PHY_CTRL, phy_ctrl);
if (phy->type != e1000_phy_igp_3) return0;
/* LPLU and SmartSpeed are mutually exclusive. LPLU is used *duringDxstateswherethepowerconservationismost *important.Duringdriveractivityweshouldenable *SmartSpeed,soperformanceismaintained.
*/ if (phy->smart_speed == e1000_smart_speed_on) {
ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
&data); if (ret_val) return ret_val;
data |= IGP01E1000_PSCFR_SMART_SPEED;
ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
data); if (ret_val) return ret_val;
} elseif (phy->smart_speed == e1000_smart_speed_off) {
ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
&data); if (ret_val) return ret_val;
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
data); if (ret_val) return ret_val;
}
}
if (!active) {
phy_ctrl &= ~E1000_PHY_CTRL_NOND0A_LPLU;
ew32(PHY_CTRL, phy_ctrl);
if (phy->type != e1000_phy_igp_3) return0;
/* LPLU and SmartSpeed are mutually exclusive. LPLU is used *duringDxstateswherethepowerconservationismost *important.Duringdriveractivityweshouldenable *SmartSpeed,soperformanceismaintained.
*/ if (phy->smart_speed == e1000_smart_speed_on) {
ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
&data); if (ret_val) return ret_val;
data |= IGP01E1000_PSCFR_SMART_SPEED;
ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
data); if (ret_val) return ret_val;
} elseif (phy->smart_speed == e1000_smart_speed_off) {
ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
&data); if (ret_val) return ret_val;
/* Call gig speed drop workaround on LPLU before accessing *anyPHYregisters
*/ if (hw->mac.type == e1000_ich8lan)
e1000e_gig_downshift_workaround_ich8lan(hw);
/* When LPLU is enabled, we should disable SmartSpeed */
ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG, &data); if (ret_val) return ret_val;
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG, data);
}
switch (hw->mac.type) { case e1000_pch_spt: case e1000_pch_cnp: case e1000_pch_tgp: case e1000_pch_adp: case e1000_pch_mtp: case e1000_pch_lnp: case e1000_pch_ptp: case e1000_pch_nvp:
bank1_offset = nvm->flash_bank_size;
act_offset = E1000_ICH_NVM_SIG_WORD;
/* set bank to 0 in case flash read fails */
*bank = 0;
/* Check bank 0 */
ret_val = e1000_read_flash_dword_ich8lan(hw, act_offset,
&nvm_dword); if (ret_val) return ret_val;
sig_byte = FIELD_GET(0xFF00, nvm_dword); if ((sig_byte & E1000_ICH_NVM_VALID_SIG_MASK) ==
E1000_ICH_NVM_SIG_VALUE) {
*bank = 0; return0;
}
e_dbg("ERROR: No valid NVM bank present\n"); return -E1000_ERR_NVM; case e1000_ich8lan: case e1000_ich9lan:
eecd = er32(EECD); if ((eecd & E1000_EECD_SEC1VAL_VALID_MASK) ==
E1000_EECD_SEC1VAL_VALID_MASK) { if (eecd & E1000_EECD_SEC1VAL)
*bank = 1; else
*bank = 0;
return0;
}
e_dbg("Unable to determine valid NVM bank via EEC - reading flash signature\n");
fallthrough; default: /* set bank to 0 in case flash read fails */
*bank = 0;
/* Check bank 0 */
ret_val = e1000_read_flash_byte_ich8lan(hw, act_offset,
&sig_byte); if (ret_val) return ret_val; if ((sig_byte & E1000_ICH_NVM_VALID_SIG_MASK) ==
E1000_ICH_NVM_SIG_VALUE) {
*bank = 0; return0;
}
/* Check bank 1 */
ret_val = e1000_read_flash_byte_ich8lan(hw, act_offset +
bank1_offset,
&sig_byte); if (ret_val) return ret_val; if ((sig_byte & E1000_ICH_NVM_VALID_SIG_MASK) ==
E1000_ICH_NVM_SIG_VALUE) {
*bank = 1; return0;
}
e_dbg("ERROR: No valid NVM bank present\n"); return -E1000_ERR_NVM;
}
}
/* Check if the flash descriptor is valid */ if (!hsfsts.hsf_status.fldesvalid) {
e_dbg("Flash descriptor invalid. SW Sequencing must be used.\n"); return -E1000_ERR_NVM;
}
/* Clear FCERR and DAEL in hw status by writing 1 */
hsfsts.hsf_status.flcerr = 1;
hsfsts.hsf_status.dael = 1; if (hw->mac.type >= e1000_pch_spt)
ew32flash(ICH_FLASH_HSFSTS, hsfsts.regval & 0xFFFF); else
ew16flash(ICH_FLASH_HSFSTS, hsfsts.regval);
/* Either we should have a hardware SPI cycle in progress *bittocheckagainst,inordertostartanewcycleor *FDONEbitshouldbechangedinthehardwaresothatit *is1afterhardwarereset,whichcanthenbeusedasan *indicationwhetheracycleisinprogressorhasbeen *completed.
*/
if (!hsfsts.hsf_status.flcinprog) { /* There is no cycle running at present, *sowecanstartacycle. *BeginbysettingFlashCycleDone.
*/
hsfsts.hsf_status.flcdone = 1; if (hw->mac.type >= e1000_pch_spt)
ew32flash(ICH_FLASH_HSFSTS, hsfsts.regval & 0xFFFF); else
ew16flash(ICH_FLASH_HSFSTS, hsfsts.regval);
ret_val = 0;
} else {
s32 i;
/* Otherwise poll for sometime so the current *cyclehasachancetoendbeforegivingup.
*/ for (i = 0; i < ICH_FLASH_READ_COMMAND_TIMEOUT; i++) {
hsfsts.regval = er16flash(ICH_FLASH_HSFSTS); if (!hsfsts.hsf_status.flcinprog) {
ret_val = 0; break;
}
udelay(1);
} if (!ret_val) { /* Successful in waiting for previous cycle to timeout, *nowsettheFlashCycleDone.
*/
hsfsts.hsf_status.flcdone = 1; if (hw->mac.type >= e1000_pch_spt)
ew32flash(ICH_FLASH_HSFSTS,
hsfsts.regval & 0xFFFF); else
ew16flash(ICH_FLASH_HSFSTS, hsfsts.regval);
} else {
e_dbg("Flash controller busy, cannot get access\n");
}
}
return ret_val;
}
/** *e1000_flash_cycle_ich8lan-Startsflashcycle(read/write/erase) *@hw:pointertotheHWstructure *@timeout:maximumtimetowaitforcompletion * *Thisfunctionstartsaflashcycleandwaitsforitscompletion.
**/ static s32 e1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout)
{ union ich8_hws_flash_ctrl hsflctl; union ich8_hws_flash_status hsfsts;
u32 i = 0;
/* Start a cycle by writing 1 in Flash Cycle Go in Hw Flash Control */ if (hw->mac.type >= e1000_pch_spt)
hsflctl.regval = er32flash(ICH_FLASH_HSFSTS) >> 16; else
hsflctl.regval = er16flash(ICH_FLASH_HSFCTL);
hsflctl.hsf_ctrl.flcgo = 1;
/* wait till FDONE bit is set to 1 */ do {
hsfsts.regval = er16flash(ICH_FLASH_HSFSTS); if (hsfsts.hsf_status.flcdone) break;
udelay(1);
} while (i++ < timeout);
if (hsfsts.hsf_status.flcdone && !hsfsts.hsf_status.flcerr) return0;
/* Check if FCERR is set to 1, if set to 1, clear it *andtrythewholesequenceafewmoretimes,else *readin(shiftin)theFlashData0,theorderis *leastsignificantbytefirstmsbtolsb
*/ if (!ret_val) {
flash_data = er32flash(ICH_FLASH_FDATA0); if (size == 1)
*data = (u8)(flash_data & 0x000000FF); elseif (size == 2)
*data = (u16)(flash_data & 0x0000FFFF); break;
} else { /* If we've gotten here, then things are probably *completelyhosed,butiftheerrorconditionis *detected,itwon'thurttogiveitanothertry... *ICH_FLASH_CYCLE_REPEAT_COUNTtimes.
*/
hsfsts.regval = er16flash(ICH_FLASH_HSFSTS); if (hsfsts.hsf_status.flcerr) { /* Repeat for some time before giving up. */ continue;
} elseif (!hsfsts.hsf_status.flcdone) {
e_dbg("Timeout error - flash cycle did not complete.\n"); break;
}
}
} while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT);
do {
udelay(1); /* Steps */
ret_val = e1000_flash_cycle_init_ich8lan(hw); if (ret_val) break; /* In SPT, This register is in Lan memory space, not flash. *Therefore,only32bitaccessissupported
*/
hsflctl.regval = er32flash(ICH_FLASH_HSFSTS) >> 16;
/* 0b/1b corresponds to 1 or 2 byte size, respectively. */
hsflctl.hsf_ctrl.fldbcount = sizeof(u32) - 1;
hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_READ; /* In SPT, This register is in Lan memory space, not flash. *Therefore,only32bitaccessissupported
*/
ew32flash(ICH_FLASH_HSFSTS, (u32)hsflctl.regval << 16);
ew32flash(ICH_FLASH_FADDR, flash_linear_addr);
/* Check if FCERR is set to 1, if set to 1, clear it *andtrythewholesequenceafewmoretimes,else *readin(shiftin)theFlashData0,theorderis *leastsignificantbytefirstmsbtolsb
*/ if (!ret_val) {
*data = er32flash(ICH_FLASH_FDATA0); break;
} else { /* If we've gotten here, then things are probably *completelyhosed,butiftheerrorconditionis *detected,itwon'thurttogiveitanothertry... *ICH_FLASH_CYCLE_REPEAT_COUNTtimes.
*/
hsfsts.regval = er16flash(ICH_FLASH_HSFSTS); if (hsfsts.hsf_status.flcerr) { /* Repeat for some time before giving up. */ continue;
} elseif (!hsfsts.hsf_status.flcdone) {
e_dbg("Timeout error - flash cycle did not complete.\n"); break;
}
}
} while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT);
ret_val = e1000e_update_nvm_checksum_generic(hw); if (ret_val) goto out;
if (nvm->type != e1000_nvm_flash_sw) goto out;
nvm->ops.acquire(hw);
/* We're writing to the opposite bank so if we're on bank 1, *writetobank0etc.Wealsoneedtoerasethesegmentthat *isgoingtobewritten
*/
ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank); if (ret_val) {
e_dbg("Could not detect valid bank, assuming bank 0\n");
bank = 0;
}
if (bank == 0) {
new_bank_offset = nvm->flash_bank_size;
old_bank_offset = 0;
ret_val = e1000_erase_flash_bank_ich8lan(hw, 1); if (ret_val) goto release;
} else {
old_bank_offset = nvm->flash_bank_size;
new_bank_offset = 0;
ret_val = e1000_erase_flash_bank_ich8lan(hw, 0); if (ret_val) goto release;
} for (i = 0; i < E1000_ICH8_SHADOW_RAM_WORDS; i += 2) { /* Determine whether to write the value stored *intheotherNVMbankoramodifiedvaluestored *intheshadowRAM
*/
ret_val = e1000_read_flash_dword_ich8lan(hw,
i + old_bank_offset,
&dword);
/* If the word is 0x13, then make sure the signature bits *(15:14)are11buntilthecommithascompleted. *Thiswillallowustowrite10bwhichindicatesthe *signatureisvalid.Wewanttodothisafterthewrite *hascompletedsothatwedon'tmarkthesegmentvalid *whilethewriteisstillinprogress
*/ if (i == E1000_ICH_NVM_SIG_WORD - 1)
dword |= E1000_ICH_NVM_SIG_MASK << 16;
/* Convert offset to bytes. */
act_offset = (i + new_bank_offset) << 1;
usleep_range(100, 200);
/* Write the data to the new bank. Offset in words */
act_offset = i + new_bank_offset;
ret_val = e1000_retry_write_flash_dword_ich8lan(hw, act_offset,
dword); if (ret_val) break;
}
/* Don't bother writing the segment valid bits if sector *programmingfailed.
*/ if (ret_val) { /* Possibly read-only, see e1000e_write_protect_nvm_ich8lan() */
e_dbg("Flash commit failed.\n"); goto release;
}
/* Finally validate the new segment by setting bit 15:14 *to10binword0x13,thiscanbedonewithoutan *eraseaswellsincethesebitsare11tostartwith *andweneedtochangebit14to0b
*/
act_offset = new_bank_offset + E1000_ICH_NVM_SIG_WORD;
/*offset in words but we read dword */
--act_offset;
ret_val = e1000_read_flash_dword_ich8lan(hw, act_offset, &dword);
/* Great! Everything worked, we can now clear the cached entries. */ for (i = 0; i < E1000_ICH8_SHADOW_RAM_WORDS; i++) {
dev_spec->shadow_ram[i].modified = false;
dev_spec->shadow_ram[i].value = 0xFFFF;
}
release:
nvm->ops.release(hw);
/* Reload the EEPROM, or else modifications will not appear *untilafterthenextadapterreset.
*/ if (!ret_val) {
nvm->ops.reload(hw);
usleep_range(10000, 11000);
}
out: if (ret_val)
e_dbg("NVM update error: %d\n", ret_val);
ret_val = e1000e_update_nvm_checksum_generic(hw); if (ret_val) goto out;
if (nvm->type != e1000_nvm_flash_sw) goto out;
nvm->ops.acquire(hw);
/* We're writing to the opposite bank so if we're on bank 1, *writetobank0etc.Wealsoneedtoerasethesegmentthat *isgoingtobewritten
*/
ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank); if (ret_val) {
e_dbg("Could not detect valid bank, assuming bank 0\n");
bank = 0;
}
if (bank == 0) {
new_bank_offset = nvm->flash_bank_size;
old_bank_offset = 0;
ret_val = e1000_erase_flash_bank_ich8lan(hw, 1); if (ret_val) goto release;
} else {
old_bank_offset = nvm->flash_bank_size;
new_bank_offset = 0;
ret_val = e1000_erase_flash_bank_ich8lan(hw, 0); if (ret_val) goto release;
} for (i = 0; i < E1000_ICH8_SHADOW_RAM_WORDS; i++) { if (dev_spec->shadow_ram[i].modified) {
data = dev_spec->shadow_ram[i].value;
} else {
ret_val = e1000_read_flash_word_ich8lan(hw, i +
old_bank_offset,
&data); if (ret_val) break;
}
/* If the word is 0x13, then make sure the signature bits *(15:14)are11buntilthecommithascompleted. *Thiswillallowustowrite10bwhichindicatesthe *signatureisvalid.Wewanttodothisafterthewrite *hascompletedsothatwedon'tmarkthesegmentvalid *whilethewriteisstillinprogress
*/ if (i == E1000_ICH_NVM_SIG_WORD)
data |= E1000_ICH_NVM_SIG_MASK;
/* Convert offset to bytes. */
act_offset = (i + new_bank_offset) << 1;
usleep_range(100, 200); /* Write the bytes to the new bank. */
ret_val = e1000_retry_write_flash_byte_ich8lan(hw,
act_offset,
(u8)data); if (ret_val) break;
/* Don't bother writing the segment valid bits if sector *programmingfailed.
*/ if (ret_val) { /* Possibly read-only, see e1000e_write_protect_nvm_ich8lan() */
e_dbg("Flash commit failed.\n"); goto release;
}
/* Finally validate the new segment by setting bit 15:14 *to10binword0x13,thiscanbedonewithoutan *eraseaswellsincethesebitsare11tostartwith *andweneedtochangebit14to0b
*/
act_offset = new_bank_offset + E1000_ICH_NVM_SIG_WORD;
ret_val = e1000_read_flash_word_ich8lan(hw, act_offset, &data); if (ret_val) goto release;
data &= 0xBFFF;
ret_val = e1000_retry_write_flash_byte_ich8lan(hw,
act_offset * 2 + 1,
(u8)(data >> 8)); if (ret_val) goto release;
/* And invalidate the previously valid segment by setting *itssignatureword(0x13)high_byteto0b.Thiscanbe *donewithoutanerasebecauseflasherasesetsallbits *to1's.Wecanwrite1'sto0'swithoutanerase
*/
act_offset = (old_bank_offset + E1000_ICH_NVM_SIG_WORD) * 2 + 1;
ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset, 0); if (ret_val) goto release;
/* Great! Everything worked, we can now clear the cached entries. */ for (i = 0; i < E1000_ICH8_SHADOW_RAM_WORDS; i++) {
dev_spec->shadow_ram[i].modified = false;
dev_spec->shadow_ram[i].value = 0xFFFF;
}
release:
nvm->ops.release(hw);
/* Reload the EEPROM, or else modifications will not appear *untilafterthenextadapterreset.
*/ if (!ret_val) {
nvm->ops.reload(hw);
usleep_range(10000, 11000);
}
out: if (ret_val)
e_dbg("NVM update error: %d\n", ret_val);
/* Read NVM and check Invalid Image CSUM bit. If this bit is 0, *thechecksumneedstobefixed.Thisbitisanindicationthat *theNVMwaspreparedbyOEMsoftwareanddidnotcalculate *thechecksum...alikelyscenario.
*/ switch (hw->mac.type) { case e1000_pch_lpt: case e1000_pch_spt: case e1000_pch_cnp: case e1000_pch_tgp: case e1000_pch_adp: case e1000_pch_mtp: case e1000_pch_lnp: case e1000_pch_ptp: case e1000_pch_nvp:
word = NVM_COMPAT;
valid_csum_mask = NVM_COMPAT_VALID_CSUM; break; default:
word = NVM_FUTURE_INIT_WORD1;
valid_csum_mask = NVM_FUTURE_INIT_WORD1_VALID_CSUM; break;
}
ret_val = e1000_read_nvm(hw, word, 1, &data); if (ret_val) return ret_val;
if (!(data & valid_csum_mask)) {
e_dbg("NVM Checksum valid bit not set\n");
if (hw->mac.type < e1000_pch_tgp) {
data |= valid_csum_mask;
ret_val = e1000_write_nvm(hw, word, 1, &data); if (ret_val) return ret_val;
ret_val = e1000e_update_nvm_checksum(hw); if (ret_val) return ret_val;
} elseif (hw->mac.type == e1000_pch_tgp) { return0;
}
}
/* Lock down a subset of GbE Flash Control Registers, e.g. *PR0topreventthewrite-protectionfrombeinglifted. *OnceFLOCKDNisset,theregistersprotectedbyitcannot *bewrittenuntilFLOCKDNisclearedbyahardwarereset.
*/
hsfsts.regval = er16flash(ICH_FLASH_HSFSTS);
hsfsts.hsf_status.flockdn = true;
ew32flash(ICH_FLASH_HSFSTS, hsfsts.regval);
do {
udelay(1); /* Steps */
ret_val = e1000_flash_cycle_init_ich8lan(hw); if (ret_val) break; /* In SPT, This register is in Lan memory space, not *flash.Therefore,only32bitaccessissupported
*/ if (hw->mac.type >= e1000_pch_spt)
hsflctl.regval = er32flash(ICH_FLASH_HSFSTS) >> 16; else
hsflctl.regval = er16flash(ICH_FLASH_HSFCTL);
/* 0b/1b corresponds to 1 or 2 byte size, respectively. */
hsflctl.hsf_ctrl.fldbcount = size - 1;
hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_WRITE; /* In SPT, This register is in Lan memory space, *notflash.Therefore,only32bitaccessis *supported
*/ if (hw->mac.type >= e1000_pch_spt)
ew32flash(ICH_FLASH_HSFSTS, hsflctl.regval << 16); else
ew16flash(ICH_FLASH_HSFCTL, hsflctl.regval);
/* check if FCERR is set to 1 , if set to 1, clear it *andtrythewholesequenceafewmoretimeselsedone
*/
ret_val =
e1000_flash_cycle_ich8lan(hw,
ICH_FLASH_WRITE_COMMAND_TIMEOUT); if (!ret_val) break;
/* If we're here, then things are most likely *completelyhosed,butiftheerrorcondition *isdetected,itwon'thurttogiveitanother *try...ICH_FLASH_CYCLE_REPEAT_COUNTtimes.
*/
hsfsts.regval = er16flash(ICH_FLASH_HSFSTS); if (hsfsts.hsf_status.flcerr) /* Repeat for some time before giving up. */ continue; if (!hsfsts.hsf_status.flcdone) {
e_dbg("Timeout error - flash cycle did not complete.\n"); break;
}
} while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT);
if (hw->mac.type >= e1000_pch_spt) { if (offset > ICH_FLASH_LINEAR_ADDR_MASK) return -E1000_ERR_NVM;
}
flash_linear_addr = ((ICH_FLASH_LINEAR_ADDR_MASK & offset) +
hw->nvm.flash_base_addr); do {
udelay(1); /* Steps */
ret_val = e1000_flash_cycle_init_ich8lan(hw); if (ret_val) break;
/* In SPT, This register is in Lan memory space, not *flash.Therefore,only32bitaccessissupported
*/ if (hw->mac.type >= e1000_pch_spt)
hsflctl.regval = er32flash(ICH_FLASH_HSFSTS)
>> 16; else
hsflctl.regval = er16flash(ICH_FLASH_HSFCTL);
/* In SPT, This register is in Lan memory space, *notflash.Therefore,only32bitaccessis *supported
*/ if (hw->mac.type >= e1000_pch_spt)
ew32flash(ICH_FLASH_HSFSTS, hsflctl.regval << 16); else
ew16flash(ICH_FLASH_HSFCTL, hsflctl.regval);
ew32flash(ICH_FLASH_FADDR, flash_linear_addr);
ew32flash(ICH_FLASH_FDATA0, data);
/* check if FCERR is set to 1 , if set to 1, clear it *andtrythewholesequenceafewmoretimeselsedone
*/
ret_val =
e1000_flash_cycle_ich8lan(hw,
ICH_FLASH_WRITE_COMMAND_TIMEOUT);
if (!ret_val) break;
/* If we're here, then things are most likely *completelyhosed,butiftheerrorcondition *isdetected,itwon'thurttogiveitanother *try...ICH_FLASH_CYCLE_REPEAT_COUNTtimes.
*/
hsfsts.regval = er16flash(ICH_FLASH_HSFSTS);
if (hsfsts.hsf_status.flcerr) /* Repeat for some time before giving up. */ continue; if (!hsfsts.hsf_status.flcdone) {
e_dbg("Timeout error - flash cycle did not complete.\n"); break;
}
} while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT);
/* Start with the base address, then add the sector offset. */
flash_linear_addr = hw->nvm.flash_base_addr;
flash_linear_addr += (bank) ? flash_bank_size : 0;
for (j = 0; j < iteration; j++) { do {
u32 timeout = ICH_FLASH_ERASE_COMMAND_TIMEOUT;
/* Steps */
ret_val = e1000_flash_cycle_init_ich8lan(hw); if (ret_val) return ret_val;
/* Write a value 11 (block Erase) in Flash *Cyclefieldinhwflashcontrol
*/ if (hw->mac.type >= e1000_pch_spt)
hsflctl.regval =
er32flash(ICH_FLASH_HSFSTS) >> 16; else
hsflctl.regval = er16flash(ICH_FLASH_HSFCTL);
/* Write the last 24 bits of an index within the *blockintoFlashLinearaddressfieldinFlash *Address.
*/
flash_linear_addr += (j * sector_size);
ew32flash(ICH_FLASH_FADDR, flash_linear_addr);
ret_val = e1000_flash_cycle_ich8lan(hw, timeout); if (!ret_val) break;
/* Check if FCERR is set to 1. If 1, *clearitandtrythewholesequence *afewmoretimeselseDone
*/
hsfsts.regval = er16flash(ICH_FLASH_HSFSTS); if (hsfsts.hsf_status.flcerr) /* repeat for some time before giving up */ continue; elseif (!hsfsts.hsf_status.flcdone) return ret_val;
} while (++count < ICH_FLASH_CYCLE_REPEAT_COUNT);
}
/* ICH devices are "PCI Express"-ish. They have *aconfigurationspace,butdonotcontain *PCIExpressCapabilityregisters,sobuswidth *mustbehardcoded.
*/ if (bus->width == e1000_bus_width_unknown)
bus->width = e1000_bus_width_pcie_x1;
/* Prevent the PCI-E bus from sticking if there is no TLP connection *onthelastTLPread/writetransactionwhenMACisreset.
*/
ret_val = e1000e_disable_pcie_master(hw); if (ret_val)
e_dbg("PCI-E Master disable polling has failed.\n");
e_dbg("Masking off all interrupts\n");
ew32(IMC, 0xffffffff);
/* Disable the Transmit and Receive units. Then delay to allow *anypendingtransactionstocompletebeforewehittheMAC *withtheglobalreset.
*/
ew32(RCTL, 0);
ew32(TCTL, E1000_TCTL_PSP);
e1e_flush();
usleep_range(10000, 11000);
/* Workaround for ICH8 bit corruption issue in FIFO memory */ if (hw->mac.type == e1000_ich8lan) { /* Set Tx and Rx buffer allocation to 8k apiece. */
ew32(PBA, E1000_PBA_8K); /* Set Packet Buffer Size to 16k. */
ew32(PBS, E1000_PBS_16K);
}
if (hw->mac.type == e1000_pchlan) { /* Save the NVM K1 bit setting */
ret_val = e1000_read_nvm(hw, E1000_NVM_K1_CONFIG, 1, &kum_cfg); if (ret_val) return ret_val;
if (!hw->phy.ops.check_reset_block(hw)) { /* Full-chip reset requires MAC and PHY reset at the same *timetomakesuretheinterfacebetweenMACandthe *externalPHYisreset.
*/
ctrl |= E1000_CTRL_PHY_RST;
/* Gate automatic PHY configuration by hardware on *non-managed82579
*/ if ((hw->mac.type == e1000_pch2lan) &&
!(er32(FWSM) & E1000_ICH_FWSM_FW_VALID))
e1000_gate_hw_phy_config_ich8lan(hw, true);
}
ret_val = e1000_acquire_swflag_ich8lan(hw);
e_dbg("Issuing a global reset to ich8lan\n");
ew32(CTRL, (ctrl | E1000_CTRL_RST)); /* cannot issue a flush here because it hangs the hardware */
msleep(20);
/* Set Phy Config Counter to 50msec */ if (hw->mac.type == e1000_pch2lan) {
reg = er32(FEXTNVM3);
reg &= ~E1000_FEXTNVM3_PHY_CFG_COUNTER_MASK;
reg |= E1000_FEXTNVM3_PHY_CFG_COUNTER_50MSEC;
ew32(FEXTNVM3, reg);
}
if (!ret_val)
clear_bit(__E1000_ACCESS_SHARED_RESOURCE, &hw->adapter->state);
if (ctrl & E1000_CTRL_PHY_RST) {
ret_val = hw->phy.ops.get_cfg_done(hw); if (ret_val) return ret_val;
ret_val = e1000_post_phy_reset_ich8lan(hw); if (ret_val) return ret_val;
}
/* For PCH, this write will make sure that any noise *willbedetectedasaCRCerrorandbedroppedratherthanshowup *asabadpackettotheDMAengine.
*/ if (hw->mac.type == e1000_pchlan)
ew32(CRC_OFFSET, 0x65656565);
e1000_initialize_hw_bits_ich8lan(hw); if (hw->mac.type >= e1000_pch_mtp) {
ret_val = hw->phy.ops.acquire(hw); if (ret_val) return ret_val;
ret_val = e1000_reconfigure_k1_exit_timeout(hw);
hw->phy.ops.release(hw); if (ret_val) {
e_dbg("Error failed to reconfigure K1 exit timeout\n"); return ret_val;
}
}
/* Initialize identification LED */
ret_val = mac->ops.id_led_init(hw); /* An error is not fatal and we should not stop init due to this */ if (ret_val)
e_dbg("Error initializing identification LED\n");
/* Setup the receive address. */
e1000e_init_rx_addrs(hw, mac->rar_entry_count);
/* Zero out the Multicast HASH table */
e_dbg("Zeroing the MTA\n"); for (i = 0; i < mac->mta_reg_count; i++)
E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
/* The 82578 Rx buffer will stall if wakeup is enabled in host and *theME.Disablewakeupbyclearingthehostwakeupbit. *ResetthephyafterdisablinghostwakeuptoresettheRxbuffer.
*/ if (hw->phy.type == e1000_phy_82578) {
e1e_rphy(hw, BM_PORT_GEN_CFG, &i);
i &= ~BM_WUC_HOST_WU_BIT;
e1e_wphy(hw, BM_PORT_GEN_CFG, i);
ret_val = e1000_phy_hw_reset_ich8lan(hw); if (ret_val) return ret_val;
}
/* Setup link and flow control */
ret_val = mac->ops.setup_link(hw);
/* Clear all of the statistics registers (clear on read). It is *importantthatwedothisafterwehavetriedtoestablishlink *becausethesymbolerrorcountwillincrementwildlyifthere *isnolink.
*/
e1000_clear_hw_cntrs_ich8lan(hw);
/* Extended Device Control */
reg = er32(CTRL_EXT);
reg |= BIT(22); /* Enable PHY low-power state when MAC is at D3 w/o WoL */ if (hw->mac.type >= e1000_pchlan)
reg |= E1000_CTRL_EXT_PHYPDEN;
ew32(CTRL_EXT, reg);
/* ICH parts do not have a word in the NVM to determine *thedefaultflowcontrolsetting,soweexplicitly *setittofull.
*/ if (hw->fc.requested_mode == e1000_fc_default) { /* Workaround h/w hang when Tx flow control enabled */ if (hw->mac.type == e1000_pchlan)
hw->fc.requested_mode = e1000_fc_rx_pause; else
hw->fc.requested_mode = e1000_fc_full;
}
/* Save off the requested flow control mode for use later. Depending *onthelinkpartner'scapabilities,wemayormaynotusethismode.
*/
hw->fc.current_mode = hw->fc.requested_mode;
e_dbg("After fix-ups FlowControl is now = %x\n", hw->fc.current_mode);
/* Continue to configure the copper link. */
ret_val = hw->mac.ops.setup_physical_interface(hw); if (ret_val) return ret_val;
/* Set the mac to wait the maximum time between each iteration *andincreasethemaxiterationswhenpollingthephy; *thisfixeserroneoustimeoutsat10Mbps.
*/
ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_TIMEOUTS, 0xFFFF); if (ret_val) return ret_val;
ret_val = e1000e_read_kmrn_reg(hw, E1000_KMRNCTRLSTA_INBAND_PARAM,
®_data); if (ret_val) return ret_val;
reg_data |= 0x3F;
ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_INBAND_PARAM,
reg_data); if (ret_val) return ret_val;
switch (hw->phy.type) { case e1000_phy_igp_3:
ret_val = e1000e_copper_link_setup_igp(hw); if (ret_val) return ret_val; break; case e1000_phy_bm: case e1000_phy_82578:
ret_val = e1000e_copper_link_setup_m88(hw); if (ret_val) return ret_val; break; case e1000_phy_82577: case e1000_phy_82579:
ret_val = e1000_copper_link_setup_82577(hw); if (ret_val) return ret_val; break; case e1000_phy_ife:
ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, ®_data); if (ret_val) return ret_val;
if (!dev_spec->kmrn_lock_loss_workaround_enabled) return0;
/* Make sure link is up before proceeding. If not just return. *Attemptingthiswhilelinkisnegotiatingfouleduplink *stability
*/
ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link); if (!link) return0;
for (i = 0; i < 10; i++) { /* read once to clear */
ret_val = e1e_rphy(hw, IGP3_KMRN_DIAG, &data); if (ret_val) return ret_val; /* and again to get new status */
ret_val = e1e_rphy(hw, IGP3_KMRN_DIAG, &data); if (ret_val) return ret_val;
/* check for PCS lock */ if (!(data & IGP3_KMRN_DIAG_PCS_LOCK_LOSS)) return0;
/* Try the workaround twice (if needed) */ do { /* Disable link */
reg = er32(PHY_CTRL);
reg |= (E1000_PHY_CTRL_GBE_DISABLE |
E1000_PHY_CTRL_NOND0A_GBE_DISABLE);
ew32(PHY_CTRL, reg);
/* Call gig speed drop workaround on Gig disable before *accessinganyPHYregisters
*/ if (hw->mac.type == e1000_ich8lan)
e1000e_gig_downshift_workaround_ich8lan(hw);
/* Write VR power-down enable */
e1e_rphy(hw, IGP3_VR_CTRL, &data);
data &= ~IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK;
e1e_wphy(hw, IGP3_VR_CTRL, data | IGP3_VR_CTRL_MODE_SHUTDOWN);
/* Read it back and test */
e1e_rphy(hw, IGP3_VR_CTRL, &data);
data &= IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK; if ((data == IGP3_VR_CTRL_MODE_SHUTDOWN) || retry) break;
/* Issue PHY reset and repeat at most one more time */
reg = er32(CTRL);
ew32(CTRL, reg | E1000_CTRL_PHY_RST);
retry++;
} while (retry);
}
ret_val = hw->phy.ops.acquire(hw); if (ret_val) goto out;
if (!dev_spec->eee_disable) {
u16 eee_advert;
ret_val =
e1000_read_emi_reg_locked(hw,
I217_EEE_ADVERTISEMENT,
&eee_advert); if (ret_val) goto release;
/* Disable LPLU if both link partners support 100BaseT *EEEand100Fullisadvertisedonbothendsofthe *link,andenableAutoEnableLPIsincetherewill *benodrivertoenableLPIwhileinSx.
*/ if ((eee_advert & I82579_EEE_100_SUPPORTED) &&
(dev_spec->eee_lp_ability &
I82579_EEE_100_SUPPORTED) &&
(hw->phy.autoneg_advertised & ADVERTISE_100_FULL)) {
phy_ctrl &= ~(E1000_PHY_CTRL_D0A_LPLU |
E1000_PHY_CTRL_NOND0A_LPLU);
/* Set Auto Enable LPI after link up */
e1e_rphy_locked(hw,
I217_LPI_GPIO_CTRL, &phy_reg);
phy_reg |= I217_LPI_GPIO_CTRL_AUTO_EN_LPI;
e1e_wphy_locked(hw,
I217_LPI_GPIO_CTRL, phy_reg);
}
}
/* For i217 Intel Rapid Start Technology support, *whenthesystemisgoingintoSxandnomanageabilityengine *ispresent,thedrivermustconfigureproxytoresetonlyon *powergood.LPI(LowPowerIdle)statemustalsoresetonly *onpowergood,aswellastheMTA(Multicasttablearray). *TheSMBusreleasemustalsobedisabledonLCDreset.
*/ if (!(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) { /* Enable proxy to reset only on power good. */
e1e_rphy_locked(hw, I217_PROXY_CTRL, &phy_reg);
phy_reg |= I217_PROXY_CTRL_AUTO_DISABLE;
e1e_wphy_locked(hw, I217_PROXY_CTRL, phy_reg);
/* Set bit enable LPI (EEE) to reset only on *powergood.
*/
e1e_rphy_locked(hw, I217_SxCTRL, &phy_reg);
phy_reg |= I217_SxCTRL_ENABLE_LPI_RESET;
e1e_wphy_locked(hw, I217_SxCTRL, phy_reg);
/* Disable the SMB release on LCD reset. */
e1e_rphy_locked(hw, I217_MEMPWR, &phy_reg);
phy_reg &= ~I217_MEMPWR_DISABLE_SMB_RELEASE;
e1e_wphy_locked(hw, I217_MEMPWR, phy_reg);
}
/* Enable MTA to reset for Intel Rapid Start Technology *Support
*/
e1e_rphy_locked(hw, I217_CGFREG, &phy_reg);
phy_reg |= I217_CGFREG_ENABLE_MTA_RESET;
e1e_wphy_locked(hw, I217_CGFREG, phy_reg);
ret_val = e1000_init_phy_workarounds_pchlan(hw); if (ret_val) {
e_dbg("Failed to init PHY flow ret_val=%d\n", ret_val); return;
}
/* For i217 Intel Rapid Start Technology support when the system *istransitioningfromSxandnomanageabilityengineispresent *configureSMBustorestoreonreset,disableproxy,andenable *theresetonMTA(Multicasttablearray).
*/ if (hw->phy.type == e1000_phy_i217) {
u16 phy_reg;
ret_val = hw->phy.ops.acquire(hw); if (ret_val) {
e_dbg("Failed to setup iRST\n"); return;
}
/* Clear Auto Enable LPI after link up */
e1e_rphy_locked(hw, I217_LPI_GPIO_CTRL, &phy_reg);
phy_reg &= ~I217_LPI_GPIO_CTRL_AUTO_EN_LPI;
e1e_wphy_locked(hw, I217_LPI_GPIO_CTRL, phy_reg);
if (!(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) { /* Restore clear on SMB if no manageability engine *ispresent
*/
ret_val = e1e_rphy_locked(hw, I217_MEMPWR, &phy_reg); if (ret_val) goto release;
phy_reg |= I217_MEMPWR_DISABLE_SMB_RELEASE;
e1e_wphy_locked(hw, I217_MEMPWR, phy_reg);
/* Disable Proxy */
e1e_wphy_locked(hw, I217_PROXY_CTRL, 0);
} /* Enable reset on MTA */
ret_val = e1e_rphy_locked(hw, I217_CGFREG, &phy_reg); if (ret_val) goto release;
phy_reg &= ~I217_CGFREG_ENABLE_MTA_RESET;
e1e_wphy_locked(hw, I217_CGFREG, phy_reg);
release: if (ret_val)
e_dbg("Error %d in resume workarounds\n", ret_val);
hw->phy.ops.release(hw);
}
}
/** *e1000_led_on_pchlan-TurnLEDson *@hw:pointertotheHWstructure * *TurnontheLEDs.
**/ static s32 e1000_led_on_pchlan(struct e1000_hw *hw)
{
u16 data = (u16)hw->mac.ledctl_mode2;
u32 i, led;
/* If no link, then turn LED on by setting the invert bit *foreachLEDthat'smodeis"link_up"inledctl_mode2.
*/ if (!(er32(STATUS) & E1000_STATUS_LU)) { for (i = 0; i < 3; i++) {
led = (data >> (i * 5)) & E1000_PHY_LED0_MASK; if ((led & E1000_PHY_LED0_MODE_MASK) !=
E1000_LEDCTL_MODE_LINK_UP) continue; if (led & E1000_PHY_LED0_IVRT)
data &= ~(E1000_PHY_LED0_IVRT << (i * 5)); else
data |= (E1000_PHY_LED0_IVRT << (i * 5));
}
}
return e1e_wphy(hw, HV_LED_CONFIG, data);
}
/** *e1000_led_off_pchlan-TurnLEDsoff *@hw:pointertotheHWstructure * *TurnofftheLEDs.
**/ static s32 e1000_led_off_pchlan(struct e1000_hw *hw)
{
u16 data = (u16)hw->mac.ledctl_mode1;
u32 i, led;
/* If no link, then turn LED off by clearing the invert bit *foreachLEDthat'smodeis"link_up"inledctl_mode1.
*/ if (!(er32(STATUS) & E1000_STATUS_LU)) { for (i = 0; i < 3; i++) {
led = (data >> (i * 5)) & E1000_PHY_LED0_MASK; if ((led & E1000_PHY_LED0_MODE_MASK) !=
E1000_LEDCTL_MODE_LINK_UP) continue; if (led & E1000_PHY_LED0_IVRT)
data &= ~(E1000_PHY_LED0_IVRT << (i * 5)); else
data |= (E1000_PHY_LED0_IVRT << (i * 5));
}
}
/* Wait for indication from h/w that it has completed basic config */ if (hw->mac.type >= e1000_ich10lan) {
e1000_lan_init_done_ich8lan(hw);
} else {
ret_val = e1000e_get_auto_rd_done(hw); if (ret_val) { /* When auto config read does not complete, do not *returnwithanerror.Thiscanhappeninsituations *wherethereisnoeepromandpreventsgettinglink.
*/
e_dbg("Auto Read Done did not complete\n");
ret_val = 0;
}
}
/* Clear PHY Reset Asserted bit */
status = er32(STATUS); if (status & E1000_STATUS_PHYRA)
ew32(STATUS, status & ~E1000_STATUS_PHYRA); else
e_dbg("PHY Reset Asserted not set - needs delay\n");
/* If EEPROM is not marked present, init the IGP 3 PHY manually */ if (hw->mac.type <= e1000_ich9lan) { if (!(er32(EECD) & E1000_EECD_PRES) &&
(hw->phy.type == e1000_phy_igp_3)) {
e1000e_phy_init_script_igp3(hw);
}
} else { if (e1000_valid_nvm_bank_detect_ich8lan(hw, &bank)) { /* Maybe we should do a basic PHY config */
e_dbg("EEPROM not present\n");
ret_val = -E1000_ERR_CONFIG;
}
}
return ret_val;
}
/** *e1000_power_down_phy_copper_ich8lan-RemovelinkduringPHYpowerdown *@hw:pointertotheHWstructure * *InthecaseofaPHYpowerdowntosavepower,ortoturnofflinkduringa *driverunload,orwakeonlanisnotenabled,removethelink.
**/ staticvoid e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw)
{ /* If the management interface is not enabled, then power down */ if (!(hw->mac.ops.check_mng_mode(hw) ||
hw->phy.ops.check_reset_block(hw)))
e1000_power_down_phy_copper(hw);
}
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.221Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-10-03)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.