diff options
author | Bruce Allan <bruce.w.allan@intel.com> | 2011-05-13 03:20:14 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-06-09 23:34:14 -0400 |
commit | 3ebfc7c9a6177794e0a1635483bd64268bed5d3c (patch) | |
tree | fc2b25e45e5eb556040d8beef7262cf9bce251af /drivers/net/e1000e | |
parent | 2b6b168d52aa044363647cfff8bda5cef8068ca3 (diff) |
e1000e: Clear host wakeup bit on 82577/8 without touching PHY page 800
The Host Wakeup Active bit in the PHY Port General Configuration register
(page 769 register 17) must be cleared after every PHY reset to prevent an
unexpected wake signal from the PHY. Originally, this was accomplished by
simply reading the PHY Wakeup Control register on page 800 which clears the
Host Wakeup Active bit as a side-effect. Unfortunately, a hardware bug on
the 82577 and 82578 PHY can cause unexpected behavior when registers on
page 800 are accessed while in gigabit mode.
This patch changes the remaining instances when the Host Wakeup Active bit
needs to be cleared while possibly in gigabit mode by accessing the Port
General Configuration register directly instead of accessing any register
on page 800.
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>
Diffstat (limited to 'drivers/net/e1000e')
-rw-r--r-- | drivers/net/e1000e/e1000.h | 1 | ||||
-rw-r--r-- | drivers/net/e1000e/ich8lan.c | 24 |
2 files changed, 14 insertions, 11 deletions
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 2c05b4f90e68..c1e7f9430546 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h | |||
@@ -104,6 +104,7 @@ struct e1000_info; | |||
104 | (((reg) & ~MAX_PHY_REG_ADDRESS) << (PHY_UPPER_SHIFT - PHY_PAGE_SHIFT))) | 104 | (((reg) & ~MAX_PHY_REG_ADDRESS) << (PHY_UPPER_SHIFT - PHY_PAGE_SHIFT))) |
105 | 105 | ||
106 | /* PHY Wakeup Registers and defines */ | 106 | /* PHY Wakeup Registers and defines */ |
107 | #define BM_PORT_GEN_CFG PHY_REG(BM_PORT_CTRL_PAGE, 17) | ||
107 | #define BM_RCTL PHY_REG(BM_WUC_PAGE, 0) | 108 | #define BM_RCTL PHY_REG(BM_WUC_PAGE, 0) |
108 | #define BM_WUC PHY_REG(BM_WUC_PAGE, 1) | 109 | #define BM_WUC PHY_REG(BM_WUC_PAGE, 1) |
109 | #define BM_WUFC PHY_REG(BM_WUC_PAGE, 2) | 110 | #define BM_WUFC PHY_REG(BM_WUC_PAGE, 2) |
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 1ede6e0f15a5..c1752124f3cd 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c | |||
@@ -1391,14 +1391,11 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) | |||
1391 | ret_val = hw->phy.ops.acquire(hw); | 1391 | ret_val = hw->phy.ops.acquire(hw); |
1392 | if (ret_val) | 1392 | if (ret_val) |
1393 | goto out; | 1393 | goto out; |
1394 | ret_val = hw->phy.ops.read_reg_locked(hw, | 1394 | ret_val = hw->phy.ops.read_reg_locked(hw, BM_PORT_GEN_CFG, &phy_data); |
1395 | PHY_REG(BM_PORT_CTRL_PAGE, 17), | ||
1396 | &phy_data); | ||
1397 | if (ret_val) | 1395 | if (ret_val) |
1398 | goto release; | 1396 | goto release; |
1399 | ret_val = hw->phy.ops.write_reg_locked(hw, | 1397 | ret_val = hw->phy.ops.write_reg_locked(hw, BM_PORT_GEN_CFG, |
1400 | PHY_REG(BM_PORT_CTRL_PAGE, 17), | 1398 | phy_data & 0x00FF); |
1401 | phy_data & 0x00FF); | ||
1402 | release: | 1399 | release: |
1403 | hw->phy.ops.release(hw); | 1400 | hw->phy.ops.release(hw); |
1404 | out: | 1401 | out: |
@@ -1760,9 +1757,12 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw) | |||
1760 | break; | 1757 | break; |
1761 | } | 1758 | } |
1762 | 1759 | ||
1763 | /* Dummy read to clear the phy wakeup bit after lcd reset */ | 1760 | /* Clear the host wakeup bit after lcd reset */ |
1764 | if (hw->mac.type >= e1000_pchlan) | 1761 | if (hw->mac.type >= e1000_pchlan) { |
1765 | e1e_rphy(hw, BM_WUC, ®); | 1762 | e1e_rphy(hw, BM_PORT_GEN_CFG, ®); |
1763 | reg &= ~BM_WUC_HOST_WU_BIT; | ||
1764 | e1e_wphy(hw, BM_PORT_GEN_CFG, reg); | ||
1765 | } | ||
1766 | 1766 | ||
1767 | /* Configure the LCD with the extended configuration region in NVM */ | 1767 | /* Configure the LCD with the extended configuration region in NVM */ |
1768 | ret_val = e1000_sw_lcd_config_ich8lan(hw); | 1768 | ret_val = e1000_sw_lcd_config_ich8lan(hw); |
@@ -3161,11 +3161,13 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw) | |||
3161 | 3161 | ||
3162 | /* | 3162 | /* |
3163 | * The 82578 Rx buffer will stall if wakeup is enabled in host and | 3163 | * The 82578 Rx buffer will stall if wakeup is enabled in host and |
3164 | * the ME. Reading the BM_WUC register will clear the host wakeup bit. | 3164 | * the ME. Disable wakeup by clearing the host wakeup bit. |
3165 | * Reset the phy after disabling host wakeup to reset the Rx buffer. | 3165 | * Reset the phy after disabling host wakeup to reset the Rx buffer. |
3166 | */ | 3166 | */ |
3167 | if (hw->phy.type == e1000_phy_82578) { | 3167 | if (hw->phy.type == e1000_phy_82578) { |
3168 | e1e_rphy(hw, BM_WUC, &i); | 3168 | e1e_rphy(hw, BM_PORT_GEN_CFG, &i); |
3169 | i &= ~BM_WUC_HOST_WU_BIT; | ||
3170 | e1e_wphy(hw, BM_PORT_GEN_CFG, i); | ||
3169 | ret_val = e1000_phy_hw_reset_ich8lan(hw); | 3171 | ret_val = e1000_phy_hw_reset_ich8lan(hw); |
3170 | if (ret_val) | 3172 | if (ret_val) |
3171 | return ret_val; | 3173 | return ret_val; |