diff options
author | Bruce Allan <bruce.w.allan@intel.com> | 2010-09-22 13:17:01 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-09-22 23:41:21 -0400 |
commit | 605c82bab5abe0816e5e32716875c245f89f39da (patch) | |
tree | d674d7ab73faf79957a9c87f850ab678537bde7d /drivers | |
parent | a1ce647378c0262fe72757f989e961b2de6460a5 (diff) |
e1000e: 82579 do not gate auto config of PHY by hardware during nominal use
For non-managed versions of 82579, set the bit that prevents the hardware
from automatically configuring the PHY after resets only when the driver
performs a reset, clear the bit after resets. This is so the hardware can
configure the PHY automatically when the part is reset in a manner that is
not controlled by the driver (e.g. in a virtual environment via PCI FLR)
otherwise the PHY will be mis-configured causing issues such as failing to
link at 1000Mbps.
For managed versions of 82579, keep the previous behavior since the
manageability firmware will handle the PHY configuration.
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-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"); |