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

📄 e1000_hw.c

📁 一个2.4.21版本的嵌入式linux内核
💻 C
📖 第 1 页 / 共 5 页
字号:
/*******************************************************************************    Copyright(c) 1999 - 2003 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_set_phy_type(struct e1000_hw *hw);static void e1000_phy_init_script(struct e1000_hw *hw);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 int32_t e1000_write_eeprom_spi(struct e1000_hw *hw, uint16_t offset,                                      uint16_t words, uint16_t *data);static int32_t e1000_write_eeprom_microwire(struct e1000_hw *hw,                                            uint16_t offset, uint16_t words,                                            uint16_t *data);static int32_t e1000_spi_eeprom_ready(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, uint16_t count);static int32_t e1000_acquire_eeprom(struct e1000_hw *hw);static void e1000_release_eeprom(struct e1000_hw *hw);static void e1000_standby_eeprom(struct e1000_hw *hw);static int32_t e1000_id_led_init(struct e1000_hw * hw);/****************************************************************************** * Set the phy type member in the hw struct. * * hw - Struct containing variables accessed by shared code *****************************************************************************/int32_te1000_set_phy_type(struct e1000_hw *hw){    DEBUGFUNC("e1000_set_phy_type");    switch(hw->phy_id) {    case M88E1000_E_PHY_ID:    case M88E1000_I_PHY_ID:    case M88E1011_I_PHY_ID:        hw->phy_type = e1000_phy_m88;        break;    case IGP01E1000_I_PHY_ID:        hw->phy_type = e1000_phy_igp;        break;    default:        /* Should never have loaded on this device */        hw->phy_type = e1000_phy_undefined;        return -E1000_ERR_PHY_TYPE;    }    return E1000_SUCCESS;}/****************************************************************************** * IGP phy init script - initializes the GbE PHY * * hw - Struct containing variables accessed by shared code *****************************************************************************/static voide1000_phy_init_script(struct e1000_hw *hw){    DEBUGFUNC("e1000_phy_init_script");    if(hw->phy_init_script) {        msec_delay(10);        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x0000);        e1000_write_phy_reg(hw,0x0000,0x0140);        msec_delay(5);        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F95);        e1000_write_phy_reg(hw,0x0015,0x0001);        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F71);        e1000_write_phy_reg(hw,0x0011,0xBD21);        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F79);        e1000_write_phy_reg(hw,0x0019,0x0018);        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F30);        e1000_write_phy_reg(hw,0x0010,0x1600);        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F31);        e1000_write_phy_reg(hw,0x0011,0x0014);        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F32);        e1000_write_phy_reg(hw,0x0012,0x161C);        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F94);        e1000_write_phy_reg(hw,0x0014,0x0003);        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F96);        e1000_write_phy_reg(hw,0x0016,0x003F);        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x2010);        e1000_write_phy_reg(hw,0x0010,0x0008);        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x0000);        e1000_write_phy_reg(hw,0x0000,0x3300);    }}/****************************************************************************** * 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:    case E1000_DEV_ID_82540EP:    case E1000_DEV_ID_82540EP_LOM:    case E1000_DEV_ID_82540EP_LP:        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;    case E1000_DEV_ID_82541EI:    case E1000_DEV_ID_82541EP:        hw->mac_type = e1000_82541;        break;    case E1000_DEV_ID_82547EI:        hw->mac_type = e1000_82547;        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;    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);    /* 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);    /* 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);    }    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 */        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);    } else {        /* Wait for EEPROM reload (it happens automatically) */        msec_delay(5);        /* Dissable HW ARPs on ASF enabled adapters */        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;        if(hw->mac_type == e1000_82547)            led_ctrl |= 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);    }}/****************************************************************************** * 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;

⌨️ 快捷键说明

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