Переглянути джерело

[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 роки тому
джерело
коміт
470454a791
2 змінених файлів з 51 додано та 3 видалено
  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 Переглянути файл

728
     /* Clear any pending interrupt events. */
728
     /* Clear any pending interrupt events. */
729
     icr = E1000_READ_REG(hw, ICR);
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
     /* If MWI was previously enabled, reenable it. */
742
     /* If MWI was previously enabled, reenable it. */
732
     if (hw->mac_type == e1000_82542_rev2_0) {
743
     if (hw->mac_type == e1000_82542_rev2_0) {
733
         if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
744
         if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
5774
 int32_t
5785
 int32_t
5775
 e1000_read_mac_addr(struct e1000_hw * hw)
5786
 e1000_read_mac_addr(struct e1000_hw * hw)
5776
 {
5787
 {
5777
-    uint16_t offset;
5788
+    uint16_t offset, mac_addr_offset = 0;
5778
     uint16_t eeprom_data, i;
5789
     uint16_t eeprom_data, i;
5790
+    int32_t ret_val;
5779
 
5791
 
5780
     DEBUGFUNC("e1000_read_mac_addr");
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
     for (i = 0; i < NODE_ADDRESS_SIZE; i += 2) {
5828
     for (i = 0; i < NODE_ADDRESS_SIZE; i += 2) {
5783
-        offset = i >> 1;
5829
+        offset = mac_addr_offset + (i >> 1);
5784
         if (e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) {
5830
         if (e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) {
5785
             DEBUGOUT("EEPROM Read Error\n");
5831
             DEBUGOUT("EEPROM Read Error\n");
5786
             return -E1000_ERR_EEPROM;
5832
             return -E1000_ERR_EEPROM;
5797
     case e1000_82571:
5843
     case e1000_82571:
5798
     case e1000_82576:
5844
     case e1000_82576:
5799
     case e1000_80003es2lan:
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
             hw->perm_mac_addr[5] ^= 0x01;
5848
             hw->perm_mac_addr[5] ^= 0x01;
5802
         break;
5849
         break;
5803
     }
5850
     }

+ 1
- 0
src/drivers/net/e1000/e1000_hw.h Переглянути файл

2299
 #define EEPROM_INIT_CONTROL3_PORT_A   0x0024
2299
 #define EEPROM_INIT_CONTROL3_PORT_A   0x0024
2300
 #define EEPROM_CFG                    0x0012
2300
 #define EEPROM_CFG                    0x0012
2301
 #define EEPROM_FLASH_VERSION          0x0032
2301
 #define EEPROM_FLASH_VERSION          0x0032
2302
+#define EEPROM_ALT_MAC_ADDR_PTR       0x0037
2302
 #define EEPROM_CHECKSUM_REG           0x003F
2303
 #define EEPROM_CHECKSUM_REG           0x003F
2303
 
2304
 
2304
 #define E1000_EEPROM_CFG_DONE         0x00040000   /* MNG config cycle done */
2305
 #define E1000_EEPROM_CFG_DONE         0x00040000   /* MNG config cycle done */

Завантаження…
Відмінити
Зберегти