diff options
author | Bruce Allan <bruce.w.allan@intel.com> | 2008-08-26 21:36:50 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-09-03 10:06:47 -0400 |
commit | f4187b56e1f8a05dd110875d5094b21b51ebd79b (patch) | |
tree | 7c3f97f98c808b6f6ab8ea6acdfb2f324e8a3c09 /drivers/net/e1000e/ich8lan.c | |
parent | 2f15f9d60190a62bc8ac50fa84fea31fc0b00ecf (diff) |
e1000e: add support for 82567LM-3 and 82567LF-3 (ICH10D) parts
Add support for new LOM devices on the latest generation ICHx platforms.
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/e1000e/ich8lan.c')
-rw-r--r-- | drivers/net/e1000e/ich8lan.c | 154 |
1 files changed, 144 insertions, 10 deletions
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index b5fc2c903044..0e76bb0378fd 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c | |||
@@ -43,7 +43,8 @@ | |||
43 | * 82567LM-2 Gigabit Network Connection | 43 | * 82567LM-2 Gigabit Network Connection |
44 | * 82567LF-2 Gigabit Network Connection | 44 | * 82567LF-2 Gigabit Network Connection |
45 | * 82567V-2 Gigabit Network Connection | 45 | * 82567V-2 Gigabit Network Connection |
46 | * 82562GT-3 10/100 Network Connection | 46 | * 82567LF-3 Gigabit Network Connection |
47 | * 82567LM-3 Gigabit Network Connection | ||
47 | * 82567LM-4 Gigabit Network Connection | 48 | * 82567LM-4 Gigabit Network Connection |
48 | */ | 49 | */ |
49 | 50 | ||
@@ -158,12 +159,15 @@ static s32 e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw); | |||
158 | static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank); | 159 | static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank); |
159 | static s32 e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw, | 160 | static s32 e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw, |
160 | u32 offset, u8 byte); | 161 | u32 offset, u8 byte); |
162 | static s32 e1000_read_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset, | ||
163 | u8 *data); | ||
161 | static s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, u32 offset, | 164 | static s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, u32 offset, |
162 | u16 *data); | 165 | u16 *data); |
163 | static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, | 166 | static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, |
164 | u8 size, u16 *data); | 167 | u8 size, u16 *data); |
165 | static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw); | 168 | static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw); |
166 | static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw); | 169 | static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw); |
170 | static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw); | ||
167 | 171 | ||
168 | static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg) | 172 | static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg) |
169 | { | 173 | { |
@@ -898,6 +902,56 @@ static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, bool active) | |||
898 | } | 902 | } |
899 | 903 | ||
900 | /** | 904 | /** |
905 | * e1000_valid_nvm_bank_detect_ich8lan - finds out the valid bank 0 or 1 | ||
906 | * @hw: pointer to the HW structure | ||
907 | * @bank: pointer to the variable that returns the active bank | ||
908 | * | ||
909 | * Reads signature byte from the NVM using the flash access registers. | ||
910 | **/ | ||
911 | static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank) | ||
912 | { | ||
913 | struct e1000_nvm_info *nvm = &hw->nvm; | ||
914 | /* flash bank size is in words */ | ||
915 | u32 bank1_offset = nvm->flash_bank_size * sizeof(u16); | ||
916 | u32 act_offset = E1000_ICH_NVM_SIG_WORD * 2 + 1; | ||
917 | u8 bank_high_byte = 0; | ||
918 | |||
919 | if (hw->mac.type != e1000_ich10lan) { | ||
920 | if (er32(EECD) & E1000_EECD_SEC1VAL) | ||
921 | *bank = 1; | ||
922 | else | ||
923 | *bank = 0; | ||
924 | } else { | ||
925 | /* | ||
926 | * Make sure the signature for bank 0 is valid, | ||
927 | * if not check for bank1 | ||
928 | */ | ||
929 | e1000_read_flash_byte_ich8lan(hw, act_offset, &bank_high_byte); | ||
930 | if ((bank_high_byte & 0xC0) == 0x80) { | ||
931 | *bank = 0; | ||
932 | } else { | ||
933 | /* | ||
934 | * find if segment 1 is valid by verifying | ||
935 | * bit 15:14 = 10b in word 0x13 | ||
936 | */ | ||
937 | e1000_read_flash_byte_ich8lan(hw, | ||
938 | act_offset + bank1_offset, | ||
939 | &bank_high_byte); | ||
940 | |||
941 | /* bank1 has a valid signature equivalent to SEC1V */ | ||
942 | if ((bank_high_byte & 0xC0) == 0x80) { | ||
943 | *bank = 1; | ||
944 | } else { | ||
945 | hw_dbg(hw, "ERROR: EEPROM not present\n"); | ||
946 | return -E1000_ERR_NVM; | ||
947 | } | ||
948 | } | ||
949 | } | ||
950 | |||
951 | return 0; | ||
952 | } | ||
953 | |||
954 | /** | ||
901 | * e1000_read_nvm_ich8lan - Read word(s) from the NVM | 955 | * e1000_read_nvm_ich8lan - Read word(s) from the NVM |
902 | * @hw: pointer to the HW structure | 956 | * @hw: pointer to the HW structure |
903 | * @offset: The offset (in bytes) of the word(s) to read. | 957 | * @offset: The offset (in bytes) of the word(s) to read. |
@@ -913,6 +967,7 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, | |||
913 | struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; | 967 | struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; |
914 | u32 act_offset; | 968 | u32 act_offset; |
915 | s32 ret_val; | 969 | s32 ret_val; |
970 | u32 bank = 0; | ||
916 | u16 i, word; | 971 | u16 i, word; |
917 | 972 | ||
918 | if ((offset >= nvm->word_size) || (words > nvm->word_size - offset) || | 973 | if ((offset >= nvm->word_size) || (words > nvm->word_size - offset) || |
@@ -925,10 +980,11 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, | |||
925 | if (ret_val) | 980 | if (ret_val) |
926 | return ret_val; | 981 | return ret_val; |
927 | 982 | ||
928 | /* Start with the bank offset, then add the relative offset. */ | 983 | ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank); |
929 | act_offset = (er32(EECD) & E1000_EECD_SEC1VAL) | 984 | if (ret_val) |
930 | ? nvm->flash_bank_size | 985 | return ret_val; |
931 | : 0; | 986 | |
987 | act_offset = (bank) ? nvm->flash_bank_size : 0; | ||
932 | act_offset += offset; | 988 | act_offset += offset; |
933 | 989 | ||
934 | for (i = 0; i < words; i++) { | 990 | for (i = 0; i < words; i++) { |
@@ -1076,6 +1132,29 @@ static s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, u32 offset, | |||
1076 | } | 1132 | } |
1077 | 1133 | ||
1078 | /** | 1134 | /** |
1135 | * e1000_read_flash_byte_ich8lan - Read byte from flash | ||
1136 | * @hw: pointer to the HW structure | ||
1137 | * @offset: The offset of the byte to read. | ||
1138 | * @data: Pointer to a byte to store the value read. | ||
1139 | * | ||
1140 | * Reads a single byte from the NVM using the flash access registers. | ||
1141 | **/ | ||
1142 | static s32 e1000_read_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset, | ||
1143 | u8 *data) | ||
1144 | { | ||
1145 | s32 ret_val; | ||
1146 | u16 word = 0; | ||
1147 | |||
1148 | ret_val = e1000_read_flash_data_ich8lan(hw, offset, 1, &word); | ||
1149 | if (ret_val) | ||
1150 | return ret_val; | ||
1151 | |||
1152 | *data = (u8)word; | ||
1153 | |||
1154 | return 0; | ||
1155 | } | ||
1156 | |||
1157 | /** | ||
1079 | * e1000_read_flash_data_ich8lan - Read byte or word from NVM | 1158 | * e1000_read_flash_data_ich8lan - Read byte or word from NVM |
1080 | * @hw: pointer to the HW structure | 1159 | * @hw: pointer to the HW structure |
1081 | * @offset: The offset (in bytes) of the byte or word to read. | 1160 | * @offset: The offset (in bytes) of the byte or word to read. |
@@ -1206,7 +1285,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) | |||
1206 | { | 1285 | { |
1207 | struct e1000_nvm_info *nvm = &hw->nvm; | 1286 | struct e1000_nvm_info *nvm = &hw->nvm; |
1208 | struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; | 1287 | struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; |
1209 | u32 i, act_offset, new_bank_offset, old_bank_offset; | 1288 | u32 i, act_offset, new_bank_offset, old_bank_offset, bank; |
1210 | s32 ret_val; | 1289 | s32 ret_val; |
1211 | u16 data; | 1290 | u16 data; |
1212 | 1291 | ||
@@ -1226,7 +1305,11 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) | |||
1226 | * write to bank 0 etc. We also need to erase the segment that | 1305 | * write to bank 0 etc. We also need to erase the segment that |
1227 | * is going to be written | 1306 | * is going to be written |
1228 | */ | 1307 | */ |
1229 | if (!(er32(EECD) & E1000_EECD_SEC1VAL)) { | 1308 | ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank); |
1309 | if (ret_val) | ||
1310 | return ret_val; | ||
1311 | |||
1312 | if (bank == 0) { | ||
1230 | new_bank_offset = nvm->flash_bank_size; | 1313 | new_bank_offset = nvm->flash_bank_size; |
1231 | old_bank_offset = 0; | 1314 | old_bank_offset = 0; |
1232 | e1000_erase_flash_bank_ich8lan(hw, 1); | 1315 | e1000_erase_flash_bank_ich8lan(hw, 1); |
@@ -2190,13 +2273,14 @@ void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw) | |||
2190 | * 'LPLU Enabled' and 'Gig Disable' to force link speed negotiation | 2273 | * 'LPLU Enabled' and 'Gig Disable' to force link speed negotiation |
2191 | * to a lower speed. | 2274 | * to a lower speed. |
2192 | * | 2275 | * |
2193 | * Should only be called for ICH9 devices. | 2276 | * Should only be called for ICH9 and ICH10 devices. |
2194 | **/ | 2277 | **/ |
2195 | void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw) | 2278 | void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw) |
2196 | { | 2279 | { |
2197 | u32 phy_ctrl; | 2280 | u32 phy_ctrl; |
2198 | 2281 | ||
2199 | if (hw->mac.type == e1000_ich9lan) { | 2282 | if ((hw->mac.type == e1000_ich10lan) || |
2283 | (hw->mac.type == e1000_ich9lan)) { | ||
2200 | phy_ctrl = er32(PHY_CTRL); | 2284 | phy_ctrl = er32(PHY_CTRL); |
2201 | phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU | | 2285 | phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU | |
2202 | E1000_PHY_CTRL_GBE_DISABLE; | 2286 | E1000_PHY_CTRL_GBE_DISABLE; |
@@ -2254,6 +2338,39 @@ static s32 e1000_led_off_ich8lan(struct e1000_hw *hw) | |||
2254 | } | 2338 | } |
2255 | 2339 | ||
2256 | /** | 2340 | /** |
2341 | * e1000_get_cfg_done_ich8lan - Read config done bit | ||
2342 | * @hw: pointer to the HW structure | ||
2343 | * | ||
2344 | * Read the management control register for the config done bit for | ||
2345 | * completion status. NOTE: silicon which is EEPROM-less will fail trying | ||
2346 | * to read the config done bit, so an error is *ONLY* logged and returns | ||
2347 | * E1000_SUCCESS. If we were to return with error, EEPROM-less silicon | ||
2348 | * would not be able to be reset or change link. | ||
2349 | **/ | ||
2350 | static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw) | ||
2351 | { | ||
2352 | u32 bank = 0; | ||
2353 | |||
2354 | e1000e_get_cfg_done(hw); | ||
2355 | |||
2356 | /* If EEPROM is not marked present, init the IGP 3 PHY manually */ | ||
2357 | if (hw->mac.type != e1000_ich10lan) { | ||
2358 | if (((er32(EECD) & E1000_EECD_PRES) == 0) && | ||
2359 | (hw->phy.type == e1000_phy_igp_3)) { | ||
2360 | e1000e_phy_init_script_igp3(hw); | ||
2361 | } | ||
2362 | } else { | ||
2363 | if (e1000_valid_nvm_bank_detect_ich8lan(hw, &bank)) { | ||
2364 | /* Maybe we should do a basic PHY config */ | ||
2365 | hw_dbg(hw, "EEPROM not present\n"); | ||
2366 | return -E1000_ERR_CONFIG; | ||
2367 | } | ||
2368 | } | ||
2369 | |||
2370 | return 0; | ||
2371 | } | ||
2372 | |||
2373 | /** | ||
2257 | * e1000_clear_hw_cntrs_ich8lan - Clear statistical counters | 2374 | * e1000_clear_hw_cntrs_ich8lan - Clear statistical counters |
2258 | * @hw: pointer to the HW structure | 2375 | * @hw: pointer to the HW structure |
2259 | * | 2376 | * |
@@ -2303,7 +2420,7 @@ static struct e1000_phy_operations ich8_phy_ops = { | |||
2303 | .check_reset_block = e1000_check_reset_block_ich8lan, | 2420 | .check_reset_block = e1000_check_reset_block_ich8lan, |
2304 | .commit_phy = NULL, | 2421 | .commit_phy = NULL, |
2305 | .force_speed_duplex = e1000_phy_force_speed_duplex_ich8lan, | 2422 | .force_speed_duplex = e1000_phy_force_speed_duplex_ich8lan, |
2306 | .get_cfg_done = e1000e_get_cfg_done, | 2423 | .get_cfg_done = e1000_get_cfg_done_ich8lan, |
2307 | .get_cable_length = e1000e_get_cable_length_igp_2, | 2424 | .get_cable_length = e1000e_get_cable_length_igp_2, |
2308 | .get_phy_info = e1000_get_phy_info_ich8lan, | 2425 | .get_phy_info = e1000_get_phy_info_ich8lan, |
2309 | .read_phy_reg = e1000e_read_phy_reg_igp, | 2426 | .read_phy_reg = e1000e_read_phy_reg_igp, |
@@ -2358,3 +2475,20 @@ struct e1000_info e1000_ich9_info = { | |||
2358 | .nvm_ops = &ich8_nvm_ops, | 2475 | .nvm_ops = &ich8_nvm_ops, |
2359 | }; | 2476 | }; |
2360 | 2477 | ||
2478 | struct e1000_info e1000_ich10_info = { | ||
2479 | .mac = e1000_ich10lan, | ||
2480 | .flags = FLAG_HAS_JUMBO_FRAMES | ||
2481 | | FLAG_IS_ICH | ||
2482 | | FLAG_HAS_WOL | ||
2483 | | FLAG_RX_CSUM_ENABLED | ||
2484 | | FLAG_HAS_CTRLEXT_ON_LOAD | ||
2485 | | FLAG_HAS_AMT | ||
2486 | | FLAG_HAS_ERT | ||
2487 | | FLAG_HAS_FLASH | ||
2488 | | FLAG_APME_IN_WUC, | ||
2489 | .pba = 10, | ||
2490 | .get_variants = e1000_get_variants_ich8lan, | ||
2491 | .mac_ops = &ich8_mac_ops, | ||
2492 | .phy_ops = &ich8_phy_ops, | ||
2493 | .nvm_ops = &ich8_nvm_ops, | ||
2494 | }; | ||