aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/e1000e/82571.c33
-rw-r--r--drivers/net/e1000e/defines.h2
-rw-r--r--drivers/net/e1000e/e1000.h11
-rw-r--r--drivers/net/e1000e/es2lan.c28
-rw-r--r--drivers/net/e1000e/hw.h5
-rw-r--r--drivers/net/e1000e/lib.c124
-rw-r--r--drivers/net/e1000e/netdev.c2
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 **/
1630static 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
1645out:
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
1711static struct e1000_phy_operations e82_phy_ops_igp = { 1738static 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);
529extern s32 e1000e_force_mac_fc(struct e1000_hw *hw); 529extern s32 e1000e_force_mac_fc(struct e1000_hw *hw);
530extern s32 e1000e_blink_led(struct e1000_hw *hw); 530extern s32 e1000e_blink_led(struct e1000_hw *hw);
531extern void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value); 531extern void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value);
532extern s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw);
532extern void e1000e_reset_adaptive(struct e1000_hw *hw); 533extern void e1000e_reset_adaptive(struct e1000_hw *hw);
533extern void e1000e_update_adaptive(struct e1000_hw *hw); 534extern 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
629extern s32 e1000e_validate_nvm_checksum_generic(struct e1000_hw *hw); 630extern s32 e1000e_validate_nvm_checksum_generic(struct e1000_hw *hw);
630extern void e1000e_release_nvm(struct e1000_hw *hw); 631extern void e1000e_release_nvm(struct e1000_hw *hw);
631extern void e1000e_reload_nvm(struct e1000_hw *hw); 632extern void e1000e_reload_nvm(struct e1000_hw *hw);
632extern s32 e1000e_read_mac_addr(struct e1000_hw *hw); 633extern s32 e1000_read_mac_addr_generic(struct e1000_hw *hw);
634
635static 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
634static inline s32 e1000_validate_nvm_checksum(struct e1000_hw *hw) 643static 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 **/
1348static 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
1363out:
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
1405static struct e1000_mac_operations es2_mac_ops = { 1430static 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
392enum e1000_mac_type { 395enum 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
898struct e1000_dev_spec_82571 { 902struct 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 **/
153s32 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
199out:
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 **/
2082s32 e1000e_read_mac_addr(struct e1000_hw *hw) 2144s32 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