[<prev] [next>] [day] [month] [year] [list]
Message-Id: <1193166879.14801.73.camel@dual.billh>
Date: Tue, 23 Oct 2007 13:14:39 -0600
From: Bill Hayes <bill.hayes@...com>
To: jeff@...zik.org, auke-jan.h.kok@...el.com, netdev@...r.kernel.org,
andy@...yhouse.net
Subject: [PATCH] e1000: alternate MAC address support
Port alternate MAC address support from the sourceforge
e1000 driver to the upstream e1000 driver.
Signed-off-by: Bill Hayes <bill.hayes@...com>
---
drivers/net/e1000/e1000_hw.c | 42 +++++++++++++++++++++++++++++++++++++++---
drivers/net/e1000/e1000_hw.h | 2 ++
2 files changed, 41 insertions(+), 3 deletions(-)
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
index 8fa0fe4..07e3178 100644
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -719,6 +719,11 @@ e1000_reset_hw(struct e1000_hw *hw)
DEBUGOUT("Masking off all interrupts\n");
E1000_WRITE_REG(hw, IMC, 0xffffffff);
+ if (hw->mac_type == e1000_82571 && hw->alt_mac_addr_is_present) {
+ hw->laa_is_present = 1;
+ e1000_rar_set(hw, hw->mac_addr, E1000_RAR_ENTRIES - 1);
+ }
+
/* Clear any pending interrupt events. */
icr = E1000_READ_REG(hw, ICR);
@@ -5693,11 +5698,41 @@ e1000_read_mac_addr(struct e1000_hw * hw)
{
uint16_t offset;
uint16_t eeprom_data, i;
+ u16 mac_addr_offset = 0;
DEBUGFUNC("e1000_read_mac_addr");
+ if (hw->mac_type == e1000_82571) {
+ /* Check for an alternate MAC address. An alternate MAC address can
+ * be setup by pre-boot software and must be treated like a permanent
+ * address and must override the actual permanent MAC address. */
+ if (e1000_read_eeprom(hw, EEPROM_ALT_MAC_ADDR_PTR, 1,
+ &mac_addr_offset) < 0) {
+ DEBUGOUT("EEPROM Read Error\n");
+ return -E1000_ERR_EEPROM;
+ }
+ if (mac_addr_offset == 0xFFFF)
+ mac_addr_offset = 0;
+
+ if (mac_addr_offset) {
+ if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
+ mac_addr_offset += NODE_ADDRESS_SIZE/sizeof(u16);
+
+ /* make sure we have a valid mac address here before using it */
+ if (e1000_read_eeprom(hw, mac_addr_offset, 1, &eeprom_data) < 0) {
+ DEBUGOUT("EEPROM Read Error\n");
+ return -E1000_ERR_EEPROM;
+ }
+ if (eeprom_data & 0x0001)
+ mac_addr_offset = 0;
+ }
+
+ if (mac_addr_offset)
+ hw->alt_mac_addr_is_present = 1;
+ }
+
for (i = 0; i < NODE_ADDRESS_SIZE; i += 2) {
- offset = i >> 1;
+ offset = mac_addr_offset + (i >> 1);
if (e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) {
DEBUGOUT("EEPROM Read Error\n");
return -E1000_ERR_EEPROM;
@@ -5713,8 +5748,9 @@ e1000_read_mac_addr(struct e1000_hw * hw)
case e1000_82546_rev_3:
case e1000_82571:
case e1000_80003es2lan:
- if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
- hw->perm_mac_addr[5] ^= 0x01;
+ if (!mac_addr_offset &&
+ (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1))
+ hw->perm_mac_addr[5] ^= 0x01;
break;
}
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index a2a86c5..e18760d 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -1456,6 +1456,7 @@ struct e1000_hw {
boolean_t tbi_compatibility_en;
boolean_t tbi_compatibility_on;
boolean_t laa_is_present;
+ boolean_t alt_mac_addr_is_present;
boolean_t phy_reset_disable;
boolean_t initialize_hw_bits_disable;
boolean_t fc_send_xon;
@@ -2286,6 +2287,7 @@ struct e1000_host_command_info {
#define EEPROM_INIT_CONTROL3_PORT_A 0x0024
#define EEPROM_CFG 0x0012
#define EEPROM_FLASH_VERSION 0x0032
+#define EEPROM_ALT_MAC_ADDR_PTR 0x0037
#define EEPROM_CHECKSUM_REG 0x003F
#define E1000_EEPROM_CFG_DONE 0x00040000 /* MNG config cycle done */
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists