aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000e
diff options
context:
space:
mode:
authorBruce Allan <bruce.w.allan@intel.com>2010-01-13 01:53:08 +0000
committerDavid S. Miller <davem@davemloft.net>2010-01-13 17:12:46 -0800
commitbaf86c9d36826fab0160251bbc87dfab3af48a21 (patch)
treedc12219fe6c866cf5fc689eb303cecb4353fcdfb /drivers/net/e1000e
parente1000e: MDIO slow mode should always be done for 82577 (diff)
downloadlinux-dev-baf86c9d36826fab0160251bbc87dfab3af48a21.tar.xz
linux-dev-baf86c9d36826fab0160251bbc87dfab3af48a21.zip
e1000e: workaround link issues on busy hub in half duplex on 82577/82578
This patch removes a delay in hardware after every received packet allowing more time for transmitted packets to go out in between received packets in half duplex. Signed-off-by: Bruce Allan <bruce.w.allan@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/e1000e')
-rw-r--r--drivers/net/e1000e/ich8lan.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index c2ea86197503..8b6ecd127889 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -1122,6 +1122,7 @@ static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw)
static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw)
{
s32 ret_val = 0;
+ u16 phy_data;
if (hw->mac.type != e1000_pchlan)
return ret_val;
@@ -1165,16 +1166,32 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw)
hw->phy.addr = 1;
ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0);
+ hw->phy.ops.release(hw);
if (ret_val)
goto out;
- hw->phy.ops.release(hw);
/*
* Configure the K1 Si workaround during phy reset assuming there is
* link so that it disables K1 if link is in 1Gbps.
*/
ret_val = e1000_k1_gig_workaround_hv(hw, true);
+ if (ret_val)
+ goto out;
+ /* Workaround for link disconnects on a busy hub in half duplex */
+ ret_val = hw->phy.ops.acquire(hw);
+ if (ret_val)
+ goto out;
+ ret_val = hw->phy.ops.read_reg_locked(hw,
+ PHY_REG(BM_PORT_CTRL_PAGE, 17),
+ &phy_data);
+ if (ret_val)
+ goto release;
+ ret_val = hw->phy.ops.write_reg_locked(hw,
+ PHY_REG(BM_PORT_CTRL_PAGE, 17),
+ phy_data & 0x00FF);
+release:
+ hw->phy.ops.release(hw);
out:
return ret_val;
}