X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fnet%2Fe1000.c;h=cd4422215fb0fbbd43c4aefb09e0f0652df01867;hb=1606b34aa50804227806971dbb6b82ea0bf81f55;hp=57aa53dbae77b06230c160dd7e56f37a4cd21d39;hpb=1a4596601fd395f3afb8f82f3f840c5e00bdd57a;p=u-boot diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c index 57aa53dbae..cd4422215f 100644 --- a/drivers/net/e1000.c +++ b/drivers/net/e1000.c @@ -41,12 +41,12 @@ tested on both gig copper and gig fiber boards /* NIC specific static variables go here */ -static char tx_pool[128 + 16]; -static char rx_pool[128 + 16]; -static char packet[2096]; +/* Intel i210 needs the DMA descriptor rings aligned to 128b */ +#define E1000_BUFFER_ALIGN 128 -static struct e1000_tx_desc *tx_base; -static struct e1000_rx_desc *rx_base; +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; @@ -92,6 +92,15 @@ static struct pci_device_id e1000_supported[] = { {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}, + {} }; @@ -114,12 +123,13 @@ static int e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, static int32_t e1000_phy_hw_reset(struct e1000_hw *hw); static int e1000_phy_reset(struct e1000_hw *hw); static int e1000_detect_gig_phy(struct e1000_hw *hw); -static void e1000_put_hw_eeprom_semaphore(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 int32_t e1000_check_phy_reset_block(struct e1000_hw *hw); +#ifndef CONFIG_E1000_NO_NVM +static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw); static int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data); @@ -339,7 +349,7 @@ int32_t e1000_acquire_eeprom(struct e1000_hw *hw) return -E1000_ERR_SWFW_SYNC; eecd = E1000_READ_REG(hw, EECD); - if (hw->mac_type != e1000_82573 || hw->mac_type != e1000_82574) { + if (hw->mac_type != e1000_82573 && hw->mac_type != e1000_82574) { /* Request EEPROM Access */ if (hw->mac_type > e1000_82544) { eecd |= E1000_EECD_REQ; @@ -390,10 +400,15 @@ int32_t e1000_acquire_eeprom(struct e1000_hw *hw) static int32_t e1000_init_eeprom_params(struct e1000_hw *hw) { struct e1000_eeprom_info *eeprom = &hw->eeprom; - uint32_t eecd = E1000_READ_REG(hw, EECD); + uint32_t eecd; int32_t ret_val = E1000_SUCCESS; uint16_t eeprom_size; + if (hw->mac_type == e1000_igb) + eecd = E1000_READ_REG(hw, I210_EECD); + else + eecd = E1000_READ_REG(hw, EECD); + DEBUGFUNC(); switch (hw->mac_type) { @@ -484,9 +499,10 @@ static int32_t e1000_init_eeprom_params(struct e1000_hw *hw) eeprom->page_size = 8; eeprom->address_bits = 8; } - eeprom->use_eerd = true; - eeprom->use_eewr = true; if (e1000_is_onboard_nvm_eeprom(hw) == false) { + eeprom->use_eerd = true; + eeprom->use_eewr = true; + eeprom->type = e1000_eeprom_flash; eeprom->word_size = 2048; @@ -510,6 +526,16 @@ static int32_t e1000_init_eeprom_params(struct e1000_hw *hw) eeprom->use_eerd = true; eeprom->use_eewr = false; break; + case e1000_igb: + /* i210 has 4k of iNVM mapped as EEPROM */ + eeprom->type = e1000_eeprom_invm; + eeprom->opcode_bits = 8; + eeprom->delay_usec = 1; + eeprom->page_size = 32; + eeprom->address_bits = 16; + eeprom->use_eerd = true; + eeprom->use_eewr = false; + break; /* ich8lan does not support currently. if needed, please * add corresponding code and functions. @@ -551,7 +577,8 @@ static int32_t e1000_init_eeprom_params(struct e1000_hw *hw) break; } - if (eeprom->type == e1000_eeprom_spi) { + if (eeprom->type == e1000_eeprom_spi || + eeprom->type == e1000_eeprom_invm) { /* eeprom_size will be an enum [0..8] that maps * to eeprom sizes 128B to * 32KB (incremented by powers of 2). @@ -595,10 +622,17 @@ e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd) int32_t done = E1000_ERR_EEPROM; for (i = 0; i < attempts; i++) { - if (eerd == E1000_EEPROM_POLL_READ) - reg = E1000_READ_REG(hw, EERD); - else - reg = E1000_READ_REG(hw, EEWR); + if (eerd == E1000_EEPROM_POLL_READ) { + if (hw->mac_type == e1000_igb) + reg = E1000_READ_REG(hw, I210_EERD); + else + reg = E1000_READ_REG(hw, EERD); + } else { + if (hw->mac_type == e1000_igb) + reg = E1000_READ_REG(hw, I210_EEWR); + else + reg = E1000_READ_REG(hw, EEWR); + } if (reg & E1000_EEPROM_RW_REG_DONE) { done = E1000_SUCCESS; @@ -631,13 +665,23 @@ e1000_read_eeprom_eerd(struct e1000_hw *hw, eerd = ((offset+i) << E1000_EEPROM_RW_ADDR_SHIFT) + E1000_EEPROM_RW_REG_START; - E1000_WRITE_REG(hw, EERD, eerd); + if (hw->mac_type == e1000_igb) + E1000_WRITE_REG(hw, I210_EERD, eerd); + else + E1000_WRITE_REG(hw, EERD, eerd); + error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_READ); if (error) break; - data[i] = (E1000_READ_REG(hw, EERD) >> + + if (hw->mac_type == e1000_igb) { + data[i] = (E1000_READ_REG(hw, I210_EERD) >> E1000_EEPROM_RW_REG_DATA); + } else { + data[i] = (E1000_READ_REG(hw, EERD) >> + E1000_EEPROM_RW_REG_DATA); + } } @@ -885,6 +929,7 @@ static int e1000_validate_eeprom_checksum(struct e1000_hw *hw) return -E1000_ERR_EEPROM; } +#endif /* CONFIG_E1000_NO_NVM */ /***************************************************************************** * Set PHY to class A mode @@ -897,6 +942,7 @@ static int e1000_validate_eeprom_checksum(struct e1000_hw *hw) static int32_t e1000_set_phy_mode(struct e1000_hw *hw) { +#ifndef CONFIG_E1000_NO_NVM int32_t ret_val; uint16_t eeprom_data; @@ -923,10 +969,11 @@ e1000_set_phy_mode(struct e1000_hw *hw) hw->phy_reset_disable = false; } } - +#endif return E1000_SUCCESS; } +#ifndef CONFIG_E1000_NO_NVM /*************************************************************************** * * Obtaining software semaphore bit (SMBI) before resetting PHY. @@ -945,6 +992,10 @@ 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; @@ -965,6 +1016,7 @@ e1000_get_software_semaphore(struct e1000_hw *hw) return E1000_SUCCESS; } +#endif /*************************************************************************** * This function clears HW semaphore bits. @@ -977,6 +1029,7 @@ e1000_get_software_semaphore(struct e1000_hw *hw) static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw) { +#ifndef CONFIG_E1000_NO_NVM uint32_t swsm; DEBUGFUNC(); @@ -991,6 +1044,7 @@ e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw) } else swsm &= ~(E1000_SWSM_SWESMBI); E1000_WRITE_REG(hw, SWSM, swsm); +#endif } /*************************************************************************** @@ -1007,6 +1061,7 @@ e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw) static int32_t e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw) { +#ifndef CONFIG_E1000_NO_NVM int32_t timeout; uint32_t swsm; @@ -1043,7 +1098,7 @@ e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw) "SWESMBI bit is set.\n"); return -E1000_ERR_EEPROM; } - +#endif return E1000_SUCCESS; } @@ -1060,7 +1115,10 @@ e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask) if (e1000_get_hw_eeprom_semaphore(hw)) return -E1000_ERR_SWFW_SYNC; - swfw_sync = E1000_READ_REG(hw, SW_FW_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); if (!(swfw_sync & (fwmask | swmask))) break; @@ -1097,6 +1155,7 @@ static bool e1000_is_second_port(struct e1000_hw *hw) } } +#ifndef CONFIG_E1000_NO_NVM /****************************************************************************** * Reads the adapter's MAC address from the EEPROM and inverts the LSB for the * second function of dual function devices @@ -1109,13 +1168,23 @@ e1000_read_mac_addr(struct eth_device *nic) struct e1000_hw *hw = nic->priv; uint16_t offset; uint16_t eeprom_data; + uint32_t reg_data = 0; int i; DEBUGFUNC(); for (i = 0; i < NODE_ADDRESS_SIZE; i += 2) { offset = i >> 1; - if (e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) { + if (hw->mac_type == e1000_igb) { + /* i210 preloads MAC address into RAL/RAH registers */ + if (offset == 0) + reg_data = E1000_READ_REG_ARRAY(hw, RA, 0); + else if (offset == 1) + reg_data >>= 16; + else if (offset == 2) + reg_data = E1000_READ_REG_ARRAY(hw, RA, 1); + eeprom_data = reg_data & 0xffff; + } else if (e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) { DEBUGOUT("EEPROM Read Error\n"); return -E1000_ERR_EEPROM; } @@ -1136,6 +1205,7 @@ e1000_read_mac_addr(struct eth_device *nic) #endif return 0; } +#endif /****************************************************************************** * Initializes receive address filters. @@ -1310,6 +1380,16 @@ e1000_set_mac_type(struct e1000_hw *hw) case E1000_DEV_ID_ICH8_IGP_M: hw->mac_type = e1000_ich8lan; break; + case PCI_DEVICE_ID_INTEL_I210_UNPROGRAMMED: + case PCI_DEVICE_ID_INTEL_I211_UNPROGRAMMED: + case PCI_DEVICE_ID_INTEL_I210_COPPER: + case PCI_DEVICE_ID_INTEL_I211_COPPER: + case PCI_DEVICE_ID_INTEL_I210_COPPER_FLASHLESS: + case PCI_DEVICE_ID_INTEL_I210_SERDES: + case PCI_DEVICE_ID_INTEL_I210_SERDES_FLASHLESS: + case PCI_DEVICE_ID_INTEL_I210_1000BASEKX: + hw->mac_type = e1000_igb; + break; default: /* Should never have loaded on this device */ return -E1000_ERR_MAC_TYPE; @@ -1329,6 +1409,7 @@ e1000_reset_hw(struct e1000_hw *hw) uint32_t ctrl_ext; uint32_t manc; uint32_t pba = 0; + uint32_t reg; DEBUGFUNC(); @@ -1347,6 +1428,8 @@ e1000_reset_hw(struct e1000_hw *hw) /* Clear interrupt mask to stop board from generating interrupts */ DEBUGOUT("Masking off all interrupts\n"); + if (hw->mac_type == e1000_igb) + E1000_WRITE_REG(hw, I210_IAM, 0); E1000_WRITE_REG(hw, IMC, 0xffffffff); /* Disable the Transmit and Receive units. Then delay to allow @@ -1376,7 +1459,15 @@ e1000_reset_hw(struct e1000_hw *hw) E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST)); /* Force a reload from the EEPROM if necessary */ - if (hw->mac_type < e1000_82540) { + if (hw->mac_type == e1000_igb) { + mdelay(20); + reg = E1000_READ_REG(hw, STATUS); + if (reg & E1000_STATUS_PF_RST_DONE) + DEBUGOUT("PF OK\n"); + reg = E1000_READ_REG(hw, I210_EECD); + if (reg & E1000_EECD_AUTO_RD) + DEBUGOUT("EEC OK\n"); + } else if (hw->mac_type < e1000_82540) { /* Wait for reset to complete */ udelay(10); ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); @@ -1396,6 +1487,8 @@ e1000_reset_hw(struct e1000_hw *hw) /* Clear interrupt mask to stop board from generating interrupts */ DEBUGOUT("Masking off all interrupts\n"); + if (hw->mac_type == e1000_igb) + E1000_WRITE_REG(hw, I210_IAM, 0); E1000_WRITE_REG(hw, IMC, 0xffffffff); /* Clear any pending interrupt events. */ @@ -1405,7 +1498,8 @@ e1000_reset_hw(struct e1000_hw *hw) if (hw->mac_type == e1000_82542_rev2_0) { pci_write_config_word(hw->pdev, PCI_COMMAND, hw->pci_cmd_word); } - E1000_WRITE_REG(hw, PBA, pba); + if (hw->mac_type != e1000_igb) + E1000_WRITE_REG(hw, PBA, pba); } /****************************************************************************** @@ -1441,6 +1535,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_82571: case e1000_82572: @@ -1631,6 +1729,7 @@ e1000_init_hw(struct eth_device *nic) switch (hw->mac_type) { case e1000_82545_rev_3: case e1000_82546_rev_3: + case e1000_igb: break; default: /* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */ @@ -1660,6 +1759,8 @@ e1000_init_hw(struct eth_device *nic) /* More time needed for PHY to initialize */ if (hw->mac_type == e1000_ich8lan) mdelay(15); + if (hw->mac_type == e1000_igb) + mdelay(15); /* Call a subroutine to configure the link and setup flow control. */ ret_val = e1000_setup_link(nic); @@ -1674,7 +1775,6 @@ e1000_init_hw(struct eth_device *nic) } /* Set the receive descriptor write back policy */ - if (hw->mac_type >= e1000_82571) { ctrl = E1000_READ_REG(hw, RXDCTL); ctrl = @@ -1721,6 +1821,8 @@ e1000_init_hw(struct eth_device *nic) reg_data = E1000_READ_REG(hw, GCR); reg_data |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX; E1000_WRITE_REG(hw, GCR, reg_data); + case e1000_igb: + break; } #if 0 @@ -1764,9 +1866,11 @@ static int e1000_setup_link(struct eth_device *nic) { struct e1000_hw *hw = nic->priv; - uint32_t ctrl_ext; int32_t ret_val; +#ifndef CONFIG_E1000_NO_NVM + uint32_t ctrl_ext; uint16_t eeprom_data; +#endif DEBUGFUNC(); @@ -1775,6 +1879,7 @@ e1000_setup_link(struct eth_device *nic) if (e1000_check_phy_reset_block(hw)) return E1000_SUCCESS; +#ifndef CONFIG_E1000_NO_NVM /* Read and store word 0x0F of the EEPROM. This word contains bits * that determine the hardware's default PAUSE (flow control) mode, * a bit that determines whether the HW defaults to enabling or @@ -1788,15 +1893,17 @@ e1000_setup_link(struct eth_device *nic) DEBUGOUT("EEPROM Read Error\n"); return -E1000_ERR_EEPROM; } - +#endif if (hw->fc == e1000_fc_default) { switch (hw->mac_type) { case e1000_ich8lan: case e1000_82573: case e1000_82574: + case e1000_igb: hw->fc = e1000_fc_full; break; default: +#ifndef CONFIG_E1000_NO_NVM ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data); if (ret_val) { @@ -1809,6 +1916,7 @@ e1000_setup_link(struct eth_device *nic) EEPROM_WORD0F_ASM_DIR) hw->fc = e1000_fc_tx_pause; else +#endif hw->fc = e1000_fc_full; break; } @@ -1828,6 +1936,7 @@ e1000_setup_link(struct eth_device *nic) DEBUGOUT("After fix-ups FlowControl is now = %x\n", hw->fc); +#ifndef CONFIG_E1000_NO_NVM /* Take the 4 bits from EEPROM word 0x0F that determine the initial * polarity value for the SW controlled pins, and setup the * Extended Device Control reg with that info. @@ -1840,6 +1949,7 @@ e1000_setup_link(struct eth_device *nic) SWDPIO__EXT_SHIFT); E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); } +#endif /* Call the necessary subroutine to configure the link. */ ret_val = (hw->media_type == e1000_media_type_fiber) ? @@ -2250,6 +2360,8 @@ e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active) if (hw->mac_type == e1000_ich8lan) { phy_ctrl = E1000_READ_REG(hw, PHY_CTRL); + } else if (hw->mac_type == e1000_igb) { + phy_ctrl = E1000_READ_REG(hw, I210_PHY_CTRL); } else { ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data); @@ -2261,6 +2373,9 @@ e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active) if (hw->mac_type == e1000_ich8lan) { phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU; E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl); + } else if (hw->mac_type == e1000_igb) { + phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU; + E1000_WRITE_REG(hw, I210_PHY_CTRL, phy_ctrl); } else { phy_data &= ~IGP02E1000_PM_D0_LPLU; ret_val = e1000_write_phy_reg(hw, @@ -2269,6 +2384,9 @@ e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active) return ret_val; } + if (hw->mac_type == e1000_igb) + return E1000_SUCCESS; + /* LPLU and SmartSpeed are mutually exclusive. LPLU is used during * Dx states where the power conservation is most important. During * driver activity we should enable SmartSpeed, so performance is @@ -2303,6 +2421,9 @@ e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active) if (hw->mac_type == e1000_ich8lan) { phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU; E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl); + } else if (hw->mac_type == e1000_igb) { + phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU; + E1000_WRITE_REG(hw, I210_PHY_CTRL, phy_ctrl); } else { phy_data |= IGP02E1000_PM_D0_LPLU; ret_val = e1000_write_phy_reg(hw, @@ -2311,6 +2432,9 @@ e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active) return ret_val; } + if (hw->mac_type == e1000_igb) + return E1000_SUCCESS; + /* When LPLU is enabled we should disable SmartSpeed */ ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data); @@ -2532,8 +2656,10 @@ e1000_read_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *data) if (e1000_is_second_port(hw)) swfw = E1000_SWFW_PHY1_SM; - if (e1000_swfw_sync_acquire(hw, swfw)) + if (e1000_swfw_sync_acquire(hw, swfw)) { + debug("%s[%i]\n", __func__, __LINE__); return -E1000_ERR_SWFW_SYNC; + } /* Write register address */ reg_val = ((reg_addr << E1000_KUMCTRLSTA_OFFSET_SHIFT) & @@ -2968,7 +3094,8 @@ e1000_setup_copper_link(struct eth_device *nic) ret_val = e1000_copper_link_igp_setup(hw); if (ret_val) return ret_val; - } else if (hw->phy_type == e1000_phy_m88) { + } else if (hw->phy_type == e1000_phy_m88 || + hw->phy_type == e1000_phy_igb) { ret_val = e1000_copper_link_mgp_setup(hw); if (ret_val) return ret_val; @@ -3212,7 +3339,8 @@ e1000_config_mac_to_phy(struct e1000_hw *hw) */ ctrl = E1000_READ_REG(hw, CTRL); ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); - ctrl &= ~(E1000_CTRL_SPD_SEL | E1000_CTRL_ILOS); + ctrl &= ~(E1000_CTRL_ILOS); + ctrl |= (E1000_CTRL_SPD_SEL); /* Set up duplex in the Device Control and Transmit Control * registers depending on negotiated values. @@ -4238,11 +4366,16 @@ e1000_get_phy_cfg_done(struct e1000_hw *hw) case e1000_82571: case e1000_82572: + case e1000_igb: while (timeout) { - if (E1000_READ_REG(hw, EEMNGCTL) & cfg_mask) - break; - else - mdelay(1); + if (hw->mac_type == e1000_igb) { + if (E1000_READ_REG(hw, I210_EEMNGCTL) & cfg_mask) + break; + } else { + if (E1000_READ_REG(hw, EEMNGCTL) & cfg_mask) + break; + } + mdelay(1); timeout--; } if (!timeout) { @@ -4305,7 +4438,6 @@ 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. @@ -4471,6 +4603,7 @@ e1000_phy_reset(struct e1000_hw *hw) case e1000_phy_igp_2: case e1000_phy_igp_3: case e1000_phy_ife: + case e1000_phy_igb: ret_val = e1000_phy_hw_reset(hw); if (ret_val) return ret_val; @@ -4515,7 +4648,6 @@ static int e1000_set_phy_type (struct e1000_hw *hw) hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2) { hw->phy_type = e1000_phy_igp; - hw->phy_type = e1000_phy_igp; break; } case IGP03E1000_E_PHY_ID: @@ -4534,6 +4666,9 @@ static int e1000_set_phy_type (struct e1000_hw *hw) case BME1000_E_PHY_ID: hw->phy_type = e1000_phy_bm; break; + case I210_I_PHY_ID: + hw->phy_type = e1000_phy_igb; + break; /* Fall Through */ default: /* Should never have loaded on this device */ @@ -4638,6 +4773,10 @@ e1000_detect_gig_phy(struct e1000_hw *hw) if (hw->phy_id == IFE_C_E_PHY_ID) match = true; break; + case e1000_igb: + if (hw->phy_id == I210_I_PHY_ID) + match = true; + break; default: DEBUGOUT("Invalid MAC type %d\n", hw->mac_type); return -E1000_ERR_CONFIG; @@ -4689,6 +4828,7 @@ e1000_set_media_type(struct e1000_hw *hw) case e1000_ich8lan: case e1000_82573: case e1000_82574: + case e1000_igb: /* The STATUS_TBIMODE bit is reserved or reused * for the this device. */ @@ -4757,6 +4897,7 @@ e1000_sw_init(struct eth_device *nic) hw->fc_send_xon = 1; /* Media type - copper or fiber */ + hw->tbi_compatibility_en = true; e1000_set_media_type(hw); if (hw->mac_type >= e1000_82543) { @@ -4773,7 +4914,6 @@ e1000_sw_init(struct eth_device *nic) hw->media_type = e1000_media_type_fiber; } - hw->tbi_compatibility_en = true; hw->wait_autoneg_complete = true; if (hw->mac_type < e1000_82543) hw->report_tx_early = 0; @@ -4787,12 +4927,26 @@ void fill_rx(struct e1000_hw *hw) { struct e1000_rx_desc *rd; + unsigned long flush_start, flush_end; rx_last = rx_tail; rd = rx_base + rx_tail; rx_tail = (rx_tail + 1) % 8; memset(rd, 0, 16); - rd->buffer_addr = cpu_to_le64((u32) & packet); + rd->buffer_addr = cpu_to_le64((unsigned long)packet); + + /* + * Make sure there are no stale data in WB over this area, which + * might get written into the memory while the e1000 also writes + * into the same memory area. + */ + invalidate_dcache_range((unsigned long)packet, + (unsigned long)packet + 4096); + /* Dump the DMA descriptor into RAM. */ + flush_start = ((unsigned long)rd) & ~(ARCH_DMA_MINALIGN - 1); + flush_end = flush_start + roundup(sizeof(*rd), ARCH_DMA_MINALIGN); + flush_dcache_range(flush_start, flush_end); + E1000_WRITE_REG(hw, RDT, rx_tail); } @@ -4806,18 +4960,11 @@ fill_rx(struct e1000_hw *hw) static void e1000_configure_tx(struct e1000_hw *hw) { - unsigned long ptr; unsigned long tctl; unsigned long tipg, tarc; uint32_t ipgr1, ipgr2; - ptr = (u32) tx_pool; - if (ptr & 0xf) - ptr = (ptr + 0x10) & (~0xf); - - tx_base = (typeof(tx_base)) ptr; - - E1000_WRITE_REG(hw, TDBAL, (u32) tx_base); + E1000_WRITE_REG(hw, TDBAL, (unsigned long)tx_base); E1000_WRITE_REG(hw, TDBAH, 0); E1000_WRITE_REG(hw, TDLEN, 128); @@ -4885,7 +5032,22 @@ e1000_configure_tx(struct e1000_hw *hw) hw->txd_cmd |= E1000_TXD_CMD_RPS; else hw->txd_cmd |= E1000_TXD_CMD_RS; + + + if (hw->mac_type == e1000_igb) { + E1000_WRITE_REG(hw, TCTL_EXT, 0x42 << 10); + + uint32_t reg_txdctl = E1000_READ_REG(hw, TXDCTL); + reg_txdctl |= 1 << 25; + E1000_WRITE_REG(hw, TXDCTL, reg_txdctl); + mdelay(20); + } + + + E1000_WRITE_REG(hw, TCTL, tctl); + + } /** @@ -4925,7 +5087,6 @@ e1000_setup_rctl(struct e1000_hw *hw) static void e1000_configure_rx(struct e1000_hw *hw) { - unsigned long ptr; unsigned long rctl, ctrl_ext; rx_tail = 0; /* make sure receives are disabled while setting up the descriptors */ @@ -4947,11 +5108,7 @@ e1000_configure_rx(struct e1000_hw *hw) E1000_WRITE_FLUSH(hw); } /* Setup the Base and Length of the Rx Descriptor Ring */ - ptr = (u32) rx_pool; - if (ptr & 0xf) - ptr = (ptr + 0x10) & (~0xf); - rx_base = (typeof(rx_base)) ptr; - E1000_WRITE_REG(hw, RDBAL, (u32) rx_base); + E1000_WRITE_REG(hw, RDBAL, (unsigned long)rx_base); E1000_WRITE_REG(hw, RDBAH, 0); E1000_WRITE_REG(hw, RDLEN, 128); @@ -4961,7 +5118,16 @@ e1000_configure_rx(struct e1000_hw *hw) E1000_WRITE_REG(hw, RDT, 0); /* Enable Receives */ + if (hw->mac_type == e1000_igb) { + + uint32_t reg_rxdctl = E1000_READ_REG(hw, RXDCTL); + reg_rxdctl |= 1 << 25; + E1000_WRITE_REG(hw, RXDCTL, reg_rxdctl); + mdelay(20); + } + E1000_WRITE_REG(hw, RCTL, rctl); + fill_rx(hw); } @@ -4973,12 +5139,26 @@ e1000_poll(struct eth_device *nic) { struct e1000_hw *hw = nic->priv; struct e1000_rx_desc *rd; + unsigned long inval_start, inval_end; + uint32_t len; + /* return true if there's an ethernet packet ready to read */ rd = rx_base + rx_last; + + /* Re-load the descriptor from RAM. */ + inval_start = ((unsigned long)rd) & ~(ARCH_DMA_MINALIGN - 1); + 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) return 0; /*DEBUGOUT("recv: packet len=%d \n", rd->length); */ - NetReceive((uchar *)packet, le32_to_cpu(rd->length)); + /* Packet received, make sure the data are re-loaded from RAM. */ + len = le32_to_cpu(rd->length); + invalidate_dcache_range((unsigned long)packet, + (unsigned long)packet + + roundup(len, ARCH_DMA_MINALIGN)); + NetReceive((uchar *)packet, len); fill_rx(hw); return 1; } @@ -4986,12 +5166,13 @@ e1000_poll(struct eth_device *nic) /************************************************************************** TRANSMIT - Transmit a frame ***************************************************************************/ -static int e1000_transmit(struct eth_device *nic, void *packet, int length) +static int e1000_transmit(struct eth_device *nic, void *txpacket, int length) { - void *nv_packet = (void *)packet; + 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; txp = tx_base + tx_tail; tx_tail = (tx_tail + 1) % 8; @@ -4999,10 +5180,23 @@ static int e1000_transmit(struct eth_device *nic, void *packet, int length) 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; + + /* Dump the packet into RAM so e1000 can pick them. */ + flush_dcache_range((unsigned long)nv_packet, + (unsigned long)nv_packet + + roundup(length, ARCH_DMA_MINALIGN)); + /* Dump the descriptor into RAM as well. */ + flush_start = ((unsigned long)txp) & ~(ARCH_DMA_MINALIGN - 1); + flush_end = flush_start + roundup(sizeof(*txp), ARCH_DMA_MINALIGN); + flush_dcache_range(flush_start, flush_end); + E1000_WRITE_REG(hw, TDT, tx_tail); E1000_WRITE_FLUSH(hw); - while (!(le32_to_cpu(txp->upper.data) & E1000_TXD_STAT_DD)) { + while (1) { + invalidate_dcache_range(flush_start, flush_end); + if (le32_to_cpu(txp->upper.data) & E1000_TXD_STAT_DD) + break; if (i++ > TOUT_LOOP) { DEBUGOUT("e1000: tx timeout\n"); return 0; @@ -5097,9 +5291,8 @@ void e1000_get_bus_type(struct e1000_hw *hw) case e1000_82573: case e1000_82574: case e1000_80003es2lan: - hw->bus_type = e1000_bus_type_pci_express; - break; case e1000_ich8lan: + case e1000_igb: hw->bus_type = e1000_bus_type_pci_express; break; default: @@ -5180,6 +5373,9 @@ e1000_initialize(bd_t * bis) 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; @@ -5196,21 +5392,29 @@ e1000_initialize(bd_t * bis) 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_validate_eeprom_checksum(hw)) + 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 /* Set up the function pointers and register the device */ nic->init = e1000_init;