aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBruce Allan <bruce.w.allan@intel.com>2010-01-12 21:04:58 -0500
committerDavid S. Miller <davem@davemloft.net>2010-01-13 23:31:56 -0500
commit608f8a0d014db6cd18d4f535934d4b5d556e3013 (patch)
tree1f3ace492bc08165c81ef7bc06ec7f5222ab1d2d /drivers
parent0159f24ee764927bf44c1a25473bd4517febd21c (diff)
e1000e: use alternate MAC address on ESB2 if available
Similar to 82571/2/3 parts that already do this, if ESB2/80003es2lan parts have an alternate MAC address provided in the EEPROM use it instead of the default MAC address. This patch makes the the actual code that does this generic so that it can be better used by both MAC families. Signed-off-by: Bruce Allan <bruce.w.allan@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-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