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

📄 e1000.c

📁 F:worksip2440a board可启动u-boot-like.tar.gz F:worksip2440a board可启动u-boot-like.tar.gz
💻 C
📖 第 1 页 / 共 5 页
字号:
/**************************************************************************Inter Pro 1000 for ppcboot/das-u-bootDrivers are port from Intel's Linux driver e1000-4.3.15and from Etherboot pro 1000 driver by mrakes at vivato dot nettested on both gig copper and gig fiber boards***************************************************************************//*******************************************************************************  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*******************************************************************************//* *  Copyright (C) Archway Digital Solutions. * *  written by Chrsitopher Li <cli at arcyway dot com> or <chrisl at gnuchina dot org> *  2/9/2002 * *  Copyright (C) Linux Networx. *  Massive upgrade to work with the new intel gigabit NICs. *  <ebiederman at lnxi dot com> */#include "e1000.h"#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) && \	defined(CONFIG_E1000)#define TOUT_LOOP   100000#undef	virt_to_bus#define	virt_to_bus(x)	((unsigned long)x)#define bus_to_phys(devno, a)	pci_mem_to_phys(devno, a)#define mdelay(n)       udelay((n)*1000)#define E1000_DEFAULT_PBA    0x00000030/* NIC specific static variables go here */static char tx_pool[128 + 16];static char rx_pool[128 + 16];static char packet[2096];static struct e1000_tx_desc *tx_base;static struct e1000_rx_desc *rx_base;static int tx_tail;static int rx_tail, rx_last;static struct pci_device_id supported[] = {	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82542},	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82543GC_FIBER},	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82543GC_COPPER},	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544EI_COPPER},	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544EI_FIBER},	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544GC_COPPER},	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544GC_LOM},	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM},	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545EM_COPPER},	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_COPPER},	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545EM_FIBER},	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_FIBER},	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM_LOM},};/* Function forward declarations */static int e1000_setup_link(struct eth_device *nic);static int e1000_setup_fiber_link(struct eth_device *nic);static int e1000_setup_copper_link(struct eth_device *nic);static int e1000_phy_setup_autoneg(struct e1000_hw *hw);static void e1000_config_collision_dist(struct e1000_hw *hw);static int e1000_config_mac_to_phy(struct e1000_hw *hw);static int e1000_config_fc_after_link_up(struct e1000_hw *hw);static int e1000_check_for_link(struct eth_device *nic);static int e1000_wait_autoneg(struct e1000_hw *hw);static void e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t * speed,				       uint16_t * duplex);static int e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr,			      uint16_t * phy_data);static int e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr,			       uint16_t phy_data);static void e1000_phy_hw_reset(struct e1000_hw *hw);static int e1000_phy_reset(struct e1000_hw *hw);static int e1000_detect_gig_phy(struct e1000_hw *hw);#define E1000_WRITE_REG(a, reg, value) (writel((value), ((a)->hw_addr + E1000_##reg)))#define E1000_READ_REG(a, reg) (readl((a)->hw_addr + E1000_##reg))#define E1000_WRITE_REG_ARRAY(a, reg, offset, value) (\			writel((value), ((a)->hw_addr + E1000_##reg + ((offset) << 2))))#define E1000_READ_REG_ARRAY(a, reg, offset) ( \	readl((a)->hw_addr + E1000_##reg + ((offset) << 2)))#define E1000_WRITE_FLUSH(a) {uint32_t x; x = E1000_READ_REG(a, STATUS);}/****************************************************************************** * Raises the EEPROM's clock input. * * hw - Struct containing variables accessed by shared code * eecd - EECD's current value *****************************************************************************/static voide1000_raise_ee_clk(struct e1000_hw *hw, uint32_t * eecd){	/* Raise the clock input to the EEPROM (by setting the SK bit), and then	 * wait 50 microseconds.	 */	*eecd = *eecd | E1000_EECD_SK;	E1000_WRITE_REG(hw, EECD, *eecd);	E1000_WRITE_FLUSH(hw);	udelay(50);}/****************************************************************************** * Lowers the EEPROM's clock input. * * hw - Struct containing variables accessed by shared code * eecd - EECD's current value *****************************************************************************/static voide1000_lower_ee_clk(struct e1000_hw *hw, uint32_t * eecd){	/* Lower the clock input to the EEPROM (by clearing the SK bit), and then	 * wait 50 microseconds.	 */	*eecd = *eecd & ~E1000_EECD_SK;	E1000_WRITE_REG(hw, EECD, *eecd);	E1000_WRITE_FLUSH(hw);	udelay(50);}/****************************************************************************** * Shift data bits out to the EEPROM. * * hw - Struct containing variables accessed by shared code * data - data to send to the EEPROM * count - number of bits to shift out *****************************************************************************/static voide1000_shift_out_ee_bits(struct e1000_hw *hw, uint16_t data, uint16_t count){	uint32_t eecd;	uint32_t mask;	/* We need to shift "count" bits out to the EEPROM. So, value in the	 * "data" parameter will be shifted out to the EEPROM one bit at a time.	 * In order to do this, "data" must be broken down into bits.	 */	mask = 0x01 << (count - 1);	eecd = E1000_READ_REG(hw, EECD);	eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);	do {		/* A "1" is shifted out to the EEPROM by setting bit "DI" to a "1",		 * and then raising and then lowering the clock (the SK bit controls		 * the clock input to the EEPROM).  A "0" is shifted out to the EEPROM		 * by setting "DI" to "0" and then raising and then lowering the clock.		 */		eecd &= ~E1000_EECD_DI;		if (data & mask)			eecd |= E1000_EECD_DI;		E1000_WRITE_REG(hw, EECD, eecd);		E1000_WRITE_FLUSH(hw);		udelay(50);		e1000_raise_ee_clk(hw, &eecd);		e1000_lower_ee_clk(hw, &eecd);		mask = mask >> 1;	} while (mask);	/* We leave the "DI" bit set to "0" when we leave this routine. */	eecd &= ~E1000_EECD_DI;	E1000_WRITE_REG(hw, EECD, eecd);}/****************************************************************************** * Shift data bits in from the EEPROM * * hw - Struct containing variables accessed by shared code *****************************************************************************/static uint16_te1000_shift_in_ee_bits(struct e1000_hw *hw){	uint32_t eecd;	uint32_t i;	uint16_t data;	/* In order to read a register from the EEPROM, we need to shift 16 bits	 * in from the EEPROM. Bits are "shifted in" by raising the clock input to	 * the EEPROM (setting the SK bit), and then reading the value of the "DO"	 * bit.  During this "shifting in" process the "DI" bit should always be	 * clear..	 */	eecd = E1000_READ_REG(hw, EECD);	eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);	data = 0;	for (i = 0; i < 16; i++) {		data = data << 1;		e1000_raise_ee_clk(hw, &eecd);		eecd = E1000_READ_REG(hw, EECD);		eecd &= ~(E1000_EECD_DI);		if (eecd & E1000_EECD_DO)			data |= 1;		e1000_lower_ee_clk(hw, &eecd);	}	return data;}/****************************************************************************** * Prepares EEPROM for access * * hw - Struct containing variables accessed by shared code * * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This * function should be called before issuing a command to the EEPROM. *****************************************************************************/static voide1000_setup_eeprom(struct e1000_hw *hw){	uint32_t eecd;	eecd = E1000_READ_REG(hw, EECD);	/* Clear SK and DI */	eecd &= ~(E1000_EECD_SK | E1000_EECD_DI);	E1000_WRITE_REG(hw, EECD, eecd);	/* Set CS */	eecd |= E1000_EECD_CS;	E1000_WRITE_REG(hw, EECD, eecd);}/****************************************************************************** * Returns EEPROM to a "standby" state * * hw - Struct containing variables accessed by shared code *****************************************************************************/static voide1000_standby_eeprom(struct e1000_hw *hw){	uint32_t eecd;	eecd = E1000_READ_REG(hw, EECD);	/* Deselct EEPROM */	eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);	E1000_WRITE_REG(hw, EECD, eecd);	E1000_WRITE_FLUSH(hw);	udelay(50);	/* Clock high */	eecd |= E1000_EECD_SK;	E1000_WRITE_REG(hw, EECD, eecd);	E1000_WRITE_FLUSH(hw);	udelay(50);	/* Select EEPROM */	eecd |= E1000_EECD_CS;	E1000_WRITE_REG(hw, EECD, eecd);	E1000_WRITE_FLUSH(hw);	udelay(50);	/* Clock low */	eecd &= ~E1000_EECD_SK;	E1000_WRITE_REG(hw, EECD, eecd);	E1000_WRITE_FLUSH(hw);	udelay(50);}/****************************************************************************** * Reads a 16 bit word from the EEPROM. * * hw - Struct containing variables accessed by shared code * offset - offset of  word in the EEPROM to read * data - word read from the EEPROM *****************************************************************************/static inte1000_read_eeprom(struct e1000_hw *hw, uint16_t offset, uint16_t * data){	uint32_t eecd;	uint32_t i = 0;	int large_eeprom = FALSE;	/* Request EEPROM Access */	if (hw->mac_type > e1000_82544) {		eecd = E1000_READ_REG(hw, EECD);		if (eecd & E1000_EECD_SIZE)			large_eeprom = TRUE;		eecd |= E1000_EECD_REQ;		E1000_WRITE_REG(hw, EECD, eecd);		eecd = E1000_READ_REG(hw, EECD);		while ((!(eecd & E1000_EECD_GNT)) && (i < 100)) {			i++;			udelay(10);			eecd = E1000_READ_REG(hw, EECD);		}		if (!(eecd & E1000_EECD_GNT)) {			eecd &= ~E1000_EECD_REQ;			E1000_WRITE_REG(hw, EECD, eecd);			DEBUGOUT("Could not acquire EEPROM grant\n");			return -E1000_ERR_EEPROM;		}	}	/*  Prepare the EEPROM for reading  */	e1000_setup_eeprom(hw);	/*  Send the READ command (opcode + addr)  */	e1000_shift_out_ee_bits(hw, EEPROM_READ_OPCODE, 3);	e1000_shift_out_ee_bits(hw, offset, (large_eeprom) ? 8 : 6);	/* Read the data */	*data = e1000_shift_in_ee_bits(hw);	/* End this read operation */	e1000_standby_eeprom(hw);	/* Stop requesting EEPROM access */	if (hw->mac_type > e1000_82544) {		eecd = E1000_READ_REG(hw, EECD);		eecd &= ~E1000_EECD_REQ;		E1000_WRITE_REG(hw, EECD, eecd);	}	return 0;}#if 0static voide1000_eeprom_cleanup(struct e1000_hw *hw){	uint32_t eecd;	eecd = E1000_READ_REG(hw, EECD);	eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);	E1000_WRITE_REG(hw, EECD, eecd);	e1000_raise_ee_clk(hw, &eecd);	e1000_lower_ee_clk(hw, &eecd);}static uint16_te1000_wait_eeprom_done(struct e1000_hw *hw){	uint32_t eecd;	uint32_t i;	e1000_standby_eeprom(hw);	for (i = 0; i < 200; i++) {		eecd = E1000_READ_REG(hw, EECD);		if (eecd & E1000_EECD_DO)			return (TRUE);		udelay(5);	}	return (FALSE);}static inte1000_write_eeprom(struct e1000_hw *hw, uint16_t Reg, uint16_t Data){	uint32_t eecd;	int large_eeprom = FALSE;	int i = 0;	/* Request EEPROM Access */	if (hw->mac_type > e1000_82544) {		eecd = E1000_READ_REG(hw, EECD);		if (eecd & E1000_EECD_SIZE)			large_eeprom = TRUE;		eecd |= E1000_EECD_REQ;		E1000_WRITE_REG(hw, EECD, eecd);		eecd = E1000_READ_REG(hw, EECD);		while ((!(eecd & E1000_EECD_GNT)) && (i < 100)) {			i++;

⌨️ 快捷键说明

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