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

📄 e1000_hw.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*******************************************************************************    Copyright(c) 1999 - 2004 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_copper_link(struct e1000_hw *hw);static int32_t e1000_setup_fiber_serdes_link(struct e1000_hw *hw);static int32_t e1000_adjust_serdes_amplitude(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 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 int32_t e1000_write_phy_reg_ex(struct e1000_hw *hw, uint32_t reg_addr,                                      uint16_t phy_data);static int32_t e1000_read_phy_reg_ex(struct e1000_hw *hw,uint32_t reg_addr,                                     uint16_t *phy_data);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);static int32_t e1000_set_vco_speed(struct e1000_hw *hw);static int32_t e1000_polarity_reversal_workaround(struct e1000_hw *hw);static int32_t e1000_set_phy_mode(struct e1000_hw *hw);/* IGP cable length table */static constuint16_t e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] =    { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,      5, 10, 10, 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 25, 25, 25,      25, 25, 25, 25, 30, 30, 30, 30, 40, 40, 40, 40, 40, 40, 40, 40,      40, 50, 50, 50, 50, 50, 50, 50, 60, 60, 60, 60, 60, 60, 60, 60,      60, 70, 70, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 90, 90, 90,      90, 90, 90, 90, 90, 90, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,      100, 100, 100, 100, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,      110, 110, 110, 110, 110, 110, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120};/****************************************************************************** * 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:        if(hw->mac_type == e1000_82541 ||           hw->mac_type == e1000_82541_rev_2 ||           hw->mac_type == e1000_82547 ||           hw->mac_type == e1000_82547_rev_2) {            hw->phy_type = e1000_phy_igp;            break;        }        /* Fall Through */    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){    uint32_t ret_val;    uint16_t phy_saved_data;    DEBUGFUNC("e1000_phy_init_script");    if(hw->phy_init_script) {        msec_delay(20);        /* Save off the current value of register 0x2F5B to be restored at         * the end of this routine. */        ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);        /* Disabled the PHY transmitter */        e1000_write_phy_reg(hw, 0x2F5B, 0x0003);        msec_delay(20);        e1000_write_phy_reg(hw,0x0000,0x0140);        msec_delay(5);        switch(hw->mac_type) {        case e1000_82541:        case e1000_82547:            e1000_write_phy_reg(hw, 0x1F95, 0x0001);            e1000_write_phy_reg(hw, 0x1F71, 0xBD21);            e1000_write_phy_reg(hw, 0x1F79, 0x0018);            e1000_write_phy_reg(hw, 0x1F30, 0x1600);            e1000_write_phy_reg(hw, 0x1F31, 0x0014);            e1000_write_phy_reg(hw, 0x1F32, 0x161C);            e1000_write_phy_reg(hw, 0x1F94, 0x0003);            e1000_write_phy_reg(hw, 0x1F96, 0x003F);            e1000_write_phy_reg(hw, 0x2010, 0x0008);            break;        case e1000_82541_rev_2:        case e1000_82547_rev_2:            e1000_write_phy_reg(hw, 0x1F73, 0x0099);            break;        default:            break;        }        e1000_write_phy_reg(hw, 0x0000, 0x3300);        msec_delay(20);        /* Now enable the transmitter */        e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);        if(hw->mac_type == e1000_82547) {            uint16_t fused, fine, coarse;            /* Move to analog registers page */            e1000_read_phy_reg(hw, IGP01E1000_ANALOG_SPARE_FUSE_STATUS, &fused);            if(!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) {                e1000_read_phy_reg(hw, IGP01E1000_ANALOG_FUSE_STATUS, &fused);                fine = fused & IGP01E1000_ANALOG_FUSE_FINE_MASK;                coarse = fused & IGP01E1000_ANALOG_FUSE_COARSE_MASK;                if(coarse > IGP01E1000_ANALOG_FUSE_COARSE_THRESH) {                    coarse -= IGP01E1000_ANALOG_FUSE_COARSE_10;                    fine -= IGP01E1000_ANALOG_FUSE_FINE_1;                } else if(coarse == IGP01E1000_ANALOG_FUSE_COARSE_THRESH)                    fine -= IGP01E1000_ANALOG_FUSE_FINE_10;                fused = (fused & IGP01E1000_ANALOG_FUSE_POLY_MASK) |                        (fine & IGP01E1000_ANALOG_FUSE_FINE_MASK) |                        (coarse & IGP01E1000_ANALOG_FUSE_COARSE_MASK);                e1000_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_CONTROL, fused);                e1000_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_BYPASS,                                    IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL);            }        }    }}/****************************************************************************** * 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_82545GM_COPPER:    case E1000_DEV_ID_82545GM_FIBER:    case E1000_DEV_ID_82545GM_SERDES:        hw->mac_type = e1000_82545_rev_3;        break;    case E1000_DEV_ID_82546EB_COPPER:    case E1000_DEV_ID_82546EB_FIBER:    case E1000_DEV_ID_82546EB_QUAD_COPPER:        hw->mac_type = e1000_82546;        break;    case E1000_DEV_ID_82546GB_COPPER:    case E1000_DEV_ID_82546GB_FIBER:    case E1000_DEV_ID_82546GB_SERDES:    case E1000_DEV_ID_82546GB_PCIE:        hw->mac_type = e1000_82546_rev_3;        break;    case E1000_DEV_ID_82541EI:    case E1000_DEV_ID_82541EI_MOBILE:        hw->mac_type = e1000_82541;        break;    case E1000_DEV_ID_82541ER:    case E1000_DEV_ID_82541GI:    case E1000_DEV_ID_82541GI_LF:    case E1000_DEV_ID_82541GI_MOBILE:        hw->mac_type = e1000_82541_rev_2;        break;    case E1000_DEV_ID_82547EI:        hw->mac_type = e1000_82547;        break;    case E1000_DEV_ID_82547GI:        hw->mac_type = e1000_82547_rev_2;        break;    default:        /* Should never have loaded on this device */        return -E1000_ERR_MAC_TYPE;    }    switch(hw->mac_type) {    case e1000_82541:    case e1000_82547:    case e1000_82541_rev_2:    case e1000_82547_rev_2:        hw->asf_firmware_present = TRUE;        break;    default:        break;    }    return E1000_SUCCESS;}/***************************************************************************** * Set media type and TBI compatibility. * * hw - Struct containing variables accessed by shared code * **************************************************************************/voide1000_set_media_type(struct e1000_hw *hw){    uint32_t status;    DEBUGFUNC("e1000_set_media_type");    if(hw->mac_type != e1000_82543) {        /* tbi_compatibility is only valid on 82543 */        hw->tbi_compatibility_en = FALSE;    }    switch (hw->device_id) {    case E1000_DEV_ID_82545GM_SERDES:    case E1000_DEV_ID_82546GB_SERDES:        hw->media_type = e1000_media_type_internal_serdes;        break;    default:        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;        }    }}/****************************************************************************** * Reset the transmit and receive units; mask and clear all interrupts. * * hw - Struct containing variables accessed by shared code *****************************************************************************/

⌨️ 快捷键说明

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