X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fnet%2Fe1000.c;h=875682b1b89e1ee31b7226e646be3c108b850933;hb=d10fc50f78ebae7c7f52469eced7c0d6d8a89f8c;hp=2d66690226763c4bd6af38752ca09a0866960882;hpb=1733259d25015c28c47990ec11af99b3f62f811c;p=u-boot diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c index 2d66690226..875682b1b8 100644 --- a/drivers/net/e1000.c +++ b/drivers/net/e1000.c @@ -29,12 +29,22 @@ tested on both gig copper and gig fiber boards * Copyright 2011 Freescale Semiconductor, Inc. */ +#include +#include +#include +#include +#include #include "e1000.h" #define TOUT_LOOP 100000 +#ifdef CONFIG_DM_ETH +#define virt_to_bus(devno, v) dm_pci_virt_to_mem(devno, (void *) (v)) +#define bus_to_phys(devno, a) dm_pci_mem_to_phys(devno, a) +#else #define virt_to_bus(devno, v) pci_virt_to_mem(devno, (void *) (v)) #define bus_to_phys(devno, a) pci_mem_to_phys(devno, a) +#endif #define E1000_DEFAULT_PCI_PBA 0x00000030 #define E1000_DEFAULT_PCIE_PBA 0x000a0026 @@ -44,75 +54,84 @@ tested on both gig copper and gig fiber boards /* Intel i210 needs the DMA descriptor rings aligned to 128b */ #define E1000_BUFFER_ALIGN 128 +/* + * TODO(sjg@chromium.org): Even with driver model we share these buffers. + * Concurrent receiving on multiple active Ethernet devices will not work. + * Normally U-Boot does not support this anyway. To fix it in this driver, + * move these buffers and the tx/rx pointers to struct e1000_hw. + */ DEFINE_ALIGN_BUFFER(struct e1000_tx_desc, tx_base, 16, E1000_BUFFER_ALIGN); DEFINE_ALIGN_BUFFER(struct e1000_rx_desc, rx_base, 16, E1000_BUFFER_ALIGN); DEFINE_ALIGN_BUFFER(unsigned char, packet, 4096, E1000_BUFFER_ALIGN); static int tx_tail; static int rx_tail, rx_last; +#ifdef CONFIG_DM_ETH +static int num_cards; /* Number of E1000 devices seen so far */ +#endif static struct pci_device_id e1000_supported[] = { - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82542}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82543GC_FIBER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82543GC_COPPER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544EI_COPPER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544EI_FIBER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544GC_COPPER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544GC_LOM}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545EM_COPPER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545GM_COPPER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_COPPER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545EM_FIBER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_FIBER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546GB_COPPER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM_LOM}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82541ER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82541GI_LF}, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82542) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82543GC_FIBER) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82543GC_COPPER) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544EI_COPPER) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544EI_FIBER) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544GC_COPPER) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544GC_LOM) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545EM_COPPER) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545GM_COPPER) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_COPPER) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545EM_FIBER) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_FIBER) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546GB_COPPER) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM_LOM) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82541ER) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82541GI_LF) }, /* E1000 PCIe card */ - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_COPPER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_FIBER }, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_SERDES }, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_QUAD_COPPER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571PT_QUAD_COPPER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_QUAD_FIBER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_QUAD_COPPER_LOWPROFILE}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_SERDES_DUAL}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_SERDES_QUAD}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI_COPPER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI_FIBER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI_SERDES}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82573E}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82573E_IAMT}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82573L}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82574L}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546GB_QUAD_COPPER_KSP3}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_COPPER_DPT}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_SERDES_DPT}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_COPPER_SPT}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_SERDES_SPT}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_UNPROGRAMMED}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I211_UNPROGRAMMED}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_COPPER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I211_COPPER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_COPPER_FLASHLESS}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_SERDES}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_SERDES_FLASHLESS}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_1000BASEKX}, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_COPPER) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_FIBER) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_SERDES) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_QUAD_COPPER) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571PT_QUAD_COPPER) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_QUAD_FIBER) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_QUAD_COPPER_LOWPROFILE) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_SERDES_DUAL) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_SERDES_QUAD) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI_COPPER) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI_FIBER) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI_SERDES) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82573E) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82573E_IAMT) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82573L) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82574L) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546GB_QUAD_COPPER_KSP3) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_COPPER_DPT) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_SERDES_DPT) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_COPPER_SPT) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_SERDES_SPT) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_UNPROGRAMMED) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I211_UNPROGRAMMED) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_COPPER) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I211_COPPER) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_COPPER_FLASHLESS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_SERDES) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_SERDES_FLASHLESS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_1000BASEKX) }, {} }; /* Function forward declarations */ -static int e1000_setup_link(struct eth_device *nic); -static int e1000_setup_fiber_link(struct eth_device *nic); -static int e1000_setup_copper_link(struct eth_device *nic); +static int e1000_setup_link(struct e1000_hw *hw); +static int e1000_setup_fiber_link(struct e1000_hw *hw); +static int e1000_setup_copper_link(struct e1000_hw *hw); static int e1000_phy_setup_autoneg(struct e1000_hw *hw); static void e1000_config_collision_dist(struct e1000_hw *hw); static int e1000_config_mac_to_phy(struct e1000_hw *hw); static int e1000_config_fc_after_link_up(struct e1000_hw *hw); -static int e1000_check_for_link(struct eth_device *nic); +static int e1000_check_for_link(struct e1000_hw *hw); static int e1000_wait_autoneg(struct e1000_hw *hw); static int e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t * speed, uint16_t * duplex); @@ -126,6 +145,7 @@ static int e1000_detect_gig_phy(struct e1000_hw *hw); static void e1000_set_media_type(struct e1000_hw *hw); static int32_t e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask); +static void e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask); static int32_t e1000_check_phy_reset_block(struct e1000_hw *hw); #ifndef CONFIG_E1000_NO_NVM @@ -536,43 +556,6 @@ static int32_t e1000_init_eeprom_params(struct e1000_hw *hw) eeprom->use_eerd = true; eeprom->use_eewr = false; break; - - /* ich8lan does not support currently. if needed, please - * add corresponding code and functions. - */ -#if 0 - case e1000_ich8lan: - { - int32_t i = 0; - - eeprom->type = e1000_eeprom_ich8; - eeprom->use_eerd = false; - eeprom->use_eewr = false; - eeprom->word_size = E1000_SHADOW_RAM_WORDS; - uint32_t flash_size = E1000_READ_ICH_FLASH_REG(hw, - ICH_FLASH_GFPREG); - /* Zero the shadow RAM structure. But don't load it from NVM - * so as to save time for driver init */ - if (hw->eeprom_shadow_ram != NULL) { - for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) { - hw->eeprom_shadow_ram[i].modified = false; - hw->eeprom_shadow_ram[i].eeprom_word = 0xFFFF; - } - } - - hw->flash_base_addr = (flash_size & ICH_GFPREG_BASE_MASK) * - ICH_FLASH_SECTOR_SIZE; - - hw->flash_bank_size = ((flash_size >> 16) - & ICH_GFPREG_BASE_MASK) + 1; - hw->flash_bank_size -= (flash_size & ICH_GFPREG_BASE_MASK); - - hw->flash_bank_size *= ICH_FLASH_SECTOR_SIZE; - - hw->flash_bank_size /= 2 * sizeof(uint16_t); - break; - } -#endif default: break; } @@ -729,7 +712,10 @@ void e1000_release_eeprom(struct e1000_hw *hw) eecd &= ~E1000_EECD_REQ; E1000_WRITE_REG(hw, EECD, eecd); } + + e1000_swfw_sync_release(hw, E1000_SWFW_EEP_SM); } + /****************************************************************************** * Reads a 16 bit word from the EEPROM. * @@ -820,14 +806,6 @@ e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset, if (eeprom->use_eerd == true) return e1000_read_eeprom_eerd(hw, offset, words, data); - /* ich8lan does not support currently. if needed, please - * add corresponding code and functions. - */ -#if 0 - /* ICH EEPROM access is done via the ICH flash controller */ - if (eeprom->type == e1000_eeprom_ich8) - return e1000_read_eeprom_ich8(hw, offset, words, data); -#endif /* Set up the SPI or Microwire EEPROM for bit-bang reading. We have * acquired the EEPROM at this point, so any returns should relase it */ if (eeprom->type == e1000_eeprom_spi) { @@ -901,13 +879,13 @@ static int e1000_validate_eeprom_checksum(struct e1000_hw *hw) /* Allocate a temporary buffer */ buf = malloc(sizeof(buf[0]) * (EEPROM_CHECKSUM_REG + 1)); if (!buf) { - E1000_ERR(hw->nic, "Unable to allocate EEPROM buffer!\n"); + E1000_ERR(hw, "Unable to allocate EEPROM buffer!\n"); return -E1000_ERR_EEPROM; } /* Read the EEPROM */ if (e1000_read_eeprom(hw, 0, EEPROM_CHECKSUM_REG + 1, buf) < 0) { - E1000_ERR(hw->nic, "Unable to read EEPROM!\n"); + E1000_ERR(hw, "Unable to read EEPROM!\n"); return -E1000_ERR_EEPROM; } @@ -923,9 +901,9 @@ static int e1000_validate_eeprom_checksum(struct e1000_hw *hw) return 0; /* Hrm, verification failed, print an error */ - E1000_ERR(hw->nic, "EEPROM checksum is incorrect!\n"); - E1000_ERR(hw->nic, " ...register was 0x%04hx, calculated 0x%04hx\n", - checksum_reg, checksum); + E1000_ERR(hw, "EEPROM checksum is incorrect!\n"); + E1000_ERR(hw, " ...register was 0x%04hx, calculated 0x%04hx\n", + checksum_reg, checksum); return -E1000_ERR_EEPROM; } @@ -992,10 +970,6 @@ e1000_get_software_semaphore(struct e1000_hw *hw) DEBUGFUNC(); - swsm = E1000_READ_REG(hw, SWSM); - swsm &= ~E1000_SWSM_SMBI; - E1000_WRITE_REG(hw, SWSM, swsm); - if (hw->mac_type != e1000_80003es2lan) return E1000_SUCCESS; @@ -1102,6 +1076,7 @@ e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw) return E1000_SUCCESS; } +/* Take ownership of the PHY */ static int32_t e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask) { @@ -1115,10 +1090,7 @@ e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask) if (e1000_get_hw_eeprom_semaphore(hw)) return -E1000_ERR_SWFW_SYNC; - if (hw->mac_type == e1000_igb) - swfw_sync = E1000_READ_REG(hw, I210_SW_FW_SYNC); - else - swfw_sync = E1000_READ_REG(hw, SW_FW_SYNC); + swfw_sync = E1000_READ_REG(hw, SW_FW_SYNC); if (!(swfw_sync & (fwmask | swmask))) break; @@ -1141,6 +1113,21 @@ e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask) return E1000_SUCCESS; } +static void e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask) +{ + uint32_t swfw_sync = 0; + + DEBUGFUNC(); + while (e1000_get_hw_eeprom_semaphore(hw)) + ; /* Empty */ + + swfw_sync = E1000_READ_REG(hw, SW_FW_SYNC); + swfw_sync &= ~mask; + E1000_WRITE_REG(hw, SW_FW_SYNC, swfw_sync); + + e1000_put_hw_eeprom_semaphore(hw); +} + static bool e1000_is_second_port(struct e1000_hw *hw) { switch (hw->mac_type) { @@ -1163,9 +1150,8 @@ static bool e1000_is_second_port(struct e1000_hw *hw) * nic - Struct containing variables accessed by shared code *****************************************************************************/ static int -e1000_read_mac_addr(struct eth_device *nic) +e1000_read_mac_addr(struct e1000_hw *hw, unsigned char enetaddr[6]) { - struct e1000_hw *hw = nic->priv; uint16_t offset; uint16_t eeprom_data; uint32_t reg_data = 0; @@ -1188,21 +1174,14 @@ e1000_read_mac_addr(struct eth_device *nic) DEBUGOUT("EEPROM Read Error\n"); return -E1000_ERR_EEPROM; } - nic->enetaddr[i] = eeprom_data & 0xff; - nic->enetaddr[i + 1] = (eeprom_data >> 8) & 0xff; + enetaddr[i] = eeprom_data & 0xff; + enetaddr[i + 1] = (eeprom_data >> 8) & 0xff; } /* Invert the last bit if this is the second device */ if (e1000_is_second_port(hw)) - nic->enetaddr[5] ^= 1; + enetaddr[5] ^= 1; -#ifdef CONFIG_E1000_FALLBACK_MAC - if (!is_valid_ethaddr(nic->enetaddr)) { - unsigned char fb_mac[NODE_ADDRESS_SIZE] = CONFIG_E1000_FALLBACK_MAC; - - memcpy (nic->enetaddr, fb_mac, NODE_ADDRESS_SIZE); - } -#endif return 0; } #endif @@ -1217,9 +1196,8 @@ e1000_read_mac_addr(struct eth_device *nic) * the receiver is in reset when the routine is called. *****************************************************************************/ static void -e1000_init_rx_addrs(struct eth_device *nic) +e1000_init_rx_addrs(struct e1000_hw *hw, unsigned char enetaddr[6]) { - struct e1000_hw *hw = nic->priv; uint32_t i; uint32_t addr_low; uint32_t addr_high; @@ -1228,11 +1206,11 @@ e1000_init_rx_addrs(struct eth_device *nic) /* Setup the receive address. */ DEBUGOUT("Programming MAC Address into RAR[0]\n"); - addr_low = (nic->enetaddr[0] | - (nic->enetaddr[1] << 8) | - (nic->enetaddr[2] << 16) | (nic->enetaddr[3] << 24)); + addr_low = (enetaddr[0] | + (enetaddr[1] << 8) | + (enetaddr[2] << 16) | (enetaddr[3] << 24)); - addr_high = (nic->enetaddr[4] | (nic->enetaddr[5] << 8) | E1000_RAH_AV); + addr_high = (enetaddr[4] | (enetaddr[5] << 8) | E1000_RAH_AV); E1000_WRITE_REG_ARRAY(hw, RA, 0, addr_low); E1000_WRITE_REG_ARRAY(hw, RA, 1, addr_high); @@ -1422,8 +1400,13 @@ e1000_reset_hw(struct e1000_hw *hw) /* For 82542 (rev 2.0), disable MWI before issuing a device reset */ if (hw->mac_type == e1000_82542_rev2_0) { DEBUGOUT("Disabling MWI on 82542 rev 2.0\n"); +#ifdef CONFIG_DM_ETH + dm_pci_write_config16(hw->pdev, PCI_COMMAND, + hw->pci_cmd_word & ~PCI_COMMAND_INVALIDATE); +#else pci_write_config_word(hw->pdev, PCI_COMMAND, hw->pci_cmd_word & ~PCI_COMMAND_INVALIDATE); +#endif } /* Clear interrupt mask to stop board from generating interrupts */ @@ -1496,7 +1479,11 @@ e1000_reset_hw(struct e1000_hw *hw) /* If MWI was previously enabled, reenable it. */ if (hw->mac_type == e1000_82542_rev2_0) { +#ifdef CONFIG_DM_ETH + dm_pci_write_config16(hw->pdev, PCI_COMMAND, hw->pci_cmd_word); +#else pci_write_config_word(hw->pdev, PCI_COMMAND, hw->pci_cmd_word); +#endif } if (hw->mac_type != e1000_igb) E1000_WRITE_REG(hw, PBA, pba); @@ -1535,11 +1522,10 @@ e1000_initialize_hardware_bits(struct e1000_hw *hw) reg_txdctl1 |= E1000_TXDCTL_COUNT_DESC; E1000_WRITE_REG(hw, TXDCTL1, reg_txdctl1); - /* IGB is cool */ - if (hw->mac_type == e1000_igb) - return; switch (hw->mac_type) { + case e1000_igb: /* IGB is cool */ + return; case e1000_82571: case e1000_82572: /* Clear PHY TX compatible mode bits */ @@ -1639,9 +1625,8 @@ e1000_initialize_hardware_bits(struct e1000_hw *hw) * the transmit and receive units disabled and uninitialized. *****************************************************************************/ static int -e1000_init_hw(struct eth_device *nic) +e1000_init_hw(struct e1000_hw *hw, unsigned char enetaddr[6]) { - struct e1000_hw *hw = nic->priv; uint32_t ctrl; uint32_t i; int32_t ret_val; @@ -1683,9 +1668,15 @@ e1000_init_hw(struct eth_device *nic) /* For 82542 (rev 2.0), disable MWI and put the receiver into reset */ if (hw->mac_type == e1000_82542_rev2_0) { DEBUGOUT("Disabling MWI on 82542 rev 2.0\n"); +#ifdef CONFIG_DM_ETH + dm_pci_write_config16(hw->pdev, PCI_COMMAND, + hw-> + pci_cmd_word & ~PCI_COMMAND_INVALIDATE); +#else pci_write_config_word(hw->pdev, PCI_COMMAND, hw-> pci_cmd_word & ~PCI_COMMAND_INVALIDATE); +#endif E1000_WRITE_REG(hw, RCTL, E1000_RCTL_RST); E1000_WRITE_FLUSH(hw); mdelay(5); @@ -1694,14 +1685,18 @@ e1000_init_hw(struct eth_device *nic) /* Setup the receive address. This involves initializing all of the Receive * Address Registers (RARs 0 - 15). */ - e1000_init_rx_addrs(nic); + e1000_init_rx_addrs(hw, enetaddr); /* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */ if (hw->mac_type == e1000_82542_rev2_0) { E1000_WRITE_REG(hw, RCTL, 0); E1000_WRITE_FLUSH(hw); mdelay(1); +#ifdef CONFIG_DM_ETH + dm_pci_write_config16(hw->pdev, PCI_COMMAND, hw->pci_cmd_word); +#else pci_write_config_word(hw->pdev, PCI_COMMAND, hw->pci_cmd_word); +#endif } /* Zero out the Multicast HASH table */ @@ -1715,17 +1710,7 @@ e1000_init_hw(struct eth_device *nic) * occuring when accessing our register space */ E1000_WRITE_FLUSH(hw); } -#if 0 - /* Set the PCI priority bit correctly in the CTRL register. This - * determines if the adapter gives priority to receives, or if it - * gives equal priority to transmits and receives. Valid only on - * 82542 and 82543 silicon. - */ - if (hw->dma_fairness && hw->mac_type <= e1000_82543) { - ctrl = E1000_READ_REG(hw, CTRL); - E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PRIOR); - } -#endif + switch (hw->mac_type) { case e1000_82545_rev_3: case e1000_82546_rev_3: @@ -1734,10 +1719,17 @@ e1000_init_hw(struct eth_device *nic) default: /* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */ if (hw->bus_type == e1000_bus_type_pcix) { +#ifdef CONFIG_DM_ETH + dm_pci_read_config16(hw->pdev, PCIX_COMMAND_REGISTER, + &pcix_cmd_word); + dm_pci_read_config16(hw->pdev, PCIX_STATUS_REGISTER_HI, + &pcix_stat_hi_word); +#else pci_read_config_word(hw->pdev, PCIX_COMMAND_REGISTER, &pcix_cmd_word); pci_read_config_word(hw->pdev, PCIX_STATUS_REGISTER_HI, &pcix_stat_hi_word); +#endif cmd_mmrbc = (pcix_cmd_word & PCIX_COMMAND_MMRBC_MASK) >> PCIX_COMMAND_MMRBC_SHIFT; @@ -1749,8 +1741,13 @@ e1000_init_hw(struct eth_device *nic) if (cmd_mmrbc > stat_mmrbc) { pcix_cmd_word &= ~PCIX_COMMAND_MMRBC_MASK; pcix_cmd_word |= stat_mmrbc << PCIX_COMMAND_MMRBC_SHIFT; +#ifdef CONFIG_DM_ETH + dm_pci_write_config16(hw->pdev, PCIX_COMMAND_REGISTER, + pcix_cmd_word); +#else pci_write_config_word(hw->pdev, PCIX_COMMAND_REGISTER, pcix_cmd_word); +#endif } } break; @@ -1763,7 +1760,7 @@ e1000_init_hw(struct eth_device *nic) mdelay(15); /* Call a subroutine to configure the link and setup flow control. */ - ret_val = e1000_setup_link(nic); + ret_val = e1000_setup_link(hw); /* Set the transmit descriptor write-back policy */ if (hw->mac_type > e1000_82544) { @@ -1825,20 +1822,6 @@ e1000_init_hw(struct eth_device *nic) break; } -#if 0 - /* Clear all of the statistics registers (clear on read). It is - * important that we do this after we have tried to establish link - * because the symbol error count will increment wildly if there - * is no link. - */ - e1000_clear_hw_cntrs(hw); - - /* ICH8 No-snoop bits are opposite polarity. - * Set to snoop by default after reset. */ - if (hw->mac_type == e1000_ich8lan) - e1000_set_pci_ex_no_snoop(hw, PCI_EX_82566_SNOOP_ALL); -#endif - if (hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER || hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3) { ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); @@ -1863,9 +1846,8 @@ e1000_init_hw(struct eth_device *nic) * transmitter and receiver are not enabled. *****************************************************************************/ static int -e1000_setup_link(struct eth_device *nic) +e1000_setup_link(struct e1000_hw *hw) { - struct e1000_hw *hw = nic->priv; int32_t ret_val; #ifndef CONFIG_E1000_NO_NVM uint32_t ctrl_ext; @@ -1953,7 +1935,7 @@ e1000_setup_link(struct eth_device *nic) /* Call the necessary subroutine to configure the link. */ ret_val = (hw->media_type == e1000_media_type_fiber) ? - e1000_setup_fiber_link(nic) : e1000_setup_copper_link(nic); + e1000_setup_fiber_link(hw) : e1000_setup_copper_link(hw); if (ret_val < 0) { return ret_val; } @@ -2010,9 +1992,8 @@ e1000_setup_link(struct eth_device *nic) * and receiver are not enabled. *****************************************************************************/ static int -e1000_setup_fiber_link(struct eth_device *nic) +e1000_setup_fiber_link(struct e1000_hw *hw) { - struct e1000_hw *hw = nic->priv; uint32_t ctrl; uint32_t status; uint32_t txcw = 0; @@ -2031,7 +2012,7 @@ e1000_setup_fiber_link(struct eth_device *nic) else signal = 0; - printf("signal for %s is %x (ctrl %08x)!!!!\n", nic->name, signal, + printf("signal for %s is %x (ctrl %08x)!!!!\n", hw->name, signal, ctrl); /* Take the link out of reset */ ctrl &= ~(E1000_CTRL_LRST); @@ -2119,7 +2100,7 @@ e1000_setup_fiber_link(struct eth_device *nic) */ DEBUGOUT("Never got a valid link from auto-neg!!!\n"); hw->autoneg_failed = 1; - ret_val = e1000_check_for_link(nic); + ret_val = e1000_check_for_link(hw); if (ret_val < 0) { DEBUGOUT("Error while checking for link\n"); return ret_val; @@ -2174,7 +2155,7 @@ e1000_copper_link_preconfig(struct e1000_hw *hw) DEBUGOUT("Error, did not detect valid phy.\n"); return ret_val; } - DEBUGOUT("Phy ID = %x \n", hw->phy_id); + DEBUGOUT("Phy ID = %x\n", hw->phy_id); /* Set PHY to class A mode (if necessary) */ ret_val = e1000_set_phy_mode(hw); @@ -3036,9 +3017,8 @@ e1000_copper_link_postconfig(struct e1000_hw *hw) * hw - Struct containing variables accessed by shared code ******************************************************************************/ static int -e1000_setup_copper_link(struct eth_device *nic) +e1000_setup_copper_link(struct e1000_hw *hw) { - struct e1000_hw *hw = nic->priv; int32_t ret_val; uint16_t i; uint16_t phy_data; @@ -3485,11 +3465,11 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw) * some "sticky" (latched) bits. */ if (e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) { - DEBUGOUT("PHY Read Error \n"); + DEBUGOUT("PHY Read Error\n"); return -E1000_ERR_PHY; } if (e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) { - DEBUGOUT("PHY Read Error \n"); + DEBUGOUT("PHY Read Error\n"); return -E1000_ERR_PHY; } @@ -3661,9 +3641,8 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw) * Called by any function that needs to check the link status of the adapter. *****************************************************************************/ static int -e1000_check_for_link(struct eth_device *nic) +e1000_check_for_link(struct e1000_hw *hw) { - struct e1000_hw *hw = nic->priv; uint32_t rxcw; uint32_t ctrl; uint32_t status; @@ -4004,7 +3983,7 @@ e1000_wait_autoneg(struct e1000_hw *hw) DEBUGFUNC(); DEBUGOUT("Waiting for Auto-Neg to complete.\n"); - /* We will wait for autoneg to complete or 4.5 seconds to expire. */ + /* We will wait for autoneg to complete or timeout to expire. */ for (i = PHY_AUTO_NEG_TIME; i > 0; i--) { /* Read the MII Status Register and wait for Auto-Neg * Complete bit to be set. @@ -4438,6 +4417,7 @@ e1000_phy_hw_reset(struct e1000_hw *hw) if (hw->mac_type >= e1000_82571) mdelay(10); + } else { /* Read the Extended Device Control Register, assert the PHY_RESET_DIR * bit to put the PHY into reset. Then, take it out of reset. @@ -4462,6 +4442,8 @@ e1000_phy_hw_reset(struct e1000_hw *hw) E1000_WRITE_REG(hw, LEDCTL, led_ctrl); } + e1000_swfw_sync_release(hw, swfw); + /* Wait for FW to finish PHY configuration. */ ret_val = e1000_get_phy_cfg_done(hw); if (ret_val != E1000_SUCCESS) @@ -4857,12 +4839,21 @@ e1000_set_media_type(struct e1000_hw *hw) **/ static int -e1000_sw_init(struct eth_device *nic) +e1000_sw_init(struct e1000_hw *hw) { - struct e1000_hw *hw = (typeof(hw)) nic->priv; int result; /* PCI config space info */ +#ifdef CONFIG_DM_ETH + dm_pci_read_config16(hw->pdev, PCI_VENDOR_ID, &hw->vendor_id); + dm_pci_read_config16(hw->pdev, PCI_DEVICE_ID, &hw->device_id); + dm_pci_read_config16(hw->pdev, PCI_SUBSYSTEM_VENDOR_ID, + &hw->subsystem_vendor_id); + dm_pci_read_config16(hw->pdev, PCI_SUBSYSTEM_ID, &hw->subsystem_id); + + dm_pci_read_config8(hw->pdev, PCI_REVISION_ID, &hw->revision_id); + dm_pci_read_config16(hw->pdev, PCI_COMMAND, &hw->pci_cmd_word); +#else pci_read_config_word(hw->pdev, PCI_VENDOR_ID, &hw->vendor_id); pci_read_config_word(hw->pdev, PCI_DEVICE_ID, &hw->device_id); pci_read_config_word(hw->pdev, PCI_SUBSYSTEM_VENDOR_ID, @@ -4871,11 +4862,12 @@ e1000_sw_init(struct eth_device *nic) pci_read_config_byte(hw->pdev, PCI_REVISION_ID, &hw->revision_id); pci_read_config_word(hw->pdev, PCI_COMMAND, &hw->pci_cmd_word); +#endif /* identify the MAC */ result = e1000_set_mac_type(hw); if (result) { - E1000_ERR(hw->nic, "Unknown MAC Type\n"); + E1000_ERR(hw, "Unknown MAC Type\n"); return result; } @@ -4964,8 +4956,8 @@ e1000_configure_tx(struct e1000_hw *hw) unsigned long tipg, tarc; uint32_t ipgr1, ipgr2; - E1000_WRITE_REG(hw, TDBAL, (unsigned long)tx_base); - E1000_WRITE_REG(hw, TDBAH, 0); + E1000_WRITE_REG(hw, TDBAL, lower_32_bits((unsigned long)tx_base)); + E1000_WRITE_REG(hw, TDBAH, upper_32_bits((unsigned long)tx_base)); E1000_WRITE_REG(hw, TDLEN, 128); @@ -5089,6 +5081,7 @@ e1000_configure_rx(struct e1000_hw *hw) { unsigned long rctl, ctrl_ext; rx_tail = 0; + /* make sure receives are disabled while setting up the descriptors */ rctl = E1000_READ_REG(hw, RCTL); E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN); @@ -5108,8 +5101,8 @@ e1000_configure_rx(struct e1000_hw *hw) E1000_WRITE_FLUSH(hw); } /* Setup the Base and Length of the Rx Descriptor Ring */ - E1000_WRITE_REG(hw, RDBAL, (unsigned long)rx_base); - E1000_WRITE_REG(hw, RDBAH, 0); + E1000_WRITE_REG(hw, RDBAL, lower_32_bits((unsigned long)rx_base)); + E1000_WRITE_REG(hw, RDBAH, upper_32_bits((unsigned long)rx_base)); E1000_WRITE_REG(hw, RDLEN, 128); @@ -5135,9 +5128,8 @@ e1000_configure_rx(struct e1000_hw *hw) POLL - Wait for a frame ***************************************************************************/ static int -e1000_poll(struct eth_device *nic) +_e1000_poll(struct e1000_hw *hw) { - struct e1000_hw *hw = nic->priv; struct e1000_rx_desc *rd; unsigned long inval_start, inval_end; uint32_t len; @@ -5150,26 +5142,20 @@ e1000_poll(struct eth_device *nic) inval_end = inval_start + roundup(sizeof(*rd), ARCH_DMA_MINALIGN); invalidate_dcache_range(inval_start, inval_end); - if (!(le32_to_cpu(rd->status)) & E1000_RXD_STAT_DD) + if (!(rd->status & E1000_RXD_STAT_DD)) return 0; - /*DEBUGOUT("recv: packet len=%d \n", rd->length); */ + /* DEBUGOUT("recv: packet len=%d\n", rd->length); */ /* Packet received, make sure the data are re-loaded from RAM. */ - len = le32_to_cpu(rd->length); + len = le16_to_cpu(rd->length); invalidate_dcache_range((unsigned long)packet, (unsigned long)packet + roundup(len, ARCH_DMA_MINALIGN)); - net_process_received_packet((uchar *)packet, len); - fill_rx(hw); - return 1; + return len; } -/************************************************************************** -TRANSMIT - Transmit a frame -***************************************************************************/ -static int e1000_transmit(struct eth_device *nic, void *txpacket, int length) +static int _e1000_transmit(struct e1000_hw *hw, void *txpacket, int length) { void *nv_packet = (void *)txpacket; - struct e1000_hw *hw = nic->priv; struct e1000_tx_desc *txp; int i = 0; unsigned long flush_start, flush_end; @@ -5206,27 +5192,9 @@ static int e1000_transmit(struct eth_device *nic, void *txpacket, int length) return 1; } -/*reset function*/ -static inline int -e1000_reset(struct eth_device *nic) -{ - struct e1000_hw *hw = nic->priv; - - e1000_reset_hw(hw); - if (hw->mac_type >= e1000_82544) { - E1000_WRITE_REG(hw, WUC, 0); - } - return e1000_init_hw(nic); -} - -/************************************************************************** -DISABLE - Turn off ethernet interface -***************************************************************************/ static void -e1000_disable(struct eth_device *nic) +_e1000_disable(struct e1000_hw *hw) { - struct e1000_hw *hw = nic->priv; - /* Turn off the ethernet interface */ E1000_WRITE_REG(hw, RCTL, 0); E1000_WRITE_REG(hw, TCTL, 0); @@ -5239,37 +5207,39 @@ e1000_disable(struct eth_device *nic) E1000_WRITE_REG(hw, RDH, 0); E1000_WRITE_REG(hw, RDT, 0); - /* put the card in its initial state */ -#if 0 - E1000_WRITE_REG(hw, CTRL, E1000_CTRL_RST); -#endif mdelay(10); +} + +/*reset function*/ +static inline int +e1000_reset(struct e1000_hw *hw, unsigned char enetaddr[6]) +{ + e1000_reset_hw(hw); + if (hw->mac_type >= e1000_82544) + E1000_WRITE_REG(hw, WUC, 0); + return e1000_init_hw(hw, enetaddr); } -/************************************************************************** -INIT - set up ethernet interface(s) -***************************************************************************/ static int -e1000_init(struct eth_device *nic, bd_t * bis) +_e1000_init(struct e1000_hw *hw, unsigned char enetaddr[6]) { - struct e1000_hw *hw = nic->priv; int ret_val = 0; - ret_val = e1000_reset(nic); + ret_val = e1000_reset(hw, enetaddr); if (ret_val < 0) { if ((ret_val == -E1000_ERR_NOLINK) || (ret_val == -E1000_ERR_TIMEOUT)) { - E1000_ERR(hw->nic, "Valid Link not detected\n"); + E1000_ERR(hw, "Valid Link not detected: %d\n", ret_val); } else { - E1000_ERR(hw->nic, "Hardware Initialization Failed\n"); + E1000_ERR(hw, "Hardware Initialization Failed\n"); } - return 0; + return ret_val; } e1000_configure_tx(hw); e1000_setup_rctl(hw); e1000_configure_rx(hw); - return 1; + return 0; } /****************************************************************************** @@ -5303,8 +5273,167 @@ void e1000_get_bus_type(struct e1000_hw *hw) } } +#ifndef CONFIG_DM_ETH /* A list of all registered e1000 devices */ static LIST_HEAD(e1000_hw_list); +#endif + +#ifdef CONFIG_DM_ETH +static int e1000_init_one(struct e1000_hw *hw, int cardnum, + struct udevice *devno, unsigned char enetaddr[6]) +#else +static int e1000_init_one(struct e1000_hw *hw, int cardnum, pci_dev_t devno, + unsigned char enetaddr[6]) +#endif +{ + u32 val; + + /* Assign the passed-in values */ +#ifdef CONFIG_DM_ETH + hw->pdev = devno; +#else + hw->pdev = devno; +#endif + hw->cardnum = cardnum; + + /* Print a debug message with the IO base address */ +#ifdef CONFIG_DM_ETH + dm_pci_read_config32(devno, PCI_BASE_ADDRESS_0, &val); +#else + pci_read_config_dword(devno, PCI_BASE_ADDRESS_0, &val); +#endif + E1000_DBG(hw, "iobase 0x%08x\n", val & 0xfffffff0); + + /* Try to enable I/O accesses and bus-mastering */ + val = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; +#ifdef CONFIG_DM_ETH + dm_pci_write_config32(devno, PCI_COMMAND, val); +#else + pci_write_config_dword(devno, PCI_COMMAND, val); +#endif + + /* Make sure it worked */ +#ifdef CONFIG_DM_ETH + dm_pci_read_config32(devno, PCI_COMMAND, &val); +#else + pci_read_config_dword(devno, PCI_COMMAND, &val); +#endif + if (!(val & PCI_COMMAND_MEMORY)) { + E1000_ERR(hw, "Can't enable I/O memory\n"); + return -ENOSPC; + } + if (!(val & PCI_COMMAND_MASTER)) { + E1000_ERR(hw, "Can't enable bus-mastering\n"); + return -EPERM; + } + + /* Are these variables needed? */ + hw->fc = e1000_fc_default; + hw->original_fc = e1000_fc_default; + hw->autoneg_failed = 0; + hw->autoneg = 1; + hw->get_link_status = true; +#ifndef CONFIG_E1000_NO_NVM + hw->eeprom_semaphore_present = true; +#endif +#ifdef CONFIG_DM_ETH + hw->hw_addr = dm_pci_map_bar(devno, PCI_BASE_ADDRESS_0, + PCI_REGION_MEM); +#else + hw->hw_addr = pci_map_bar(devno, PCI_BASE_ADDRESS_0, + PCI_REGION_MEM); +#endif + hw->mac_type = e1000_undefined; + + /* MAC and Phy settings */ + if (e1000_sw_init(hw) < 0) { + E1000_ERR(hw, "Software init failed\n"); + return -EIO; + } + if (e1000_check_phy_reset_block(hw)) + E1000_ERR(hw, "PHY Reset is blocked!\n"); + + /* Basic init was OK, reset the hardware and allow SPI access */ + e1000_reset_hw(hw); + +#ifndef CONFIG_E1000_NO_NVM + /* Validate the EEPROM and get chipset information */ + if (e1000_init_eeprom_params(hw)) { + E1000_ERR(hw, "EEPROM is invalid!\n"); + return -EINVAL; + } + if ((E1000_READ_REG(hw, I210_EECD) & E1000_EECD_FLUPD) && + e1000_validate_eeprom_checksum(hw)) + return -ENXIO; + e1000_read_mac_addr(hw, enetaddr); +#endif + e1000_get_bus_type(hw); + +#ifndef CONFIG_E1000_NO_NVM + printf("e1000: %02x:%02x:%02x:%02x:%02x:%02x\n ", + enetaddr[0], enetaddr[1], enetaddr[2], + enetaddr[3], enetaddr[4], enetaddr[5]); +#else + memset(enetaddr, 0, 6); + printf("e1000: no NVM\n"); +#endif + + return 0; +} + +/* Put the name of a device in a string */ +static void e1000_name(char *str, int cardnum) +{ + sprintf(str, "e1000#%u", cardnum); +} + +#ifndef CONFIG_DM_ETH +/************************************************************************** +TRANSMIT - Transmit a frame +***************************************************************************/ +static int e1000_transmit(struct eth_device *nic, void *txpacket, int length) +{ + struct e1000_hw *hw = nic->priv; + + return _e1000_transmit(hw, txpacket, length); +} + +/************************************************************************** +DISABLE - Turn off ethernet interface +***************************************************************************/ +static void +e1000_disable(struct eth_device *nic) +{ + struct e1000_hw *hw = nic->priv; + + _e1000_disable(hw); +} + +/************************************************************************** +INIT - set up ethernet interface(s) +***************************************************************************/ +static int +e1000_init(struct eth_device *nic, bd_t *bis) +{ + struct e1000_hw *hw = nic->priv; + + return _e1000_init(hw, nic->enetaddr); +} + +static int +e1000_poll(struct eth_device *nic) +{ + struct e1000_hw *hw = nic->priv; + int len; + + len = _e1000_poll(hw); + if (len) { + net_process_received_packet((uchar *)packet, len); + fill_rx(hw); + } + + return len ? 1 : 0; +} /************************************************************************** PROBE - Look for an adapter, this routine's visible to the outside @@ -5315,16 +5444,15 @@ e1000_initialize(bd_t * bis) { unsigned int i; pci_dev_t devno; + int ret; DEBUGFUNC(); /* Find and probe all the matching PCI devices */ for (i = 0; (devno = pci_find_devices(e1000_supported, i)) >= 0; i++) { - u32 val; - /* * These will never get freed due to errors, this allows us to - * perform SPI EEPROM programming from U-boot, for example. + * perform SPI EEPROM programming from U-Boot, for example. */ struct eth_device *nic = malloc(sizeof(*nic)); struct e1000_hw *hw = malloc(sizeof(*hw)); @@ -5338,83 +5466,18 @@ e1000_initialize(bd_t * bis) /* Make sure all of the fields are initially zeroed */ memset(nic, 0, sizeof(*nic)); memset(hw, 0, sizeof(*hw)); - - /* Assign the passed-in values */ - hw->cardnum = i; - hw->pdev = devno; - hw->nic = nic; nic->priv = hw; /* Generate a card name */ - sprintf(nic->name, "e1000#%u", hw->cardnum); - - /* Print a debug message with the IO base address */ - pci_read_config_dword(devno, PCI_BASE_ADDRESS_0, &val); - E1000_DBG(nic, "iobase 0x%08x\n", val & 0xfffffff0); - - /* Try to enable I/O accesses and bus-mastering */ - val = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; - pci_write_config_dword(devno, PCI_COMMAND, val); - - /* Make sure it worked */ - pci_read_config_dword(devno, PCI_COMMAND, &val); - if (!(val & PCI_COMMAND_MEMORY)) { - E1000_ERR(nic, "Can't enable I/O memory\n"); - continue; - } - if (!(val & PCI_COMMAND_MASTER)) { - E1000_ERR(nic, "Can't enable bus-mastering\n"); - continue; - } + e1000_name(nic->name, i); + hw->name = nic->name; - /* Are these variables needed? */ - hw->fc = e1000_fc_default; - hw->original_fc = e1000_fc_default; - hw->autoneg_failed = 0; - hw->autoneg = 1; - hw->get_link_status = true; -#ifndef CONFIG_E1000_NO_NVM - hw->eeprom_semaphore_present = true; -#endif - hw->hw_addr = pci_map_bar(devno, PCI_BASE_ADDRESS_0, - PCI_REGION_MEM); - hw->mac_type = e1000_undefined; - - /* MAC and Phy settings */ - if (e1000_sw_init(nic) < 0) { - E1000_ERR(nic, "Software init failed\n"); + ret = e1000_init_one(hw, i, devno, nic->enetaddr); + if (ret) continue; - } - if (e1000_check_phy_reset_block(hw)) - E1000_ERR(nic, "PHY Reset is blocked!\n"); - - /* Basic init was OK, reset the hardware and allow SPI access */ - e1000_reset_hw(hw); list_add_tail(&hw->list_node, &e1000_hw_list); -#ifndef CONFIG_E1000_NO_NVM - /* Validate the EEPROM and get chipset information */ -#if !defined(CONFIG_MVBC_1G) - if (e1000_init_eeprom_params(hw)) { - E1000_ERR(nic, "EEPROM is invalid!\n"); - continue; - } - if ((E1000_READ_REG(hw, I210_EECD) & E1000_EECD_FLUPD) && - e1000_validate_eeprom_checksum(hw)) - continue; -#endif - e1000_read_mac_addr(nic); -#endif - e1000_get_bus_type(hw); - -#ifndef CONFIG_E1000_NO_NVM - printf("e1000: %02x:%02x:%02x:%02x:%02x:%02x\n ", - nic->enetaddr[0], nic->enetaddr[1], nic->enetaddr[2], - nic->enetaddr[3], nic->enetaddr[4], nic->enetaddr[5]); -#else - memset(nic->enetaddr, 0, 6); - printf("e1000: no NVM\n"); -#endif + hw->nic = nic; /* Set up the function pointers and register the device */ nic->init = e1000_init; @@ -5437,12 +5500,23 @@ struct e1000_hw *e1000_find_card(unsigned int cardnum) return NULL; } +#endif /* !CONFIG_DM_ETH */ #ifdef CONFIG_CMD_E1000 static int do_e1000(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { + unsigned char *mac = NULL; +#ifdef CONFIG_DM_ETH + struct eth_pdata *plat; + struct udevice *dev; + char name[30]; + int ret; +#endif +#if !defined(CONFIG_DM_ETH) || defined(CONFIG_E1000_SPI) struct e1000_hw *hw; +#endif + int cardnum; if (argc < 3) { cmd_usage(cmdtp); @@ -5450,20 +5524,34 @@ static int do_e1000(cmd_tbl_t *cmdtp, int flag, } /* Make sure we can find the requested e1000 card */ - hw = e1000_find_card(simple_strtoul(argv[1], NULL, 10)); - if (!hw) { + cardnum = simple_strtoul(argv[1], NULL, 10); +#ifdef CONFIG_DM_ETH + e1000_name(name, cardnum); + ret = uclass_get_device_by_name(UCLASS_ETH, name, &dev); + if (!ret) { + plat = dev_get_platdata(dev); + mac = plat->enetaddr; + } +#else + hw = e1000_find_card(cardnum); + if (hw) + mac = hw->nic->enetaddr; +#endif + if (!mac) { printf("e1000: ERROR: No such device: e1000#%s\n", argv[1]); return 1; } if (!strcmp(argv[2], "print-mac-address")) { - unsigned char *mac = hw->nic->enetaddr; printf("%02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); return 0; } #ifdef CONFIG_E1000_SPI +#ifdef CONFIG_DM_ETH + hw = dev_get_priv(dev); +#endif /* Handle the "SPI" subcommand */ if (!strcmp(argv[2], "spi")) return do_e1000_spi(cmdtp, hw, argc - 3, argv + 3); @@ -5486,3 +5574,109 @@ U_BOOT_CMD( " - Manage the Intel E1000 PCI device" ); #endif /* not CONFIG_CMD_E1000 */ + +#ifdef CONFIG_DM_ETH +static int e1000_eth_start(struct udevice *dev) +{ + struct eth_pdata *plat = dev_get_platdata(dev); + struct e1000_hw *hw = dev_get_priv(dev); + + return _e1000_init(hw, plat->enetaddr); +} + +static void e1000_eth_stop(struct udevice *dev) +{ + struct e1000_hw *hw = dev_get_priv(dev); + + _e1000_disable(hw); +} + +static int e1000_eth_send(struct udevice *dev, void *packet, int length) +{ + struct e1000_hw *hw = dev_get_priv(dev); + int ret; + + ret = _e1000_transmit(hw, packet, length); + + return ret ? 0 : -ETIMEDOUT; +} + +static int e1000_eth_recv(struct udevice *dev, int flags, uchar **packetp) +{ + struct e1000_hw *hw = dev_get_priv(dev); + int len; + + len = _e1000_poll(hw); + if (len) + *packetp = packet; + + return len ? len : -EAGAIN; +} + +static int e1000_free_pkt(struct udevice *dev, uchar *packet, int length) +{ + struct e1000_hw *hw = dev_get_priv(dev); + + fill_rx(hw); + + return 0; +} + +static int e1000_eth_probe(struct udevice *dev) +{ + struct eth_pdata *plat = dev_get_platdata(dev); + struct e1000_hw *hw = dev_get_priv(dev); + int ret; + + hw->name = dev->name; + ret = e1000_init_one(hw, trailing_strtol(dev->name), + dev, plat->enetaddr); + if (ret < 0) { + printf(pr_fmt("failed to initialize card: %d\n"), ret); + return ret; + } + + return 0; +} + +static int e1000_eth_bind(struct udevice *dev) +{ + char name[20]; + + /* + * A simple way to number the devices. When device tree is used this + * is unnecessary, but when the device is just discovered on the PCI + * bus we need a name. We could instead have the uclass figure out + * which devices are different and number them. + */ + e1000_name(name, num_cards++); + + return device_set_name(dev, name); +} + +static const struct eth_ops e1000_eth_ops = { + .start = e1000_eth_start, + .send = e1000_eth_send, + .recv = e1000_eth_recv, + .stop = e1000_eth_stop, + .free_pkt = e1000_free_pkt, +}; + +static const struct udevice_id e1000_eth_ids[] = { + { .compatible = "intel,e1000" }, + { } +}; + +U_BOOT_DRIVER(eth_e1000) = { + .name = "eth_e1000", + .id = UCLASS_ETH, + .of_match = e1000_eth_ids, + .bind = e1000_eth_bind, + .probe = e1000_eth_probe, + .ops = &e1000_eth_ops, + .priv_auto_alloc_size = sizeof(struct e1000_hw), + .platdata_auto_alloc_size = sizeof(struct eth_pdata), +}; + +U_BOOT_PCI_DEVICE(eth_e1000, e1000_supported); +#endif