aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBruce Allan <bruce.w.allan@intel.com>2010-11-24 01:01:46 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2010-12-11 01:13:34 -0500
commit664dc878ed6f0476b875547547a49e06f7a4e73b (patch)
treeae17b4d149081ed45d344894ba8aff79b3b425e8
parentce54afd16d874ac07378a8bb55d26f7f5b613c0e (diff)
e1000e: 82579 PHY incorrectly identified during init
During init, reading the 2 PHY ID registers back-to-back in the default fast mode could return invalid data (all F's) and in slow mode could return data to the second read the data from the first read. To resolve the issue in fast mode, set to slow mode before any PHY accesses; to resolve the issue in slow mode, put in a delay for every 82579 PHY access. Since this PHY is currently only paired with the pch2lan MAC and the PHY type is not known before the first PHY access which can fail this way, check for this based on MAC-type. 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>
-rw-r--r--drivers/net/e1000e/ich8lan.c16
-rw-r--r--drivers/net/e1000e/phy.c14
2 files changed, 25 insertions, 5 deletions
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index d7fc930d1aa5..5080372b0fd7 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -338,12 +338,17 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
338 } 338 }
339 339
340 phy->id = e1000_phy_unknown; 340 phy->id = e1000_phy_unknown;
341 ret_val = e1000e_get_phy_id(hw); 341 switch (hw->mac.type) {
342 if (ret_val) 342 default:
343 goto out; 343 ret_val = e1000e_get_phy_id(hw);
344 if ((phy->id == 0) || (phy->id == PHY_REVISION_MASK)) { 344 if (ret_val)
345 goto out;
346 if ((phy->id != 0) && (phy->id != PHY_REVISION_MASK))
347 break;
348 /* fall-through */
349 case e1000_pch2lan:
345 /* 350 /*
346 * In case the PHY needs to be in mdio slow mode (eg. 82577), 351 * In case the PHY needs to be in mdio slow mode,
347 * set slow mode and try to get the PHY id again. 352 * set slow mode and try to get the PHY id again.
348 */ 353 */
349 ret_val = e1000_set_mdio_slow_mode_hv(hw); 354 ret_val = e1000_set_mdio_slow_mode_hv(hw);
@@ -352,6 +357,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
352 ret_val = e1000e_get_phy_id(hw); 357 ret_val = e1000e_get_phy_id(hw);
353 if (ret_val) 358 if (ret_val)
354 goto out; 359 goto out;
360 break;
355 } 361 }
356 phy->type = e1000e_get_phy_type_from_id(phy->id); 362 phy->type = e1000e_get_phy_type_from_id(phy->id);
357 363
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c
index 6ad90ccb4bab..95da38693b77 100644
--- a/drivers/net/e1000e/phy.c
+++ b/drivers/net/e1000e/phy.c
@@ -226,6 +226,13 @@ s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
226 } 226 }
227 *data = (u16) mdic; 227 *data = (u16) mdic;
228 228
229 /*
230 * Allow some time after each MDIC transaction to avoid
231 * reading duplicate data in the next MDIC transaction.
232 */
233 if (hw->mac.type == e1000_pch2lan)
234 udelay(100);
235
229 return 0; 236 return 0;
230} 237}
231 238
@@ -279,6 +286,13 @@ s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
279 return -E1000_ERR_PHY; 286 return -E1000_ERR_PHY;
280 } 287 }
281 288
289 /*
290 * Allow some time after each MDIC transaction to avoid
291 * reading duplicate data in the next MDIC transaction.
292 */
293 if (hw->mac.type == e1000_pch2lan)
294 udelay(100);
295
282 return 0; 296 return 0;
283} 297}
284 298