diff options
author | Bruce Allan <bruce.w.allan@intel.com> | 2012-04-12 23:16:22 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2012-05-02 04:58:45 -0400 |
commit | cb17aab916b0467faecf241c9b3b396b6da045d9 (patch) | |
tree | bdfb68caca112d9bc2408cd7edcf651356d16508 /drivers/net/ethernet/intel/e1000e/ich8lan.c | |
parent | 62bc813e48aef39c187bb426ddd5441862f1d8d1 (diff) |
e1000e: PHY initialization flow changes for 82577/8/9
The PHY initialization flows and assorted workarounds for 82577/8/9 done
during driver load and resume from Sx should be the same yet they are not.
Combine the current flows/workarounds into a common set of functions that
are called during the different code paths.
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/e1000e/ich8lan.c')
-rw-r--r-- | drivers/net/ethernet/intel/e1000e/ich8lan.c | 247 |
1 files changed, 146 insertions, 101 deletions
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 2506ee275312..4c8b0fb6534f 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c | |||
@@ -287,25 +287,126 @@ static inline void __ew32flash(struct e1000_hw *hw, unsigned long reg, u32 val) | |||
287 | #define ew16flash(reg, val) __ew16flash(hw, (reg), (val)) | 287 | #define ew16flash(reg, val) __ew16flash(hw, (reg), (val)) |
288 | #define ew32flash(reg, val) __ew32flash(hw, (reg), (val)) | 288 | #define ew32flash(reg, val) __ew32flash(hw, (reg), (val)) |
289 | 289 | ||
290 | static void e1000_toggle_lanphypc_value_ich8lan(struct e1000_hw *hw) | 290 | /** |
291 | * e1000_phy_is_accessible_pchlan - Check if able to access PHY registers | ||
292 | * @hw: pointer to the HW structure | ||
293 | * | ||
294 | * Test access to the PHY registers by reading the PHY ID registers. If | ||
295 | * the PHY ID is already known (e.g. resume path) compare it with known ID, | ||
296 | * otherwise assume the read PHY ID is correct if it is valid. | ||
297 | * | ||
298 | * Assumes the sw/fw/hw semaphore is already acquired. | ||
299 | **/ | ||
300 | static bool e1000_phy_is_accessible_pchlan(struct e1000_hw *hw) | ||
291 | { | 301 | { |
292 | u32 reg; | 302 | u16 phy_reg; |
303 | u32 phy_id; | ||
293 | 304 | ||
294 | /* Set Phy Config Counter to 50msec */ | 305 | hw->phy.ops.read_reg_locked(hw, PHY_ID1, &phy_reg); |
295 | reg = er32(FEXTNVM3); | 306 | phy_id = (u32)(phy_reg << 16); |
296 | reg &= ~E1000_FEXTNVM3_PHY_CFG_COUNTER_MASK; | 307 | hw->phy.ops.read_reg_locked(hw, PHY_ID2, &phy_reg); |
297 | reg |= E1000_FEXTNVM3_PHY_CFG_COUNTER_50MSEC; | 308 | phy_id |= (u32)(phy_reg & PHY_REVISION_MASK); |
298 | ew32(FEXTNVM3, reg); | 309 | |
299 | 310 | if (hw->phy.id) { | |
300 | /* Toggle LANPHYPC Value bit */ | 311 | if (hw->phy.id == phy_id) |
301 | reg = er32(CTRL); | 312 | return true; |
302 | reg |= E1000_CTRL_LANPHYPC_OVERRIDE; | 313 | } else { |
303 | reg &= ~E1000_CTRL_LANPHYPC_VALUE; | 314 | if ((phy_id != 0) && (phy_id != PHY_REVISION_MASK)) |
304 | ew32(CTRL, reg); | 315 | hw->phy.id = phy_id; |
305 | e1e_flush(); | 316 | return true; |
306 | udelay(10); | 317 | } |
307 | reg &= ~E1000_CTRL_LANPHYPC_OVERRIDE; | 318 | |
308 | ew32(CTRL, reg); | 319 | return false; |
320 | } | ||
321 | |||
322 | /** | ||
323 | * e1000_init_phy_workarounds_pchlan - PHY initialization workarounds | ||
324 | * @hw: pointer to the HW structure | ||
325 | * | ||
326 | * Workarounds/flow necessary for PHY initialization during driver load | ||
327 | * and resume paths. | ||
328 | **/ | ||
329 | static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw) | ||
330 | { | ||
331 | u32 mac_reg, fwsm = er32(FWSM); | ||
332 | s32 ret_val; | ||
333 | |||
334 | ret_val = hw->phy.ops.acquire(hw); | ||
335 | if (ret_val) { | ||
336 | e_dbg("Failed to initialize PHY flow\n"); | ||
337 | return ret_val; | ||
338 | } | ||
339 | |||
340 | /* | ||
341 | * The MAC-PHY interconnect may be in SMBus mode. If the PHY is | ||
342 | * inaccessible and resetting the PHY is not blocked, toggle the | ||
343 | * LANPHYPC Value bit to force the interconnect to PCIe mode. | ||
344 | */ | ||
345 | switch (hw->mac.type) { | ||
346 | case e1000_pch2lan: | ||
347 | /* | ||
348 | * Gate automatic PHY configuration by hardware on | ||
349 | * non-managed 82579 | ||
350 | */ | ||
351 | if (!(fwsm & E1000_ICH_FWSM_FW_VALID)) | ||
352 | e1000_gate_hw_phy_config_ich8lan(hw, true); | ||
353 | |||
354 | if (e1000_phy_is_accessible_pchlan(hw)) | ||
355 | break; | ||
356 | |||
357 | /* fall-through */ | ||
358 | case e1000_pchlan: | ||
359 | if ((hw->mac.type == e1000_pchlan) && | ||
360 | (fwsm & E1000_ICH_FWSM_FW_VALID)) | ||
361 | break; | ||
362 | |||
363 | if (hw->phy.ops.check_reset_block(hw)) { | ||
364 | e_dbg("Required LANPHYPC toggle blocked by ME\n"); | ||
365 | break; | ||
366 | } | ||
367 | |||
368 | e_dbg("Toggling LANPHYPC\n"); | ||
369 | |||
370 | /* Set Phy Config Counter to 50msec */ | ||
371 | mac_reg = er32(FEXTNVM3); | ||
372 | mac_reg &= ~E1000_FEXTNVM3_PHY_CFG_COUNTER_MASK; | ||
373 | mac_reg |= E1000_FEXTNVM3_PHY_CFG_COUNTER_50MSEC; | ||
374 | ew32(FEXTNVM3, mac_reg); | ||
375 | |||
376 | /* Toggle LANPHYPC Value bit */ | ||
377 | mac_reg = er32(CTRL); | ||
378 | mac_reg |= E1000_CTRL_LANPHYPC_OVERRIDE; | ||
379 | mac_reg &= ~E1000_CTRL_LANPHYPC_VALUE; | ||
380 | ew32(CTRL, mac_reg); | ||
381 | e1e_flush(); | ||
382 | udelay(10); | ||
383 | mac_reg &= ~E1000_CTRL_LANPHYPC_OVERRIDE; | ||
384 | ew32(CTRL, mac_reg); | ||
385 | e1e_flush(); | ||
386 | msleep(50); | ||
387 | break; | ||
388 | default: | ||
389 | break; | ||
390 | } | ||
391 | |||
392 | hw->phy.ops.release(hw); | ||
393 | |||
394 | /* | ||
395 | * Reset the PHY before any access to it. Doing so, ensures | ||
396 | * that the PHY is in a known good state before we read/write | ||
397 | * PHY registers. The generic reset is sufficient here, | ||
398 | * because we haven't determined the PHY type yet. | ||
399 | */ | ||
400 | ret_val = e1000e_phy_hw_reset_generic(hw); | ||
401 | |||
402 | /* Ungate automatic PHY configuration on non-managed 82579 */ | ||
403 | if ((hw->mac.type == e1000_pch2lan) && | ||
404 | !(fwsm & E1000_ICH_FWSM_FW_VALID)) { | ||
405 | usleep_range(10000, 20000); | ||
406 | e1000_gate_hw_phy_config_ich8lan(hw, false); | ||
407 | } | ||
408 | |||
409 | return ret_val; | ||
309 | } | 410 | } |
310 | 411 | ||
311 | /** | 412 | /** |
@@ -335,65 +436,34 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) | |||
335 | phy->ops.power_down = e1000_power_down_phy_copper_ich8lan; | 436 | phy->ops.power_down = e1000_power_down_phy_copper_ich8lan; |
336 | phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; | 437 | phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; |
337 | 438 | ||
338 | if (!hw->phy.ops.check_reset_block(hw)) { | 439 | phy->id = e1000_phy_unknown; |
339 | u32 fwsm = er32(FWSM); | ||
340 | |||
341 | /* | ||
342 | * The MAC-PHY interconnect may still be in SMBus mode after | ||
343 | * Sx->S0. If resetting the PHY is not blocked, toggle the | ||
344 | * LANPHYPC Value bit to force the interconnect to PCIe mode. | ||
345 | */ | ||
346 | e1000_toggle_lanphypc_value_ich8lan(hw); | ||
347 | msleep(50); | ||
348 | |||
349 | /* | ||
350 | * Gate automatic PHY configuration by hardware on | ||
351 | * non-managed 82579 | ||
352 | */ | ||
353 | if ((hw->mac.type == e1000_pch2lan) && | ||
354 | !(fwsm & E1000_ICH_FWSM_FW_VALID)) | ||
355 | e1000_gate_hw_phy_config_ich8lan(hw, true); | ||
356 | |||
357 | /* | ||
358 | * Reset the PHY before any access to it. Doing so, ensures | ||
359 | * that the PHY is in a known good state before we read/write | ||
360 | * PHY registers. The generic reset is sufficient here, | ||
361 | * because we haven't determined the PHY type yet. | ||
362 | */ | ||
363 | ret_val = e1000e_phy_hw_reset_generic(hw); | ||
364 | if (ret_val) | ||
365 | return ret_val; | ||
366 | 440 | ||
367 | /* Ungate automatic PHY configuration on non-managed 82579 */ | 441 | ret_val = e1000_init_phy_workarounds_pchlan(hw); |
368 | if ((hw->mac.type == e1000_pch2lan) && | 442 | if (ret_val) |
369 | !(fwsm & E1000_ICH_FWSM_FW_VALID)) { | 443 | return ret_val; |
370 | usleep_range(10000, 20000); | ||
371 | e1000_gate_hw_phy_config_ich8lan(hw, false); | ||
372 | } | ||
373 | } | ||
374 | 444 | ||
375 | phy->id = e1000_phy_unknown; | 445 | if (phy->id == e1000_phy_unknown) |
376 | switch (hw->mac.type) { | 446 | switch (hw->mac.type) { |
377 | default: | 447 | default: |
378 | ret_val = e1000e_get_phy_id(hw); | 448 | ret_val = e1000e_get_phy_id(hw); |
379 | if (ret_val) | 449 | if (ret_val) |
380 | return ret_val; | 450 | return ret_val; |
381 | if ((phy->id != 0) && (phy->id != PHY_REVISION_MASK)) | 451 | if ((phy->id != 0) && (phy->id != PHY_REVISION_MASK)) |
452 | break; | ||
453 | /* fall-through */ | ||
454 | case e1000_pch2lan: | ||
455 | /* | ||
456 | * In case the PHY needs to be in mdio slow mode, | ||
457 | * set slow mode and try to get the PHY id again. | ||
458 | */ | ||
459 | ret_val = e1000_set_mdio_slow_mode_hv(hw); | ||
460 | if (ret_val) | ||
461 | return ret_val; | ||
462 | ret_val = e1000e_get_phy_id(hw); | ||
463 | if (ret_val) | ||
464 | return ret_val; | ||
382 | break; | 465 | break; |
383 | /* fall-through */ | 466 | } |
384 | case e1000_pch2lan: | ||
385 | /* | ||
386 | * In case the PHY needs to be in mdio slow mode, | ||
387 | * set slow mode and try to get the PHY id again. | ||
388 | */ | ||
389 | ret_val = e1000_set_mdio_slow_mode_hv(hw); | ||
390 | if (ret_val) | ||
391 | return ret_val; | ||
392 | ret_val = e1000e_get_phy_id(hw); | ||
393 | if (ret_val) | ||
394 | return ret_val; | ||
395 | break; | ||
396 | } | ||
397 | phy->type = e1000e_get_phy_type_from_id(phy->id); | 467 | phy->type = e1000e_get_phy_type_from_id(phy->id); |
398 | 468 | ||
399 | switch (phy->type) { | 469 | switch (phy->type) { |
@@ -3736,41 +3806,16 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw) | |||
3736 | **/ | 3806 | **/ |
3737 | void e1000_resume_workarounds_pchlan(struct e1000_hw *hw) | 3807 | void e1000_resume_workarounds_pchlan(struct e1000_hw *hw) |
3738 | { | 3808 | { |
3739 | u16 phy_id1, phy_id2; | ||
3740 | s32 ret_val; | 3809 | s32 ret_val; |
3741 | 3810 | ||
3742 | if ((hw->mac.type != e1000_pch2lan) || | 3811 | if (hw->mac.type < e1000_pch2lan) |
3743 | hw->phy.ops.check_reset_block(hw)) | ||
3744 | return; | 3812 | return; |
3745 | 3813 | ||
3746 | ret_val = hw->phy.ops.acquire(hw); | 3814 | ret_val = e1000_init_phy_workarounds_pchlan(hw); |
3747 | if (ret_val) { | 3815 | if (ret_val) { |
3748 | e_dbg("Failed to acquire PHY semaphore in resume\n"); | 3816 | e_dbg("Failed to init PHY flow ret_val=%d\n", ret_val); |
3749 | return; | 3817 | return; |
3750 | } | 3818 | } |
3751 | |||
3752 | /* Test access to the PHY registers by reading the ID regs */ | ||
3753 | ret_val = hw->phy.ops.read_reg_locked(hw, PHY_ID1, &phy_id1); | ||
3754 | if (ret_val) | ||
3755 | goto release; | ||
3756 | ret_val = hw->phy.ops.read_reg_locked(hw, PHY_ID2, &phy_id2); | ||
3757 | if (ret_val) | ||
3758 | goto release; | ||
3759 | |||
3760 | if (hw->phy.id == ((u32)(phy_id1 << 16) | | ||
3761 | (u32)(phy_id2 & PHY_REVISION_MASK))) | ||
3762 | goto release; | ||
3763 | |||
3764 | e1000_toggle_lanphypc_value_ich8lan(hw); | ||
3765 | |||
3766 | hw->phy.ops.release(hw); | ||
3767 | msleep(50); | ||
3768 | e1000_phy_hw_reset(hw); | ||
3769 | msleep(50); | ||
3770 | return; | ||
3771 | |||
3772 | release: | ||
3773 | hw->phy.ops.release(hw); | ||
3774 | } | 3819 | } |
3775 | 3820 | ||
3776 | /** | 3821 | /** |