⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 e1000_hw.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
int32_te1000_reset_hw(struct e1000_hw *hw){    uint32_t ctrl;    uint32_t ctrl_ext;    uint32_t icr;    uint32_t manc;    uint32_t led_ctrl;    DEBUGFUNC("e1000_reset_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");        e1000_pci_clear_mwi(hw);    }    /* Clear interrupt mask to stop board from generating interrupts */    DEBUGOUT("Masking off all interrupts\n");    E1000_WRITE_REG(hw, IMC, 0xffffffff);    /* Disable the Transmit and Receive units.  Then delay to allow     * any pending transactions to complete before we hit the MAC with     * the global reset.     */    E1000_WRITE_REG(hw, RCTL, 0);    E1000_WRITE_REG(hw, TCTL, E1000_TCTL_PSP);    E1000_WRITE_FLUSH(hw);    /* The tbi_compatibility_on Flag must be cleared when Rctl is cleared. */    hw->tbi_compatibility_on = FALSE;    /* Delay to allow any outstanding PCI transactions to complete before     * resetting the device     */    msec_delay(10);    ctrl = E1000_READ_REG(hw, CTRL);    /* Must reset the PHY before resetting the MAC */    if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {        E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST));        msec_delay(5);    }    /* Issue a global reset to the MAC.  This will reset the chip's     * transmit, receive, DMA, and link units.  It will not effect     * the current PCI configuration.  The global reset bit is self-     * clearing, and should clear within a microsecond.     */    DEBUGOUT("Issuing a global reset to MAC\n");    switch(hw->mac_type) {        case e1000_82544:        case e1000_82540:        case e1000_82545:        case e1000_82546:        case e1000_82541:        case e1000_82541_rev_2:            /* These controllers can't ack the 64-bit write when issuing the             * reset, so use IO-mapping as a workaround to issue the reset */            E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST));            break;        case e1000_82545_rev_3:        case e1000_82546_rev_3:            /* Reset is performed on a shadow of the control register */            E1000_WRITE_REG(hw, CTRL_DUP, (ctrl | E1000_CTRL_RST));            break;        default:            E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));            break;    }    /* After MAC reset, force reload of EEPROM to restore power-on settings to     * device.  Later controllers reload the EEPROM automatically, so just wait     * for reload to complete.     */    switch(hw->mac_type) {        case e1000_82542_rev2_0:        case e1000_82542_rev2_1:        case e1000_82543:        case e1000_82544:            /* Wait for reset to complete */            udelay(10);            ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);            ctrl_ext |= E1000_CTRL_EXT_EE_RST;            E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);            E1000_WRITE_FLUSH(hw);            /* Wait for EEPROM reload */            msec_delay(2);            break;        case e1000_82541:        case e1000_82541_rev_2:        case e1000_82547:        case e1000_82547_rev_2:            /* Wait for EEPROM reload */            msec_delay(20);            break;        default:            /* Wait for EEPROM reload (it happens automatically) */            msec_delay(5);            break;    }    /* Disable HW ARPs on ASF enabled adapters */    if(hw->mac_type >= e1000_82540) {        manc = E1000_READ_REG(hw, MANC);        manc &= ~(E1000_MANC_ARP_EN);        E1000_WRITE_REG(hw, MANC, manc);    }    if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {        e1000_phy_init_script(hw);        /* Configure activity LED after PHY reset */        led_ctrl = E1000_READ_REG(hw, LEDCTL);        led_ctrl &= IGP_ACTIVITY_LED_MASK;        led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);        E1000_WRITE_REG(hw, LEDCTL, led_ctrl);    }    /* Clear interrupt mask to stop board from generating interrupts */    DEBUGOUT("Masking off all interrupts\n");    E1000_WRITE_REG(hw, IMC, 0xffffffff);    /* Clear any pending interrupt events. */    icr = E1000_READ_REG(hw, ICR);    /* If MWI was previously enabled, reenable it. */    if(hw->mac_type == e1000_82542_rev2_0) {        if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)            e1000_pci_set_mwi(hw);    }    return E1000_SUCCESS;}/****************************************************************************** * Performs basic configuration of the adapter. * * hw - Struct containing variables accessed by shared code * * Assumes that the controller has previously been reset and is in a * post-reset uninitialized state. Initializes the receive address registers, * multicast table, and VLAN filter table. Calls routines to setup link * configuration and flow control settings. Clears all on-chip counters. Leaves * the transmit and receive units disabled and uninitialized. *****************************************************************************/int32_te1000_init_hw(struct e1000_hw *hw){    uint32_t ctrl;    uint32_t i;    int32_t ret_val;    uint16_t pcix_cmd_word;    uint16_t pcix_stat_hi_word;    uint16_t cmd_mmrbc;    uint16_t stat_mmrbc;    DEBUGFUNC("e1000_init_hw");    /* Initialize Identification LED */    ret_val = e1000_id_led_init(hw);    if(ret_val) {        DEBUGOUT("Error Initializing Identification LED\n");        return ret_val;    }    /* Set the media type and TBI compatibility */    e1000_set_media_type(hw);    /* Disabling VLAN filtering. */    DEBUGOUT("Initializing the IEEE VLAN\n");    E1000_WRITE_REG(hw, VET, 0);    e1000_clear_vfta(hw);    /* 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");        e1000_pci_clear_mwi(hw);        E1000_WRITE_REG(hw, RCTL, E1000_RCTL_RST);        E1000_WRITE_FLUSH(hw);        msec_delay(5);    }    /* Setup the receive address. This involves initializing all of the Receive     * Address Registers (RARs 0 - 15).     */    e1000_init_rx_addrs(hw);    /* 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);        msec_delay(1);        if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)            e1000_pci_set_mwi(hw);    }    /* Zero out the Multicast HASH table */    DEBUGOUT("Zeroing the MTA\n");    for(i = 0; i < E1000_MC_TBL_SIZE; i++)        E1000_WRITE_REG_ARRAY(hw, MTA, i, 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.     */    if(hw->dma_fairness) {        ctrl = E1000_READ_REG(hw, CTRL);        E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PRIOR);    }    switch(hw->mac_type) {    case e1000_82545_rev_3:    case e1000_82546_rev_3:        break;    default:        /* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */        if(hw->bus_type == e1000_bus_type_pcix) {            e1000_read_pci_cfg(hw, PCIX_COMMAND_REGISTER, &pcix_cmd_word);            e1000_read_pci_cfg(hw, PCIX_STATUS_REGISTER_HI,                &pcix_stat_hi_word);            cmd_mmrbc = (pcix_cmd_word & PCIX_COMMAND_MMRBC_MASK) >>                PCIX_COMMAND_MMRBC_SHIFT;            stat_mmrbc = (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >>                PCIX_STATUS_HI_MMRBC_SHIFT;            if(stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K)                stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K;            if(cmd_mmrbc > stat_mmrbc) {                pcix_cmd_word &= ~PCIX_COMMAND_MMRBC_MASK;                pcix_cmd_word |= stat_mmrbc << PCIX_COMMAND_MMRBC_SHIFT;                e1000_write_pci_cfg(hw, PCIX_COMMAND_REGISTER,                    &pcix_cmd_word);            }        }        break;    }    /* Call a subroutine to configure the link and setup flow control. */    ret_val = e1000_setup_link(hw);    /* Set the transmit descriptor write-back policy */    if(hw->mac_type > e1000_82544) {        ctrl = E1000_READ_REG(hw, TXDCTL);        ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB;        E1000_WRITE_REG(hw, TXDCTL, ctrl);    }    /* 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);    return ret_val;}/****************************************************************************** * Adjust SERDES output amplitude based on EEPROM setting. * * hw - Struct containing variables accessed by shared code. *****************************************************************************/static int32_te1000_adjust_serdes_amplitude(struct e1000_hw *hw){    uint16_t eeprom_data;    int32_t  ret_val;    DEBUGFUNC("e1000_adjust_serdes_amplitude");    if(hw->media_type != e1000_media_type_internal_serdes)        return E1000_SUCCESS;    switch(hw->mac_type) {    case e1000_82545_rev_3:    case e1000_82546_rev_3:        break;    default:        return E1000_SUCCESS;    }    ret_val = e1000_read_eeprom(hw, EEPROM_SERDES_AMPLITUDE, 1, &eeprom_data);    if (ret_val) {        return ret_val;    }    if(eeprom_data != EEPROM_RESERVED_WORD) {        /* Adjust SERDES output amplitude only. */        eeprom_data &= EEPROM_SERDES_AMPLITUDE_MASK;         ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_EXT_CTRL, eeprom_data);        if(ret_val)            return ret_val;    }    return E1000_SUCCESS;}/****************************************************************************** * Configures flow control and link settings. * * hw - Struct containing variables accessed by shared code * * Determines which flow control settings to use. Calls the apropriate media- * specific link configuration function. Configures the flow control settings. * Assuming the adapter has a valid link partner, a valid link should be * established. Assumes the hardware has previously been reset and the * transmitter and receiver are not enabled. *****************************************************************************/int32_te1000_setup_link(struct e1000_hw *hw){    uint32_t ctrl_ext;    int32_t ret_val;    uint16_t eeprom_data;    DEBUGFUNC("e1000_setup_link");    /* 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     * disabling auto-negotiation, and the direction of the     * SW defined pins. If there is no SW over-ride of the flow     * control setting, then the variable hw->fc will     * be initialized based on a value in the EEPROM.     */    if(e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data) < 0) {        DEBUGOUT("EEPROM Read Error\n");        return -E1000_ERR_EEPROM;    }    if(hw->fc == e1000_fc_default) {        if((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)            hw->fc = e1000_fc_none;        else if((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==                EEPROM_WORD0F_ASM_DIR)            hw->fc = e1000_fc_tx_pause;        else            hw->fc = e1000_fc_full;    }    /* We want to save off the original Flow Control configuration just     * in case we get disconnected and then reconnected into a different     * hub or switch with different Flow Control capabilities.     */    if(hw->mac_type == e1000_82542_rev2_0)        hw->fc &= (~e1000_fc_tx_pause);    if((hw->mac_type < e1000_82543) && (hw->report_tx_early == 1))        hw->fc &= (~e1000_fc_rx_pause);    hw->original_fc = hw->fc;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -