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/es2lan.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/es2lan.c')
-rw-r--r-- | drivers/net/e1000e/es2lan.c | 127 |
1 files changed, 94 insertions, 33 deletions
diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c index 13a6f4484de9..dc552d7d6fac 100644 --- a/drivers/net/e1000e/es2lan.c +++ b/drivers/net/e1000e/es2lan.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #define E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL 0x00 | 41 | #define E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL 0x00 |
42 | #define E1000_KMRNCTRLSTA_OFFSET_INB_CTRL 0x02 | 42 | #define E1000_KMRNCTRLSTA_OFFSET_INB_CTRL 0x02 |
43 | #define E1000_KMRNCTRLSTA_OFFSET_HD_CTRL 0x10 | 43 | #define E1000_KMRNCTRLSTA_OFFSET_HD_CTRL 0x10 |
44 | #define E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE 0x1F | ||
44 | 45 | ||
45 | #define E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS 0x0008 | 46 | #define E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS 0x0008 |
46 | #define E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS 0x0800 | 47 | #define E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS 0x0800 |
@@ -48,6 +49,7 @@ | |||
48 | 49 | ||
49 | #define E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT 0x0004 | 50 | #define E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT 0x0004 |
50 | #define E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT 0x0000 | 51 | #define E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT 0x0000 |
52 | #define E1000_KMRNCTRLSTA_OPMODE_E_IDLE 0x2000 | ||
51 | 53 | ||
52 | #define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gigabit Carry Extend Padding */ | 54 | #define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gigabit Carry Extend Padding */ |
53 | #define DEFAULT_TCTL_EXT_GCEX_80003ES2LAN 0x00010000 | 55 | #define DEFAULT_TCTL_EXT_GCEX_80003ES2LAN 0x00010000 |
@@ -85,6 +87,9 @@ | |||
85 | /* Kumeran Mode Control Register (Page 193, Register 16) */ | 87 | /* Kumeran Mode Control Register (Page 193, Register 16) */ |
86 | #define GG82563_KMCR_PASS_FALSE_CARRIER 0x0800 | 88 | #define GG82563_KMCR_PASS_FALSE_CARRIER 0x0800 |
87 | 89 | ||
90 | /* Max number of times Kumeran read/write should be validated */ | ||
91 | #define GG82563_MAX_KMRN_RETRY 0x5 | ||
92 | |||
88 | /* Power Management Control Register (Page 193, Register 20) */ | 93 | /* Power Management Control Register (Page 193, Register 20) */ |
89 | #define GG82563_PMCR_ENABLE_ELECTRICAL_IDLE 0x0001 | 94 | #define GG82563_PMCR_ENABLE_ELECTRICAL_IDLE 0x0001 |
90 | /* 1=Enable SERDES Electrical Idle */ | 95 | /* 1=Enable SERDES Electrical Idle */ |
@@ -270,6 +275,7 @@ static s32 e1000_acquire_phy_80003es2lan(struct e1000_hw *hw) | |||
270 | u16 mask; | 275 | u16 mask; |
271 | 276 | ||
272 | mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM; | 277 | mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM; |
278 | mask |= E1000_SWFW_CSR_SM; | ||
273 | 279 | ||
274 | return e1000_acquire_swfw_sync_80003es2lan(hw, mask); | 280 | return e1000_acquire_swfw_sync_80003es2lan(hw, mask); |
275 | } | 281 | } |
@@ -286,6 +292,8 @@ static void e1000_release_phy_80003es2lan(struct e1000_hw *hw) | |||
286 | u16 mask; | 292 | u16 mask; |
287 | 293 | ||
288 | mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM; | 294 | mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM; |
295 | mask |= E1000_SWFW_CSR_SM; | ||
296 | |||
289 | e1000_release_swfw_sync_80003es2lan(hw, mask); | 297 | e1000_release_swfw_sync_80003es2lan(hw, mask); |
290 | } | 298 | } |
291 | 299 | ||
@@ -410,20 +418,27 @@ static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, | |||
410 | u32 page_select; | 418 | u32 page_select; |
411 | u16 temp; | 419 | u16 temp; |
412 | 420 | ||
421 | ret_val = e1000_acquire_phy_80003es2lan(hw); | ||
422 | if (ret_val) | ||
423 | return ret_val; | ||
424 | |||
413 | /* Select Configuration Page */ | 425 | /* Select Configuration Page */ |
414 | if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) | 426 | if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) { |
415 | page_select = GG82563_PHY_PAGE_SELECT; | 427 | page_select = GG82563_PHY_PAGE_SELECT; |
416 | else | 428 | } else { |
417 | /* | 429 | /* |
418 | * Use Alternative Page Select register to access | 430 | * Use Alternative Page Select register to access |
419 | * registers 30 and 31 | 431 | * registers 30 and 31 |
420 | */ | 432 | */ |
421 | page_select = GG82563_PHY_PAGE_SELECT_ALT; | 433 | page_select = GG82563_PHY_PAGE_SELECT_ALT; |
434 | } | ||
422 | 435 | ||
423 | temp = (u16)((u16)offset >> GG82563_PAGE_SHIFT); | 436 | temp = (u16)((u16)offset >> GG82563_PAGE_SHIFT); |
424 | ret_val = e1000e_write_phy_reg_m88(hw, page_select, temp); | 437 | ret_val = e1000e_write_phy_reg_mdic(hw, page_select, temp); |
425 | if (ret_val) | 438 | if (ret_val) { |
439 | e1000_release_phy_80003es2lan(hw); | ||
426 | return ret_val; | 440 | return ret_val; |
441 | } | ||
427 | 442 | ||
428 | /* | 443 | /* |
429 | * The "ready" bit in the MDIC register may be incorrectly set | 444 | * The "ready" bit in the MDIC register may be incorrectly set |
@@ -433,20 +448,21 @@ static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, | |||
433 | udelay(200); | 448 | udelay(200); |
434 | 449 | ||
435 | /* ...and verify the command was successful. */ | 450 | /* ...and verify the command was successful. */ |
436 | ret_val = e1000e_read_phy_reg_m88(hw, page_select, &temp); | 451 | ret_val = e1000e_read_phy_reg_mdic(hw, page_select, &temp); |
437 | 452 | ||
438 | if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) { | 453 | if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) { |
439 | ret_val = -E1000_ERR_PHY; | 454 | ret_val = -E1000_ERR_PHY; |
455 | e1000_release_phy_80003es2lan(hw); | ||
440 | return ret_val; | 456 | return ret_val; |
441 | } | 457 | } |
442 | 458 | ||
443 | udelay(200); | 459 | udelay(200); |
444 | 460 | ||
445 | ret_val = e1000e_read_phy_reg_m88(hw, | 461 | ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, |
446 | MAX_PHY_REG_ADDRESS & offset, | 462 | data); |
447 | data); | ||
448 | 463 | ||
449 | udelay(200); | 464 | udelay(200); |
465 | e1000_release_phy_80003es2lan(hw); | ||
450 | 466 | ||
451 | return ret_val; | 467 | return ret_val; |
452 | } | 468 | } |
@@ -467,20 +483,27 @@ static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, | |||
467 | u32 page_select; | 483 | u32 page_select; |
468 | u16 temp; | 484 | u16 temp; |
469 | 485 | ||
486 | ret_val = e1000_acquire_phy_80003es2lan(hw); | ||
487 | if (ret_val) | ||
488 | return ret_val; | ||
489 | |||
470 | /* Select Configuration Page */ | 490 | /* Select Configuration Page */ |
471 | if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) | 491 | if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) { |
472 | page_select = GG82563_PHY_PAGE_SELECT; | 492 | page_select = GG82563_PHY_PAGE_SELECT; |
473 | else | 493 | } else { |
474 | /* | 494 | /* |
475 | * Use Alternative Page Select register to access | 495 | * Use Alternative Page Select register to access |
476 | * registers 30 and 31 | 496 | * registers 30 and 31 |
477 | */ | 497 | */ |
478 | page_select = GG82563_PHY_PAGE_SELECT_ALT; | 498 | page_select = GG82563_PHY_PAGE_SELECT_ALT; |
499 | } | ||
479 | 500 | ||
480 | temp = (u16)((u16)offset >> GG82563_PAGE_SHIFT); | 501 | temp = (u16)((u16)offset >> GG82563_PAGE_SHIFT); |
481 | ret_val = e1000e_write_phy_reg_m88(hw, page_select, temp); | 502 | ret_val = e1000e_write_phy_reg_mdic(hw, page_select, temp); |
482 | if (ret_val) | 503 | if (ret_val) { |
504 | e1000_release_phy_80003es2lan(hw); | ||
483 | return ret_val; | 505 | return ret_val; |
506 | } | ||
484 | 507 | ||
485 | 508 | ||
486 | /* | 509 | /* |
@@ -491,18 +514,20 @@ static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, | |||
491 | udelay(200); | 514 | udelay(200); |
492 | 515 | ||
493 | /* ...and verify the command was successful. */ | 516 | /* ...and verify the command was successful. */ |
494 | ret_val = e1000e_read_phy_reg_m88(hw, page_select, &temp); | 517 | ret_val = e1000e_read_phy_reg_mdic(hw, page_select, &temp); |
495 | 518 | ||
496 | if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) | 519 | if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) { |
520 | e1000_release_phy_80003es2lan(hw); | ||
497 | return -E1000_ERR_PHY; | 521 | return -E1000_ERR_PHY; |
522 | } | ||
498 | 523 | ||
499 | udelay(200); | 524 | udelay(200); |
500 | 525 | ||
501 | ret_val = e1000e_write_phy_reg_m88(hw, | 526 | ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, |
502 | MAX_PHY_REG_ADDRESS & offset, | 527 | data); |
503 | data); | ||
504 | 528 | ||
505 | udelay(200); | 529 | udelay(200); |
530 | e1000_release_phy_80003es2lan(hw); | ||
506 | 531 | ||
507 | return ret_val; | 532 | return ret_val; |
508 | } | 533 | } |
@@ -882,10 +907,10 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) | |||
882 | struct e1000_phy_info *phy = &hw->phy; | 907 | struct e1000_phy_info *phy = &hw->phy; |
883 | s32 ret_val; | 908 | s32 ret_val; |
884 | u32 ctrl_ext; | 909 | u32 ctrl_ext; |
885 | u16 data; | 910 | u32 i = 0; |
911 | u16 data, data2; | ||
886 | 912 | ||
887 | ret_val = e1e_rphy(hw, GG82563_PHY_MAC_SPEC_CTRL, | 913 | ret_val = e1e_rphy(hw, GG82563_PHY_MAC_SPEC_CTRL, &data); |
888 | &data); | ||
889 | if (ret_val) | 914 | if (ret_val) |
890 | return ret_val; | 915 | return ret_val; |
891 | 916 | ||
@@ -893,8 +918,7 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) | |||
893 | /* Use 25MHz for both link down and 1000Base-T for Tx clock. */ | 918 | /* Use 25MHz for both link down and 1000Base-T for Tx clock. */ |
894 | data |= GG82563_MSCR_TX_CLK_1000MBPS_25; | 919 | data |= GG82563_MSCR_TX_CLK_1000MBPS_25; |
895 | 920 | ||
896 | ret_val = e1e_wphy(hw, GG82563_PHY_MAC_SPEC_CTRL, | 921 | ret_val = e1e_wphy(hw, GG82563_PHY_MAC_SPEC_CTRL, data); |
897 | data); | ||
898 | if (ret_val) | 922 | if (ret_val) |
899 | return ret_val; | 923 | return ret_val; |
900 | 924 | ||
@@ -954,6 +978,18 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) | |||
954 | if (ret_val) | 978 | if (ret_val) |
955 | return ret_val; | 979 | return ret_val; |
956 | 980 | ||
981 | ret_val = e1000e_read_kmrn_reg(hw, | ||
982 | E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE, | ||
983 | &data); | ||
984 | if (ret_val) | ||
985 | return ret_val; | ||
986 | data |= E1000_KMRNCTRLSTA_OPMODE_E_IDLE; | ||
987 | ret_val = e1000e_write_kmrn_reg(hw, | ||
988 | E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE, | ||
989 | data); | ||
990 | if (ret_val) | ||
991 | return ret_val; | ||
992 | |||
957 | ret_val = e1e_rphy(hw, GG82563_PHY_SPEC_CTRL_2, &data); | 993 | ret_val = e1e_rphy(hw, GG82563_PHY_SPEC_CTRL_2, &data); |
958 | if (ret_val) | 994 | if (ret_val) |
959 | return ret_val; | 995 | return ret_val; |
@@ -983,9 +1019,18 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) | |||
983 | if (ret_val) | 1019 | if (ret_val) |
984 | return ret_val; | 1020 | return ret_val; |
985 | 1021 | ||
986 | ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, &data); | 1022 | do { |
987 | if (ret_val) | 1023 | ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, |
988 | return ret_val; | 1024 | &data); |
1025 | if (ret_val) | ||
1026 | return ret_val; | ||
1027 | |||
1028 | ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, | ||
1029 | &data2); | ||
1030 | if (ret_val) | ||
1031 | return ret_val; | ||
1032 | i++; | ||
1033 | } while ((data != data2) && (i < GG82563_MAX_KMRN_RETRY)); | ||
989 | 1034 | ||
990 | data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; | 1035 | data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; |
991 | ret_val = e1e_wphy(hw, GG82563_PHY_KMRN_MODE_CTRL, data); | 1036 | ret_val = e1e_wphy(hw, GG82563_PHY_KMRN_MODE_CTRL, data); |
@@ -1074,7 +1119,8 @@ static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex) | |||
1074 | { | 1119 | { |
1075 | s32 ret_val; | 1120 | s32 ret_val; |
1076 | u32 tipg; | 1121 | u32 tipg; |
1077 | u16 reg_data; | 1122 | u32 i = 0; |
1123 | u16 reg_data, reg_data2; | ||
1078 | 1124 | ||
1079 | reg_data = E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT; | 1125 | reg_data = E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT; |
1080 | ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_OFFSET_HD_CTRL, | 1126 | ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_OFFSET_HD_CTRL, |
@@ -1088,9 +1134,16 @@ static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex) | |||
1088 | tipg |= DEFAULT_TIPG_IPGT_10_100_80003ES2LAN; | 1134 | tipg |= DEFAULT_TIPG_IPGT_10_100_80003ES2LAN; |
1089 | ew32(TIPG, tipg); | 1135 | ew32(TIPG, tipg); |
1090 | 1136 | ||
1091 | ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data); | 1137 | do { |
1092 | if (ret_val) | 1138 | ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data); |
1093 | return ret_val; | 1139 | if (ret_val) |
1140 | return ret_val; | ||
1141 | |||
1142 | ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data2); | ||
1143 | if (ret_val) | ||
1144 | return ret_val; | ||
1145 | i++; | ||
1146 | } while ((reg_data != reg_data2) && (i < GG82563_MAX_KMRN_RETRY)); | ||
1094 | 1147 | ||
1095 | if (duplex == HALF_DUPLEX) | 1148 | if (duplex == HALF_DUPLEX) |
1096 | reg_data |= GG82563_KMCR_PASS_FALSE_CARRIER; | 1149 | reg_data |= GG82563_KMCR_PASS_FALSE_CARRIER; |
@@ -1112,8 +1165,9 @@ static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex) | |||
1112 | static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw) | 1165 | static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw) |
1113 | { | 1166 | { |
1114 | s32 ret_val; | 1167 | s32 ret_val; |
1115 | u16 reg_data; | 1168 | u16 reg_data, reg_data2; |
1116 | u32 tipg; | 1169 | u32 tipg; |
1170 | u32 i = 0; | ||
1117 | 1171 | ||
1118 | reg_data = E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT; | 1172 | reg_data = E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT; |
1119 | ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_OFFSET_HD_CTRL, | 1173 | ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_OFFSET_HD_CTRL, |
@@ -1127,9 +1181,16 @@ static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw) | |||
1127 | tipg |= DEFAULT_TIPG_IPGT_1000_80003ES2LAN; | 1181 | tipg |= DEFAULT_TIPG_IPGT_1000_80003ES2LAN; |
1128 | ew32(TIPG, tipg); | 1182 | ew32(TIPG, tipg); |
1129 | 1183 | ||
1130 | ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data); | 1184 | do { |
1131 | if (ret_val) | 1185 | ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data); |
1132 | return ret_val; | 1186 | if (ret_val) |
1187 | return ret_val; | ||
1188 | |||
1189 | ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data2); | ||
1190 | if (ret_val) | ||
1191 | return ret_val; | ||
1192 | i++; | ||
1193 | } while ((reg_data != reg_data2) && (i < GG82563_MAX_KMRN_RETRY)); | ||
1133 | 1194 | ||
1134 | reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; | 1195 | reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; |
1135 | ret_val = e1e_wphy(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data); | 1196 | ret_val = e1e_wphy(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data); |