diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/e1000e/82571.c | 4 | ||||
-rw-r--r-- | drivers/net/e1000e/defines.h | 1 | ||||
-rw-r--r-- | drivers/net/e1000e/hw.h | 1 | ||||
-rw-r--r-- | drivers/net/e1000e/lib.c | 39 |
4 files changed, 43 insertions, 2 deletions
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index 14141a55eaa6..b6401abc17d6 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c | |||
@@ -752,6 +752,10 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) | |||
752 | ew32(IMC, 0xffffffff); | 752 | ew32(IMC, 0xffffffff); |
753 | icr = er32(ICR); | 753 | icr = er32(ICR); |
754 | 754 | ||
755 | if (hw->mac.type == e1000_82571 && | ||
756 | hw->dev_spec.e82571.alt_mac_addr_is_present) | ||
757 | e1000e_set_laa_state_82571(hw, true); | ||
758 | |||
755 | return 0; | 759 | return 0; |
756 | } | 760 | } |
757 | 761 | ||
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h index b32ed45b4b34..f2175ea46b83 100644 --- a/drivers/net/e1000e/defines.h +++ b/drivers/net/e1000e/defines.h | |||
@@ -557,6 +557,7 @@ | |||
557 | #define NVM_INIT_3GIO_3 0x001A | 557 | #define NVM_INIT_3GIO_3 0x001A |
558 | #define NVM_INIT_CONTROL3_PORT_A 0x0024 | 558 | #define NVM_INIT_CONTROL3_PORT_A 0x0024 |
559 | #define NVM_CFG 0x0012 | 559 | #define NVM_CFG 0x0012 |
560 | #define NVM_ALT_MAC_ADDR_PTR 0x0037 | ||
560 | #define NVM_CHECKSUM_REG 0x003F | 561 | #define NVM_CHECKSUM_REG 0x003F |
561 | 562 | ||
562 | #define E1000_NVM_CFG_DONE_PORT_0 0x40000 /* MNG config cycle done */ | 563 | #define E1000_NVM_CFG_DONE_PORT_0 0x40000 /* MNG config cycle done */ |
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h index 64515789fd4d..1bb20521df0e 100644 --- a/drivers/net/e1000e/hw.h +++ b/drivers/net/e1000e/hw.h | |||
@@ -816,6 +816,7 @@ struct e1000_bus_info { | |||
816 | 816 | ||
817 | struct e1000_dev_spec_82571 { | 817 | struct e1000_dev_spec_82571 { |
818 | bool laa_is_present; | 818 | bool laa_is_present; |
819 | bool alt_mac_addr_is_present; | ||
819 | }; | 820 | }; |
820 | 821 | ||
821 | struct e1000_shadow_ram { | 822 | struct e1000_shadow_ram { |
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index 0bdeca30c75f..16f35fadb74b 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c | |||
@@ -2059,9 +2059,44 @@ s32 e1000e_read_mac_addr(struct e1000_hw *hw) | |||
2059 | { | 2059 | { |
2060 | s32 ret_val; | 2060 | s32 ret_val; |
2061 | u16 offset, nvm_data, i; | 2061 | u16 offset, nvm_data, i; |
2062 | u16 mac_addr_offset = 0; | ||
2063 | |||
2064 | if (hw->mac.type == e1000_82571) { | ||
2065 | /* Check for an alternate MAC address. An alternate MAC | ||
2066 | * address can be setup by pre-boot software and must be | ||
2067 | * treated like a permanent address and must override the | ||
2068 | * actual permanent MAC address. */ | ||
2069 | ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1, | ||
2070 | &mac_addr_offset); | ||
2071 | if (ret_val) { | ||
2072 | hw_dbg(hw, "NVM Read Error\n"); | ||
2073 | return ret_val; | ||
2074 | } | ||
2075 | if (mac_addr_offset == 0xFFFF) | ||
2076 | mac_addr_offset = 0; | ||
2077 | |||
2078 | if (mac_addr_offset) { | ||
2079 | if (hw->bus.func == E1000_FUNC_1) | ||
2080 | mac_addr_offset += ETH_ALEN/sizeof(u16); | ||
2081 | |||
2082 | /* make sure we have a valid mac address here | ||
2083 | * before using it */ | ||
2084 | ret_val = e1000_read_nvm(hw, mac_addr_offset, 1, | ||
2085 | &nvm_data); | ||
2086 | if (ret_val) { | ||
2087 | hw_dbg(hw, "NVM Read Error\n"); | ||
2088 | return ret_val; | ||
2089 | } | ||
2090 | if (nvm_data & 0x0001) | ||
2091 | mac_addr_offset = 0; | ||
2092 | } | ||
2093 | |||
2094 | if (mac_addr_offset) | ||
2095 | hw->dev_spec.e82571.alt_mac_addr_is_present = 1; | ||
2096 | } | ||
2062 | 2097 | ||
2063 | for (i = 0; i < ETH_ALEN; i += 2) { | 2098 | for (i = 0; i < ETH_ALEN; i += 2) { |
2064 | offset = i >> 1; | 2099 | offset = mac_addr_offset + (i >> 1); |
2065 | ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data); | 2100 | ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data); |
2066 | if (ret_val) { | 2101 | if (ret_val) { |
2067 | hw_dbg(hw, "NVM Read Error\n"); | 2102 | hw_dbg(hw, "NVM Read Error\n"); |
@@ -2072,7 +2107,7 @@ s32 e1000e_read_mac_addr(struct e1000_hw *hw) | |||
2072 | } | 2107 | } |
2073 | 2108 | ||
2074 | /* Flip last bit of mac address if we're on second port */ | 2109 | /* Flip last bit of mac address if we're on second port */ |
2075 | if (hw->bus.func == E1000_FUNC_1) | 2110 | if (!mac_addr_offset && hw->bus.func == E1000_FUNC_1) |
2076 | hw->mac.perm_addr[5] ^= 1; | 2111 | hw->mac.perm_addr[5] ^= 1; |
2077 | 2112 | ||
2078 | for (i = 0; i < ETH_ALEN; i++) | 2113 | for (i = 0; i < ETH_ALEN; i++) |