e1000_hw.c

来自「是关于linux2.5.1的完全源码」· C语言 代码 · 共 1,650 行 · 第 1/5 页

C
1,650
字号
/*******************************************************************************  This software program is available to you under a choice of one of two  licenses. You may choose to be licensed under either the GNU General Public  License 2.0, June 1991, available at http://www.fsf.org/copyleft/gpl.html,  or the Intel BSD + Patent License, the text of which follows:    Recipient has requested a license and Intel Corporation ("Intel") is willing  to grant a license for the software entitled Linux Base Driver for the  Intel(R) PRO/1000 Family of Adapters (e1000) (the "Software") being provided  by Intel Corporation. The following definitions apply to this license:    "Licensed Patents" means patent claims licensable by Intel Corporation which  are necessarily infringed by the use of sale of the Software alone or when  combined with the operating system referred to below.    "Recipient" means the party to whom Intel delivers this Software.    "Licensee" means Recipient and those third parties that receive a license to  any operating system available under the GNU General Public License 2.0 or  later.    Copyright (c) 1999 - 2002 Intel Corporation.  All rights reserved.    The license is provided to Recipient and Recipient's Licensees under the  following terms.    Redistribution and use in source and binary forms of the Software, with or  without modification, are permitted provided that the following conditions  are met:    Redistributions of source code of the Software may retain the above  copyright notice, this list of conditions and the following disclaimer.    Redistributions in binary form of the Software may reproduce the above  copyright notice, this list of conditions and the following disclaimer in  the documentation and/or materials provided with the distribution.    Neither the name of Intel Corporation nor the names of its contributors  shall be used to endorse or promote products derived from this Software  without specific prior written permission.    Intel hereby grants Recipient and Licensees a non-exclusive, worldwide,  royalty-free patent license under Licensed Patents to make, use, sell, offer  to sell, import and otherwise transfer the Software, if any, in source code  and object code form. This license shall include changes to the Software  that are error corrections or other minor changes to the Software that do  not add functionality or features when the Software is incorporated in any  version of an operating system that has been distributed under the GNU  General Public License 2.0 or later. This patent license shall apply to the  combination of the Software and any operating system licensed under the GNU  General Public License 2.0 or later if, at the time Intel provides the  Software to Recipient, such addition of the Software to the then publicly  available versions of such operating systems available under the GNU General  Public License 2.0 or later (whether in gold, beta or alpha form) causes  such combination to be covered by the Licensed Patents. The patent license  shall not apply to any other combinations which include the Software. NO  hardware per se is licensed hereunder.    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE  IMPLIED WARRANTIES OF MECHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE  ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR IT CONTRIBUTORS BE LIABLE FOR ANY  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES  (INCLUDING, BUT NOT LIMITED, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  ANY LOSS OF USE; DATA, OR PROFITS; OR BUSINESS INTERUPTION) HOWEVER CAUSED  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*******************************************************************************//* 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);/****************************************************************************** * 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;    uint16_t pci_cmd_word;    DEBUGFUNC("e1000_reset_hw");        /* For 82542 (rev 2.0), disable MWI before issuing a device reset */    if(hw->mac_type == e1000_82542_rev2_0) {        if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE) {            DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");            pci_cmd_word = hw->pci_cmd_word & ~CMD_MEM_WRT_INVALIDATE;            e1000_write_pci_cfg(hw, PCI_COMMAND_REGISTER, &pci_cmd_word);        }    }    /* 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);    /* 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);    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);        /* 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_write_pci_cfg(hw, PCI_COMMAND_REGISTER, &hw->pci_cmd_word);    }}/****************************************************************************** * 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 pci_cmd_word;    DEBUGFUNC("e1000_init_hw");    /* 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) {        if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE) {            DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");            pci_cmd_word = hw->pci_cmd_word & ~CMD_MEM_WRT_INVALIDATE;            e1000_write_pci_cfg(hw, PCI_COMMAND_REGISTER, &pci_cmd_word);        }        E1000_WRITE_REG(hw, RCTL, E1000_RCTL_RST);        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);        msec_delay(1);        if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)            e1000_write_pci_cfg(hw, PCI_COMMAND_REGISTER, &hw->pci_cmd_word);    }    /* 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);    }    /* Call a subroutine to configure the link and setup flow control. */    ret_val = e1000_setup_link(hw);    /* 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;    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, &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))

⌨️ 快捷键说明

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