X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fe1000.c;h=e726f398d4f2e87ea560374fa5252fd73a1530be;hb=a939ea3ab459d5fb3d1eaaec289c6ca85f2f74c1;hp=2825342ff5290980ba9dc4ce554c8d6c25b7a950;hpb=6ca9da4d42aeb43df5ef29f7d0518009df583b2f;p=oweals%2Fu-boot.git diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c index 2825342ff5..e726f398d4 100644 --- a/drivers/net/e1000.c +++ b/drivers/net/e1000.c @@ -40,6 +40,8 @@ tested on both gig copper and gig fiber boards * Copyright (C) Linux Networx. * Massive upgrade to work with the new intel gigabit NICs. * + * + * Copyright 2011 Freescale Semiconductor, Inc. */ #include "e1000.h" @@ -48,7 +50,6 @@ tested on both gig copper and gig fiber boards #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) -#define mdelay(n) udelay((n)*1000) #define E1000_DEFAULT_PCI_PBA 0x00000030 #define E1000_DEFAULT_PCIE_PBA 0x000a0026 @@ -65,7 +66,7 @@ static struct e1000_rx_desc *rx_base; static int tx_tail; static int rx_tail, rx_last; -static struct pci_device_id supported[] = { +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}, @@ -100,6 +101,7 @@ static struct pci_device_id supported[] = { {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}, @@ -132,13 +134,6 @@ 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 int32_t e1000_check_phy_reset_block(struct e1000_hw *hw); -#define E1000_WRITE_REG(a, reg, value) (writel((value), ((a)->hw_addr + E1000_##reg))) -#define E1000_READ_REG(a, reg) (readl((a)->hw_addr + E1000_##reg)) -#define E1000_WRITE_REG_ARRAY(a, reg, offset, value) (\ - writel((value), ((a)->hw_addr + E1000_##reg + ((offset) << 2)))) -#define E1000_READ_REG_ARRAY(a, reg, offset) ( \ - readl((a)->hw_addr + E1000_##reg + ((offset) << 2))) -#define E1000_WRITE_FLUSH(a) {uint32_t x; x = E1000_READ_REG(a, STATUS);} #ifndef CONFIG_AP1000 /* remove for warnings */ static int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset, @@ -150,8 +145,7 @@ static int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset, * hw - Struct containing variables accessed by shared code * eecd - EECD's current value *****************************************************************************/ -static void -e1000_raise_ee_clk(struct e1000_hw *hw, uint32_t * eecd) +void e1000_raise_ee_clk(struct e1000_hw *hw, uint32_t * eecd) { /* Raise the clock input to the EEPROM (by setting the SK bit), and then * wait 50 microseconds. @@ -168,8 +162,7 @@ e1000_raise_ee_clk(struct e1000_hw *hw, uint32_t * eecd) * hw - Struct containing variables accessed by shared code * eecd - EECD's current value *****************************************************************************/ -static void -e1000_lower_ee_clk(struct e1000_hw *hw, uint32_t * eecd) +void e1000_lower_ee_clk(struct e1000_hw *hw, uint32_t * eecd) { /* Lower the clock input to the EEPROM (by clearing the SK bit), and then * wait 50 microseconds. @@ -273,8 +266,7 @@ e1000_shift_in_ee_bits(struct e1000_hw *hw, uint16_t count) * * hw - Struct containing variables accessed by shared code *****************************************************************************/ -static void -e1000_standby_eeprom(struct e1000_hw *hw) +void e1000_standby_eeprom(struct e1000_hw *hw) { struct e1000_eeprom_info *eeprom = &hw->eeprom; uint32_t eecd; @@ -331,7 +323,7 @@ static boolean_t e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw) if (hw->mac_type == e1000_ich8lan) return FALSE; - if (hw->mac_type == e1000_82573) { + if (hw->mac_type == e1000_82573 || hw->mac_type == e1000_82574) { eecd = E1000_READ_REG(hw, EECD); /* Isolate bits 15 & 16 */ @@ -352,8 +344,7 @@ static boolean_t e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw) * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This * function should be called before issuing a command to the EEPROM. *****************************************************************************/ -static int32_t -e1000_acquire_eeprom(struct e1000_hw *hw) +int32_t e1000_acquire_eeprom(struct e1000_hw *hw) { struct e1000_eeprom_info *eeprom = &hw->eeprom; uint32_t eecd, i = 0; @@ -364,7 +355,7 @@ e1000_acquire_eeprom(struct e1000_hw *hw) return -E1000_ERR_SWFW_SYNC; eecd = E1000_READ_REG(hw, EECD); - if (hw->mac_type != e1000_82573) { + if (hw->mac_type != e1000_82573 || hw->mac_type != e1000_82574) { /* Request EEPROM Access */ if (hw->mac_type > e1000_82544) { eecd |= E1000_EECD_REQ; @@ -498,6 +489,7 @@ static int32_t e1000_init_eeprom_params(struct e1000_hw *hw) eeprom->use_eewr = FALSE; break; case e1000_82573: + case e1000_82574: eeprom->type = e1000_eeprom_spi; eeprom->opcode_bits = 8; eeprom->delay_usec = 1; @@ -668,8 +660,7 @@ e1000_read_eeprom_eerd(struct e1000_hw *hw, return error; } -static void -e1000_release_eeprom(struct e1000_hw *hw) +void e1000_release_eeprom(struct e1000_hw *hw) { uint32_t eecd; @@ -873,29 +864,42 @@ e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset, * If the the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is * valid. *****************************************************************************/ -static int -e1000_validate_eeprom_checksum(struct eth_device *nic) +static int e1000_validate_eeprom_checksum(struct e1000_hw *hw) { - struct e1000_hw *hw = nic->priv; - uint16_t checksum = 0; - uint16_t i, eeprom_data; + uint16_t i, checksum, checksum_reg, *buf; DEBUGFUNC(); - for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) { - if (e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) { - DEBUGOUT("EEPROM Read Error\n"); - return -E1000_ERR_EEPROM; - } - checksum += eeprom_data; + /* 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"); + return -E1000_ERR_EEPROM; } - if (checksum == (uint16_t) EEPROM_SUM) { - return 0; - } else { - DEBUGOUT("EEPROM Checksum Invalid\n"); + /* Read the EEPROM */ + if (e1000_read_eeprom(hw, 0, EEPROM_CHECKSUM_REG + 1, buf) < 0) { + E1000_ERR(hw->nic, "Unable to read EEPROM!\n"); return -E1000_ERR_EEPROM; } + + /* Compute the checksum */ + checksum = 0; + for (i = 0; i < EEPROM_CHECKSUM_REG; i++) + checksum += buf[i]; + checksum = ((uint16_t)EEPROM_SUM) - checksum; + checksum_reg = buf[i]; + + /* Verify it! */ + if (checksum == checksum_reg) + 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); + + return -E1000_ERR_EEPROM; } /***************************************************************************** @@ -1096,6 +1100,20 @@ e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask) return E1000_SUCCESS; } +static boolean_t e1000_is_second_port(struct e1000_hw *hw) +{ + switch (hw->mac_type) { + case e1000_80003es2lan: + case e1000_82546: + case e1000_82571: + if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1) + return TRUE; + /* Fallthrough */ + default: + return FALSE; + } +} + /****************************************************************************** * Reads the adapter's MAC address from the EEPROM and inverts the LSB for the * second function of dual function devices @@ -1122,13 +1140,13 @@ e1000_read_mac_addr(struct eth_device *nic) nic->enetaddr[i] = eeprom_data & 0xff; nic->enetaddr[i + 1] = (eeprom_data >> 8) & 0xff; } - if ((hw->mac_type == e1000_82546) && - (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) { - /* Invert the last bit if this is the second device */ - nic->enetaddr[5] += 1; - } + + /* Invert the last bit if this is the second device */ + if (e1000_is_second_port(hw)) + nic->enetaddr[5] ^= 1; + #ifdef CONFIG_E1000_FALLBACK_MAC - if ( *(u32*)(nic->enetaddr) == 0 || *(u32*)(nic->enetaddr) == ~0 ) { + if (!is_valid_ether_addr(nic->enetaddr)) { unsigned char fb_mac[NODE_ADDRESS_SIZE] = CONFIG_E1000_FALLBACK_MAC; memcpy (nic->enetaddr, fb_mac, NODE_ADDRESS_SIZE); @@ -1317,6 +1335,9 @@ e1000_set_mac_type(struct e1000_hw *hw) case E1000_DEV_ID_82573L: hw->mac_type = e1000_82573; break; + case E1000_DEV_ID_82574L: + hw->mac_type = e1000_82574; + break; case E1000_DEV_ID_80003ES2LAN_COPPER_SPT: case E1000_DEV_ID_80003ES2LAN_SERDES_SPT: case E1000_DEV_ID_80003ES2LAN_COPPER_DPT: @@ -1349,7 +1370,6 @@ e1000_reset_hw(struct e1000_hw *hw) { uint32_t ctrl; uint32_t ctrl_ext; - uint32_t icr; uint32_t manc; uint32_t pba = 0; @@ -1422,7 +1442,7 @@ e1000_reset_hw(struct e1000_hw *hw) E1000_WRITE_REG(hw, IMC, 0xffffffff); /* Clear any pending interrupt events. */ - icr = E1000_READ_REG(hw, ICR); + E1000_READ_REG(hw, ICR); /* If MWI was previously enabled, reenable it. */ if (hw->mac_type == e1000_82542_rev2_0) { @@ -1487,6 +1507,7 @@ e1000_initialize_hardware_bits(struct e1000_hw *hw) E1000_WRITE_REG(hw, TARC1, reg_tarc1); break; case e1000_82573: + case e1000_82574: reg_ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); reg_ctrl_ext &= ~(1 << 23); reg_ctrl_ext |= (1 << 22); @@ -1728,12 +1749,11 @@ e1000_init_hw(struct eth_device *nic) | E1000_TXDCTL_FULL_TX_DESC_WB; E1000_WRITE_REG(hw, TXDCTL1, ctrl); break; - } - - if (hw->mac_type == e1000_82573) { - uint32_t gcr = E1000_READ_REG(hw, GCR); - gcr |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX; - E1000_WRITE_REG(hw, GCR, gcr); + case e1000_82573: + case e1000_82574: + reg_data = E1000_READ_REG(hw, GCR); + reg_data |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX; + E1000_WRITE_REG(hw, GCR, reg_data); } #if 0 @@ -1812,6 +1832,7 @@ e1000_setup_link(struct eth_device *nic) switch (hw->mac_type) { case e1000_ich8lan: case e1000_82573: + case e1000_82574: hw->fc = e1000_fc_full; break; default: @@ -2528,16 +2549,13 @@ e1000_check_mng_mode(struct e1000_hw *hw) static int32_t e1000_write_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t data) { + uint16_t swfw = E1000_SWFW_PHY0_SM; uint32_t reg_val; - uint16_t swfw; DEBUGFUNC(); - if ((hw->mac_type == e1000_80003es2lan) && - (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) { + if (e1000_is_second_port(hw)) swfw = E1000_SWFW_PHY1_SM; - } else { - swfw = E1000_SWFW_PHY0_SM; - } + if (e1000_swfw_sync_acquire(hw, swfw)) return -E1000_ERR_SWFW_SYNC; @@ -2552,16 +2570,13 @@ e1000_write_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t data) static int32_t e1000_read_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *data) { + uint16_t swfw = E1000_SWFW_PHY0_SM; uint32_t reg_val; - uint16_t swfw; DEBUGFUNC(); - if ((hw->mac_type == e1000_80003es2lan) && - (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) { + if (e1000_is_second_port(hw)) swfw = E1000_SWFW_PHY1_SM; - } else { - swfw = E1000_SWFW_PHY0_SM; - } + if (e1000_swfw_sync_acquire(hw, swfw)) return -E1000_ERR_SWFW_SYNC; @@ -4259,11 +4274,13 @@ e1000_get_phy_cfg_done(struct e1000_hw *hw) default: mdelay(10); break; + case e1000_80003es2lan: /* Separate *_CFG_DONE_* bit for each port */ - if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1) + if (e1000_is_second_port(hw)) cfg_mask = E1000_EEPROM_CFG_DONE_PORT_1; - /* Fall Through */ + /* Fall Through */ + case e1000_82571: case e1000_82572: while (timeout) { @@ -4292,10 +4309,10 @@ e1000_get_phy_cfg_done(struct e1000_hw *hw) int32_t e1000_phy_hw_reset(struct e1000_hw *hw) { + uint16_t swfw = E1000_SWFW_PHY0_SM; uint32_t ctrl, ctrl_ext; uint32_t led_ctrl; int32_t ret_val; - uint16_t swfw; DEBUGFUNC(); @@ -4308,16 +4325,14 @@ e1000_phy_hw_reset(struct e1000_hw *hw) DEBUGOUT("Resetting Phy...\n"); if (hw->mac_type > e1000_82543) { - if ((hw->mac_type == e1000_80003es2lan) && - (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) { + if (e1000_is_second_port(hw)) swfw = E1000_SWFW_PHY1_SM; - } else { - swfw = E1000_SWFW_PHY0_SM; - } + if (e1000_swfw_sync_acquire(hw, swfw)) { DEBUGOUT("Unable to acquire swfw sync\n"); return -E1000_ERR_SWFW_SYNC; } + /* Read the device control register and assert the E1000_CTRL_PHY_RST * bit. Then, take it out of reset. */ @@ -4431,7 +4446,8 @@ e1000_phy_init_script(struct e1000_hw *hw) mdelay(20); /* Now enable the transmitter */ - e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data); + if (!ret_val) + e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data); if (hw->mac_type == e1000_82547) { uint16_t fused, fine, coarse; @@ -4560,6 +4576,9 @@ static int e1000_set_phy_type (struct e1000_hw *hw) hw->phy_type = e1000_phy_gg82563; break; } + case BME1000_E_PHY_ID: + hw->phy_type = e1000_phy_bm; + break; /* Fall Through */ default: /* Should never have loaded on this device */ @@ -4646,6 +4665,10 @@ e1000_detect_gig_phy(struct e1000_hw *hw) if (hw->phy_id == M88E1111_I_PHY_ID) match = TRUE; break; + case e1000_82574: + if (hw->phy_id == BME1000_E_PHY_ID) + match = TRUE; + break; case e1000_80003es2lan: if (hw->phy_id == GG82563_E_PHY_ID) match = TRUE; @@ -4710,6 +4733,7 @@ e1000_set_media_type(struct e1000_hw *hw) break; case e1000_ich8lan: case e1000_82573: + case e1000_82574: /* The STATUS_TBIMODE bit is reserved or reused * for the this device. */ @@ -4738,7 +4762,7 @@ e1000_set_media_type(struct e1000_hw *hw) **/ static int -e1000_sw_init(struct eth_device *nic, int cardnum) +e1000_sw_init(struct eth_device *nic) { struct e1000_hw *hw = (typeof(hw)) nic->priv; int result; @@ -4756,7 +4780,7 @@ e1000_sw_init(struct eth_device *nic, int cardnum) /* identify the MAC */ result = e1000_set_mac_type(hw); if (result) { - E1000_ERR("Unknown MAC Type\n"); + E1000_ERR(hw->nic, "Unknown MAC Type\n"); return result; } @@ -4771,14 +4795,6 @@ e1000_sw_init(struct eth_device *nic, int cardnum) break; } - /* lan a vs. lan b settings */ - if (hw->mac_type == e1000_82546) - /*this also works w/ multiple 82546 cards */ - /*but not if they're intermingled /w other e1000s */ - hw->lan_loc = (cardnum % 2) ? e1000_lan_b : e1000_lan_a; - else - hw->lan_loc = e1000_lan_a; - /* flow control settings */ hw->fc_high_water = E1000_FC_HIGH_THRESH; hw->fc_low_water = E1000_FC_LOW_THRESH; @@ -5018,6 +5034,7 @@ TRANSMIT - Transmit a frame static int e1000_transmit(struct eth_device *nic, volatile void *packet, int length) { + void * nv_packet = (void *)packet; struct e1000_hw *hw = nic->priv; struct e1000_tx_desc *txp; int i = 0; @@ -5025,7 +5042,7 @@ e1000_transmit(struct eth_device *nic, volatile void *packet, int length) txp = tx_base + tx_tail; tx_tail = (tx_tail + 1) % 8; - txp->buffer_addr = cpu_to_le64(virt_to_bus(hw->pdev, packet)); + txp->buffer_addr = cpu_to_le64(virt_to_bus(hw->pdev, nv_packet)); txp->lower.data = cpu_to_le32(hw->txd_cmd | length); txp->upper.data = 0; E1000_WRITE_REG(hw, TDT, tx_tail); @@ -5095,9 +5112,9 @@ e1000_init(struct eth_device *nic, bd_t * bis) if (ret_val < 0) { if ((ret_val == -E1000_ERR_NOLINK) || (ret_val == -E1000_ERR_TIMEOUT)) { - E1000_ERR("Valid Link not detected\n"); + E1000_ERR(hw->nic, "Valid Link not detected\n"); } else { - E1000_ERR("Hardware Initialization Failed\n"); + E1000_ERR(hw->nic, "Hardware Initialization Failed\n"); } return 0; } @@ -5124,6 +5141,7 @@ void e1000_get_bus_type(struct e1000_hw *hw) case e1000_82571: case e1000_82572: case e1000_82573: + case e1000_82574: case e1000_80003es2lan: hw->bus_type = e1000_bus_type_pci_express; break; @@ -5138,6 +5156,9 @@ void e1000_get_bus_type(struct e1000_hw *hw) } } +/* A list of all registered e1000 devices */ +static LIST_HEAD(e1000_hw_list); + /************************************************************************** PROBE - Look for an adapter, this routine's visible to the outside You should omit the last argument struct pci_device * for a non-PCI NIC @@ -5145,43 +5166,59 @@ You should omit the last argument struct pci_device * for a non-PCI NIC int e1000_initialize(bd_t * bis) { + unsigned int i; pci_dev_t devno; - int card_number = 0; - struct eth_device *nic = NULL; - struct e1000_hw *hw = NULL; - u32 iobase; - int idx = 0; - u32 PciCommandWord; DEBUGFUNC(); - while (1) { /* Find PCI device(s) */ - if ((devno = pci_find_devices(supported, idx++)) < 0) { - break; - } - - pci_read_config_dword(devno, PCI_BASE_ADDRESS_0, &iobase); - iobase &= ~0xf; /* Mask the bits that say "this is an io addr" */ - DEBUGOUT("e1000#%d: iobase 0x%08x\n", card_number, iobase); + /* Find and probe all the matching PCI devices */ + for (i = 0; (devno = pci_find_devices(e1000_supported, i)) >= 0; i++) { + u32 val; - pci_write_config_dword(devno, PCI_COMMAND, - PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); - /* Check if I/O accesses and Bus Mastering are enabled. */ - pci_read_config_dword(devno, PCI_COMMAND, &PciCommandWord); - if (!(PciCommandWord & PCI_COMMAND_MEMORY)) { - printf("Error: Can not enable MEM access.\n"); - continue; - } else if (!(PciCommandWord & PCI_COMMAND_MASTER)) { - printf("Error: Can not enable Bus Mastering.\n"); + /* + * These will never get freed due to errors, this allows us to + * perform SPI EEPROM programming from U-boot, for example. + */ + struct eth_device *nic = malloc(sizeof(*nic)); + struct e1000_hw *hw = malloc(sizeof(*hw)); + if (!nic || !hw) { + printf("e1000#%u: Out of Memory!\n", i); + free(nic); + free(hw); continue; } - nic = (struct eth_device *) malloc(sizeof (*nic)); - hw = (struct e1000_hw *) malloc(sizeof (*hw)); + /* 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; - sprintf(nic->name, "e1000#%d", card_number); + /* 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; + } /* Are these variables needed? */ hw->fc = e1000_fc_default; @@ -5189,50 +5226,105 @@ e1000_initialize(bd_t * bis) hw->autoneg_failed = 0; hw->autoneg = 1; hw->get_link_status = TRUE; - hw->hw_addr = - pci_map_bar(devno, PCI_BASE_ADDRESS_0, PCI_REGION_MEM); + 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, card_number) < 0) { - free(hw); - free(nic); - return 0; + if (e1000_sw_init(nic) < 0) { + E1000_ERR(nic, "Software init failed\n"); + continue; } if (e1000_check_phy_reset_block(hw)) - printf("phy reset block error \n"); + 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); + + /* Validate the EEPROM and get chipset information */ #if !(defined(CONFIG_AP1000) || defined(CONFIG_MVBC_1G)) if (e1000_init_eeprom_params(hw)) { - printf("The EEPROM Checksum Is Not Valid\n"); - free(hw); - free(nic); - return 0; - } - if (e1000_validate_eeprom_checksum(nic) < 0) { - printf("The EEPROM Checksum Is Not Valid\n"); - free(hw); - free(nic); - return 0; + E1000_ERR(nic, "EEPROM is invalid!\n"); + continue; } + if (e1000_validate_eeprom_checksum(hw)) + continue; #endif e1000_read_mac_addr(nic); - - /* get the bus type information */ e1000_get_bus_type(hw); - printf("e1000: %02x:%02x:%02x:%02x:%02x:%02x\n", + 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]); + /* Set up the function pointers and register the device */ nic->init = e1000_init; nic->recv = e1000_poll; nic->send = e1000_transmit; nic->halt = e1000_disable; - eth_register(nic); + } + + return i; +} + +struct e1000_hw *e1000_find_card(unsigned int cardnum) +{ + struct e1000_hw *hw; + + list_for_each_entry(hw, &e1000_hw_list, list_node) + if (hw->cardnum == cardnum) + return hw; + + return NULL; +} + +#ifdef CONFIG_CMD_E1000 +static int do_e1000(cmd_tbl_t *cmdtp, int flag, + int argc, char * const argv[]) +{ + struct e1000_hw *hw; + + if (argc < 3) { + cmd_usage(cmdtp); + return 1; + } + + /* Make sure we can find the requested e1000 card */ + hw = e1000_find_card(simple_strtoul(argv[1], NULL, 10)); + if (!hw) { + printf("e1000: ERROR: No such device: e1000#%s\n", argv[1]); + return 1; + } - card_number++; + 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; } - return card_number; + +#ifdef CONFIG_E1000_SPI + /* Handle the "SPI" subcommand */ + if (!strcmp(argv[2], "spi")) + return do_e1000_spi(cmdtp, hw, argc - 3, argv + 3); +#endif + + cmd_usage(cmdtp); + return 1; } + +U_BOOT_CMD( + e1000, 7, 0, do_e1000, + "Intel e1000 controller management", + /* */" print-mac-address\n" +#ifdef CONFIG_E1000_SPI + "e1000 spi show [ []]\n" + "e1000 spi dump \n" + "e1000 spi program \n" + "e1000 spi checksum [update]\n" +#endif + " - Manage the Intel E1000 PCI device" +); +#endif /* not CONFIG_CMD_E1000 */