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

📄 e1000_hw.c

📁 COPE the first practical network coding scheme which is developped on click
💻 C
📖 第 1 页 / 共 5 页
字号:
/*******************************************************************************    Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved.    This program is free software; you can redistribute it and/or modify it   under the terms of the GNU General Public License as published by the Free   Software Foundation; either version 2 of the License, or (at your option)   any later version.    This program is distributed in the hope that it will be useful, but WITHOUT   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for   more details.    You should have received a copy of the GNU General Public License along with  this program; if not, write to the Free Software Foundation, Inc., 59   Temple Place - Suite 330, Boston, MA  02111-1307, USA.    The full GNU General Public License is included in this distribution in the  file called LICENSE.    Contact Information:  Linux NICS <linux.nics@intel.com>  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497*******************************************************************************//* e1000_hw.c * Shared functions for accessing and configuring the MAC */#include "e1000_hw.h"static int32_t e1000_setup_fiber_link(struct e1000_hw *hw);static int32_t e1000_setup_copper_link(struct e1000_hw *hw);static int32_t e1000_phy_force_speed_duplex(struct e1000_hw *hw);static int32_t e1000_config_mac_to_phy(struct e1000_hw *hw);static int32_t e1000_force_mac_fc(struct e1000_hw *hw);static void e1000_raise_mdi_clk(struct e1000_hw *hw, uint32_t *ctrl);static void e1000_lower_mdi_clk(struct e1000_hw *hw, uint32_t *ctrl);static void e1000_shift_out_mdi_bits(struct e1000_hw *hw, uint32_t data, uint16_t count);static uint16_t e1000_shift_in_mdi_bits(struct e1000_hw *hw);static int32_t e1000_phy_reset_dsp(struct e1000_hw *hw);static void e1000_raise_ee_clk(struct e1000_hw *hw, uint32_t *eecd);static void e1000_lower_ee_clk(struct e1000_hw *hw, uint32_t *eecd);static void e1000_shift_out_ee_bits(struct e1000_hw *hw, uint16_t data, uint16_t count);static uint16_t e1000_shift_in_ee_bits(struct e1000_hw *hw);static void e1000_setup_eeprom(struct e1000_hw *hw);static void e1000_standby_eeprom(struct e1000_hw *hw);static void e1000_clock_eeprom(struct e1000_hw *hw);static void e1000_cleanup_eeprom(struct e1000_hw *hw);static int32_t e1000_id_led_init(struct e1000_hw * hw);/****************************************************************************** * Set the mac type member in the hw struct. *  * hw - Struct containing variables accessed by shared code *****************************************************************************/int32_te1000_set_mac_type(struct e1000_hw *hw){    DEBUGFUNC("e1000_set_mac_type");    switch (hw->device_id) {    case E1000_DEV_ID_82542:        switch (hw->revision_id) {        case E1000_82542_2_0_REV_ID:            hw->mac_type = e1000_82542_rev2_0;            break;        case E1000_82542_2_1_REV_ID:            hw->mac_type = e1000_82542_rev2_1;            break;        default:            /* Invalid 82542 revision ID */            return -E1000_ERR_MAC_TYPE;        }        break;    case E1000_DEV_ID_82543GC_FIBER:    case E1000_DEV_ID_82543GC_COPPER:        hw->mac_type = e1000_82543;        break;    case E1000_DEV_ID_82544EI_COPPER:    case E1000_DEV_ID_82544EI_FIBER:    case E1000_DEV_ID_82544GC_COPPER:    case E1000_DEV_ID_82544GC_LOM:        hw->mac_type = e1000_82544;        break;    case E1000_DEV_ID_82540EM:    case E1000_DEV_ID_82540EM_LOM:        hw->mac_type = e1000_82540;        break;    case E1000_DEV_ID_82545EM_COPPER:    case E1000_DEV_ID_82545EM_FIBER:        hw->mac_type = e1000_82545;        break;    case E1000_DEV_ID_82546EB_COPPER:    case E1000_DEV_ID_82546EB_FIBER:        hw->mac_type = e1000_82546;        break;    default:        /* Should never have loaded on this device */        return -E1000_ERR_MAC_TYPE;    }    return E1000_SUCCESS;}/****************************************************************************** * Reset the transmit and receive units; mask and clear all interrupts. * * hw - Struct containing variables accessed by shared code *****************************************************************************/voide1000_reset_hw(struct e1000_hw *hw){    uint32_t ctrl;    uint32_t ctrl_ext;    uint32_t icr;    uint32_t manc;    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);    /* 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");    ctrl = E1000_READ_REG(hw, CTRL);    if(hw->mac_type > e1000_82543)        E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST));    else        E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));    /* Force a reload from the EEPROM if necessary */    if(hw->mac_type < e1000_82540) {        /* Wait for reset to complete */        usec_delay(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);    } else {        /* Wait for EEPROM reload (it happens automatically) */        msec_delay(4);        /* Dissable HW ARPs on ASF enabled adapters */        manc = E1000_READ_REG(hw, MANC);        manc &= ~(E1000_MANC_ARP_EN);        E1000_WRITE_REG(hw, MANC, manc);    }        /* 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);    }}/****************************************************************************** * 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, status;    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 < 0) {        DEBUGOUT("Error Initializing Identification LED\n");        return ret_val;    }        /* Set the Media Type and exit with error if it is not valid. */    if(hw->mac_type != e1000_82543) {        /* tbi_compatibility is only valid on 82543 */        hw->tbi_compatibility_en = FALSE;    }    if(hw->mac_type >= e1000_82543) {        status = E1000_READ_REG(hw, STATUS);        if(status & E1000_STATUS_TBIMODE) {            hw->media_type = e1000_media_type_fiber;            /* tbi_compatibility not valid on fiber */            hw->tbi_compatibility_en = FALSE;        } else {            hw->media_type = e1000_media_type_copper;        }    } else {        /* This is an 82542 (fiber only) */        hw->media_type = e1000_media_type_fiber;    }    /* 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);    }    /* 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);        }    }    /* 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;}/****************************************************************************** * 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;

⌨️ 快捷键说明

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