aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/e1000e
diff options
context:
space:
mode:
authorDavid Ertman <davidx.m.ertman@intel.com>2014-01-23 01:29:13 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2014-03-08 00:24:55 -0500
commitf7235ef66938ac3db51762c5dbab9f849fa9e795 (patch)
tree21b457d3e22bfed30826ef123fc069b41b175b3d /drivers/net/ethernet/intel/e1000e
parentb485dbaecdee2fec7d973de50a48d284dec532f1 (diff)
e1000e: Resolve issues with Management Engine (ME) briefly blocking PHY resets
On a ME enabled system with the cable out, the driver init flow would generate an erroneous message indicating that resets were being blocked by an active ME session. Cause was ME clearing the semaphore bit to block further PHY resets for up to 50 msec during power-on/cycle. After this interval, ME would re-set the bit and allow PHY resets. To resolve this, change the flow of e1000e_phy_hw_reset_generic() to utilize a delay and retry method. Poll the FWSM register to minimize any extra time added to the flow. If the delay times out at 100ms (checked in 10msec increments), then return the value E1000_BLK_PHY_RESET, as this is the accurate state of the PHY. Attempting to alter just the call to e1000e_phy_hw_reset_generic() in e1000_init_phy_workarounds_pchlan() just caused the problem to move further down the flow. Signed-off-by: Dave Ertman <davidx.m.ertman@intel.com> Acked-by: Bruce W. 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>
Diffstat (limited to 'drivers/net/ethernet/intel/e1000e')
-rw-r--r--drivers/net/ethernet/intel/e1000e/ich8lan.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c
index 42f0f6717511..4f3da87f0cef 100644
--- a/drivers/net/ethernet/intel/e1000e/ich8lan.c
+++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c
@@ -247,6 +247,7 @@ out:
247 **/ 247 **/
248static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw) 248static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw)
249{ 249{
250 struct e1000_adapter *adapter = hw->adapter;
250 u32 mac_reg, fwsm = er32(FWSM); 251 u32 mac_reg, fwsm = er32(FWSM);
251 s32 ret_val; 252 s32 ret_val;
252 253
@@ -349,12 +350,31 @@ static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw)
349 350
350 hw->phy.ops.release(hw); 351 hw->phy.ops.release(hw);
351 if (!ret_val) { 352 if (!ret_val) {
353
354 /* Check to see if able to reset PHY. Print error if not */
355 if (hw->phy.ops.check_reset_block(hw)) {
356 e_err("Reset blocked by ME\n");
357 goto out;
358 }
359
352 /* Reset the PHY before any access to it. Doing so, ensures 360 /* Reset the PHY before any access to it. Doing so, ensures
353 * that the PHY is in a known good state before we read/write 361 * that the PHY is in a known good state before we read/write
354 * PHY registers. The generic reset is sufficient here, 362 * PHY registers. The generic reset is sufficient here,
355 * because we haven't determined the PHY type yet. 363 * because we haven't determined the PHY type yet.
356 */ 364 */
357 ret_val = e1000e_phy_hw_reset_generic(hw); 365 ret_val = e1000e_phy_hw_reset_generic(hw);
366 if (ret_val)
367 goto out;
368
369 /* On a successful reset, possibly need to wait for the PHY
370 * to quiesce to an accessible state before returning control
371 * to the calling function. If the PHY does not quiesce, then
372 * return E1000E_BLK_PHY_RESET, as this is the condition that
373 * the PHY is in.
374 */
375 ret_val = hw->phy.ops.check_reset_block(hw);
376 if (ret_val)
377 e_err("ME blocked access to PHY after reset\n");
358 } 378 }
359 379
360out: 380out:
@@ -1484,11 +1504,13 @@ out:
1484 **/ 1504 **/
1485static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw) 1505static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw)
1486{ 1506{
1487 u32 fwsm; 1507 bool blocked = false;
1508 int i = 0;
1488 1509
1489 fwsm = er32(FWSM); 1510 while ((blocked = !(er32(FWSM) & E1000_ICH_FWSM_RSPCIPHY)) &&
1490 1511 (i++ < 10))
1491 return (fwsm & E1000_ICH_FWSM_RSPCIPHY) ? 0 : E1000_BLK_PHY_RESET; 1512 usleep_range(10000, 20000);
1513 return blocked ? E1000_BLK_PHY_RESET : 0;
1492} 1514}
1493 1515
1494/** 1516/**