aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000e/ich8lan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/e1000e/ich8lan.c')
-rw-r--r--drivers/net/e1000e/ich8lan.c187
1 files changed, 170 insertions, 17 deletions
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index 095ffa56ed94..51ddb04ab195 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -140,6 +140,9 @@
140#define HV_OEM_BITS_GBE_DIS 0x0040 /* Gigabit Disable */ 140#define HV_OEM_BITS_GBE_DIS 0x0040 /* Gigabit Disable */
141#define HV_OEM_BITS_RESTART_AN 0x0400 /* Restart Auto-negotiation */ 141#define HV_OEM_BITS_RESTART_AN 0x0400 /* Restart Auto-negotiation */
142 142
143#define E1000_NVM_K1_CONFIG 0x1B /* NVM K1 Config Word */
144#define E1000_NVM_K1_ENABLE 0x1 /* NVM Enable K1 bit */
145
143/* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */ 146/* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */
144/* Offset 04h HSFSTS */ 147/* Offset 04h HSFSTS */
145union ich8_hws_flash_status { 148union ich8_hws_flash_status {
@@ -220,6 +223,8 @@ static s32 e1000_led_on_pchlan(struct e1000_hw *hw);
220static s32 e1000_led_off_pchlan(struct e1000_hw *hw); 223static s32 e1000_led_off_pchlan(struct e1000_hw *hw);
221static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active); 224static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active);
222static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw); 225static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw);
226static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link);
227static s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable);
223 228
224static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg) 229static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg)
225{ 230{
@@ -495,14 +500,6 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
495 goto out; 500 goto out;
496 } 501 }
497 502
498 if (hw->mac.type == e1000_pchlan) {
499 ret_val = e1000e_write_kmrn_reg(hw,
500 E1000_KMRNCTRLSTA_K1_CONFIG,
501 E1000_KMRNCTRLSTA_K1_ENABLE);
502 if (ret_val)
503 goto out;
504 }
505
506 /* 503 /*
507 * First we want to see if the MII Status Register reports 504 * First we want to see if the MII Status Register reports
508 * link. If so, then we want to get the current speed/duplex 505 * link. If so, then we want to get the current speed/duplex
@@ -512,6 +509,12 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
512 if (ret_val) 509 if (ret_val)
513 goto out; 510 goto out;
514 511
512 if (hw->mac.type == e1000_pchlan) {
513 ret_val = e1000_k1_gig_workaround_hv(hw, link);
514 if (ret_val)
515 goto out;
516 }
517
515 if (!link) 518 if (!link)
516 goto out; /* No link detected */ 519 goto out; /* No link detected */
517 520
@@ -929,6 +932,141 @@ out:
929} 932}
930 933
931/** 934/**
935 * e1000_k1_gig_workaround_hv - K1 Si workaround
936 * @hw: pointer to the HW structure
937 * @link: link up bool flag
938 *
939 * If K1 is enabled for 1Gbps, the MAC might stall when transitioning
940 * from a lower speed. This workaround disables K1 whenever link is at 1Gig
941 * If link is down, the function will restore the default K1 setting located
942 * in the NVM.
943 **/
944static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link)
945{
946 s32 ret_val = 0;
947 u16 status_reg = 0;
948 bool k1_enable = hw->dev_spec.ich8lan.nvm_k1_enabled;
949
950 if (hw->mac.type != e1000_pchlan)
951 goto out;
952
953 /* Wrap the whole flow with the sw flag */
954 ret_val = hw->phy.ops.acquire_phy(hw);
955 if (ret_val)
956 goto out;
957
958 /* Disable K1 when link is 1Gbps, otherwise use the NVM setting */
959 if (link) {
960 if (hw->phy.type == e1000_phy_82578) {
961 ret_val = hw->phy.ops.read_phy_reg_locked(hw,
962 BM_CS_STATUS,
963 &status_reg);
964 if (ret_val)
965 goto release;
966
967 status_reg &= BM_CS_STATUS_LINK_UP |
968 BM_CS_STATUS_RESOLVED |
969 BM_CS_STATUS_SPEED_MASK;
970
971 if (status_reg == (BM_CS_STATUS_LINK_UP |
972 BM_CS_STATUS_RESOLVED |
973 BM_CS_STATUS_SPEED_1000))
974 k1_enable = false;
975 }
976
977 if (hw->phy.type == e1000_phy_82577) {
978 ret_val = hw->phy.ops.read_phy_reg_locked(hw,
979 HV_M_STATUS,
980 &status_reg);
981 if (ret_val)
982 goto release;
983
984 status_reg &= HV_M_STATUS_LINK_UP |
985 HV_M_STATUS_AUTONEG_COMPLETE |
986 HV_M_STATUS_SPEED_MASK;
987
988 if (status_reg == (HV_M_STATUS_LINK_UP |
989 HV_M_STATUS_AUTONEG_COMPLETE |
990 HV_M_STATUS_SPEED_1000))
991 k1_enable = false;
992 }
993
994 /* Link stall fix for link up */
995 ret_val = hw->phy.ops.write_phy_reg_locked(hw, PHY_REG(770, 19),
996 0x0100);
997 if (ret_val)
998 goto release;
999
1000 } else {
1001 /* Link stall fix for link down */
1002 ret_val = hw->phy.ops.write_phy_reg_locked(hw, PHY_REG(770, 19),
1003 0x4100);
1004 if (ret_val)
1005 goto release;
1006 }
1007
1008 ret_val = e1000_configure_k1_ich8lan(hw, k1_enable);
1009
1010release:
1011 hw->phy.ops.release_phy(hw);
1012out:
1013 return ret_val;
1014}
1015
1016/**
1017 * e1000_configure_k1_ich8lan - Configure K1 power state
1018 * @hw: pointer to the HW structure
1019 * @enable: K1 state to configure
1020 *
1021 * Configure the K1 power state based on the provided parameter.
1022 * Assumes semaphore already acquired.
1023 *
1024 * Success returns 0, Failure returns -E1000_ERR_PHY (-2)
1025 **/
1026static s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable)
1027{
1028 s32 ret_val = 0;
1029 u32 ctrl_reg = 0;
1030 u32 ctrl_ext = 0;
1031 u32 reg = 0;
1032 u16 kmrn_reg = 0;
1033
1034 ret_val = e1000e_read_kmrn_reg_locked(hw,
1035 E1000_KMRNCTRLSTA_K1_CONFIG,
1036 &kmrn_reg);
1037 if (ret_val)
1038 goto out;
1039
1040 if (k1_enable)
1041 kmrn_reg |= E1000_KMRNCTRLSTA_K1_ENABLE;
1042 else
1043 kmrn_reg &= ~E1000_KMRNCTRLSTA_K1_ENABLE;
1044
1045 ret_val = e1000e_write_kmrn_reg_locked(hw,
1046 E1000_KMRNCTRLSTA_K1_CONFIG,
1047 kmrn_reg);
1048 if (ret_val)
1049 goto out;
1050
1051 udelay(20);
1052 ctrl_ext = er32(CTRL_EXT);
1053 ctrl_reg = er32(CTRL);
1054
1055 reg = ctrl_reg & ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
1056 reg |= E1000_CTRL_FRCSPD;
1057 ew32(CTRL, reg);
1058
1059 ew32(CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_SPD_BYPS);
1060 udelay(20);
1061 ew32(CTRL, ctrl_reg);
1062 ew32(CTRL_EXT, ctrl_ext);
1063 udelay(20);
1064
1065out:
1066 return ret_val;
1067}
1068
1069/**
932 * e1000_oem_bits_config_ich8lan - SW-based LCD Configuration 1070 * e1000_oem_bits_config_ich8lan - SW-based LCD Configuration
933 * @hw: pointer to the HW structure 1071 * @hw: pointer to the HW structure
934 * @d0_state: boolean if entering d0 or d3 device state 1072 * @d0_state: boolean if entering d0 or d3 device state
@@ -1030,10 +1168,20 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw)
1030 ret_val = hw->phy.ops.acquire_phy(hw); 1168 ret_val = hw->phy.ops.acquire_phy(hw);
1031 if (ret_val) 1169 if (ret_val)
1032 return ret_val; 1170 return ret_val;
1171
1033 hw->phy.addr = 1; 1172 hw->phy.addr = 1;
1034 e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0); 1173 ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0);
1174 if (ret_val)
1175 goto out;
1035 hw->phy.ops.release_phy(hw); 1176 hw->phy.ops.release_phy(hw);
1036 1177
1178 /*
1179 * Configure the K1 Si workaround during phy reset assuming there is
1180 * link so that it disables K1 if link is in 1Gbps.
1181 */
1182 ret_val = e1000_k1_gig_workaround_hv(hw, true);
1183
1184out:
1037 return ret_val; 1185 return ret_val;
1038} 1186}
1039 1187
@@ -2435,6 +2583,7 @@ static s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw)
2435 **/ 2583 **/
2436static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) 2584static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
2437{ 2585{
2586 struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
2438 u16 reg; 2587 u16 reg;
2439 u32 ctrl, icr, kab; 2588 u32 ctrl, icr, kab;
2440 s32 ret_val; 2589 s32 ret_val;
@@ -2470,6 +2619,18 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
2470 ew32(PBS, E1000_PBS_16K); 2619 ew32(PBS, E1000_PBS_16K);
2471 } 2620 }
2472 2621
2622 if (hw->mac.type == e1000_pchlan) {
2623 /* Save the NVM K1 bit setting*/
2624 ret_val = e1000_read_nvm(hw, E1000_NVM_K1_CONFIG, 1, &reg);
2625 if (ret_val)
2626 return ret_val;
2627
2628 if (reg & E1000_NVM_K1_ENABLE)
2629 dev_spec->nvm_k1_enabled = true;
2630 else
2631 dev_spec->nvm_k1_enabled = false;
2632 }
2633
2473 ctrl = er32(CTRL); 2634 ctrl = er32(CTRL);
2474 2635
2475 if (!e1000_check_reset_block(hw)) { 2636 if (!e1000_check_reset_block(hw)) {
@@ -2847,14 +3008,6 @@ static s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *speed,
2847 if (ret_val) 3008 if (ret_val)
2848 return ret_val; 3009 return ret_val;
2849 3010
2850 if ((hw->mac.type == e1000_pchlan) && (*speed == SPEED_1000)) {
2851 ret_val = e1000e_write_kmrn_reg(hw,
2852 E1000_KMRNCTRLSTA_K1_CONFIG,
2853 E1000_KMRNCTRLSTA_K1_DISABLE);
2854 if (ret_val)
2855 return ret_val;
2856 }
2857
2858 if ((hw->mac.type == e1000_ich8lan) && 3011 if ((hw->mac.type == e1000_ich8lan) &&
2859 (hw->phy.type == e1000_phy_igp_3) && 3012 (hw->phy.type == e1000_phy_igp_3) &&
2860 (*speed == SPEED_1000)) { 3013 (*speed == SPEED_1000)) {