Browse Source

[e1000] Use the alternate MAC in NVRAM when available

The 82571 supports an alternate MAC address location in NVRAM.
When this is set, use this for the MAC rather than the default
physical MAC address.

Ported from linux-2.6.git 93ca161027

Signed-off-by: Alex Williamson <alex.williamson@hp.com>
Tested-by: Thomas Miletich <thomas.miletich@gmail.com>
Signed-off-by: Marty Connor <mdc@etherboot.org>
tags/v1.0.0-rc1
Alex Williamson 14 years ago
parent
commit
470454a791
2 changed files with 51 additions and 3 deletions
  1. 50
    3
      src/drivers/net/e1000/e1000_hw.c
  2. 1
    0
      src/drivers/net/e1000/e1000_hw.h

+ 50
- 3
src/drivers/net/e1000/e1000_hw.c View File

@@ -728,6 +728,17 @@ e1000_reset_hw(struct e1000_hw *hw)
728 728
     /* Clear any pending interrupt events. */
729 729
     icr = E1000_READ_REG(hw, ICR);
730 730
 
731
+    if (hw->mac_type == e1000_82571 && hw->laa_is_present == TRUE) {
732
+        /*
733
+         * Hold a copy of the LAA in RAR[14] This is done so that
734
+         * between the time RAR[0] gets clobbered and the time it
735
+         * gets fixed, the actual LAA is in one of the RARs and no
736
+         * incoming packets directed to this port are dropped.
737
+         * Eventually the LAA will be in RAR[0] and RAR[14].
738
+         */
739
+        e1000_rar_set(hw, hw->mac_addr, E1000_RAR_ENTRIES - 1);
740
+    }
741
+
731 742
     /* If MWI was previously enabled, reenable it. */
732 743
     if (hw->mac_type == e1000_82542_rev2_0) {
733 744
         if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
@@ -5774,13 +5785,48 @@ e1000_commit_shadow_ram(struct e1000_hw *hw)
5774 5785
 int32_t
5775 5786
 e1000_read_mac_addr(struct e1000_hw * hw)
5776 5787
 {
5777
-    uint16_t offset;
5788
+    uint16_t offset, mac_addr_offset = 0;
5778 5789
     uint16_t eeprom_data, i;
5790
+    int32_t ret_val;
5779 5791
 
5780 5792
     DEBUGFUNC("e1000_read_mac_addr");
5781 5793
 
5794
+    if (hw->mac_type == e1000_82571) {
5795
+        /* Check for an alternate MAC address.  An alternate MAC
5796
+         * address can be setup by pre-boot software and must be
5797
+         * treated like a permanent address and must override the
5798
+         * actual permanent MAC address.*/
5799
+        ret_val = e1000_read_eeprom(hw, EEPROM_ALT_MAC_ADDR_PTR, 1,
5800
+                                    &mac_addr_offset);
5801
+        if (ret_val) {
5802
+            DEBUGOUT("EEPROM Read Error\n");
5803
+            return -E1000_ERR_EEPROM;
5804
+        }
5805
+        if (mac_addr_offset == 0xFFFF)
5806
+            mac_addr_offset = 0;
5807
+
5808
+        if (mac_addr_offset) {
5809
+            if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
5810
+                mac_addr_offset += NODE_ADDRESS_SIZE/sizeof(u16);
5811
+
5812
+                /* make sure we have a valid mac address here
5813
+                 * before using it */
5814
+               ret_val = e1000_read_eeprom(hw, mac_addr_offset, 1,
5815
+                                           &eeprom_data);
5816
+               if (ret_val) {
5817
+                   DEBUGOUT("EEPROM Read Error\n");
5818
+                   return -E1000_ERR_EEPROM;
5819
+               }
5820
+               if (eeprom_data & 0x0001)
5821
+                   mac_addr_offset = 0;
5822
+        }
5823
+
5824
+        if (mac_addr_offset)
5825
+            hw->laa_is_present = TRUE;
5826
+    }
5827
+
5782 5828
     for (i = 0; i < NODE_ADDRESS_SIZE; i += 2) {
5783
-        offset = i >> 1;
5829
+        offset = mac_addr_offset + (i >> 1);
5784 5830
         if (e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) {
5785 5831
             DEBUGOUT("EEPROM Read Error\n");
5786 5832
             return -E1000_ERR_EEPROM;
@@ -5797,7 +5843,8 @@ e1000_read_mac_addr(struct e1000_hw * hw)
5797 5843
     case e1000_82571:
5798 5844
     case e1000_82576:
5799 5845
     case e1000_80003es2lan:
5800
-        if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
5846
+        if (!mac_addr_offset &&
5847
+            E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
5801 5848
             hw->perm_mac_addr[5] ^= 0x01;
5802 5849
         break;
5803 5850
     }

+ 1
- 0
src/drivers/net/e1000/e1000_hw.h View File

@@ -2299,6 +2299,7 @@ struct e1000_host_command_info {
2299 2299
 #define EEPROM_INIT_CONTROL3_PORT_A   0x0024
2300 2300
 #define EEPROM_CFG                    0x0012
2301 2301
 #define EEPROM_FLASH_VERSION          0x0032
2302
+#define EEPROM_ALT_MAC_ADDR_PTR       0x0037
2302 2303
 #define EEPROM_CHECKSUM_REG           0x003F
2303 2304
 
2304 2305
 #define E1000_EEPROM_CFG_DONE         0x00040000   /* MNG config cycle done */

Loading…
Cancel
Save