aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000e/ich8lan.c
diff options
context:
space:
mode:
authorBruce Allan <bruce.w.allan@intel.com>2010-01-12 20:52:49 -0500
committerDavid S. Miller <davem@davemloft.net>2010-01-13 20:12:46 -0500
commitfddaa1aff881c98f524221236af98ce70dcd04cf (patch)
tree49f21c354f986851ab3650d4a9d274b1ed34cc8e /drivers/net/e1000e/ich8lan.c
parent8c47eaa76600cebc4869a42abb4568925ade6c47 (diff)
e1000e: MDIO slow mode should always be done for 82577
A previous 82577 workaround that set the MDIO access speed to slow mode for every PHY register read/write when the cable is unplugged should instead set the access mode to always be slow before any PHY register access. Since the mode bit gets cleared when the PHY is reset, set the mode after every PHY reset. 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/ich8lan.c')
-rw-r--r--drivers/net/e1000e/ich8lan.c57
1 files changed, 53 insertions, 4 deletions
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index ad08cf3f40c0..c2ea86197503 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -138,6 +138,10 @@
138#define E1000_NVM_K1_CONFIG 0x1B /* NVM K1 Config Word */ 138#define E1000_NVM_K1_CONFIG 0x1B /* NVM K1 Config Word */
139#define E1000_NVM_K1_ENABLE 0x1 /* NVM Enable K1 bit */ 139#define E1000_NVM_K1_ENABLE 0x1 /* NVM Enable K1 bit */
140 140
141/* KMRN Mode Control */
142#define HV_KMRN_MODE_CTRL PHY_REG(769, 16)
143#define HV_KMRN_MDIO_SLOW 0x0400
144
141/* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */ 145/* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */
142/* Offset 04h HSFSTS */ 146/* Offset 04h HSFSTS */
143union ich8_hws_flash_status { 147union ich8_hws_flash_status {
@@ -219,6 +223,7 @@ static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active);
219static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw); 223static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw);
220static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw); 224static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw);
221static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link); 225static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link);
226static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw);
222 227
223static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg) 228static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg)
224{ 229{
@@ -270,7 +275,21 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
270 phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; 275 phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
271 276
272 phy->id = e1000_phy_unknown; 277 phy->id = e1000_phy_unknown;
273 e1000e_get_phy_id(hw); 278 ret_val = e1000e_get_phy_id(hw);
279 if (ret_val)
280 goto out;
281 if ((phy->id == 0) || (phy->id == PHY_REVISION_MASK)) {
282 /*
283 * In case the PHY needs to be in mdio slow mode (eg. 82577),
284 * set slow mode and try to get the PHY id again.
285 */
286 ret_val = e1000_set_mdio_slow_mode_hv(hw);
287 if (ret_val)
288 goto out;
289 ret_val = e1000e_get_phy_id(hw);
290 if (ret_val)
291 goto out;
292 }
274 phy->type = e1000e_get_phy_type_from_id(phy->id); 293 phy->type = e1000e_get_phy_type_from_id(phy->id);
275 294
276 switch (phy->type) { 295 switch (phy->type) {
@@ -292,6 +311,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
292 break; 311 break;
293 } 312 }
294 313
314out:
295 return ret_val; 315 return ret_val;
296} 316}
297 317
@@ -1076,6 +1096,26 @@ out:
1076 1096
1077 1097
1078/** 1098/**
1099 * e1000_set_mdio_slow_mode_hv - Set slow MDIO access mode
1100 * @hw: pointer to the HW structure
1101 **/
1102static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw)
1103{
1104 s32 ret_val;
1105 u16 data;
1106
1107 ret_val = e1e_rphy(hw, HV_KMRN_MODE_CTRL, &data);
1108 if (ret_val)
1109 return ret_val;
1110
1111 data |= HV_KMRN_MDIO_SLOW;
1112
1113 ret_val = e1e_wphy(hw, HV_KMRN_MODE_CTRL, data);
1114
1115 return ret_val;
1116}
1117
1118/**
1079 * e1000_hv_phy_workarounds_ich8lan - A series of Phy workarounds to be 1119 * e1000_hv_phy_workarounds_ich8lan - A series of Phy workarounds to be
1080 * done after every PHY reset. 1120 * done after every PHY reset.
1081 **/ 1121 **/
@@ -1086,6 +1126,13 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw)
1086 if (hw->mac.type != e1000_pchlan) 1126 if (hw->mac.type != e1000_pchlan)
1087 return ret_val; 1127 return ret_val;
1088 1128
1129 /* Set MDIO slow mode before any other MDIO access */
1130 if (hw->phy.type == e1000_phy_82577) {
1131 ret_val = e1000_set_mdio_slow_mode_hv(hw);
1132 if (ret_val)
1133 goto out;
1134 }
1135
1089 if (((hw->phy.type == e1000_phy_82577) && 1136 if (((hw->phy.type == e1000_phy_82577) &&
1090 ((hw->phy.revision == 1) || (hw->phy.revision == 2))) || 1137 ((hw->phy.revision == 1) || (hw->phy.revision == 2))) ||
1091 ((hw->phy.type == e1000_phy_82578) && (hw->phy.revision == 1))) { 1138 ((hw->phy.type == e1000_phy_82578) && (hw->phy.revision == 1))) {
@@ -1184,6 +1231,7 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw)
1184 /* Allow time for h/w to get to a quiescent state after reset */ 1231 /* Allow time for h/w to get to a quiescent state after reset */
1185 mdelay(10); 1232 mdelay(10);
1186 1233
1234 /* Perform any necessary post-reset workarounds */
1187 if (hw->mac.type == e1000_pchlan) { 1235 if (hw->mac.type == e1000_pchlan) {
1188 ret_val = e1000_hv_phy_workarounds_ich8lan(hw); 1236 ret_val = e1000_hv_phy_workarounds_ich8lan(hw);
1189 if (ret_val) 1237 if (ret_val)
@@ -2484,6 +2532,10 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
2484 if (!ret_val) 2532 if (!ret_val)
2485 e1000_release_swflag_ich8lan(hw); 2533 e1000_release_swflag_ich8lan(hw);
2486 2534
2535 /* Perform any necessary post-reset workarounds */
2536 if (hw->mac.type == e1000_pchlan)
2537 ret_val = e1000_hv_phy_workarounds_ich8lan(hw);
2538
2487 if (ctrl & E1000_CTRL_PHY_RST) 2539 if (ctrl & E1000_CTRL_PHY_RST)
2488 ret_val = hw->phy.ops.get_cfg_done(hw); 2540 ret_val = hw->phy.ops.get_cfg_done(hw);
2489 2541
@@ -2528,9 +2580,6 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
2528 kab |= E1000_KABGTXD_BGSQLBIAS; 2580 kab |= E1000_KABGTXD_BGSQLBIAS;
2529 ew32(KABGTXD, kab); 2581 ew32(KABGTXD, kab);
2530 2582
2531 if (hw->mac.type == e1000_pchlan)
2532 ret_val = e1000_hv_phy_workarounds_ich8lan(hw);
2533
2534out: 2583out:
2535 return ret_val; 2584 return ret_val;
2536} 2585}