aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000e/lib.c
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/net/e1000e/lib.c
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/net/e1000e/lib.c')
-rw-r--r--drivers/net/e1000e/lib.c124
1 files changed, 73 insertions, 51 deletions
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];