diff options
Diffstat (limited to 'drivers/net/ethernet/intel/e1000e/ich8lan.c')
| -rw-r--r-- | drivers/net/ethernet/intel/e1000e/ich8lan.c | 71 |
1 files changed, 70 insertions, 1 deletions
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index dff7bff8b8e0..121a865c7fbd 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c | |||
| @@ -782,6 +782,59 @@ release: | |||
| 782 | } | 782 | } |
| 783 | 783 | ||
| 784 | /** | 784 | /** |
| 785 | * e1000_k1_workaround_lpt_lp - K1 workaround on Lynxpoint-LP | ||
| 786 | * @hw: pointer to the HW structure | ||
| 787 | * @link: link up bool flag | ||
| 788 | * | ||
| 789 | * When K1 is enabled for 1Gbps, the MAC can miss 2 DMA completion indications | ||
| 790 | * preventing further DMA write requests. Workaround the issue by disabling | ||
| 791 | * the de-assertion of the clock request when in 1Gpbs mode. | ||
| 792 | **/ | ||
| 793 | static s32 e1000_k1_workaround_lpt_lp(struct e1000_hw *hw, bool link) | ||
| 794 | { | ||
| 795 | u32 fextnvm6 = er32(FEXTNVM6); | ||
| 796 | s32 ret_val = 0; | ||
| 797 | |||
| 798 | if (link && (er32(STATUS) & E1000_STATUS_SPEED_1000)) { | ||
| 799 | u16 kmrn_reg; | ||
| 800 | |||
| 801 | ret_val = hw->phy.ops.acquire(hw); | ||
| 802 | if (ret_val) | ||
| 803 | return ret_val; | ||
| 804 | |||
| 805 | ret_val = | ||
| 806 | e1000e_read_kmrn_reg_locked(hw, E1000_KMRNCTRLSTA_K1_CONFIG, | ||
| 807 | &kmrn_reg); | ||
| 808 | if (ret_val) | ||
| 809 | goto release; | ||
| 810 | |||
| 811 | ret_val = | ||
| 812 | e1000e_write_kmrn_reg_locked(hw, | ||
| 813 | E1000_KMRNCTRLSTA_K1_CONFIG, | ||
| 814 | kmrn_reg & | ||
| 815 | ~E1000_KMRNCTRLSTA_K1_ENABLE); | ||
| 816 | if (ret_val) | ||
| 817 | goto release; | ||
| 818 | |||
| 819 | usleep_range(10, 20); | ||
| 820 | |||
| 821 | ew32(FEXTNVM6, fextnvm6 | E1000_FEXTNVM6_REQ_PLL_CLK); | ||
| 822 | |||
| 823 | ret_val = | ||
| 824 | e1000e_write_kmrn_reg_locked(hw, | ||
| 825 | E1000_KMRNCTRLSTA_K1_CONFIG, | ||
| 826 | kmrn_reg); | ||
| 827 | release: | ||
| 828 | hw->phy.ops.release(hw); | ||
| 829 | } else { | ||
| 830 | /* clear FEXTNVM6 bit 8 on link down or 10/100 */ | ||
| 831 | ew32(FEXTNVM6, fextnvm6 & ~E1000_FEXTNVM6_REQ_PLL_CLK); | ||
| 832 | } | ||
| 833 | |||
| 834 | return ret_val; | ||
| 835 | } | ||
| 836 | |||
| 837 | /** | ||
| 785 | * e1000_check_for_copper_link_ich8lan - Check for link (Copper) | 838 | * e1000_check_for_copper_link_ich8lan - Check for link (Copper) |
| 786 | * @hw: pointer to the HW structure | 839 | * @hw: pointer to the HW structure |
| 787 | * | 840 | * |
| @@ -818,6 +871,14 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) | |||
| 818 | return ret_val; | 871 | return ret_val; |
| 819 | } | 872 | } |
| 820 | 873 | ||
| 874 | /* Work-around I218 hang issue */ | ||
| 875 | if ((hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPTLP_I218_LM) || | ||
| 876 | (hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPTLP_I218_V)) { | ||
| 877 | ret_val = e1000_k1_workaround_lpt_lp(hw, link); | ||
| 878 | if (ret_val) | ||
| 879 | return ret_val; | ||
| 880 | } | ||
| 881 | |||
| 821 | /* Clear link partner's EEE ability */ | 882 | /* Clear link partner's EEE ability */ |
| 822 | hw->dev_spec.ich8lan.eee_lp_ability = 0; | 883 | hw->dev_spec.ich8lan.eee_lp_ability = 0; |
| 823 | 884 | ||
| @@ -3954,8 +4015,16 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw) | |||
| 3954 | 4015 | ||
| 3955 | phy_ctrl = er32(PHY_CTRL); | 4016 | phy_ctrl = er32(PHY_CTRL); |
| 3956 | phy_ctrl |= E1000_PHY_CTRL_GBE_DISABLE; | 4017 | phy_ctrl |= E1000_PHY_CTRL_GBE_DISABLE; |
| 4018 | |||
| 3957 | if (hw->phy.type == e1000_phy_i217) { | 4019 | if (hw->phy.type == e1000_phy_i217) { |
| 3958 | u16 phy_reg; | 4020 | u16 phy_reg, device_id = hw->adapter->pdev->device; |
| 4021 | |||
| 4022 | if ((device_id == E1000_DEV_ID_PCH_LPTLP_I218_LM) || | ||
| 4023 | (device_id == E1000_DEV_ID_PCH_LPTLP_I218_V)) { | ||
| 4024 | u32 fextnvm6 = er32(FEXTNVM6); | ||
| 4025 | |||
| 4026 | ew32(FEXTNVM6, fextnvm6 & ~E1000_FEXTNVM6_REQ_PLL_CLK); | ||
| 4027 | } | ||
| 3959 | 4028 | ||
| 3960 | ret_val = hw->phy.ops.acquire(hw); | 4029 | ret_val = hw->phy.ops.acquire(hw); |
| 3961 | if (ret_val) | 4030 | if (ret_val) |
