diff options
author | Bruce Allan <bruce.w.allan@intel.com> | 2010-01-12 20:52:49 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-01-13 20:12:46 -0500 |
commit | fddaa1aff881c98f524221236af98ce70dcd04cf (patch) | |
tree | 49f21c354f986851ab3650d4a9d274b1ed34cc8e /drivers/net/e1000e/phy.c | |
parent | 8c47eaa76600cebc4869a42abb4568925ade6c47 (diff) |
e1000e: MDIO slow mode should always be done for 82577
A previous 82577 workaround that set the MDIO access speed to slow mode for
every PHY register read/write when the cable is unplugged should instead
set the access mode to always be slow before any PHY register access.
Since the mode bit gets cleared when the PHY is reset, set the mode after
every PHY reset.
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/e1000e/phy.c')
-rw-r--r-- | drivers/net/e1000e/phy.c | 85 |
1 files changed, 0 insertions, 85 deletions
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c index 55a2c0acfee7..7f3ceb9dad6a 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c | |||
@@ -152,32 +152,9 @@ s32 e1000e_get_phy_id(struct e1000_hw *hw) | |||
152 | if (phy->id != 0 && phy->id != PHY_REVISION_MASK) | 152 | if (phy->id != 0 && phy->id != PHY_REVISION_MASK) |
153 | goto out; | 153 | goto out; |
154 | 154 | ||
155 | /* | ||
156 | * If the PHY ID is still unknown, we may have an 82577 | ||
157 | * without link. We will try again after setting Slow MDIC | ||
158 | * mode. No harm in trying again in this case since the PHY | ||
159 | * ID is unknown at this point anyway. | ||
160 | */ | ||
161 | ret_val = phy->ops.acquire(hw); | ||
162 | if (ret_val) | ||
163 | goto out; | ||
164 | ret_val = e1000_set_mdio_slow_mode_hv(hw, true); | ||
165 | if (ret_val) | ||
166 | goto out; | ||
167 | phy->ops.release(hw); | ||
168 | |||
169 | retry_count++; | 155 | retry_count++; |
170 | } | 156 | } |
171 | out: | 157 | out: |
172 | /* Revert to MDIO fast mode, if applicable */ | ||
173 | if (retry_count) { | ||
174 | ret_val = phy->ops.acquire(hw); | ||
175 | if (ret_val) | ||
176 | return ret_val; | ||
177 | ret_val = e1000_set_mdio_slow_mode_hv(hw, false); | ||
178 | phy->ops.release(hw); | ||
179 | } | ||
180 | |||
181 | return ret_val; | 158 | return ret_val; |
182 | } | 159 | } |
183 | 160 | ||
@@ -2791,38 +2768,6 @@ static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active) | |||
2791 | } | 2768 | } |
2792 | 2769 | ||
2793 | /** | 2770 | /** |
2794 | * e1000_set_mdio_slow_mode_hv - Set slow MDIO access mode | ||
2795 | * @hw: pointer to the HW structure | ||
2796 | * @slow: true for slow mode, false for normal mode | ||
2797 | * | ||
2798 | * Assumes semaphore already acquired. | ||
2799 | **/ | ||
2800 | s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow) | ||
2801 | { | ||
2802 | s32 ret_val = 0; | ||
2803 | u16 data = 0; | ||
2804 | |||
2805 | /* Set MDIO mode - page 769, register 16: 0x2580==slow, 0x2180==fast */ | ||
2806 | hw->phy.addr = 1; | ||
2807 | ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, | ||
2808 | (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT)); | ||
2809 | if (ret_val) | ||
2810 | goto out; | ||
2811 | |||
2812 | ret_val = e1000e_write_phy_reg_mdic(hw, BM_CS_CTRL1, | ||
2813 | (0x2180 | (slow << 10))); | ||
2814 | if (ret_val) | ||
2815 | goto out; | ||
2816 | |||
2817 | /* dummy read when reverting to fast mode - throw away result */ | ||
2818 | if (!slow) | ||
2819 | ret_val = e1000e_read_phy_reg_mdic(hw, BM_CS_CTRL1, &data); | ||
2820 | |||
2821 | out: | ||
2822 | return ret_val; | ||
2823 | } | ||
2824 | |||
2825 | /** | ||
2826 | * __e1000_read_phy_reg_hv - Read HV PHY register | 2771 | * __e1000_read_phy_reg_hv - Read HV PHY register |
2827 | * @hw: pointer to the HW structure | 2772 | * @hw: pointer to the HW structure |
2828 | * @offset: register offset to be read | 2773 | * @offset: register offset to be read |
@@ -2839,7 +2784,6 @@ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data, | |||
2839 | s32 ret_val; | 2784 | s32 ret_val; |
2840 | u16 page = BM_PHY_REG_PAGE(offset); | 2785 | u16 page = BM_PHY_REG_PAGE(offset); |
2841 | u16 reg = BM_PHY_REG_NUM(offset); | 2786 | u16 reg = BM_PHY_REG_NUM(offset); |
2842 | bool in_slow_mode = false; | ||
2843 | 2787 | ||
2844 | if (!locked) { | 2788 | if (!locked) { |
2845 | ret_val = hw->phy.ops.acquire(hw); | 2789 | ret_val = hw->phy.ops.acquire(hw); |
@@ -2847,16 +2791,6 @@ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data, | |||
2847 | return ret_val; | 2791 | return ret_val; |
2848 | } | 2792 | } |
2849 | 2793 | ||
2850 | /* Workaround failure in MDIO access while cable is disconnected */ | ||
2851 | if ((hw->phy.type == e1000_phy_82577) && | ||
2852 | !(er32(STATUS) & E1000_STATUS_LU)) { | ||
2853 | ret_val = e1000_set_mdio_slow_mode_hv(hw, true); | ||
2854 | if (ret_val) | ||
2855 | goto out; | ||
2856 | |||
2857 | in_slow_mode = true; | ||
2858 | } | ||
2859 | |||
2860 | /* Page 800 works differently than the rest so it has its own func */ | 2794 | /* Page 800 works differently than the rest so it has its own func */ |
2861 | if (page == BM_WUC_PAGE) { | 2795 | if (page == BM_WUC_PAGE) { |
2862 | ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, | 2796 | ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, |
@@ -2893,10 +2827,6 @@ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data, | |||
2893 | ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, | 2827 | ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, |
2894 | data); | 2828 | data); |
2895 | out: | 2829 | out: |
2896 | /* Revert to MDIO fast mode, if applicable */ | ||
2897 | if ((hw->phy.type == e1000_phy_82577) && in_slow_mode) | ||
2898 | ret_val |= e1000_set_mdio_slow_mode_hv(hw, false); | ||
2899 | |||
2900 | if (!locked) | 2830 | if (!locked) |
2901 | hw->phy.ops.release(hw); | 2831 | hw->phy.ops.release(hw); |
2902 | 2832 | ||
@@ -2948,7 +2878,6 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data, | |||
2948 | s32 ret_val; | 2878 | s32 ret_val; |
2949 | u16 page = BM_PHY_REG_PAGE(offset); | 2879 | u16 page = BM_PHY_REG_PAGE(offset); |
2950 | u16 reg = BM_PHY_REG_NUM(offset); | 2880 | u16 reg = BM_PHY_REG_NUM(offset); |
2951 | bool in_slow_mode = false; | ||
2952 | 2881 | ||
2953 | if (!locked) { | 2882 | if (!locked) { |
2954 | ret_val = hw->phy.ops.acquire(hw); | 2883 | ret_val = hw->phy.ops.acquire(hw); |
@@ -2956,16 +2885,6 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data, | |||
2956 | return ret_val; | 2885 | return ret_val; |
2957 | } | 2886 | } |
2958 | 2887 | ||
2959 | /* Workaround failure in MDIO access while cable is disconnected */ | ||
2960 | if ((hw->phy.type == e1000_phy_82577) && | ||
2961 | !(er32(STATUS) & E1000_STATUS_LU)) { | ||
2962 | ret_val = e1000_set_mdio_slow_mode_hv(hw, true); | ||
2963 | if (ret_val) | ||
2964 | goto out; | ||
2965 | |||
2966 | in_slow_mode = true; | ||
2967 | } | ||
2968 | |||
2969 | /* Page 800 works differently than the rest so it has its own func */ | 2888 | /* Page 800 works differently than the rest so it has its own func */ |
2970 | if (page == BM_WUC_PAGE) { | 2889 | if (page == BM_WUC_PAGE) { |
2971 | ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, | 2890 | ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, |
@@ -3019,10 +2938,6 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data, | |||
3019 | data); | 2938 | data); |
3020 | 2939 | ||
3021 | out: | 2940 | out: |
3022 | /* Revert to MDIO fast mode, if applicable */ | ||
3023 | if ((hw->phy.type == e1000_phy_82577) && in_slow_mode) | ||
3024 | ret_val |= e1000_set_mdio_slow_mode_hv(hw, false); | ||
3025 | |||
3026 | if (!locked) | 2941 | if (!locked) |
3027 | hw->phy.ops.release(hw); | 2942 | hw->phy.ops.release(hw); |
3028 | 2943 | ||