FreeBSD Bugzilla – Attachment 228110 Details for
Bug 258153
em0: Hardware Initialization Failed - after wake up from sleep
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
e1000 dpdk ich8lan sync
e1k-ich8lan.patch (text/plain), 14.30 KB, created by
Kevin Bowling
on 2021-09-22 01:37:40 UTC
(
hide
)
Description:
e1000 dpdk ich8lan sync
Filename:
MIME Type:
Creator:
Kevin Bowling
Created:
2021-09-22 01:37:40 UTC
Size:
14.30 KB
patch
obsolete
>diff --git a/sys/dev/e1000/e1000_ich8lan.c b/sys/dev/e1000/e1000_ich8lan.c >index 4209595a911c..6a51889d94d8 100644 >--- a/sys/dev/e1000/e1000_ich8lan.c >+++ b/sys/dev/e1000/e1000_ich8lan.c >@@ -72,6 +72,7 @@ > > #include "e1000_api.h" > >+static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state); > static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw); > static void e1000_release_swflag_ich8lan(struct e1000_hw *hw); > static s32 e1000_acquire_nvm_ich8lan(struct e1000_hw *hw); >@@ -330,7 +331,6 @@ static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw) > * so forcibly disable it. > */ > hw->dev_spec.ich8lan.ulp_state = e1000_ulp_state_unknown; >- e1000_disable_ulp_lpt_lp(hw, TRUE); > > ret_val = hw->phy.ops.acquire(hw); > if (ret_val) { >@@ -730,6 +730,7 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw) > static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw) > { > struct e1000_mac_info *mac = &hw->mac; >+ u16 pci_cfg; > > DEBUGFUNC("e1000_init_mac_params_ich8lan"); > >@@ -808,6 +809,15 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw) > e1000_update_mc_addr_list_pch2lan; > /* FALLTHROUGH */ > case e1000_pchlan: >+ /* save PCH revision_id */ >+ e1000_read_pci_cfg(hw, E1000_PCI_REVISION_ID_REG, &pci_cfg); >+ /* SPT uses full byte for revision ID, >+ * as opposed to previous generations >+ */ >+ if (hw->mac.type >= e1000_pch_spt) >+ hw->revision_id = (u8)(pci_cfg &= 0x00FF); >+ else >+ hw->revision_id = (u8)(pci_cfg &= 0x000F); > /* check management mode */ > mac->ops.check_mng_mode = e1000_check_mng_mode_pchlan; > /* ID LED init */ >@@ -1279,25 +1289,14 @@ s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx) > (hw->dev_spec.ich8lan.ulp_state == e1000_ulp_state_on)) > return 0; > >- if (E1000_READ_REG(hw, E1000_FWSM) & E1000_ICH_FWSM_FW_VALID) { >- /* Request ME configure ULP mode in the PHY */ >- mac_reg = E1000_READ_REG(hw, E1000_H2ME); >- mac_reg |= E1000_H2ME_ULP | E1000_H2ME_ENFORCE_SETTINGS; >- E1000_WRITE_REG(hw, E1000_H2ME, mac_reg); >- >- goto out; >- } >- > if (!to_sx) { > int i = 0; >- > /* Poll up to 5 seconds for Cable Disconnected indication */ > while (!(E1000_READ_REG(hw, E1000_FEXT) & > E1000_FEXT_PHY_CABLE_DISCONNECTED)) { > /* Bail if link is re-acquired */ > if (E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_LU) > return -E1000_ERR_PHY; >- > if (i++ == 100) > break; > >@@ -1310,13 +1309,25 @@ s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx) > if (!(E1000_READ_REG(hw, E1000_FEXT) & > E1000_FEXT_PHY_CABLE_DISCONNECTED)) > return 0; >+ } > >+ if (E1000_READ_REG(hw, E1000_FWSM) & E1000_ICH_FWSM_FW_VALID) { >+ /* Request ME configure ULP mode in the PHY */ >+ mac_reg = E1000_READ_REG(hw, E1000_H2ME); >+ mac_reg |= E1000_H2ME_ULP | E1000_H2ME_ENFORCE_SETTINGS; >+ E1000_WRITE_REG(hw, E1000_H2ME, mac_reg); >+ >+ goto out; > } > > ret_val = hw->phy.ops.acquire(hw); > if (ret_val) > goto out; > >+ /* During S0 Idle keep the phy in PCI-E mode */ >+ if (hw->dev_spec.ich8lan.smbus_disable) >+ goto skip_smbus; >+ > /* Force SMBus mode in PHY */ > ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &phy_reg); > if (ret_val) >@@ -1348,6 +1359,21 @@ s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx) > goto release; > } > >+skip_smbus: >+ if (!to_sx) { >+ /* Change the 'Link Status Change' interrupt to trigger >+ * on 'Cable Status Change' >+ */ >+ ret_val = e1000_read_kmrn_reg_locked(hw, >+ E1000_KMRNCTRLSTA_OP_MODES, >+ &phy_reg); >+ if (ret_val) >+ goto release; >+ phy_reg |= E1000_KMRNCTRLSTA_OP_MODES_LSC2CSC; >+ e1000_write_kmrn_reg_locked(hw, E1000_KMRNCTRLSTA_OP_MODES, >+ phy_reg); >+ } >+ > /* Set Inband ULP Exit, Reset to SMBus mode and > * Disable SMBus Release on PERST# in PHY > */ >@@ -1380,6 +1406,15 @@ s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx) > phy_reg |= I218_ULP_CONFIG1_START; > e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg); > >+ if (!to_sx) { >+ /* Disable Tx so that the MAC doesn't send any (buffered) >+ * packets to the PHY. >+ */ >+ mac_reg = E1000_READ_REG(hw, E1000_TCTL); >+ mac_reg &= ~E1000_TCTL_EN; >+ E1000_WRITE_REG(hw, E1000_TCTL, mac_reg); >+ } >+ > if ((hw->phy.type == e1000_phy_i217) && (hw->phy.revision == 6) && > to_sx && (E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_LU)) { > ret_val = e1000_write_phy_reg_hv_locked(hw, HV_OEM_BITS, >@@ -1413,6 +1448,12 @@ s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx) > * to disable ULP mode (force=false); otherwise, for example when unloading > * the driver or during Sx->S0 transitions, this is called with force=true > * to forcibly disable ULP. >+ * >+ * When the cable is plugged in while the device is in D0, a Cable Status >+ * Change interrupt is generated which causes this function to be called >+ * to partially disable ULP mode and restart autonegotiation. This function >+ * is then called again due to the resulting Link Status Change interrupt >+ * to finish cleaning up after the ULP flow. > */ > s32 e1000_disable_ulp_lpt_lp(struct e1000_hw *hw, bool force) > { >@@ -1462,6 +1503,20 @@ s32 e1000_disable_ulp_lpt_lp(struct e1000_hw *hw, bool force) > mac_reg = E1000_READ_REG(hw, E1000_H2ME); > mac_reg &= ~E1000_H2ME_ULP; > E1000_WRITE_REG(hw, E1000_H2ME, mac_reg); >+ >+ /* Restore link speed advertisements and restart >+ * Auto-negotiation >+ */ >+ if (hw->mac.autoneg) { >+ ret_val = e1000_phy_setup_autoneg(hw); >+ if (ret_val) >+ goto out; >+ } else { >+ ret_val = e1000_setup_copper_link_generic(hw); >+ if (ret_val) >+ goto out; >+ } >+ ret_val = e1000_oem_bits_config_ich8lan(hw, true); > } > > goto out; >@@ -1471,6 +1526,16 @@ s32 e1000_disable_ulp_lpt_lp(struct e1000_hw *hw, bool force) > if (ret_val) > goto out; > >+ /* Revert the change to the 'Link Status Change' >+ * interrupt to trigger on 'Cable Status Change' >+ */ >+ ret_val = e1000_read_kmrn_reg_locked(hw, E1000_KMRNCTRLSTA_OP_MODES, >+ &phy_reg); >+ if (ret_val) >+ goto release; >+ phy_reg &= ~E1000_KMRNCTRLSTA_OP_MODES_LSC2CSC; >+ e1000_write_kmrn_reg_locked(hw, E1000_KMRNCTRLSTA_OP_MODES, phy_reg); >+ > if (force) > /* Toggle LANPHYPC Value bit */ > e1000_toggle_lanphypc_pch_lpt(hw); >@@ -1513,24 +1578,54 @@ s32 e1000_disable_ulp_lpt_lp(struct e1000_hw *hw, bool force) > ret_val = e1000_read_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, &phy_reg); > if (ret_val) > goto release; >- phy_reg &= ~(I218_ULP_CONFIG1_IND | >- I218_ULP_CONFIG1_STICKY_ULP | >- I218_ULP_CONFIG1_RESET_TO_SMBUS | >- I218_ULP_CONFIG1_WOL_HOST | >- I218_ULP_CONFIG1_INBAND_EXIT | >- I218_ULP_CONFIG1_EN_ULP_LANPHYPC | >- I218_ULP_CONFIG1_DIS_CLR_STICKY_ON_PERST | >- I218_ULP_CONFIG1_DISABLE_SMB_PERST); >- e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg); >+ /* CSC interrupt received due to ULP Indication */ >+ if ((phy_reg & I218_ULP_CONFIG1_IND) || force) { >+ phy_reg &= ~(I218_ULP_CONFIG1_IND | >+ I218_ULP_CONFIG1_STICKY_ULP | >+ I218_ULP_CONFIG1_RESET_TO_SMBUS | >+ I218_ULP_CONFIG1_WOL_HOST | >+ I218_ULP_CONFIG1_INBAND_EXIT | >+ I218_ULP_CONFIG1_EN_ULP_LANPHYPC | >+ I218_ULP_CONFIG1_DIS_CLR_STICKY_ON_PERST | >+ I218_ULP_CONFIG1_DISABLE_SMB_PERST); >+ e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg); >+ >+ /* Commit ULP changes by starting auto ULP configuration */ >+ phy_reg |= I218_ULP_CONFIG1_START; >+ e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg); >+ >+ /* Clear Disable SMBus Release on PERST# in MAC */ >+ mac_reg = E1000_READ_REG(hw, E1000_FEXTNVM7); >+ mac_reg &= ~E1000_FEXTNVM7_DISABLE_SMB_PERST; >+ E1000_WRITE_REG(hw, E1000_FEXTNVM7, mac_reg); >+ >+ if (!force) { >+ hw->phy.ops.release(hw); >+ >+ if (hw->mac.autoneg) >+ e1000_phy_setup_autoneg(hw); >+ else >+ e1000_setup_copper_link_generic(hw); > >- /* Commit ULP changes by starting auto ULP configuration */ >- phy_reg |= I218_ULP_CONFIG1_START; >- e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg); >+ e1000_sw_lcd_config_ich8lan(hw); > >- /* Clear Disable SMBus Release on PERST# in MAC */ >- mac_reg = E1000_READ_REG(hw, E1000_FEXTNVM7); >- mac_reg &= ~E1000_FEXTNVM7_DISABLE_SMB_PERST; >- E1000_WRITE_REG(hw, E1000_FEXTNVM7, mac_reg); >+ e1000_oem_bits_config_ich8lan(hw, true); >+ >+ /* Set ULP state to unknown and return non-zero to >+ * indicate no link (yet) and re-enter on the next LSC >+ * to finish disabling ULP flow. >+ */ >+ hw->dev_spec.ich8lan.ulp_state = >+ e1000_ulp_state_unknown; >+ >+ return 1; >+ } >+ } >+ >+ /* Re-enable Tx */ >+ mac_reg = E1000_READ_REG(hw, E1000_TCTL); >+ mac_reg |= E1000_TCTL_EN; >+ E1000_WRITE_REG(hw, E1000_TCTL, mac_reg); > > release: > hw->phy.ops.release(hw); >@@ -1560,7 +1655,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) > struct e1000_mac_info *mac = &hw->mac; > s32 ret_val, tipg_reg = 0; > u16 emi_addr, emi_val = 0; >- bool link; >+ bool link = false; > u16 phy_reg; > > DEBUGFUNC("e1000_check_for_copper_link_ich8lan"); >@@ -1573,13 +1668,28 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) > if (!mac->get_link_status) > return E1000_SUCCESS; > >- /* First we want to see if the MII Status Register reports >- * link. If so, then we want to get the current speed/duplex >- * of the PHY. >- */ >- ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link); >- if (ret_val) >- return ret_val; >+ if ((hw->mac.type < e1000_pch_lpt) || >+ (hw->device_id == E1000_DEV_ID_PCH_LPT_I217_LM) || >+ (hw->device_id == E1000_DEV_ID_PCH_LPT_I217_V)) { >+ /* First we want to see if the MII Status Register reports >+ * link. If so, then we want to get the current speed/duplex >+ * of the PHY. >+ */ >+ ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link); >+ if (ret_val) >+ return ret_val; >+ } else { >+ /* Check the MAC's STATUS register to determine link state >+ * since the PHY could be inaccessible while in ULP mode. >+ */ >+ link = !!(E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_LU); >+ if (link) >+ ret_val = e1000_disable_ulp_lpt_lp(hw, false); >+ else >+ ret_val = e1000_enable_ulp_lpt_lp(hw, false); >+ if (ret_val) >+ return ret_val; >+ } > > if (hw->mac.type == e1000_pchlan) { > ret_val = e1000_k1_gig_workaround_hv(hw, link); >@@ -1728,7 +1838,6 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) > if (ret_val) > return ret_val; > } >- > /* Clear link partner's EEE ability */ > hw->dev_spec.ich8lan.eee_lp_ability = 0; > >@@ -1749,6 +1858,9 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) > fextnvm6 &= ~E1000_FEXTNVM6_K1_OFF_ENABLE; > > E1000_WRITE_REG(hw, E1000_FEXTNVM6, fextnvm6); >+ >+ /* Configure K0s minimum time */ >+ e1000_configure_k0s_lpt(hw, K1_ENTRY_LATENCY, K1_MIN_TIME); > } > > if (!link) >@@ -4316,7 +4428,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) > (u8)(data >> 8)); > if (ret_val) > break; >- } >+ } > > /* Don't bother writing the segment valid bits if sector > * programming failed. >@@ -6144,3 +6256,44 @@ static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw) > } > } > >+/** >+ * e1000_configure_k0s_lpt - Configure K0s power state >+ * @hw: pointer to the HW structure >+ * @entry_latency: Tx idle period for entering K0s - valid values are 0 to 3. >+ * 0 corresponds to 128ns, each value over 0 doubles the duration. >+ * @min_time: Minimum Tx idle period allowed - valid values are 0 to 4. >+ * 0 corresponds to 128ns, each value over 0 doubles the duration. >+ * >+ * Configure the K1 power state based on the provided parameter. >+ * Assumes semaphore already acquired. >+ * >+ * Success returns 0, Failure returns: >+ * -E1000_ERR_PHY (-2) in case of access error >+ * -E1000_ERR_PARAM (-4) in case of parameters error >+ **/ >+s32 e1000_configure_k0s_lpt(struct e1000_hw *hw, u8 entry_latency, u8 min_time) >+{ >+ s32 ret_val; >+ u16 kmrn_reg = 0; >+ >+ DEBUGFUNC("e1000_configure_k0s_lpt"); >+ >+ if (entry_latency > 3 || min_time > 4) >+ return -E1000_ERR_PARAM; >+ >+ ret_val = e1000_read_kmrn_reg_locked(hw, E1000_KMRNCTRLSTA_K0S_CTRL, >+ &kmrn_reg); >+ if (ret_val) >+ return ret_val; >+ >+ /* for now don't touch the latency */ >+ kmrn_reg &= ~(E1000_KMRNCTRLSTA_K0S_CTRL_MIN_TIME_MASK); >+ kmrn_reg |= ((min_time << E1000_KMRNCTRLSTA_K0S_CTRL_MIN_TIME_SHIFT)); >+ >+ ret_val = e1000_write_kmrn_reg_locked(hw, E1000_KMRNCTRLSTA_K0S_CTRL, >+ kmrn_reg); >+ if (ret_val) >+ return ret_val; >+ >+ return E1000_SUCCESS; >+} >diff --git a/sys/dev/e1000/e1000_ich8lan.h b/sys/dev/e1000/e1000_ich8lan.h >index caff11cbb899..5889cfa7efe7 100644 >--- a/sys/dev/e1000/e1000_ich8lan.h >+++ b/sys/dev/e1000/e1000_ich8lan.h >@@ -330,6 +330,7 @@ > > #define E1000_PCI_VENDOR_ID_REGISTER 0x00 > >+#define E1000_PCI_REVISION_ID_REG 0x08 > void e1000_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw, > bool state); > void e1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw); >@@ -337,6 +338,7 @@ void e1000_gig_downshift_workaround_ich8lan(struct e1000_hw *hw); > void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw); > u32 e1000_resume_workarounds_pchlan(struct e1000_hw *hw); > s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable); >+s32 e1000_configure_k0s_lpt(struct e1000_hw *hw, u8 entry_latency, u8 min_time); > void e1000_copy_rx_addrs_to_phy_ich8lan(struct e1000_hw *hw); > s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable); > s32 e1000_read_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 *data); >diff --git a/sys/dev/e1000/e1000_phy.h b/sys/dev/e1000/e1000_phy.h >index 38c8f9b466ce..28b1c5de2a54 100644 >--- a/sys/dev/e1000/e1000_phy.h >+++ b/sys/dev/e1000/e1000_phy.h >@@ -281,6 +281,15 @@ s32 e1000_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, > #define E1000_KMRNCTRLSTA_K1_CONFIG 0x7 > #define E1000_KMRNCTRLSTA_K1_ENABLE 0x0002 /* enable K1 */ > #define E1000_KMRNCTRLSTA_HD_CTRL 0x10 /* Kumeran HD Control */ >+#define E1000_KMRNCTRLSTA_K0S_CTRL 0x1E /* Kumeran K0s Control */ >+#define E1000_KMRNCTRLSTA_K0S_CTRL_ENTRY_LTNCY_SHIFT 0 >+#define E1000_KMRNCTRLSTA_K0S_CTRL_MIN_TIME_SHIFT 4 >+#define E1000_KMRNCTRLSTA_K0S_CTRL_ENTRY_LTNCY_MASK \ >+ (3 << E1000_KMRNCTRLSTA_K0S_CTRL_ENTRY_LTNCY_SHIFT) >+#define E1000_KMRNCTRLSTA_K0S_CTRL_MIN_TIME_MASK \ >+ (7 << E1000_KMRNCTRLSTA_K0S_CTRL_MIN_TIME_SHIFT) >+#define E1000_KMRNCTRLSTA_OP_MODES 0x1F /* Kumeran Modes of Operation */ >+#define E1000_KMRNCTRLSTA_OP_MODES_LSC2CSC 0x0002 /* change LSC to CSC */ > > #define IFE_PHY_EXTENDED_STATUS_CONTROL 0x10 > #define IFE_PHY_SPECIAL_CONTROL 0x11 /* 100BaseTx PHY Special Ctrl */
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 258153
:
227701
|
228109
| 228110