aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/igb/e1000_phy.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/igb/e1000_phy.c')
-rw-r--r--drivers/net/igb/e1000_phy.c39
1 files changed, 25 insertions, 14 deletions
diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c
index 5fe03e114b83..83b706c460b3 100644
--- a/drivers/net/igb/e1000_phy.c
+++ b/drivers/net/igb/e1000_phy.c
@@ -39,6 +39,9 @@ static s32 igb_wait_autoneg(struct e1000_hw *hw);
39/* Cable length tables */ 39/* Cable length tables */
40static const u16 e1000_m88_cable_length_table[] = 40static const u16 e1000_m88_cable_length_table[] =
41 { 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED }; 41 { 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED };
42#define M88E1000_CABLE_LENGTH_TABLE_SIZE \
43 (sizeof(e1000_m88_cable_length_table) / \
44 sizeof(e1000_m88_cable_length_table[0]))
42 45
43static const u16 e1000_igp_2_cable_length_table[] = 46static const u16 e1000_igp_2_cable_length_table[] =
44 { 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21, 47 { 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21,
@@ -109,7 +112,10 @@ out:
109 **/ 112 **/
110static s32 igb_phy_reset_dsp(struct e1000_hw *hw) 113static s32 igb_phy_reset_dsp(struct e1000_hw *hw)
111{ 114{
112 s32 ret_val; 115 s32 ret_val = 0;
116
117 if (!(hw->phy.ops.write_reg))
118 goto out;
113 119
114 ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xC1); 120 ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xC1);
115 if (ret_val) 121 if (ret_val)
@@ -1059,22 +1065,19 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
1059 1065
1060 igb_phy_force_speed_duplex_setup(hw, &phy_data); 1066 igb_phy_force_speed_duplex_setup(hw, &phy_data);
1061 1067
1062 /* Reset the phy to commit changes. */
1063 phy_data |= MII_CR_RESET;
1064
1065 ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data); 1068 ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data);
1066 if (ret_val) 1069 if (ret_val)
1067 goto out; 1070 goto out;
1068 1071
1069 udelay(1); 1072 /* Reset the phy to commit changes. */
1073 ret_val = igb_phy_sw_reset(hw);
1074 if (ret_val)
1075 goto out;
1070 1076
1071 if (phy->autoneg_wait_to_complete) { 1077 if (phy->autoneg_wait_to_complete) {
1072 hw_dbg("Waiting for forced speed/duplex link on M88 phy.\n"); 1078 hw_dbg("Waiting for forced speed/duplex link on M88 phy.\n");
1073 1079
1074 ret_val = igb_phy_has_link(hw, 1080 ret_val = igb_phy_has_link(hw, PHY_FORCE_LIMIT, 100000, &link);
1075 PHY_FORCE_LIMIT,
1076 100000,
1077 &link);
1078 if (ret_val) 1081 if (ret_val)
1079 goto out; 1082 goto out;
1080 1083
@@ -1084,8 +1087,8 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
1084 * Reset the DSP and cross our fingers. 1087 * Reset the DSP and cross our fingers.
1085 */ 1088 */
1086 ret_val = phy->ops.write_reg(hw, 1089 ret_val = phy->ops.write_reg(hw,
1087 M88E1000_PHY_PAGE_SELECT, 1090 M88E1000_PHY_PAGE_SELECT,
1088 0x001d); 1091 0x001d);
1089 if (ret_val) 1092 if (ret_val)
1090 goto out; 1093 goto out;
1091 ret_val = igb_phy_reset_dsp(hw); 1094 ret_val = igb_phy_reset_dsp(hw);
@@ -1095,7 +1098,7 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
1095 1098
1096 /* Try once more */ 1099 /* Try once more */
1097 ret_val = igb_phy_has_link(hw, PHY_FORCE_LIMIT, 1100 ret_val = igb_phy_has_link(hw, PHY_FORCE_LIMIT,
1098 100000, &link); 1101 100000, &link);
1099 if (ret_val) 1102 if (ret_val)
1100 goto out; 1103 goto out;
1101 } 1104 }
@@ -1207,9 +1210,12 @@ static void igb_phy_force_speed_duplex_setup(struct e1000_hw *hw,
1207s32 igb_set_d3_lplu_state(struct e1000_hw *hw, bool active) 1210s32 igb_set_d3_lplu_state(struct e1000_hw *hw, bool active)
1208{ 1211{
1209 struct e1000_phy_info *phy = &hw->phy; 1212 struct e1000_phy_info *phy = &hw->phy;
1210 s32 ret_val; 1213 s32 ret_val = 0;
1211 u16 data; 1214 u16 data;
1212 1215
1216 if (!(hw->phy.ops.read_reg))
1217 goto out;
1218
1213 ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data); 1219 ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
1214 if (ret_val) 1220 if (ret_val)
1215 goto out; 1221 goto out;
@@ -1495,8 +1501,13 @@ s32 igb_get_cable_length_m88(struct e1000_hw *hw)
1495 1501
1496 index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >> 1502 index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
1497 M88E1000_PSSR_CABLE_LENGTH_SHIFT; 1503 M88E1000_PSSR_CABLE_LENGTH_SHIFT;
1504 if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1) {
1505 ret_val = -E1000_ERR_PHY;
1506 goto out;
1507 }
1508
1498 phy->min_cable_length = e1000_m88_cable_length_table[index]; 1509 phy->min_cable_length = e1000_m88_cable_length_table[index];
1499 phy->max_cable_length = e1000_m88_cable_length_table[index+1]; 1510 phy->max_cable_length = e1000_m88_cable_length_table[index + 1];
1500 1511
1501 phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2; 1512 phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
1502 1513