diff options
-rw-r--r-- | drivers/net/e1000e/82571.c | 33 | ||||
-rw-r--r-- | drivers/net/e1000e/defines.h | 2 | ||||
-rw-r--r-- | drivers/net/e1000e/e1000.h | 11 | ||||
-rw-r--r-- | drivers/net/e1000e/es2lan.c | 28 | ||||
-rw-r--r-- | drivers/net/e1000e/hw.h | 5 | ||||
-rw-r--r-- | drivers/net/e1000e/lib.c | 124 | ||||
-rw-r--r-- | drivers/net/e1000e/netdev.c | 2 |
7 files changed, 147 insertions, 58 deletions
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index 02d67d047d96..d1a45143c2aa 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c | |||
@@ -922,9 +922,12 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) | |||
922 | ew32(IMC, 0xffffffff); | 922 | ew32(IMC, 0xffffffff); |
923 | icr = er32(ICR); | 923 | icr = er32(ICR); |
924 | 924 | ||
925 | if (hw->mac.type == e1000_82571 && | 925 | /* Install any alternate MAC address into RAR0 */ |
926 | hw->dev_spec.e82571.alt_mac_addr_is_present) | 926 | ret_val = e1000_check_alt_mac_addr_generic(hw); |
927 | e1000e_set_laa_state_82571(hw, true); | 927 | if (ret_val) |
928 | return ret_val; | ||
929 | |||
930 | e1000e_set_laa_state_82571(hw, true); | ||
928 | 931 | ||
929 | /* Reinitialize the 82571 serdes link state machine */ | 932 | /* Reinitialize the 82571 serdes link state machine */ |
930 | if (hw->phy.media_type == e1000_media_type_internal_serdes) | 933 | if (hw->phy.media_type == e1000_media_type_internal_serdes) |
@@ -1621,6 +1624,29 @@ static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw) | |||
1621 | } | 1624 | } |
1622 | 1625 | ||
1623 | /** | 1626 | /** |
1627 | * e1000_read_mac_addr_82571 - Read device MAC address | ||
1628 | * @hw: pointer to the HW structure | ||
1629 | **/ | ||
1630 | static s32 e1000_read_mac_addr_82571(struct e1000_hw *hw) | ||
1631 | { | ||
1632 | s32 ret_val = 0; | ||
1633 | |||
1634 | /* | ||
1635 | * If there's an alternate MAC address place it in RAR0 | ||
1636 | * so that it will override the Si installed default perm | ||
1637 | * address. | ||
1638 | */ | ||
1639 | ret_val = e1000_check_alt_mac_addr_generic(hw); | ||
1640 | if (ret_val) | ||
1641 | goto out; | ||
1642 | |||
1643 | ret_val = e1000_read_mac_addr_generic(hw); | ||
1644 | |||
1645 | out: | ||
1646 | return ret_val; | ||
1647 | } | ||
1648 | |||
1649 | /** | ||
1624 | * e1000_power_down_phy_copper_82571 - Remove link during PHY power down | 1650 | * e1000_power_down_phy_copper_82571 - Remove link during PHY power down |
1625 | * @hw: pointer to the HW structure | 1651 | * @hw: pointer to the HW structure |
1626 | * | 1652 | * |
@@ -1706,6 +1732,7 @@ static struct e1000_mac_operations e82571_mac_ops = { | |||
1706 | .setup_link = e1000_setup_link_82571, | 1732 | .setup_link = e1000_setup_link_82571, |
1707 | /* .setup_physical_interface: media type dependent */ | 1733 | /* .setup_physical_interface: media type dependent */ |
1708 | .setup_led = e1000e_setup_led_generic, | 1734 | .setup_led = e1000e_setup_led_generic, |
1735 | .read_mac_addr = e1000_read_mac_addr_82571, | ||
1709 | }; | 1736 | }; |
1710 | 1737 | ||
1711 | static struct e1000_phy_operations e82_phy_ops_igp = { | 1738 | static struct e1000_phy_operations e82_phy_ops_igp = { |
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h index e02e38221ed4..db05ec355749 100644 --- a/drivers/net/e1000e/defines.h +++ b/drivers/net/e1000e/defines.h | |||
@@ -460,6 +460,8 @@ | |||
460 | */ | 460 | */ |
461 | #define E1000_RAR_ENTRIES 15 | 461 | #define E1000_RAR_ENTRIES 15 |
462 | #define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */ | 462 | #define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */ |
463 | #define E1000_RAL_MAC_ADDR_LEN 4 | ||
464 | #define E1000_RAH_MAC_ADDR_LEN 2 | ||
463 | 465 | ||
464 | /* Error Codes */ | 466 | /* Error Codes */ |
465 | #define E1000_ERR_NVM 1 | 467 | #define E1000_ERR_NVM 1 |
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index cebbd9079d53..7c91e4bdd361 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h | |||
@@ -529,6 +529,7 @@ extern s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw); | |||
529 | extern s32 e1000e_force_mac_fc(struct e1000_hw *hw); | 529 | extern s32 e1000e_force_mac_fc(struct e1000_hw *hw); |
530 | extern s32 e1000e_blink_led(struct e1000_hw *hw); | 530 | extern s32 e1000e_blink_led(struct e1000_hw *hw); |
531 | extern void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value); | 531 | extern void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value); |
532 | extern s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw); | ||
532 | extern void e1000e_reset_adaptive(struct e1000_hw *hw); | 533 | extern void e1000e_reset_adaptive(struct e1000_hw *hw); |
533 | extern void e1000e_update_adaptive(struct e1000_hw *hw); | 534 | extern void e1000e_update_adaptive(struct e1000_hw *hw); |
534 | 535 | ||
@@ -629,7 +630,15 @@ extern s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 | |||
629 | extern s32 e1000e_validate_nvm_checksum_generic(struct e1000_hw *hw); | 630 | extern s32 e1000e_validate_nvm_checksum_generic(struct e1000_hw *hw); |
630 | extern void e1000e_release_nvm(struct e1000_hw *hw); | 631 | extern void e1000e_release_nvm(struct e1000_hw *hw); |
631 | extern void e1000e_reload_nvm(struct e1000_hw *hw); | 632 | extern void e1000e_reload_nvm(struct e1000_hw *hw); |
632 | extern s32 e1000e_read_mac_addr(struct e1000_hw *hw); | 633 | extern s32 e1000_read_mac_addr_generic(struct e1000_hw *hw); |
634 | |||
635 | static inline s32 e1000e_read_mac_addr(struct e1000_hw *hw) | ||
636 | { | ||
637 | if (hw->mac.ops.read_mac_addr) | ||
638 | return hw->mac.ops.read_mac_addr(hw); | ||
639 | |||
640 | return e1000_read_mac_addr_generic(hw); | ||
641 | } | ||
633 | 642 | ||
634 | static inline s32 e1000_validate_nvm_checksum(struct e1000_hw *hw) | 643 | static inline s32 e1000_validate_nvm_checksum(struct e1000_hw *hw) |
635 | { | 644 | { |
diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c index e2aa3b788564..4bb9d88ad976 100644 --- a/drivers/net/e1000e/es2lan.c +++ b/drivers/net/e1000e/es2lan.c | |||
@@ -814,7 +814,9 @@ static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw) | |||
814 | ew32(IMC, 0xffffffff); | 814 | ew32(IMC, 0xffffffff); |
815 | icr = er32(ICR); | 815 | icr = er32(ICR); |
816 | 816 | ||
817 | return 0; | 817 | ret_val = e1000_check_alt_mac_addr_generic(hw); |
818 | |||
819 | return ret_val; | ||
818 | } | 820 | } |
819 | 821 | ||
820 | /** | 822 | /** |
@@ -1340,6 +1342,29 @@ static s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, | |||
1340 | } | 1342 | } |
1341 | 1343 | ||
1342 | /** | 1344 | /** |
1345 | * e1000_read_mac_addr_80003es2lan - Read device MAC address | ||
1346 | * @hw: pointer to the HW structure | ||
1347 | **/ | ||
1348 | static s32 e1000_read_mac_addr_80003es2lan(struct e1000_hw *hw) | ||
1349 | { | ||
1350 | s32 ret_val = 0; | ||
1351 | |||
1352 | /* | ||
1353 | * If there's an alternate MAC address place it in RAR0 | ||
1354 | * so that it will override the Si installed default perm | ||
1355 | * address. | ||
1356 | */ | ||
1357 | ret_val = e1000_check_alt_mac_addr_generic(hw); | ||
1358 | if (ret_val) | ||
1359 | goto out; | ||
1360 | |||
1361 | ret_val = e1000_read_mac_addr_generic(hw); | ||
1362 | |||
1363 | out: | ||
1364 | return ret_val; | ||
1365 | } | ||
1366 | |||
1367 | /** | ||
1343 | * e1000_power_down_phy_copper_80003es2lan - Remove link during PHY power down | 1368 | * e1000_power_down_phy_copper_80003es2lan - Remove link during PHY power down |
1344 | * @hw: pointer to the HW structure | 1369 | * @hw: pointer to the HW structure |
1345 | * | 1370 | * |
@@ -1403,6 +1428,7 @@ static void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw) | |||
1403 | } | 1428 | } |
1404 | 1429 | ||
1405 | static struct e1000_mac_operations es2_mac_ops = { | 1430 | static struct e1000_mac_operations es2_mac_ops = { |
1431 | .read_mac_addr = e1000_read_mac_addr_80003es2lan, | ||
1406 | .id_led_init = e1000e_id_led_init, | 1432 | .id_led_init = e1000e_id_led_init, |
1407 | .check_mng_mode = e1000e_check_mng_mode_generic, | 1433 | .check_mng_mode = e1000e_check_mng_mode_generic, |
1408 | /* check_for_link dependent on media type */ | 1434 | /* check_for_link dependent on media type */ |
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h index eccf29b75c41..127e6a226da1 100644 --- a/drivers/net/e1000e/hw.h +++ b/drivers/net/e1000e/hw.h | |||
@@ -389,6 +389,9 @@ enum e1e_registers { | |||
389 | 389 | ||
390 | #define E1000_FUNC_1 1 | 390 | #define E1000_FUNC_1 1 |
391 | 391 | ||
392 | #define E1000_ALT_MAC_ADDRESS_OFFSET_LAN0 0 | ||
393 | #define E1000_ALT_MAC_ADDRESS_OFFSET_LAN1 3 | ||
394 | |||
392 | enum e1000_mac_type { | 395 | enum e1000_mac_type { |
393 | e1000_82571, | 396 | e1000_82571, |
394 | e1000_82572, | 397 | e1000_82572, |
@@ -756,6 +759,7 @@ struct e1000_mac_operations { | |||
756 | s32 (*setup_physical_interface)(struct e1000_hw *); | 759 | s32 (*setup_physical_interface)(struct e1000_hw *); |
757 | s32 (*setup_led)(struct e1000_hw *); | 760 | s32 (*setup_led)(struct e1000_hw *); |
758 | void (*write_vfta)(struct e1000_hw *, u32, u32); | 761 | void (*write_vfta)(struct e1000_hw *, u32, u32); |
762 | s32 (*read_mac_addr)(struct e1000_hw *); | ||
759 | }; | 763 | }; |
760 | 764 | ||
761 | /* Function pointers for the PHY. */ | 765 | /* Function pointers for the PHY. */ |
@@ -897,7 +901,6 @@ struct e1000_fc_info { | |||
897 | 901 | ||
898 | struct e1000_dev_spec_82571 { | 902 | struct e1000_dev_spec_82571 { |
899 | bool laa_is_present; | 903 | bool laa_is_present; |
900 | bool alt_mac_addr_is_present; | ||
901 | u32 smb_counter; | 904 | u32 smb_counter; |
902 | }; | 905 | }; |
903 | 906 | ||
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index 2fa9b36a2c5a..547542428edc 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c | |||
@@ -139,6 +139,68 @@ void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count) | |||
139 | } | 139 | } |
140 | 140 | ||
141 | /** | 141 | /** |
142 | * e1000_check_alt_mac_addr_generic - Check for alternate MAC addr | ||
143 | * @hw: pointer to the HW structure | ||
144 | * | ||
145 | * Checks the nvm for an alternate MAC address. An alternate MAC address | ||
146 | * can be setup by pre-boot software and must be treated like a permanent | ||
147 | * address and must override the actual permanent MAC address. If an | ||
148 | * alternate MAC address is found it is programmed into RAR0, replacing | ||
149 | * the permanent address that was installed into RAR0 by the Si on reset. | ||
150 | * This function will return SUCCESS unless it encounters an error while | ||
151 | * reading the EEPROM. | ||
152 | **/ | ||
153 | s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) | ||
154 | { | ||
155 | u32 i; | ||
156 | s32 ret_val = 0; | ||
157 | u16 offset, nvm_alt_mac_addr_offset, nvm_data; | ||
158 | u8 alt_mac_addr[ETH_ALEN]; | ||
159 | |||
160 | ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1, | ||
161 | &nvm_alt_mac_addr_offset); | ||
162 | if (ret_val) { | ||
163 | e_dbg("NVM Read Error\n"); | ||
164 | goto out; | ||
165 | } | ||
166 | |||
167 | if (nvm_alt_mac_addr_offset == 0xFFFF) { | ||
168 | /* There is no Alternate MAC Address */ | ||
169 | goto out; | ||
170 | } | ||
171 | |||
172 | if (hw->bus.func == E1000_FUNC_1) | ||
173 | nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN1; | ||
174 | for (i = 0; i < ETH_ALEN; i += 2) { | ||
175 | offset = nvm_alt_mac_addr_offset + (i >> 1); | ||
176 | ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data); | ||
177 | if (ret_val) { | ||
178 | e_dbg("NVM Read Error\n"); | ||
179 | goto out; | ||
180 | } | ||
181 | |||
182 | alt_mac_addr[i] = (u8)(nvm_data & 0xFF); | ||
183 | alt_mac_addr[i + 1] = (u8)(nvm_data >> 8); | ||
184 | } | ||
185 | |||
186 | /* if multicast bit is set, the alternate address will not be used */ | ||
187 | if (alt_mac_addr[0] & 0x01) { | ||
188 | e_dbg("Ignoring Alternate Mac Address with MC bit set\n"); | ||
189 | goto out; | ||
190 | } | ||
191 | |||
192 | /* | ||
193 | * We have a valid alternate MAC address, and we want to treat it the | ||
194 | * same as the normal permanent MAC address stored by the HW into the | ||
195 | * RAR. Do this by mapping this address into RAR0. | ||
196 | */ | ||
197 | e1000e_rar_set(hw, alt_mac_addr, 0); | ||
198 | |||
199 | out: | ||
200 | return ret_val; | ||
201 | } | ||
202 | |||
203 | /** | ||
142 | * e1000e_rar_set - Set receive address register | 204 | * e1000e_rar_set - Set receive address register |
143 | * @hw: pointer to the HW structure | 205 | * @hw: pointer to the HW structure |
144 | * @addr: pointer to the receive address | 206 | * @addr: pointer to the receive address |
@@ -2072,67 +2134,27 @@ s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) | |||
2072 | } | 2134 | } |
2073 | 2135 | ||
2074 | /** | 2136 | /** |
2075 | * e1000e_read_mac_addr - Read device MAC address | 2137 | * e1000_read_mac_addr_generic - Read device MAC address |
2076 | * @hw: pointer to the HW structure | 2138 | * @hw: pointer to the HW structure |
2077 | * | 2139 | * |
2078 | * Reads the device MAC address from the EEPROM and stores the value. | 2140 | * Reads the device MAC address from the EEPROM and stores the value. |
2079 | * Since devices with two ports use the same EEPROM, we increment the | 2141 | * Since devices with two ports use the same EEPROM, we increment the |
2080 | * last bit in the MAC address for the second port. | 2142 | * last bit in the MAC address for the second port. |
2081 | **/ | 2143 | **/ |
2082 | s32 e1000e_read_mac_addr(struct e1000_hw *hw) | 2144 | s32 e1000_read_mac_addr_generic(struct e1000_hw *hw) |
2083 | { | 2145 | { |
2084 | s32 ret_val; | 2146 | u32 rar_high; |
2085 | u16 offset, nvm_data, i; | 2147 | u32 rar_low; |
2086 | u16 mac_addr_offset = 0; | 2148 | u16 i; |
2087 | |||
2088 | if (hw->mac.type == e1000_82571) { | ||
2089 | /* Check for an alternate MAC address. An alternate MAC | ||
2090 | * address can be setup by pre-boot software and must be | ||
2091 | * treated like a permanent address and must override the | ||
2092 | * actual permanent MAC address.*/ | ||
2093 | ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1, | ||
2094 | &mac_addr_offset); | ||
2095 | if (ret_val) { | ||
2096 | e_dbg("NVM Read Error\n"); | ||
2097 | return ret_val; | ||
2098 | } | ||
2099 | if (mac_addr_offset == 0xFFFF) | ||
2100 | mac_addr_offset = 0; | ||
2101 | |||
2102 | if (mac_addr_offset) { | ||
2103 | if (hw->bus.func == E1000_FUNC_1) | ||
2104 | mac_addr_offset += ETH_ALEN/sizeof(u16); | ||
2105 | |||
2106 | /* make sure we have a valid mac address here | ||
2107 | * before using it */ | ||
2108 | ret_val = e1000_read_nvm(hw, mac_addr_offset, 1, | ||
2109 | &nvm_data); | ||
2110 | if (ret_val) { | ||
2111 | e_dbg("NVM Read Error\n"); | ||
2112 | return ret_val; | ||
2113 | } | ||
2114 | if (nvm_data & 0x0001) | ||
2115 | mac_addr_offset = 0; | ||
2116 | } | ||
2117 | 2149 | ||
2118 | if (mac_addr_offset) | 2150 | rar_high = er32(RAH(0)); |
2119 | hw->dev_spec.e82571.alt_mac_addr_is_present = 1; | 2151 | rar_low = er32(RAL(0)); |
2120 | } | ||
2121 | 2152 | ||
2122 | for (i = 0; i < ETH_ALEN; i += 2) { | 2153 | for (i = 0; i < E1000_RAL_MAC_ADDR_LEN; i++) |
2123 | offset = mac_addr_offset + (i >> 1); | 2154 | hw->mac.perm_addr[i] = (u8)(rar_low >> (i*8)); |
2124 | ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data); | ||
2125 | if (ret_val) { | ||
2126 | e_dbg("NVM Read Error\n"); | ||
2127 | return ret_val; | ||
2128 | } | ||
2129 | hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF); | ||
2130 | hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8); | ||
2131 | } | ||
2132 | 2155 | ||
2133 | /* Flip last bit of mac address if we're on second port */ | 2156 | for (i = 0; i < E1000_RAH_MAC_ADDR_LEN; i++) |
2134 | if (!mac_addr_offset && hw->bus.func == E1000_FUNC_1) | 2157 | hw->mac.perm_addr[i+4] = (u8)(rar_high >> (i*8)); |
2135 | hw->mac.perm_addr[5] ^= 1; | ||
2136 | 2158 | ||
2137 | for (i = 0; i < ETH_ALEN; i++) | 2159 | for (i = 0; i < ETH_ALEN; i++) |
2138 | hw->mac.addr[i] = hw->mac.perm_addr[i]; | 2160 | hw->mac.addr[i] = hw->mac.perm_addr[i]; |
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index c3745c9d21aa..0d5ef4c5c6db 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -5135,7 +5135,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, | |||
5135 | 5135 | ||
5136 | e1000_eeprom_checks(adapter); | 5136 | e1000_eeprom_checks(adapter); |
5137 | 5137 | ||
5138 | /* copy the MAC address out of the NVM */ | 5138 | /* copy the MAC address */ |
5139 | if (e1000e_read_mac_addr(&adapter->hw)) | 5139 | if (e1000e_read_mac_addr(&adapter->hw)) |
5140 | e_err("NVM Read Error while reading MAC address\n"); | 5140 | e_err("NVM Read Error while reading MAC address\n"); |
5141 | 5141 | ||