diff options
Diffstat (limited to 'drivers/net/igb/e1000_82575.c')
| -rw-r--r-- | drivers/net/igb/e1000_82575.c | 285 |
1 files changed, 280 insertions, 5 deletions
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index 65c1833244f7..6b256c275e10 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c | |||
| @@ -64,7 +64,14 @@ static s32 igb_reset_init_script_82575(struct e1000_hw *); | |||
| 64 | static s32 igb_read_mac_addr_82575(struct e1000_hw *); | 64 | static s32 igb_read_mac_addr_82575(struct e1000_hw *); |
| 65 | static s32 igb_set_pcie_completion_timeout(struct e1000_hw *hw); | 65 | static s32 igb_set_pcie_completion_timeout(struct e1000_hw *hw); |
| 66 | static s32 igb_reset_mdicnfg_82580(struct e1000_hw *hw); | 66 | static s32 igb_reset_mdicnfg_82580(struct e1000_hw *hw); |
| 67 | 67 | static s32 igb_validate_nvm_checksum_82580(struct e1000_hw *hw); | |
| 68 | static s32 igb_update_nvm_checksum_82580(struct e1000_hw *hw); | ||
| 69 | static s32 igb_update_nvm_checksum_with_offset(struct e1000_hw *hw, | ||
| 70 | u16 offset); | ||
| 71 | static s32 igb_validate_nvm_checksum_with_offset(struct e1000_hw *hw, | ||
| 72 | u16 offset); | ||
| 73 | static s32 igb_validate_nvm_checksum_i350(struct e1000_hw *hw); | ||
| 74 | static s32 igb_update_nvm_checksum_i350(struct e1000_hw *hw); | ||
| 68 | static const u16 e1000_82580_rxpbs_table[] = | 75 | static const u16 e1000_82580_rxpbs_table[] = |
| 69 | { 36, 72, 144, 1, 2, 4, 8, 16, | 76 | { 36, 72, 144, 1, 2, 4, 8, 16, |
| 70 | 35, 70, 140 }; | 77 | 35, 70, 140 }; |
| @@ -195,7 +202,11 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) | |||
| 195 | mac->arc_subsystem_valid = | 202 | mac->arc_subsystem_valid = |
| 196 | (rd32(E1000_FWSM) & E1000_FWSM_MODE_MASK) | 203 | (rd32(E1000_FWSM) & E1000_FWSM_MODE_MASK) |
| 197 | ? true : false; | 204 | ? true : false; |
| 198 | 205 | /* enable EEE on i350 parts */ | |
| 206 | if (mac->type == e1000_i350) | ||
| 207 | dev_spec->eee_disable = false; | ||
| 208 | else | ||
| 209 | dev_spec->eee_disable = true; | ||
| 199 | /* physical interface link setup */ | 210 | /* physical interface link setup */ |
| 200 | mac->ops.setup_physical_interface = | 211 | mac->ops.setup_physical_interface = |
| 201 | (hw->phy.media_type == e1000_media_type_copper) | 212 | (hw->phy.media_type == e1000_media_type_copper) |
| @@ -233,10 +244,32 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) | |||
| 233 | */ | 244 | */ |
| 234 | size += NVM_WORD_SIZE_BASE_SHIFT; | 245 | size += NVM_WORD_SIZE_BASE_SHIFT; |
| 235 | 246 | ||
| 236 | /* EEPROM access above 16k is unsupported */ | ||
| 237 | if (size > 14) | ||
| 238 | size = 14; | ||
| 239 | nvm->word_size = 1 << size; | 247 | nvm->word_size = 1 << size; |
| 248 | if (nvm->word_size == (1 << 15)) | ||
| 249 | nvm->page_size = 128; | ||
| 250 | |||
| 251 | /* NVM Function Pointers */ | ||
| 252 | nvm->ops.acquire = igb_acquire_nvm_82575; | ||
| 253 | if (nvm->word_size < (1 << 15)) | ||
| 254 | nvm->ops.read = igb_read_nvm_eerd; | ||
| 255 | else | ||
| 256 | nvm->ops.read = igb_read_nvm_spi; | ||
| 257 | |||
| 258 | nvm->ops.release = igb_release_nvm_82575; | ||
| 259 | switch (hw->mac.type) { | ||
| 260 | case e1000_82580: | ||
| 261 | nvm->ops.validate = igb_validate_nvm_checksum_82580; | ||
| 262 | nvm->ops.update = igb_update_nvm_checksum_82580; | ||
| 263 | break; | ||
| 264 | case e1000_i350: | ||
| 265 | nvm->ops.validate = igb_validate_nvm_checksum_i350; | ||
| 266 | nvm->ops.update = igb_update_nvm_checksum_i350; | ||
| 267 | break; | ||
| 268 | default: | ||
| 269 | nvm->ops.validate = igb_validate_nvm_checksum; | ||
| 270 | nvm->ops.update = igb_update_nvm_checksum; | ||
| 271 | } | ||
| 272 | nvm->ops.write = igb_write_nvm_spi; | ||
| 240 | 273 | ||
| 241 | /* if part supports SR-IOV then initialize mailbox parameters */ | 274 | /* if part supports SR-IOV then initialize mailbox parameters */ |
| 242 | switch (mac->type) { | 275 | switch (mac->type) { |
| @@ -1754,6 +1787,248 @@ u16 igb_rxpbs_adjust_82580(u32 data) | |||
| 1754 | return ret_val; | 1787 | return ret_val; |
| 1755 | } | 1788 | } |
| 1756 | 1789 | ||
| 1790 | /** | ||
| 1791 | * igb_validate_nvm_checksum_with_offset - Validate EEPROM | ||
| 1792 | * checksum | ||
| 1793 | * @hw: pointer to the HW structure | ||
| 1794 | * @offset: offset in words of the checksum protected region | ||
| 1795 | * | ||
| 1796 | * Calculates the EEPROM checksum by reading/adding each word of the EEPROM | ||
| 1797 | * and then verifies that the sum of the EEPROM is equal to 0xBABA. | ||
| 1798 | **/ | ||
| 1799 | s32 igb_validate_nvm_checksum_with_offset(struct e1000_hw *hw, u16 offset) | ||
| 1800 | { | ||
| 1801 | s32 ret_val = 0; | ||
| 1802 | u16 checksum = 0; | ||
| 1803 | u16 i, nvm_data; | ||
| 1804 | |||
| 1805 | for (i = offset; i < ((NVM_CHECKSUM_REG + offset) + 1); i++) { | ||
| 1806 | ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data); | ||
| 1807 | if (ret_val) { | ||
| 1808 | hw_dbg("NVM Read Error\n"); | ||
| 1809 | goto out; | ||
| 1810 | } | ||
| 1811 | checksum += nvm_data; | ||
| 1812 | } | ||
| 1813 | |||
| 1814 | if (checksum != (u16) NVM_SUM) { | ||
| 1815 | hw_dbg("NVM Checksum Invalid\n"); | ||
| 1816 | ret_val = -E1000_ERR_NVM; | ||
| 1817 | goto out; | ||
| 1818 | } | ||
| 1819 | |||
| 1820 | out: | ||
| 1821 | return ret_val; | ||
| 1822 | } | ||
| 1823 | |||
| 1824 | /** | ||
| 1825 | * igb_update_nvm_checksum_with_offset - Update EEPROM | ||
| 1826 | * checksum | ||
| 1827 | * @hw: pointer to the HW structure | ||
| 1828 | * @offset: offset in words of the checksum protected region | ||
| 1829 | * | ||
| 1830 | * Updates the EEPROM checksum by reading/adding each word of the EEPROM | ||
| 1831 | * up to the checksum. Then calculates the EEPROM checksum and writes the | ||
| 1832 | * value to the EEPROM. | ||
| 1833 | **/ | ||
| 1834 | s32 igb_update_nvm_checksum_with_offset(struct e1000_hw *hw, u16 offset) | ||
| 1835 | { | ||
| 1836 | s32 ret_val; | ||
| 1837 | u16 checksum = 0; | ||
| 1838 | u16 i, nvm_data; | ||
| 1839 | |||
| 1840 | for (i = offset; i < (NVM_CHECKSUM_REG + offset); i++) { | ||
| 1841 | ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data); | ||
| 1842 | if (ret_val) { | ||
| 1843 | hw_dbg("NVM Read Error while updating checksum.\n"); | ||
| 1844 | goto out; | ||
| 1845 | } | ||
| 1846 | checksum += nvm_data; | ||
| 1847 | } | ||
| 1848 | checksum = (u16) NVM_SUM - checksum; | ||
| 1849 | ret_val = hw->nvm.ops.write(hw, (NVM_CHECKSUM_REG + offset), 1, | ||
| 1850 | &checksum); | ||
| 1851 | if (ret_val) | ||
| 1852 | hw_dbg("NVM Write Error while updating checksum.\n"); | ||
| 1853 | |||
| 1854 | out: | ||
| 1855 | return ret_val; | ||
| 1856 | } | ||
| 1857 | |||
| 1858 | /** | ||
| 1859 | * igb_validate_nvm_checksum_82580 - Validate EEPROM checksum | ||
| 1860 | * @hw: pointer to the HW structure | ||
| 1861 | * | ||
| 1862 | * Calculates the EEPROM section checksum by reading/adding each word of | ||
| 1863 | * the EEPROM and then verifies that the sum of the EEPROM is | ||
| 1864 | * equal to 0xBABA. | ||
| 1865 | **/ | ||
| 1866 | static s32 igb_validate_nvm_checksum_82580(struct e1000_hw *hw) | ||
| 1867 | { | ||
| 1868 | s32 ret_val = 0; | ||
| 1869 | u16 eeprom_regions_count = 1; | ||
| 1870 | u16 j, nvm_data; | ||
| 1871 | u16 nvm_offset; | ||
| 1872 | |||
| 1873 | ret_val = hw->nvm.ops.read(hw, NVM_COMPATIBILITY_REG_3, 1, &nvm_data); | ||
| 1874 | if (ret_val) { | ||
| 1875 | hw_dbg("NVM Read Error\n"); | ||
| 1876 | goto out; | ||
| 1877 | } | ||
| 1878 | |||
| 1879 | if (nvm_data & NVM_COMPATIBILITY_BIT_MASK) { | ||
| 1880 | /* if chekcsums compatibility bit is set validate checksums | ||
| 1881 | * for all 4 ports. */ | ||
| 1882 | eeprom_regions_count = 4; | ||
| 1883 | } | ||
| 1884 | |||
| 1885 | for (j = 0; j < eeprom_regions_count; j++) { | ||
| 1886 | nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j); | ||
| 1887 | ret_val = igb_validate_nvm_checksum_with_offset(hw, | ||
| 1888 | nvm_offset); | ||
| 1889 | if (ret_val != 0) | ||
| 1890 | goto out; | ||
| 1891 | } | ||
| 1892 | |||
| 1893 | out: | ||
| 1894 | return ret_val; | ||
| 1895 | } | ||
| 1896 | |||
| 1897 | /** | ||
| 1898 | * igb_update_nvm_checksum_82580 - Update EEPROM checksum | ||
| 1899 | * @hw: pointer to the HW structure | ||
| 1900 | * | ||
| 1901 | * Updates the EEPROM section checksums for all 4 ports by reading/adding | ||
| 1902 | * each word of the EEPROM up to the checksum. Then calculates the EEPROM | ||
| 1903 | * checksum and writes the value to the EEPROM. | ||
| 1904 | **/ | ||
| 1905 | static s32 igb_update_nvm_checksum_82580(struct e1000_hw *hw) | ||
| 1906 | { | ||
| 1907 | s32 ret_val; | ||
| 1908 | u16 j, nvm_data; | ||
| 1909 | u16 nvm_offset; | ||
| 1910 | |||
| 1911 | ret_val = hw->nvm.ops.read(hw, NVM_COMPATIBILITY_REG_3, 1, &nvm_data); | ||
| 1912 | if (ret_val) { | ||
| 1913 | hw_dbg("NVM Read Error while updating checksum" | ||
| 1914 | " compatibility bit.\n"); | ||
| 1915 | goto out; | ||
| 1916 | } | ||
| 1917 | |||
| 1918 | if ((nvm_data & NVM_COMPATIBILITY_BIT_MASK) == 0) { | ||
| 1919 | /* set compatibility bit to validate checksums appropriately */ | ||
| 1920 | nvm_data = nvm_data | NVM_COMPATIBILITY_BIT_MASK; | ||
| 1921 | ret_val = hw->nvm.ops.write(hw, NVM_COMPATIBILITY_REG_3, 1, | ||
| 1922 | &nvm_data); | ||
| 1923 | if (ret_val) { | ||
| 1924 | hw_dbg("NVM Write Error while updating checksum" | ||
| 1925 | " compatibility bit.\n"); | ||
| 1926 | goto out; | ||
| 1927 | } | ||
| 1928 | } | ||
| 1929 | |||
| 1930 | for (j = 0; j < 4; j++) { | ||
| 1931 | nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j); | ||
| 1932 | ret_val = igb_update_nvm_checksum_with_offset(hw, nvm_offset); | ||
| 1933 | if (ret_val) | ||
| 1934 | goto out; | ||
| 1935 | } | ||
| 1936 | |||
| 1937 | out: | ||
| 1938 | return ret_val; | ||
| 1939 | } | ||
| 1940 | |||
| 1941 | /** | ||
| 1942 | * igb_validate_nvm_checksum_i350 - Validate EEPROM checksum | ||
| 1943 | * @hw: pointer to the HW structure | ||
| 1944 | * | ||
| 1945 | * Calculates the EEPROM section checksum by reading/adding each word of | ||
| 1946 | * the EEPROM and then verifies that the sum of the EEPROM is | ||
| 1947 | * equal to 0xBABA. | ||
| 1948 | **/ | ||
| 1949 | static s32 igb_validate_nvm_checksum_i350(struct e1000_hw *hw) | ||
| 1950 | { | ||
| 1951 | s32 ret_val = 0; | ||
| 1952 | u16 j; | ||
| 1953 | u16 nvm_offset; | ||
| 1954 | |||
| 1955 | for (j = 0; j < 4; j++) { | ||
| 1956 | nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j); | ||
| 1957 | ret_val = igb_validate_nvm_checksum_with_offset(hw, | ||
| 1958 | nvm_offset); | ||
| 1959 | if (ret_val != 0) | ||
| 1960 | goto out; | ||
| 1961 | } | ||
| 1962 | |||
| 1963 | out: | ||
| 1964 | return ret_val; | ||
| 1965 | } | ||
| 1966 | |||
| 1967 | /** | ||
| 1968 | * igb_update_nvm_checksum_i350 - Update EEPROM checksum | ||
| 1969 | * @hw: pointer to the HW structure | ||
| 1970 | * | ||
| 1971 | * Updates the EEPROM section checksums for all 4 ports by reading/adding | ||
| 1972 | * each word of the EEPROM up to the checksum. Then calculates the EEPROM | ||
| 1973 | * checksum and writes the value to the EEPROM. | ||
| 1974 | **/ | ||
| 1975 | static s32 igb_update_nvm_checksum_i350(struct e1000_hw *hw) | ||
| 1976 | { | ||
| 1977 | s32 ret_val = 0; | ||
| 1978 | u16 j; | ||
| 1979 | u16 nvm_offset; | ||
| 1980 | |||
| 1981 | for (j = 0; j < 4; j++) { | ||
| 1982 | nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j); | ||
| 1983 | ret_val = igb_update_nvm_checksum_with_offset(hw, nvm_offset); | ||
| 1984 | if (ret_val != 0) | ||
| 1985 | goto out; | ||
| 1986 | } | ||
| 1987 | |||
| 1988 | out: | ||
| 1989 | return ret_val; | ||
| 1990 | } | ||
| 1991 | /** | ||
| 1992 | * igb_set_eee_i350 - Enable/disable EEE support | ||
| 1993 | * @hw: pointer to the HW structure | ||
| 1994 | * | ||
| 1995 | * Enable/disable EEE based on setting in dev_spec structure. | ||
| 1996 | * | ||
| 1997 | **/ | ||
| 1998 | s32 igb_set_eee_i350(struct e1000_hw *hw) | ||
| 1999 | { | ||
| 2000 | s32 ret_val = 0; | ||
| 2001 | u32 ipcnfg, eeer, ctrl_ext; | ||
| 2002 | |||
| 2003 | ctrl_ext = rd32(E1000_CTRL_EXT); | ||
| 2004 | if ((hw->mac.type != e1000_i350) || | ||
| 2005 | (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK)) | ||
| 2006 | goto out; | ||
| 2007 | ipcnfg = rd32(E1000_IPCNFG); | ||
| 2008 | eeer = rd32(E1000_EEER); | ||
| 2009 | |||
| 2010 | /* enable or disable per user setting */ | ||
| 2011 | if (!(hw->dev_spec._82575.eee_disable)) { | ||
| 2012 | ipcnfg |= (E1000_IPCNFG_EEE_1G_AN | | ||
| 2013 | E1000_IPCNFG_EEE_100M_AN); | ||
| 2014 | eeer |= (E1000_EEER_TX_LPI_EN | | ||
| 2015 | E1000_EEER_RX_LPI_EN | | ||
| 2016 | E1000_EEER_LPI_FC); | ||
| 2017 | |||
| 2018 | } else { | ||
| 2019 | ipcnfg &= ~(E1000_IPCNFG_EEE_1G_AN | | ||
| 2020 | E1000_IPCNFG_EEE_100M_AN); | ||
| 2021 | eeer &= ~(E1000_EEER_TX_LPI_EN | | ||
| 2022 | E1000_EEER_RX_LPI_EN | | ||
| 2023 | E1000_EEER_LPI_FC); | ||
| 2024 | } | ||
| 2025 | wr32(E1000_IPCNFG, ipcnfg); | ||
| 2026 | wr32(E1000_EEER, eeer); | ||
| 2027 | out: | ||
| 2028 | |||
| 2029 | return ret_val; | ||
| 2030 | } | ||
| 2031 | |||
| 1757 | static struct e1000_mac_operations e1000_mac_ops_82575 = { | 2032 | static struct e1000_mac_operations e1000_mac_ops_82575 = { |
| 1758 | .init_hw = igb_init_hw_82575, | 2033 | .init_hw = igb_init_hw_82575, |
| 1759 | .check_for_link = igb_check_for_link_82575, | 2034 | .check_for_link = igb_check_for_link_82575, |
