diff options
| -rw-r--r-- | drivers/net/e1000e/ich8lan.c | 77 |
1 files changed, 68 insertions, 9 deletions
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index bb346ae3d9a0..57b5435599ab 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c | |||
| @@ -243,6 +243,7 @@ static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw); | |||
| 243 | static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw); | 243 | static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw); |
| 244 | static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw); | 244 | static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw); |
| 245 | static s32 e1000_k1_workaround_lv(struct e1000_hw *hw); | 245 | static s32 e1000_k1_workaround_lv(struct e1000_hw *hw); |
| 246 | static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate); | ||
| 246 | 247 | ||
| 247 | static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg) | 248 | static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg) |
| 248 | { | 249 | { |
| @@ -278,7 +279,7 @@ static inline void __ew32flash(struct e1000_hw *hw, unsigned long reg, u32 val) | |||
| 278 | static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) | 279 | static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) |
| 279 | { | 280 | { |
| 280 | struct e1000_phy_info *phy = &hw->phy; | 281 | struct e1000_phy_info *phy = &hw->phy; |
| 281 | u32 ctrl; | 282 | u32 ctrl, fwsm; |
| 282 | s32 ret_val = 0; | 283 | s32 ret_val = 0; |
| 283 | 284 | ||
| 284 | phy->addr = 1; | 285 | phy->addr = 1; |
| @@ -300,7 +301,8 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) | |||
| 300 | * disabled, then toggle the LANPHYPC Value bit to force | 301 | * disabled, then toggle the LANPHYPC Value bit to force |
| 301 | * the interconnect to PCIe mode. | 302 | * the interconnect to PCIe mode. |
| 302 | */ | 303 | */ |
| 303 | if (!(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) { | 304 | fwsm = er32(FWSM); |
| 305 | if (!(fwsm & E1000_ICH_FWSM_FW_VALID)) { | ||
| 304 | ctrl = er32(CTRL); | 306 | ctrl = er32(CTRL); |
| 305 | ctrl |= E1000_CTRL_LANPHYPC_OVERRIDE; | 307 | ctrl |= E1000_CTRL_LANPHYPC_OVERRIDE; |
| 306 | ctrl &= ~E1000_CTRL_LANPHYPC_VALUE; | 308 | ctrl &= ~E1000_CTRL_LANPHYPC_VALUE; |
| @@ -309,6 +311,13 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) | |||
| 309 | ctrl &= ~E1000_CTRL_LANPHYPC_OVERRIDE; | 311 | ctrl &= ~E1000_CTRL_LANPHYPC_OVERRIDE; |
| 310 | ew32(CTRL, ctrl); | 312 | ew32(CTRL, ctrl); |
| 311 | msleep(50); | 313 | msleep(50); |
| 314 | |||
| 315 | /* | ||
| 316 | * Gate automatic PHY configuration by hardware on | ||
| 317 | * non-managed 82579 | ||
| 318 | */ | ||
| 319 | if (hw->mac.type == e1000_pch2lan) | ||
| 320 | e1000_gate_hw_phy_config_ich8lan(hw, true); | ||
| 312 | } | 321 | } |
| 313 | 322 | ||
| 314 | /* | 323 | /* |
| @@ -321,6 +330,13 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) | |||
| 321 | if (ret_val) | 330 | if (ret_val) |
| 322 | goto out; | 331 | goto out; |
| 323 | 332 | ||
| 333 | /* Ungate automatic PHY configuration on non-managed 82579 */ | ||
| 334 | if ((hw->mac.type == e1000_pch2lan) && | ||
| 335 | !(fwsm & E1000_ICH_FWSM_FW_VALID)) { | ||
| 336 | msleep(10); | ||
| 337 | e1000_gate_hw_phy_config_ich8lan(hw, false); | ||
| 338 | } | ||
| 339 | |||
| 324 | phy->id = e1000_phy_unknown; | 340 | phy->id = e1000_phy_unknown; |
| 325 | ret_val = e1000e_get_phy_id(hw); | 341 | ret_val = e1000e_get_phy_id(hw); |
| 326 | if (ret_val) | 342 | if (ret_val) |
| @@ -567,13 +583,10 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter) | |||
| 567 | if (mac->type == e1000_ich8lan) | 583 | if (mac->type == e1000_ich8lan) |
| 568 | e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, true); | 584 | e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, true); |
| 569 | 585 | ||
| 570 | /* Disable PHY configuration by hardware, config by software */ | 586 | /* Gate automatic PHY configuration by hardware on managed 82579 */ |
| 571 | if (mac->type == e1000_pch2lan) { | 587 | if ((mac->type == e1000_pch2lan) && |
| 572 | u32 extcnf_ctrl = er32(EXTCNF_CTRL); | 588 | (er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) |
| 573 | 589 | e1000_gate_hw_phy_config_ich8lan(hw, true); | |
| 574 | extcnf_ctrl |= E1000_EXTCNF_CTRL_GATE_PHY_CFG; | ||
| 575 | ew32(EXTCNF_CTRL, extcnf_ctrl); | ||
| 576 | } | ||
| 577 | 590 | ||
| 578 | return 0; | 591 | return 0; |
| 579 | } | 592 | } |
| @@ -1621,6 +1634,32 @@ out: | |||
| 1621 | } | 1634 | } |
| 1622 | 1635 | ||
| 1623 | /** | 1636 | /** |
| 1637 | * e1000_gate_hw_phy_config_ich8lan - disable PHY config via hardware | ||
| 1638 | * @hw: pointer to the HW structure | ||
| 1639 | * @gate: boolean set to true to gate, false to ungate | ||
| 1640 | * | ||
| 1641 | * Gate/ungate the automatic PHY configuration via hardware; perform | ||
| 1642 | * the configuration via software instead. | ||
| 1643 | **/ | ||
| 1644 | static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate) | ||
| 1645 | { | ||
| 1646 | u32 extcnf_ctrl; | ||
| 1647 | |||
| 1648 | if (hw->mac.type != e1000_pch2lan) | ||
| 1649 | return; | ||
| 1650 | |||
| 1651 | extcnf_ctrl = er32(EXTCNF_CTRL); | ||
| 1652 | |||
| 1653 | if (gate) | ||
| 1654 | extcnf_ctrl |= E1000_EXTCNF_CTRL_GATE_PHY_CFG; | ||
| 1655 | else | ||
| 1656 | extcnf_ctrl &= ~E1000_EXTCNF_CTRL_GATE_PHY_CFG; | ||
| 1657 | |||
| 1658 | ew32(EXTCNF_CTRL, extcnf_ctrl); | ||
| 1659 | return; | ||
| 1660 | } | ||
| 1661 | |||
| 1662 | /** | ||
| 1624 | * e1000_lan_init_done_ich8lan - Check for PHY config completion | 1663 | * e1000_lan_init_done_ich8lan - Check for PHY config completion |
| 1625 | * @hw: pointer to the HW structure | 1664 | * @hw: pointer to the HW structure |
| 1626 | * | 1665 | * |
| @@ -1695,6 +1734,13 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw) | |||
| 1695 | /* Configure the LCD with the OEM bits in NVM */ | 1734 | /* Configure the LCD with the OEM bits in NVM */ |
| 1696 | ret_val = e1000_oem_bits_config_ich8lan(hw, true); | 1735 | ret_val = e1000_oem_bits_config_ich8lan(hw, true); |
| 1697 | 1736 | ||
| 1737 | /* Ungate automatic PHY configuration on non-managed 82579 */ | ||
| 1738 | if ((hw->mac.type == e1000_pch2lan) && | ||
| 1739 | !(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) { | ||
| 1740 | msleep(10); | ||
| 1741 | e1000_gate_hw_phy_config_ich8lan(hw, false); | ||
| 1742 | } | ||
| 1743 | |||
| 1698 | out: | 1744 | out: |
| 1699 | return ret_val; | 1745 | return ret_val; |
| 1700 | } | 1746 | } |
| @@ -1711,6 +1757,11 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) | |||
| 1711 | { | 1757 | { |
| 1712 | s32 ret_val = 0; | 1758 | s32 ret_val = 0; |
| 1713 | 1759 | ||
| 1760 | /* Gate automatic PHY configuration by hardware on non-managed 82579 */ | ||
| 1761 | if ((hw->mac.type == e1000_pch2lan) && | ||
| 1762 | !(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) | ||
| 1763 | e1000_gate_hw_phy_config_ich8lan(hw, true); | ||
| 1764 | |||
| 1714 | ret_val = e1000e_phy_hw_reset_generic(hw); | 1765 | ret_val = e1000e_phy_hw_reset_generic(hw); |
| 1715 | if (ret_val) | 1766 | if (ret_val) |
| 1716 | goto out; | 1767 | goto out; |
| @@ -2975,6 +3026,14 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) | |||
| 2975 | * external PHY is reset. | 3026 | * external PHY is reset. |
| 2976 | */ | 3027 | */ |
| 2977 | ctrl |= E1000_CTRL_PHY_RST; | 3028 | ctrl |= E1000_CTRL_PHY_RST; |
| 3029 | |||
| 3030 | /* | ||
| 3031 | * Gate automatic PHY configuration by hardware on | ||
| 3032 | * non-managed 82579 | ||
| 3033 | */ | ||
| 3034 | if ((hw->mac.type == e1000_pch2lan) && | ||
| 3035 | !(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) | ||
| 3036 | e1000_gate_hw_phy_config_ich8lan(hw, true); | ||
| 2978 | } | 3037 | } |
| 2979 | ret_val = e1000_acquire_swflag_ich8lan(hw); | 3038 | ret_val = e1000_acquire_swflag_ich8lan(hw); |
| 2980 | e_dbg("Issuing a global reset to ich8lan\n"); | 3039 | e_dbg("Issuing a global reset to ich8lan\n"); |
