diff options
author | Bruce Allan <bruce.w.allan@intel.com> | 2010-11-24 01:01:46 -0500 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2010-12-11 01:13:34 -0500 |
commit | 664dc878ed6f0476b875547547a49e06f7a4e73b (patch) | |
tree | ae17b4d149081ed45d344894ba8aff79b3b425e8 | |
parent | ce54afd16d874ac07378a8bb55d26f7f5b613c0e (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.c | 16 | ||||
-rw-r--r-- | drivers/net/e1000e/phy.c | 14 |
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 | ||