aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBruce Allan <bruce.w.allan@intel.com>2009-10-29 09:45:45 -0400
committerDavid S. Miller <davem@davemloft.net>2009-10-30 01:48:37 -0400
commitf523d2114e93c559dbcf1b49d46b339fc0eda37a (patch)
tree9155879569dea7244193e927b1218fd7d6aaf22f
parent8fbd962e39517dfb2bfd363eba4b51cdfa299593 (diff)
e1000e: config PHY via software after resets
On PCH-based (82577/82578) and some ICH8-based parts (82566) there is an issue with the hardware automatically configuring the PHY with contents from the EEPROM after the PHY is reset, so do the configuration by the driver instead. This was already similarly done for some 82566 parts in e1000_phy_hw_reset_ich8lan() but needs to be done after other resets, so move the PHY configuration code to its own function and call after all PHY resets. Signed-off-by: Bruce Allan <bruce.w.allan@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/e1000e/defines.h1
-rw-r--r--drivers/net/e1000e/ich8lan.c295
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);
208static s32 e1000_led_on_pchlan(struct e1000_hw *hw); 219static s32 e1000_led_on_pchlan(struct e1000_hw *hw);
209static s32 e1000_led_off_pchlan(struct e1000_hw *hw); 220static s32 e1000_led_off_pchlan(struct e1000_hw *hw);
210static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active); 221static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active);
222static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw);
211 223
212static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg) 224static 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 **/
815static 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 &reg_data);
901 if (ret_val)
902 goto out;
903
904 ret_val = e1000_read_nvm(hw, (word_addr + i * 2 + 1),
905 1, &reg_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
926out:
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 **/
940static 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
986out:
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 **/
883static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) 1080static 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, &reg); 1100 e1e_rphy(hw, BM_WUC, &reg);
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 &reg_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 &reg_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
1111out:
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, &reg); 2516 e1e_rphy(hw, BM_WUC, &reg);
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
2545out:
2407 return ret_val; 2546 return ret_val;
2408} 2547}
2409 2548