diff options
Diffstat (limited to 'drivers/net/e1000e/ich8lan.c')
| -rw-r--r-- | drivers/net/e1000e/ich8lan.c | 76 |
1 files changed, 71 insertions, 5 deletions
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index ad08cf3f40c0..8b6ecd127889 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c | |||
| @@ -138,6 +138,10 @@ | |||
| 138 | #define E1000_NVM_K1_CONFIG 0x1B /* NVM K1 Config Word */ | 138 | #define E1000_NVM_K1_CONFIG 0x1B /* NVM K1 Config Word */ |
| 139 | #define E1000_NVM_K1_ENABLE 0x1 /* NVM Enable K1 bit */ | 139 | #define E1000_NVM_K1_ENABLE 0x1 /* NVM Enable K1 bit */ |
| 140 | 140 | ||
| 141 | /* KMRN Mode Control */ | ||
| 142 | #define HV_KMRN_MODE_CTRL PHY_REG(769, 16) | ||
| 143 | #define HV_KMRN_MDIO_SLOW 0x0400 | ||
| 144 | |||
| 141 | /* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */ | 145 | /* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */ |
| 142 | /* Offset 04h HSFSTS */ | 146 | /* Offset 04h HSFSTS */ |
| 143 | union ich8_hws_flash_status { | 147 | union ich8_hws_flash_status { |
| @@ -219,6 +223,7 @@ static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active); | |||
| 219 | static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw); | 223 | static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw); |
| 220 | static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw); | 224 | static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw); |
| 221 | static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link); | 225 | static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link); |
| 226 | static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw); | ||
| 222 | 227 | ||
| 223 | static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg) | 228 | static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg) |
| 224 | { | 229 | { |
| @@ -270,7 +275,21 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) | |||
| 270 | phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; | 275 | phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; |
| 271 | 276 | ||
| 272 | phy->id = e1000_phy_unknown; | 277 | phy->id = e1000_phy_unknown; |
| 273 | e1000e_get_phy_id(hw); | 278 | ret_val = e1000e_get_phy_id(hw); |
| 279 | if (ret_val) | ||
| 280 | goto out; | ||
| 281 | if ((phy->id == 0) || (phy->id == PHY_REVISION_MASK)) { | ||
| 282 | /* | ||
| 283 | * In case the PHY needs to be in mdio slow mode (eg. 82577), | ||
| 284 | * set slow mode and try to get the PHY id again. | ||
| 285 | */ | ||
| 286 | ret_val = e1000_set_mdio_slow_mode_hv(hw); | ||
| 287 | if (ret_val) | ||
| 288 | goto out; | ||
| 289 | ret_val = e1000e_get_phy_id(hw); | ||
| 290 | if (ret_val) | ||
| 291 | goto out; | ||
| 292 | } | ||
| 274 | phy->type = e1000e_get_phy_type_from_id(phy->id); | 293 | phy->type = e1000e_get_phy_type_from_id(phy->id); |
| 275 | 294 | ||
| 276 | switch (phy->type) { | 295 | switch (phy->type) { |
| @@ -292,6 +311,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) | |||
| 292 | break; | 311 | break; |
| 293 | } | 312 | } |
| 294 | 313 | ||
| 314 | out: | ||
| 295 | return ret_val; | 315 | return ret_val; |
| 296 | } | 316 | } |
| 297 | 317 | ||
| @@ -1076,16 +1096,44 @@ out: | |||
| 1076 | 1096 | ||
| 1077 | 1097 | ||
| 1078 | /** | 1098 | /** |
| 1099 | * e1000_set_mdio_slow_mode_hv - Set slow MDIO access mode | ||
| 1100 | * @hw: pointer to the HW structure | ||
| 1101 | **/ | ||
| 1102 | static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw) | ||
| 1103 | { | ||
| 1104 | s32 ret_val; | ||
| 1105 | u16 data; | ||
| 1106 | |||
| 1107 | ret_val = e1e_rphy(hw, HV_KMRN_MODE_CTRL, &data); | ||
| 1108 | if (ret_val) | ||
| 1109 | return ret_val; | ||
| 1110 | |||
| 1111 | data |= HV_KMRN_MDIO_SLOW; | ||
| 1112 | |||
| 1113 | ret_val = e1e_wphy(hw, HV_KMRN_MODE_CTRL, data); | ||
| 1114 | |||
| 1115 | return ret_val; | ||
| 1116 | } | ||
| 1117 | |||
| 1118 | /** | ||
| 1079 | * e1000_hv_phy_workarounds_ich8lan - A series of Phy workarounds to be | 1119 | * e1000_hv_phy_workarounds_ich8lan - A series of Phy workarounds to be |
| 1080 | * done after every PHY reset. | 1120 | * done after every PHY reset. |
| 1081 | **/ | 1121 | **/ |
| 1082 | static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) | 1122 | static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) |
| 1083 | { | 1123 | { |
| 1084 | s32 ret_val = 0; | 1124 | s32 ret_val = 0; |
| 1125 | u16 phy_data; | ||
| 1085 | 1126 | ||
| 1086 | if (hw->mac.type != e1000_pchlan) | 1127 | if (hw->mac.type != e1000_pchlan) |
| 1087 | return ret_val; | 1128 | return ret_val; |
| 1088 | 1129 | ||
| 1130 | /* Set MDIO slow mode before any other MDIO access */ | ||
| 1131 | if (hw->phy.type == e1000_phy_82577) { | ||
| 1132 | ret_val = e1000_set_mdio_slow_mode_hv(hw); | ||
| 1133 | if (ret_val) | ||
| 1134 | goto out; | ||
| 1135 | } | ||
| 1136 | |||
| 1089 | if (((hw->phy.type == e1000_phy_82577) && | 1137 | if (((hw->phy.type == e1000_phy_82577) && |
| 1090 | ((hw->phy.revision == 1) || (hw->phy.revision == 2))) || | 1138 | ((hw->phy.revision == 1) || (hw->phy.revision == 2))) || |
| 1091 | ((hw->phy.type == e1000_phy_82578) && (hw->phy.revision == 1))) { | 1139 | ((hw->phy.type == e1000_phy_82578) && (hw->phy.revision == 1))) { |
| @@ -1118,16 +1166,32 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) | |||
| 1118 | 1166 | ||
| 1119 | hw->phy.addr = 1; | 1167 | hw->phy.addr = 1; |
| 1120 | ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0); | 1168 | ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0); |
| 1169 | hw->phy.ops.release(hw); | ||
| 1121 | if (ret_val) | 1170 | if (ret_val) |
| 1122 | goto out; | 1171 | goto out; |
| 1123 | hw->phy.ops.release(hw); | ||
| 1124 | 1172 | ||
| 1125 | /* | 1173 | /* |
| 1126 | * Configure the K1 Si workaround during phy reset assuming there is | 1174 | * Configure the K1 Si workaround during phy reset assuming there is |
| 1127 | * link so that it disables K1 if link is in 1Gbps. | 1175 | * link so that it disables K1 if link is in 1Gbps. |
| 1128 | */ | 1176 | */ |
| 1129 | ret_val = e1000_k1_gig_workaround_hv(hw, true); | 1177 | ret_val = e1000_k1_gig_workaround_hv(hw, true); |
| 1178 | if (ret_val) | ||
| 1179 | goto out; | ||
| 1130 | 1180 | ||
| 1181 | /* Workaround for link disconnects on a busy hub in half duplex */ | ||
| 1182 | ret_val = hw->phy.ops.acquire(hw); | ||
| 1183 | if (ret_val) | ||
| 1184 | goto out; | ||
| 1185 | ret_val = hw->phy.ops.read_reg_locked(hw, | ||
| 1186 | PHY_REG(BM_PORT_CTRL_PAGE, 17), | ||
| 1187 | &phy_data); | ||
| 1188 | if (ret_val) | ||
| 1189 | goto release; | ||
| 1190 | ret_val = hw->phy.ops.write_reg_locked(hw, | ||
| 1191 | PHY_REG(BM_PORT_CTRL_PAGE, 17), | ||
| 1192 | phy_data & 0x00FF); | ||
| 1193 | release: | ||
| 1194 | hw->phy.ops.release(hw); | ||
| 1131 | out: | 1195 | out: |
| 1132 | return ret_val; | 1196 | return ret_val; |
| 1133 | } | 1197 | } |
| @@ -1184,6 +1248,7 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) | |||
| 1184 | /* Allow time for h/w to get to a quiescent state after reset */ | 1248 | /* Allow time for h/w to get to a quiescent state after reset */ |
| 1185 | mdelay(10); | 1249 | mdelay(10); |
| 1186 | 1250 | ||
| 1251 | /* Perform any necessary post-reset workarounds */ | ||
| 1187 | if (hw->mac.type == e1000_pchlan) { | 1252 | if (hw->mac.type == e1000_pchlan) { |
| 1188 | ret_val = e1000_hv_phy_workarounds_ich8lan(hw); | 1253 | ret_val = e1000_hv_phy_workarounds_ich8lan(hw); |
| 1189 | if (ret_val) | 1254 | if (ret_val) |
| @@ -2484,6 +2549,10 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) | |||
| 2484 | if (!ret_val) | 2549 | if (!ret_val) |
| 2485 | e1000_release_swflag_ich8lan(hw); | 2550 | e1000_release_swflag_ich8lan(hw); |
| 2486 | 2551 | ||
| 2552 | /* Perform any necessary post-reset workarounds */ | ||
| 2553 | if (hw->mac.type == e1000_pchlan) | ||
| 2554 | ret_val = e1000_hv_phy_workarounds_ich8lan(hw); | ||
| 2555 | |||
| 2487 | if (ctrl & E1000_CTRL_PHY_RST) | 2556 | if (ctrl & E1000_CTRL_PHY_RST) |
| 2488 | ret_val = hw->phy.ops.get_cfg_done(hw); | 2557 | ret_val = hw->phy.ops.get_cfg_done(hw); |
| 2489 | 2558 | ||
| @@ -2528,9 +2597,6 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) | |||
| 2528 | kab |= E1000_KABGTXD_BGSQLBIAS; | 2597 | kab |= E1000_KABGTXD_BGSQLBIAS; |
| 2529 | ew32(KABGTXD, kab); | 2598 | ew32(KABGTXD, kab); |
| 2530 | 2599 | ||
| 2531 | if (hw->mac.type == e1000_pchlan) | ||
| 2532 | ret_val = e1000_hv_phy_workarounds_ich8lan(hw); | ||
| 2533 | |||
| 2534 | out: | 2600 | out: |
| 2535 | return ret_val; | 2601 | return ret_val; |
| 2536 | } | 2602 | } |
