diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/e1000e/defines.h | 1 | ||||
-rw-r--r-- | drivers/net/e1000e/ich8lan.c | 295 |
2 files changed, 218 insertions, 78 deletions
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h index c0f185beb8bc..4741ef9ec385 100644 --- a/drivers/net/e1000e/defines.h +++ b/drivers/net/e1000e/defines.h | |||
@@ -347,6 +347,7 @@ | |||
347 | /* Extended Configuration Control and Size */ | 347 | /* Extended Configuration Control and Size */ |
348 | #define E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP 0x00000020 | 348 | #define E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP 0x00000020 |
349 | #define E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE 0x00000001 | 349 | #define E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE 0x00000001 |
350 | #define E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE 0x00000008 | ||
350 | #define E1000_EXTCNF_CTRL_SWFLAG 0x00000020 | 351 | #define E1000_EXTCNF_CTRL_SWFLAG 0x00000020 |
351 | #define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK 0x00FF0000 | 352 | #define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK 0x00FF0000 |
352 | #define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT 16 | 353 | #define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT 16 |
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index b6388b9535fd..095ffa56ed94 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c | |||
@@ -124,9 +124,20 @@ | |||
124 | 124 | ||
125 | #define SW_FLAG_TIMEOUT 1000 /* SW Semaphore flag timeout in milliseconds */ | 125 | #define SW_FLAG_TIMEOUT 1000 /* SW Semaphore flag timeout in milliseconds */ |
126 | 126 | ||
127 | /* SMBus Address Phy Register */ | ||
128 | #define HV_SMB_ADDR PHY_REG(768, 26) | ||
129 | #define HV_SMB_ADDR_PEC_EN 0x0200 | ||
130 | #define HV_SMB_ADDR_VALID 0x0080 | ||
131 | |||
132 | /* Strapping Option Register - RO */ | ||
133 | #define E1000_STRAP 0x0000C | ||
134 | #define E1000_STRAP_SMBUS_ADDRESS_MASK 0x00FE0000 | ||
135 | #define E1000_STRAP_SMBUS_ADDRESS_SHIFT 17 | ||
136 | |||
127 | /* OEM Bits Phy Register */ | 137 | /* OEM Bits Phy Register */ |
128 | #define HV_OEM_BITS PHY_REG(768, 25) | 138 | #define HV_OEM_BITS PHY_REG(768, 25) |
129 | #define HV_OEM_BITS_LPLU 0x0004 /* Low Power Link Up */ | 139 | #define HV_OEM_BITS_LPLU 0x0004 /* Low Power Link Up */ |
140 | #define HV_OEM_BITS_GBE_DIS 0x0040 /* Gigabit Disable */ | ||
130 | #define HV_OEM_BITS_RESTART_AN 0x0400 /* Restart Auto-negotiation */ | 141 | #define HV_OEM_BITS_RESTART_AN 0x0400 /* Restart Auto-negotiation */ |
131 | 142 | ||
132 | /* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */ | 143 | /* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */ |
@@ -208,6 +219,7 @@ static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw); | |||
208 | static s32 e1000_led_on_pchlan(struct e1000_hw *hw); | 219 | static s32 e1000_led_on_pchlan(struct e1000_hw *hw); |
209 | static s32 e1000_led_off_pchlan(struct e1000_hw *hw); | 220 | static s32 e1000_led_off_pchlan(struct e1000_hw *hw); |
210 | static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active); | 221 | static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active); |
222 | static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw); | ||
211 | 223 | ||
212 | static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg) | 224 | static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg) |
213 | { | 225 | { |
@@ -794,6 +806,191 @@ static s32 e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw) | |||
794 | } | 806 | } |
795 | 807 | ||
796 | /** | 808 | /** |
809 | * e1000_sw_lcd_config_ich8lan - SW-based LCD Configuration | ||
810 | * @hw: pointer to the HW structure | ||
811 | * | ||
812 | * SW should configure the LCD from the NVM extended configuration region | ||
813 | * as a workaround for certain parts. | ||
814 | **/ | ||
815 | static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) | ||
816 | { | ||
817 | struct e1000_phy_info *phy = &hw->phy; | ||
818 | u32 i, data, cnf_size, cnf_base_addr, sw_cfg_mask; | ||
819 | s32 ret_val; | ||
820 | u16 word_addr, reg_data, reg_addr, phy_page = 0; | ||
821 | |||
822 | ret_val = hw->phy.ops.acquire_phy(hw); | ||
823 | if (ret_val) | ||
824 | return ret_val; | ||
825 | |||
826 | /* | ||
827 | * Initialize the PHY from the NVM on ICH platforms. This | ||
828 | * is needed due to an issue where the NVM configuration is | ||
829 | * not properly autoloaded after power transitions. | ||
830 | * Therefore, after each PHY reset, we will load the | ||
831 | * configuration data out of the NVM manually. | ||
832 | */ | ||
833 | if ((hw->mac.type == e1000_ich8lan && phy->type == e1000_phy_igp_3) || | ||
834 | (hw->mac.type == e1000_pchlan)) { | ||
835 | struct e1000_adapter *adapter = hw->adapter; | ||
836 | |||
837 | /* Check if SW needs to configure the PHY */ | ||
838 | if ((adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M_AMT) || | ||
839 | (adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M) || | ||
840 | (hw->mac.type == e1000_pchlan)) | ||
841 | sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M; | ||
842 | else | ||
843 | sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG; | ||
844 | |||
845 | data = er32(FEXTNVM); | ||
846 | if (!(data & sw_cfg_mask)) | ||
847 | goto out; | ||
848 | |||
849 | /* Wait for basic configuration completes before proceeding */ | ||
850 | e1000_lan_init_done_ich8lan(hw); | ||
851 | |||
852 | /* | ||
853 | * Make sure HW does not configure LCD from PHY | ||
854 | * extended configuration before SW configuration | ||
855 | */ | ||
856 | data = er32(EXTCNF_CTRL); | ||
857 | if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE) | ||
858 | goto out; | ||
859 | |||
860 | cnf_size = er32(EXTCNF_SIZE); | ||
861 | cnf_size &= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK; | ||
862 | cnf_size >>= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT; | ||
863 | if (!cnf_size) | ||
864 | goto out; | ||
865 | |||
866 | cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK; | ||
867 | cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT; | ||
868 | |||
869 | if (!(data & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) && | ||
870 | (hw->mac.type == e1000_pchlan)) { | ||
871 | /* | ||
872 | * HW configures the SMBus address and LEDs when the | ||
873 | * OEM and LCD Write Enable bits are set in the NVM. | ||
874 | * When both NVM bits are cleared, SW will configure | ||
875 | * them instead. | ||
876 | */ | ||
877 | data = er32(STRAP); | ||
878 | data &= E1000_STRAP_SMBUS_ADDRESS_MASK; | ||
879 | reg_data = data >> E1000_STRAP_SMBUS_ADDRESS_SHIFT; | ||
880 | reg_data |= HV_SMB_ADDR_PEC_EN | HV_SMB_ADDR_VALID; | ||
881 | ret_val = e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR, | ||
882 | reg_data); | ||
883 | if (ret_val) | ||
884 | goto out; | ||
885 | |||
886 | data = er32(LEDCTL); | ||
887 | ret_val = e1000_write_phy_reg_hv_locked(hw, | ||
888 | HV_LED_CONFIG, | ||
889 | (u16)data); | ||
890 | if (ret_val) | ||
891 | goto out; | ||
892 | } | ||
893 | /* Configure LCD from extended configuration region. */ | ||
894 | |||
895 | /* cnf_base_addr is in DWORD */ | ||
896 | word_addr = (u16)(cnf_base_addr << 1); | ||
897 | |||
898 | for (i = 0; i < cnf_size; i++) { | ||
899 | ret_val = e1000_read_nvm(hw, (word_addr + i * 2), 1, | ||
900 | ®_data); | ||
901 | if (ret_val) | ||
902 | goto out; | ||
903 | |||
904 | ret_val = e1000_read_nvm(hw, (word_addr + i * 2 + 1), | ||
905 | 1, ®_addr); | ||
906 | if (ret_val) | ||
907 | goto out; | ||
908 | |||
909 | /* Save off the PHY page for future writes. */ | ||
910 | if (reg_addr == IGP01E1000_PHY_PAGE_SELECT) { | ||
911 | phy_page = reg_data; | ||
912 | continue; | ||
913 | } | ||
914 | |||
915 | reg_addr &= PHY_REG_MASK; | ||
916 | reg_addr |= phy_page; | ||
917 | |||
918 | ret_val = phy->ops.write_phy_reg_locked(hw, | ||
919 | (u32)reg_addr, | ||
920 | reg_data); | ||
921 | if (ret_val) | ||
922 | goto out; | ||
923 | } | ||
924 | } | ||
925 | |||
926 | out: | ||
927 | hw->phy.ops.release_phy(hw); | ||
928 | return ret_val; | ||
929 | } | ||
930 | |||
931 | /** | ||
932 | * e1000_oem_bits_config_ich8lan - SW-based LCD Configuration | ||
933 | * @hw: pointer to the HW structure | ||
934 | * @d0_state: boolean if entering d0 or d3 device state | ||
935 | * | ||
936 | * SW will configure Gbe Disable and LPLU based on the NVM. The four bits are | ||
937 | * collectively called OEM bits. The OEM Write Enable bit and SW Config bit | ||
938 | * in NVM determines whether HW should configure LPLU and Gbe Disable. | ||
939 | **/ | ||
940 | static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state) | ||
941 | { | ||
942 | s32 ret_val = 0; | ||
943 | u32 mac_reg; | ||
944 | u16 oem_reg; | ||
945 | |||
946 | if (hw->mac.type != e1000_pchlan) | ||
947 | return ret_val; | ||
948 | |||
949 | ret_val = hw->phy.ops.acquire_phy(hw); | ||
950 | if (ret_val) | ||
951 | return ret_val; | ||
952 | |||
953 | mac_reg = er32(EXTCNF_CTRL); | ||
954 | if (mac_reg & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) | ||
955 | goto out; | ||
956 | |||
957 | mac_reg = er32(FEXTNVM); | ||
958 | if (!(mac_reg & E1000_FEXTNVM_SW_CONFIG_ICH8M)) | ||
959 | goto out; | ||
960 | |||
961 | mac_reg = er32(PHY_CTRL); | ||
962 | |||
963 | ret_val = hw->phy.ops.read_phy_reg_locked(hw, HV_OEM_BITS, &oem_reg); | ||
964 | if (ret_val) | ||
965 | goto out; | ||
966 | |||
967 | oem_reg &= ~(HV_OEM_BITS_GBE_DIS | HV_OEM_BITS_LPLU); | ||
968 | |||
969 | if (d0_state) { | ||
970 | if (mac_reg & E1000_PHY_CTRL_GBE_DISABLE) | ||
971 | oem_reg |= HV_OEM_BITS_GBE_DIS; | ||
972 | |||
973 | if (mac_reg & E1000_PHY_CTRL_D0A_LPLU) | ||
974 | oem_reg |= HV_OEM_BITS_LPLU; | ||
975 | } else { | ||
976 | if (mac_reg & E1000_PHY_CTRL_NOND0A_GBE_DISABLE) | ||
977 | oem_reg |= HV_OEM_BITS_GBE_DIS; | ||
978 | |||
979 | if (mac_reg & E1000_PHY_CTRL_NOND0A_LPLU) | ||
980 | oem_reg |= HV_OEM_BITS_LPLU; | ||
981 | } | ||
982 | /* Restart auto-neg to activate the bits */ | ||
983 | oem_reg |= HV_OEM_BITS_RESTART_AN; | ||
984 | ret_val = hw->phy.ops.write_phy_reg_locked(hw, HV_OEM_BITS, oem_reg); | ||
985 | |||
986 | out: | ||
987 | hw->phy.ops.release_phy(hw); | ||
988 | |||
989 | return ret_val; | ||
990 | } | ||
991 | |||
992 | |||
993 | /** | ||
797 | * e1000_hv_phy_workarounds_ich8lan - A series of Phy workarounds to be | 994 | * e1000_hv_phy_workarounds_ich8lan - A series of Phy workarounds to be |
798 | * done after every PHY reset. | 995 | * done after every PHY reset. |
799 | **/ | 996 | **/ |
@@ -882,11 +1079,8 @@ static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw) | |||
882 | **/ | 1079 | **/ |
883 | static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) | 1080 | static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) |
884 | { | 1081 | { |
885 | struct e1000_phy_info *phy = &hw->phy; | 1082 | s32 ret_val = 0; |
886 | u32 i; | 1083 | u16 reg; |
887 | u32 data, cnf_size, cnf_base_addr, sw_cfg_mask; | ||
888 | s32 ret_val; | ||
889 | u16 reg, word_addr, reg_data, reg_addr, phy_page = 0; | ||
890 | 1084 | ||
891 | ret_val = e1000e_phy_hw_reset_generic(hw); | 1085 | ret_val = e1000e_phy_hw_reset_generic(hw); |
892 | if (ret_val) | 1086 | if (ret_val) |
@@ -905,81 +1099,16 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) | |||
905 | if (hw->mac.type == e1000_pchlan) | 1099 | if (hw->mac.type == e1000_pchlan) |
906 | e1e_rphy(hw, BM_WUC, ®); | 1100 | e1e_rphy(hw, BM_WUC, ®); |
907 | 1101 | ||
908 | /* | 1102 | /* Configure the LCD with the extended configuration region in NVM */ |
909 | * Initialize the PHY from the NVM on ICH platforms. This | 1103 | ret_val = e1000_sw_lcd_config_ich8lan(hw); |
910 | * is needed due to an issue where the NVM configuration is | 1104 | if (ret_val) |
911 | * not properly autoloaded after power transitions. | 1105 | goto out; |
912 | * Therefore, after each PHY reset, we will load the | ||
913 | * configuration data out of the NVM manually. | ||
914 | */ | ||
915 | if (hw->mac.type == e1000_ich8lan && phy->type == e1000_phy_igp_3) { | ||
916 | struct e1000_adapter *adapter = hw->adapter; | ||
917 | |||
918 | /* Check if SW needs configure the PHY */ | ||
919 | if ((adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M_AMT) || | ||
920 | (adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M)) | ||
921 | sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M; | ||
922 | else | ||
923 | sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG; | ||
924 | |||
925 | data = er32(FEXTNVM); | ||
926 | if (!(data & sw_cfg_mask)) | ||
927 | return 0; | ||
928 | |||
929 | /* Wait for basic configuration completes before proceeding */ | ||
930 | e1000_lan_init_done_ich8lan(hw); | ||
931 | |||
932 | /* | ||
933 | * Make sure HW does not configure LCD from PHY | ||
934 | * extended configuration before SW configuration | ||
935 | */ | ||
936 | data = er32(EXTCNF_CTRL); | ||
937 | if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE) | ||
938 | return 0; | ||
939 | |||
940 | cnf_size = er32(EXTCNF_SIZE); | ||
941 | cnf_size &= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK; | ||
942 | cnf_size >>= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT; | ||
943 | if (!cnf_size) | ||
944 | return 0; | ||
945 | |||
946 | cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK; | ||
947 | cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT; | ||
948 | |||
949 | /* Configure LCD from extended configuration region. */ | ||
950 | |||
951 | /* cnf_base_addr is in DWORD */ | ||
952 | word_addr = (u16)(cnf_base_addr << 1); | ||
953 | |||
954 | for (i = 0; i < cnf_size; i++) { | ||
955 | ret_val = e1000_read_nvm(hw, | ||
956 | (word_addr + i * 2), | ||
957 | 1, | ||
958 | ®_data); | ||
959 | if (ret_val) | ||
960 | return ret_val; | ||
961 | |||
962 | ret_val = e1000_read_nvm(hw, | ||
963 | (word_addr + i * 2 + 1), | ||
964 | 1, | ||
965 | ®_addr); | ||
966 | if (ret_val) | ||
967 | return ret_val; | ||
968 | |||
969 | /* Save off the PHY page for future writes. */ | ||
970 | if (reg_addr == IGP01E1000_PHY_PAGE_SELECT) { | ||
971 | phy_page = reg_data; | ||
972 | continue; | ||
973 | } | ||
974 | |||
975 | reg_addr |= phy_page; | ||
976 | 1106 | ||
977 | ret_val = e1e_wphy(hw, (u32)reg_addr, reg_data); | 1107 | /* Configure the LCD with the OEM bits in NVM */ |
978 | if (ret_val) | 1108 | if (hw->mac.type == e1000_pchlan) |
979 | return ret_val; | 1109 | ret_val = e1000_oem_bits_config_ich8lan(hw, true); |
980 | } | ||
981 | } | ||
982 | 1110 | ||
1111 | out: | ||
983 | return 0; | 1112 | return 0; |
984 | } | 1113 | } |
985 | 1114 | ||
@@ -2386,6 +2515,15 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) | |||
2386 | if (hw->mac.type == e1000_pchlan) | 2515 | if (hw->mac.type == e1000_pchlan) |
2387 | e1e_rphy(hw, BM_WUC, ®); | 2516 | e1e_rphy(hw, BM_WUC, ®); |
2388 | 2517 | ||
2518 | ret_val = e1000_sw_lcd_config_ich8lan(hw); | ||
2519 | if (ret_val) | ||
2520 | goto out; | ||
2521 | |||
2522 | if (hw->mac.type == e1000_pchlan) { | ||
2523 | ret_val = e1000_oem_bits_config_ich8lan(hw, true); | ||
2524 | if (ret_val) | ||
2525 | goto out; | ||
2526 | } | ||
2389 | /* | 2527 | /* |
2390 | * For PCH, this write will make sure that any noise | 2528 | * For PCH, this write will make sure that any noise |
2391 | * will be detected as a CRC error and be dropped rather than show up | 2529 | * will be detected as a CRC error and be dropped rather than show up |
@@ -2404,6 +2542,7 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) | |||
2404 | if (hw->mac.type == e1000_pchlan) | 2542 | if (hw->mac.type == e1000_pchlan) |
2405 | ret_val = e1000_hv_phy_workarounds_ich8lan(hw); | 2543 | ret_val = e1000_hv_phy_workarounds_ich8lan(hw); |
2406 | 2544 | ||
2545 | out: | ||
2407 | return ret_val; | 2546 | return ret_val; |
2408 | } | 2547 | } |
2409 | 2548 | ||