diff options
author | David Graham <david.graham@intel.com> | 2008-04-23 14:09:14 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-04-25 02:07:12 -0400 |
commit | 2d9498f369706d6db174abd2e75b37732b9dbbde (patch) | |
tree | f11d1940f92b0f9c70dc5e02cf5f462c752d6a80 /drivers/net/e1000e/phy.c | |
parent | de5b3077da8275e87196a1e34c5535f5279c5e1a (diff) |
e1000e: Fix HW Error on es2lan, ARP capture issue by BMC
Several components to this complex fix. The es2lan cards occasionally
gave a "HW Error" especially when forcing speed. Some users also
reported that the BMC stole ARP packets.
The fixes include setting the proper SW_FW bits to tell the BMC
that we're active and not do any un-initialization at all, so the
setup routine is largely changed.
Signed-off-by: David Graham <david.graham@intel.com>
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/e1000e/phy.c')
-rw-r--r-- | drivers/net/e1000e/phy.c | 73 |
1 files changed, 40 insertions, 33 deletions
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c index 3a4574caa75b..e102332a6bee 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c | |||
@@ -116,7 +116,7 @@ s32 e1000e_phy_reset_dsp(struct e1000_hw *hw) | |||
116 | } | 116 | } |
117 | 117 | ||
118 | /** | 118 | /** |
119 | * e1000_read_phy_reg_mdic - Read MDI control register | 119 | * e1000e_read_phy_reg_mdic - Read MDI control register |
120 | * @hw: pointer to the HW structure | 120 | * @hw: pointer to the HW structure |
121 | * @offset: register offset to be read | 121 | * @offset: register offset to be read |
122 | * @data: pointer to the read data | 122 | * @data: pointer to the read data |
@@ -124,7 +124,7 @@ s32 e1000e_phy_reset_dsp(struct e1000_hw *hw) | |||
124 | * Reads the MDI control register in the PHY at offset and stores the | 124 | * Reads the MDI control register in the PHY at offset and stores the |
125 | * information read to data. | 125 | * information read to data. |
126 | **/ | 126 | **/ |
127 | static s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) | 127 | s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) |
128 | { | 128 | { |
129 | struct e1000_phy_info *phy = &hw->phy; | 129 | struct e1000_phy_info *phy = &hw->phy; |
130 | u32 i, mdic = 0; | 130 | u32 i, mdic = 0; |
@@ -150,7 +150,7 @@ static s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) | |||
150 | * Increasing the time out as testing showed failures with | 150 | * Increasing the time out as testing showed failures with |
151 | * the lower time out | 151 | * the lower time out |
152 | */ | 152 | */ |
153 | for (i = 0; i < 64; i++) { | 153 | for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) { |
154 | udelay(50); | 154 | udelay(50); |
155 | mdic = er32(MDIC); | 155 | mdic = er32(MDIC); |
156 | if (mdic & E1000_MDIC_READY) | 156 | if (mdic & E1000_MDIC_READY) |
@@ -170,14 +170,14 @@ static s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) | |||
170 | } | 170 | } |
171 | 171 | ||
172 | /** | 172 | /** |
173 | * e1000_write_phy_reg_mdic - Write MDI control register | 173 | * e1000e_write_phy_reg_mdic - Write MDI control register |
174 | * @hw: pointer to the HW structure | 174 | * @hw: pointer to the HW structure |
175 | * @offset: register offset to write to | 175 | * @offset: register offset to write to |
176 | * @data: data to write to register at offset | 176 | * @data: data to write to register at offset |
177 | * | 177 | * |
178 | * Writes data to MDI control register in the PHY at offset. | 178 | * Writes data to MDI control register in the PHY at offset. |
179 | **/ | 179 | **/ |
180 | static s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) | 180 | s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) |
181 | { | 181 | { |
182 | struct e1000_phy_info *phy = &hw->phy; | 182 | struct e1000_phy_info *phy = &hw->phy; |
183 | u32 i, mdic = 0; | 183 | u32 i, mdic = 0; |
@@ -199,9 +199,13 @@ static s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) | |||
199 | 199 | ||
200 | ew32(MDIC, mdic); | 200 | ew32(MDIC, mdic); |
201 | 201 | ||
202 | /* Poll the ready bit to see if the MDI read completed */ | 202 | /* |
203 | for (i = 0; i < E1000_GEN_POLL_TIMEOUT; i++) { | 203 | * Poll the ready bit to see if the MDI read completed |
204 | udelay(5); | 204 | * Increasing the time out as testing showed failures with |
205 | * the lower time out | ||
206 | */ | ||
207 | for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) { | ||
208 | udelay(50); | ||
205 | mdic = er32(MDIC); | 209 | mdic = er32(MDIC); |
206 | if (mdic & E1000_MDIC_READY) | 210 | if (mdic & E1000_MDIC_READY) |
207 | break; | 211 | break; |
@@ -210,6 +214,10 @@ static s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) | |||
210 | hw_dbg(hw, "MDI Write did not complete\n"); | 214 | hw_dbg(hw, "MDI Write did not complete\n"); |
211 | return -E1000_ERR_PHY; | 215 | return -E1000_ERR_PHY; |
212 | } | 216 | } |
217 | if (mdic & E1000_MDIC_ERROR) { | ||
218 | hw_dbg(hw, "MDI Error\n"); | ||
219 | return -E1000_ERR_PHY; | ||
220 | } | ||
213 | 221 | ||
214 | return 0; | 222 | return 0; |
215 | } | 223 | } |
@@ -232,9 +240,8 @@ s32 e1000e_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data) | |||
232 | if (ret_val) | 240 | if (ret_val) |
233 | return ret_val; | 241 | return ret_val; |
234 | 242 | ||
235 | ret_val = e1000_read_phy_reg_mdic(hw, | 243 | ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, |
236 | MAX_PHY_REG_ADDRESS & offset, | 244 | data); |
237 | data); | ||
238 | 245 | ||
239 | hw->phy.ops.release_phy(hw); | 246 | hw->phy.ops.release_phy(hw); |
240 | 247 | ||
@@ -258,9 +265,8 @@ s32 e1000e_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data) | |||
258 | if (ret_val) | 265 | if (ret_val) |
259 | return ret_val; | 266 | return ret_val; |
260 | 267 | ||
261 | ret_val = e1000_write_phy_reg_mdic(hw, | 268 | ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, |
262 | MAX_PHY_REG_ADDRESS & offset, | 269 | data); |
263 | data); | ||
264 | 270 | ||
265 | hw->phy.ops.release_phy(hw); | 271 | hw->phy.ops.release_phy(hw); |
266 | 272 | ||
@@ -286,18 +292,17 @@ s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data) | |||
286 | return ret_val; | 292 | return ret_val; |
287 | 293 | ||
288 | if (offset > MAX_PHY_MULTI_PAGE_REG) { | 294 | if (offset > MAX_PHY_MULTI_PAGE_REG) { |
289 | ret_val = e1000_write_phy_reg_mdic(hw, | 295 | ret_val = e1000e_write_phy_reg_mdic(hw, |
290 | IGP01E1000_PHY_PAGE_SELECT, | 296 | IGP01E1000_PHY_PAGE_SELECT, |
291 | (u16)offset); | 297 | (u16)offset); |
292 | if (ret_val) { | 298 | if (ret_val) { |
293 | hw->phy.ops.release_phy(hw); | 299 | hw->phy.ops.release_phy(hw); |
294 | return ret_val; | 300 | return ret_val; |
295 | } | 301 | } |
296 | } | 302 | } |
297 | 303 | ||
298 | ret_val = e1000_read_phy_reg_mdic(hw, | 304 | ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, |
299 | MAX_PHY_REG_ADDRESS & offset, | 305 | data); |
300 | data); | ||
301 | 306 | ||
302 | hw->phy.ops.release_phy(hw); | 307 | hw->phy.ops.release_phy(hw); |
303 | 308 | ||
@@ -322,18 +327,17 @@ s32 e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data) | |||
322 | return ret_val; | 327 | return ret_val; |
323 | 328 | ||
324 | if (offset > MAX_PHY_MULTI_PAGE_REG) { | 329 | if (offset > MAX_PHY_MULTI_PAGE_REG) { |
325 | ret_val = e1000_write_phy_reg_mdic(hw, | 330 | ret_val = e1000e_write_phy_reg_mdic(hw, |
326 | IGP01E1000_PHY_PAGE_SELECT, | 331 | IGP01E1000_PHY_PAGE_SELECT, |
327 | (u16)offset); | 332 | (u16)offset); |
328 | if (ret_val) { | 333 | if (ret_val) { |
329 | hw->phy.ops.release_phy(hw); | 334 | hw->phy.ops.release_phy(hw); |
330 | return ret_val; | 335 | return ret_val; |
331 | } | 336 | } |
332 | } | 337 | } |
333 | 338 | ||
334 | ret_val = e1000_write_phy_reg_mdic(hw, | 339 | ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, |
335 | MAX_PHY_REG_ADDRESS & offset, | 340 | data); |
336 | data); | ||
337 | 341 | ||
338 | hw->phy.ops.release_phy(hw); | 342 | hw->phy.ops.release_phy(hw); |
339 | 343 | ||
@@ -420,7 +424,9 @@ s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw) | |||
420 | if (ret_val) | 424 | if (ret_val) |
421 | return ret_val; | 425 | return ret_val; |
422 | 426 | ||
423 | phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX; | 427 | /* For newer PHYs this bit is downshift enable */ |
428 | if (phy->type == e1000_phy_m88) | ||
429 | phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX; | ||
424 | 430 | ||
425 | /* | 431 | /* |
426 | * Options: | 432 | * Options: |
@@ -463,7 +469,7 @@ s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw) | |||
463 | if (ret_val) | 469 | if (ret_val) |
464 | return ret_val; | 470 | return ret_val; |
465 | 471 | ||
466 | if (phy->revision < 4) { | 472 | if ((phy->type == e1000_phy_m88) && (phy->revision < 4)) { |
467 | /* | 473 | /* |
468 | * Force TX_CLK in the Extended PHY Specific Control Register | 474 | * Force TX_CLK in the Extended PHY Specific Control Register |
469 | * to 25MHz clock. | 475 | * to 25MHz clock. |
@@ -518,8 +524,11 @@ s32 e1000e_copper_link_setup_igp(struct e1000_hw *hw) | |||
518 | return ret_val; | 524 | return ret_val; |
519 | } | 525 | } |
520 | 526 | ||
521 | /* Wait 15ms for MAC to configure PHY from NVM settings. */ | 527 | /* |
522 | msleep(15); | 528 | * Wait 100ms for MAC to configure PHY from NVM settings, to avoid |
529 | * timeout issues when LFS is enabled. | ||
530 | */ | ||
531 | msleep(100); | ||
523 | 532 | ||
524 | /* disable lplu d0 during driver init */ | 533 | /* disable lplu d0 during driver init */ |
525 | ret_val = e1000_set_d0_lplu_state(hw, 0); | 534 | ret_val = e1000_set_d0_lplu_state(hw, 0); |
@@ -1152,9 +1161,7 @@ s32 e1000e_set_d3_lplu_state(struct e1000_hw *hw, bool active) | |||
1152 | 1161 | ||
1153 | if (!active) { | 1162 | if (!active) { |
1154 | data &= ~IGP02E1000_PM_D3_LPLU; | 1163 | data &= ~IGP02E1000_PM_D3_LPLU; |
1155 | ret_val = e1e_wphy(hw, | 1164 | ret_val = e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, data); |
1156 | IGP02E1000_PHY_POWER_MGMT, | ||
1157 | data); | ||
1158 | if (ret_val) | 1165 | if (ret_val) |
1159 | return ret_val; | 1166 | return ret_val; |
1160 | /* | 1167 | /* |