Linux "igb" driver also reads the address for NVM_ALT_MAC_ADDR_PTR from EEPROM, iPXE has hardcoded value (0x00) to NVM_ALT_MAC location.
 
Probably you need to add a few lines more (untested :)):
 
static int intel_fetch_mac_eeprom ( struct intel_nic *intel,
                                    uint8_t *hw_addr ) {
        int rc;
        uint16_t offset;

        /* Initialise EEPROM */
        if ( ( rc = intel_init_eeprom ( intel ) ) != 0 )
                return rc;
 
        if ( ( rc = nvs_read ( &intel->eeprom, 0x37 /* NVM_ALT_MAC_ADDR_PTR */,
                               &offset, sizeof(offset) ) ) != 0 ) {
                DBGC ( intel, "INTEL %p could not read EEPROM alternate MAC"
                       "address PTR: %s\n", intel, strerror ( rc ) );
                return rc;
        }
 
        if (offset == 0xffff) {
                /* There is no Alternate MAC Address */
                return rc;
        }
        
        /* Read base MAC address from EEPROM */
        if (intel->port == 1)
                offset += 3; /* E1000_ALT_MAC_ADDRESS_OFFSET_LAN1 */
        if ( ( rc = nvs_read ( &intel->eeprom, offset << 1,
                               hw_addr, ETH_ALEN ) ) != 0 ) {
                DBGC ( intel, "INTEL %p could not read EEPROM base MAC "
                       "address: %s\n", intel, strerror ( rc ) );
                return rc;
        }

        /* Adjust MAC address for multi-port devices */
        hw_addr[ETH_ALEN-1] ^= intel->port;

        DBGC ( intel, "INTEL %p has EEPROM MAC address %s (port %d)\n",
               intel, eth_ntoa ( hw_addr ), intel->port );
        return 0;
}
 
27.07.2012, 15:22, "Anton D. Kachalov" <[email protected]>:
Oh, sorry. Got you.
 
From the Linux igb driver:
/**
 *  igb_check_alt_mac_addr - Check for alternate MAC addr
 *  @hw: pointer to the HW structure
 *
 *  Checks the nvm 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 an
 *  alternate MAC address is fopund it is saved in the hw struct and
 *  prgrammed into RAR0 and the cuntion returns success, otherwise the
 *  function returns an error.
 **/
 
igb_check_alt_mac_addr()
{
     …
     if (hw->bus.func == E1000_FUNC_1)
         nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN1;
     for (i = 0; i < ETH_ALEN; i += 2) {
         offset = nvm_alt_mac_addr_offset + (i >> 1);
         …
     }
}
and general function:
 
static s32 igb_read_mac_addr_82575(struct e1000_hw *hw)
{
        s32 ret_val = 0;

        /*
         * If there's an alternate MAC address place it in RAR0
         * so that it will override the Si installed default perm
         * address.
         */
        ret_val = igb_check_alt_mac_addr(hw);
        if (ret_val)
                goto out;

        ret_val = igb_read_mac_addr(hw);

out:
        return ret_val;
}

So, the "intel" driver in iPXE works almost correctly at this point except that for PORT_ONE it reads EEPROM from the same location instead of shifted by 6 bytes (3 words).
 
Try to modify "intel_fetch_mac_eeprom()" routine:
 
static int intel_fetch_mac_eeprom ( struct intel_nic *intel,
                                    uint8_t *hw_addr ) {
        int rc;
        int offset = 0;

        /* Initialise EEPROM */
        if ( ( rc = intel_init_eeprom ( intel ) ) != 0 )
                return rc;

        /* Read base MAC address from EEPROM */
        if (intel->port == 1)
                offset = 6; /* E1000_ALT_MAC_ADDRESS_OFFSET_LAN1 */
        if ( ( rc = nvs_read ( &intel->eeprom, INTEL_EEPROM_MAC + offset,
                               hw_addr, ETH_ALEN ) ) != 0 ) {
                DBGC ( intel, "INTEL %p could not read EEPROM base MAC "
                       "address: %s\n", intel, strerror ( rc ) );
                return rc;
        }

        /* Adjust MAC address for multi-port devices */
        hw_addr[ETH_ALEN-1] ^= intel->port;

        DBGC ( intel, "INTEL %p has EEPROM MAC address %s (port %d)\n",
               intel, eth_ntoa ( hw_addr ), intel->port );
        return 0;
}

--
Anton D. Kachalov

ITO, R&D group, Senior System Engineer
Tel: +7 (495) 739-70-00 ext.7613
_______________________________________________
ipxe-devel mailing list
[email protected]
https://lists.ipxe.org/mailman/listinfo.cgi/ipxe-devel

Reply via email to