diff options
| -rw-r--r-- | drivers/net/e1000e/ich8lan.c | 152 |
1 files changed, 75 insertions, 77 deletions
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 448e12378dbc..61f89275d7c3 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c | |||
| @@ -815,11 +815,16 @@ static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw) | |||
| 815 | **/ | 815 | **/ |
| 816 | static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) | 816 | static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) |
| 817 | { | 817 | { |
| 818 | struct e1000_adapter *adapter = hw->adapter; | ||
| 818 | struct e1000_phy_info *phy = &hw->phy; | 819 | struct e1000_phy_info *phy = &hw->phy; |
| 819 | u32 i, data, cnf_size, cnf_base_addr, sw_cfg_mask; | 820 | u32 i, data, cnf_size, cnf_base_addr, sw_cfg_mask; |
| 820 | s32 ret_val; | 821 | s32 ret_val = 0; |
| 821 | u16 word_addr, reg_data, reg_addr, phy_page = 0; | 822 | u16 word_addr, reg_data, reg_addr, phy_page = 0; |
| 822 | 823 | ||
| 824 | if (!(hw->mac.type == e1000_ich8lan && phy->type == e1000_phy_igp_3) && | ||
| 825 | !(hw->mac.type == e1000_pchlan)) | ||
| 826 | return ret_val; | ||
| 827 | |||
| 823 | ret_val = hw->phy.ops.acquire(hw); | 828 | ret_val = hw->phy.ops.acquire(hw); |
| 824 | if (ret_val) | 829 | if (ret_val) |
| 825 | return ret_val; | 830 | return ret_val; |
| @@ -831,97 +836,90 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) | |||
| 831 | * Therefore, after each PHY reset, we will load the | 836 | * Therefore, after each PHY reset, we will load the |
| 832 | * configuration data out of the NVM manually. | 837 | * configuration data out of the NVM manually. |
| 833 | */ | 838 | */ |
| 834 | if ((hw->mac.type == e1000_ich8lan && phy->type == e1000_phy_igp_3) || | 839 | if ((adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M_AMT) || |
| 835 | (hw->mac.type == e1000_pchlan)) { | 840 | (adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M) || |
| 836 | struct e1000_adapter *adapter = hw->adapter; | 841 | (hw->mac.type == e1000_pchlan)) |
| 837 | 842 | sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M; | |
| 838 | /* Check if SW needs to configure the PHY */ | 843 | else |
| 839 | if ((adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M_AMT) || | 844 | sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG; |
| 840 | (adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M) || | ||
| 841 | (hw->mac.type == e1000_pchlan)) | ||
| 842 | sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M; | ||
| 843 | else | ||
| 844 | sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG; | ||
| 845 | 845 | ||
| 846 | data = er32(FEXTNVM); | 846 | data = er32(FEXTNVM); |
| 847 | if (!(data & sw_cfg_mask)) | 847 | if (!(data & sw_cfg_mask)) |
| 848 | goto out; | 848 | goto out; |
| 849 | 849 | ||
| 850 | /* Wait for basic configuration completes before proceeding */ | 850 | /* Wait for basic configuration completes before proceeding */ |
| 851 | e1000_lan_init_done_ich8lan(hw); | 851 | e1000_lan_init_done_ich8lan(hw); |
| 852 | 852 | ||
| 853 | /* | ||
| 854 | * Make sure HW does not configure LCD from PHY | ||
| 855 | * extended configuration before SW configuration | ||
| 856 | */ | ||
| 857 | data = er32(EXTCNF_CTRL); | ||
| 858 | if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE) | ||
| 859 | goto out; | ||
| 860 | |||
| 861 | cnf_size = er32(EXTCNF_SIZE); | ||
| 862 | cnf_size &= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK; | ||
| 863 | cnf_size >>= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT; | ||
| 864 | if (!cnf_size) | ||
| 865 | goto out; | ||
| 866 | |||
| 867 | cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK; | ||
| 868 | cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT; | ||
| 869 | |||
| 870 | if (!(data & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) && | ||
| 871 | (hw->mac.type == e1000_pchlan)) { | ||
| 853 | /* | 872 | /* |
| 854 | * Make sure HW does not configure LCD from PHY | 873 | * HW configures the SMBus address and LEDs when the |
| 855 | * extended configuration before SW configuration | 874 | * OEM and LCD Write Enable bits are set in the NVM. |
| 875 | * When both NVM bits are cleared, SW will configure | ||
| 876 | * them instead. | ||
| 856 | */ | 877 | */ |
| 857 | data = er32(EXTCNF_CTRL); | 878 | data = er32(STRAP); |
| 858 | if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE) | 879 | data &= E1000_STRAP_SMBUS_ADDRESS_MASK; |
| 880 | reg_data = data >> E1000_STRAP_SMBUS_ADDRESS_SHIFT; | ||
| 881 | reg_data |= HV_SMB_ADDR_PEC_EN | HV_SMB_ADDR_VALID; | ||
| 882 | ret_val = e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR, | ||
| 883 | reg_data); | ||
| 884 | if (ret_val) | ||
| 859 | goto out; | 885 | goto out; |
| 860 | 886 | ||
| 861 | cnf_size = er32(EXTCNF_SIZE); | 887 | data = er32(LEDCTL); |
| 862 | cnf_size &= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK; | 888 | ret_val = e1000_write_phy_reg_hv_locked(hw, HV_LED_CONFIG, |
| 863 | cnf_size >>= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT; | 889 | (u16)data); |
| 864 | if (!cnf_size) | 890 | if (ret_val) |
| 865 | goto out; | 891 | goto out; |
| 892 | } | ||
| 866 | 893 | ||
| 867 | cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK; | 894 | /* Configure LCD from extended configuration region. */ |
| 868 | cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT; | ||
| 869 | |||
| 870 | if (!(data & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) && | ||
| 871 | (hw->mac.type == e1000_pchlan)) { | ||
| 872 | /* | ||
| 873 | * HW configures the SMBus address and LEDs when the | ||
| 874 | * OEM and LCD Write Enable bits are set in the NVM. | ||
| 875 | * When both NVM bits are cleared, SW will configure | ||
| 876 | * them instead. | ||
| 877 | */ | ||
| 878 | data = er32(STRAP); | ||
| 879 | data &= E1000_STRAP_SMBUS_ADDRESS_MASK; | ||
| 880 | reg_data = data >> E1000_STRAP_SMBUS_ADDRESS_SHIFT; | ||
| 881 | reg_data |= HV_SMB_ADDR_PEC_EN | HV_SMB_ADDR_VALID; | ||
| 882 | ret_val = e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR, | ||
| 883 | reg_data); | ||
| 884 | if (ret_val) | ||
| 885 | goto out; | ||
| 886 | |||
| 887 | data = er32(LEDCTL); | ||
| 888 | ret_val = e1000_write_phy_reg_hv_locked(hw, | ||
| 889 | HV_LED_CONFIG, | ||
| 890 | (u16)data); | ||
| 891 | if (ret_val) | ||
| 892 | goto out; | ||
| 893 | } | ||
| 894 | /* Configure LCD from extended configuration region. */ | ||
| 895 | 895 | ||
| 896 | /* cnf_base_addr is in DWORD */ | 896 | /* cnf_base_addr is in DWORD */ |
| 897 | word_addr = (u16)(cnf_base_addr << 1); | 897 | word_addr = (u16)(cnf_base_addr << 1); |
| 898 | 898 | ||
| 899 | for (i = 0; i < cnf_size; i++) { | 899 | for (i = 0; i < cnf_size; i++) { |
| 900 | ret_val = e1000_read_nvm(hw, (word_addr + i * 2), 1, | 900 | ret_val = e1000_read_nvm(hw, (word_addr + i * 2), 1, |
| 901 | ®_data); | 901 | ®_data); |
| 902 | if (ret_val) | 902 | if (ret_val) |
| 903 | goto out; | 903 | goto out; |
| 904 | 904 | ||
| 905 | ret_val = e1000_read_nvm(hw, (word_addr + i * 2 + 1), | 905 | ret_val = e1000_read_nvm(hw, (word_addr + i * 2 + 1), |
| 906 | 1, ®_addr); | 906 | 1, ®_addr); |
| 907 | if (ret_val) | 907 | if (ret_val) |
| 908 | goto out; | 908 | goto out; |
| 909 | 909 | ||
| 910 | /* Save off the PHY page for future writes. */ | 910 | /* Save off the PHY page for future writes. */ |
| 911 | if (reg_addr == IGP01E1000_PHY_PAGE_SELECT) { | 911 | if (reg_addr == IGP01E1000_PHY_PAGE_SELECT) { |
| 912 | phy_page = reg_data; | 912 | phy_page = reg_data; |
| 913 | continue; | 913 | continue; |
| 914 | } | 914 | } |
| 915 | 915 | ||
| 916 | reg_addr &= PHY_REG_MASK; | 916 | reg_addr &= PHY_REG_MASK; |
| 917 | reg_addr |= phy_page; | 917 | reg_addr |= phy_page; |
| 918 | 918 | ||
| 919 | ret_val = phy->ops.write_reg_locked(hw, | 919 | ret_val = phy->ops.write_reg_locked(hw, (u32)reg_addr, |
| 920 | (u32)reg_addr, | 920 | reg_data); |
| 921 | reg_data); | 921 | if (ret_val) |
| 922 | if (ret_val) | 922 | goto out; |
| 923 | goto out; | ||
| 924 | } | ||
| 925 | } | 923 | } |
| 926 | 924 | ||
| 927 | out: | 925 | out: |
