📄 e1000_hw.c
字号:
/******************************************************************************* 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 + -