summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/e1000e/phy.c
diff options
context:
space:
mode:
authorMatthew Vick <matthew.vick@intel.com>2012-04-25 07:25:18 +0000
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2012-05-03 02:26:48 -0700
commit885fe7be4b23d8b9e46cdd87148cefbec926868b (patch)
tree57e0d7b8457bdf61a2a87ef451c7edc21178b8e4 /drivers/net/ethernet/intel/e1000e/phy.c
parentf1430d698d0caa743af61f72fd539726055718d3 (diff)
downloadlinux-885fe7be4b23d8b9e46cdd87148cefbec926868b.tar.bz2
e1000e: Resolve intermittent negotiation issue on 82574/82583.
For 82574 and 82583 devices, resolve an intermittent link issue where the link negotiates to 100Mbps rather than 1Gbps when powering off the PHY and powering on the PHY after several seconds. Signed-off-by: Matthew Vick <matthew.vick@intel.com> Tested-by: Aaron Brown <aaron.f.brown@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/e1000e/phy.c')
-rw-r--r--drivers/net/ethernet/intel/e1000e/phy.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/drivers/net/ethernet/intel/e1000e/phy.c b/drivers/net/ethernet/intel/e1000e/phy.c
index bd5ef64b3003..ad22b8c8abd2 100644
--- a/drivers/net/ethernet/intel/e1000e/phy.c
+++ b/drivers/net/ethernet/intel/e1000e/phy.c
@@ -722,8 +722,24 @@ s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw)
phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
/* Enable downshift on BM (disabled by default) */
- if (phy->type == e1000_phy_bm)
+ if (phy->type == e1000_phy_bm) {
+ /* For 82574/82583, first disable then enable downshift */
+ if (phy->id == BME1000_E_PHY_ID_R2) {
+ phy_data &= ~BME1000_PSCR_ENABLE_DOWNSHIFT;
+ ret_val = e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL,
+ phy_data);
+ if (ret_val)
+ return ret_val;
+ /* Commit the changes. */
+ ret_val = e1000e_commit_phy(hw);
+ if (ret_val) {
+ e_dbg("Error committing the PHY changes\n");
+ return ret_val;
+ }
+ }
+
phy_data |= BME1000_PSCR_ENABLE_DOWNSHIFT;
+ }
ret_val = e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
if (ret_val)