diff options
author | Bruce Allan <bruce.w.allan@intel.com> | 2010-09-22 13:15:08 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-09-22 23:41:18 -0400 |
commit | 8395ae8303255b31a8625035fc98391c88b0c257 (patch) | |
tree | 176950114d1368f87949026d626690031e85628f /drivers/net | |
parent | 94e2238969e89f5112297ad2a00103089dde7e8f (diff) |
e1000e: 82577/8/9 issues with device in Sx
When going to Sx, disable gigabit in PHY (e1000_oem_bits_config_ich8lan)
in addition to the MAC before configuring PHY wakeup otherwise the PHY
configuration writes might be missed. Also write the LED configuration
and SMBus address to the PHY registers (e1000_oem_bits_config_ich8lan and
e1000_write_smbus_addr, respectively). The reset is no longer needed
since re-auto-negotiation is forced in e1000_oem_bits_config_ich8lan and
leaving it in causes issues with auto-negotiating the link.
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/net')
-rw-r--r-- | drivers/net/e1000e/ich8lan.c | 47 |
1 files changed, 39 insertions, 8 deletions
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 63930d12711c..822de4830c67 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c | |||
@@ -125,6 +125,7 @@ | |||
125 | 125 | ||
126 | /* SMBus Address Phy Register */ | 126 | /* SMBus Address Phy Register */ |
127 | #define HV_SMB_ADDR PHY_REG(768, 26) | 127 | #define HV_SMB_ADDR PHY_REG(768, 26) |
128 | #define HV_SMB_ADDR_MASK 0x007F | ||
128 | #define HV_SMB_ADDR_PEC_EN 0x0200 | 129 | #define HV_SMB_ADDR_PEC_EN 0x0200 |
129 | #define HV_SMB_ADDR_VALID 0x0080 | 130 | #define HV_SMB_ADDR_VALID 0x0080 |
130 | 131 | ||
@@ -895,6 +896,34 @@ static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw) | |||
895 | } | 896 | } |
896 | 897 | ||
897 | /** | 898 | /** |
899 | * e1000_write_smbus_addr - Write SMBus address to PHY needed during Sx states | ||
900 | * @hw: pointer to the HW structure | ||
901 | * | ||
902 | * Assumes semaphore already acquired. | ||
903 | * | ||
904 | **/ | ||
905 | static s32 e1000_write_smbus_addr(struct e1000_hw *hw) | ||
906 | { | ||
907 | u16 phy_data; | ||
908 | u32 strap = er32(STRAP); | ||
909 | s32 ret_val = 0; | ||
910 | |||
911 | strap &= E1000_STRAP_SMBUS_ADDRESS_MASK; | ||
912 | |||
913 | ret_val = e1000_read_phy_reg_hv_locked(hw, HV_SMB_ADDR, &phy_data); | ||
914 | if (ret_val) | ||
915 | goto out; | ||
916 | |||
917 | phy_data &= ~HV_SMB_ADDR_MASK; | ||
918 | phy_data |= (strap >> E1000_STRAP_SMBUS_ADDRESS_SHIFT); | ||
919 | phy_data |= HV_SMB_ADDR_PEC_EN | HV_SMB_ADDR_VALID; | ||
920 | ret_val = e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR, phy_data); | ||
921 | |||
922 | out: | ||
923 | return ret_val; | ||
924 | } | ||
925 | |||
926 | /** | ||
898 | * e1000_sw_lcd_config_ich8lan - SW-based LCD Configuration | 927 | * e1000_sw_lcd_config_ich8lan - SW-based LCD Configuration |
899 | * @hw: pointer to the HW structure | 928 | * @hw: pointer to the HW structure |
900 | * | 929 | * |
@@ -970,12 +999,7 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) | |||
970 | * When both NVM bits are cleared, SW will configure | 999 | * When both NVM bits are cleared, SW will configure |
971 | * them instead. | 1000 | * them instead. |
972 | */ | 1001 | */ |
973 | data = er32(STRAP); | 1002 | ret_val = e1000_write_smbus_addr(hw); |
974 | data &= E1000_STRAP_SMBUS_ADDRESS_MASK; | ||
975 | reg_data = data >> E1000_STRAP_SMBUS_ADDRESS_SHIFT; | ||
976 | reg_data |= HV_SMB_ADDR_PEC_EN | HV_SMB_ADDR_VALID; | ||
977 | ret_val = e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR, | ||
978 | reg_data); | ||
979 | if (ret_val) | 1003 | if (ret_val) |
980 | goto out; | 1004 | goto out; |
981 | 1005 | ||
@@ -3460,13 +3484,20 @@ void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw) | |||
3460 | void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw) | 3484 | void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw) |
3461 | { | 3485 | { |
3462 | u32 phy_ctrl; | 3486 | u32 phy_ctrl; |
3487 | s32 ret_val; | ||
3463 | 3488 | ||
3464 | phy_ctrl = er32(PHY_CTRL); | 3489 | phy_ctrl = er32(PHY_CTRL); |
3465 | phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU | E1000_PHY_CTRL_GBE_DISABLE; | 3490 | phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU | E1000_PHY_CTRL_GBE_DISABLE; |
3466 | ew32(PHY_CTRL, phy_ctrl); | 3491 | ew32(PHY_CTRL, phy_ctrl); |
3467 | 3492 | ||
3468 | if (hw->mac.type >= e1000_pchlan) | 3493 | if (hw->mac.type >= e1000_pchlan) { |
3469 | e1000_phy_hw_reset_ich8lan(hw); | 3494 | e1000_oem_bits_config_ich8lan(hw, true); |
3495 | ret_val = hw->phy.ops.acquire(hw); | ||
3496 | if (ret_val) | ||
3497 | return; | ||
3498 | e1000_write_smbus_addr(hw); | ||
3499 | hw->phy.ops.release(hw); | ||
3500 | } | ||
3470 | } | 3501 | } |
3471 | 3502 | ||
3472 | /** | 3503 | /** |