if_i82544.c
来自「eCos操作系统源码」· C语言 代码 · 共 2,128 行 · 第 1/5 页
C
2,128 行
//==========================================================================//// if_i82544.c//// Intel 82544 ethernet driver////==========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.//// eCos 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 or (at your option) any later version.//// eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.// at http://sources.redhat.com/ecos/ecos-license/// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####//####BSDCOPYRIGHTBEGIN####//// -------------------------------------------//// Portions of this software may have been derived from OpenBSD or// other sources, and are covered by the appropriate copyright// disclaimers included herein.//// -------------------------------------------////####BSDCOPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s): hmt, gthomas// Contributors: Ron Spence, Pacific Softworks, jskov// Date: 2000-02-01// Purpose: // Description: hardware driver for 82544 Intel PRO/100+ ethernet// Notes: CU commands such as dump and config should, according// to the docs, set the CU active state while executing.// That does not seem to be the case though, and the// driver polls the completion bit in the packet status// word instead.//// Platform code may provide this vector:// CYGNUM_DEVS_ETH_INTEL_I82544_SEPARATE_MUX_INTERRUPT if it// requires the interrupts to be handled via demuxers// attached to a distinct interrupt.//// Platform code may alternatively define:// CYGHWR_DEVS_ETH_INTEL_I82544_DEMUX_ALL if it is necessary// to demux all interrupt sources - for example if they are// wire-or'd together on some hardware but distinct on// others. In this circumstance it is permitted for// cyg_pci_translate_interrupt [HAL_PCI_TRANSLATE_INTERRUPT]// to return invalid for 2nd and subsequent devices.//// Platform code can also define these three:// CYGPRI_DEVS_ETH_INTEL_I82544_MASK_INTERRUPTS(p_i82544,old)// CYGPRI_DEVS_ETH_INTEL_I82544_UNMASK_INTERRUPTS(p_i82544,old)// CYGPRI_DEVS_ETH_INTEL_I82544_ACK_INTERRUPTS(p_i82544)// which are particularly useful when nested interrupt// management is needed (which is always IMHO).//// Platform code can define this:// CYGHWR_DEVS_ETH_INTEL_I82544_MISSED_INTERRUPT(p_i82544)// to detect a dropped interrupt and loop again or// direct-call the DSR to reschedule the delivery routine.// Only a problem on edge-triggered interrupt systems.//// Platform code can also provide this macro:// CYGPRI_DEVS_ETH_INTEL_I82544_INTERRUPT_ACK_LOOP(p_i82544)// to handle delaying for acks to register on the interrupt// controller as necessary on the EBSA.//// Platform can define CYGHWR_DEVS_ETH_INTEL_I82544_GET_ESA()// as an external means to get ESAs, possibly from RedBoot// configuration info that's stored in flash memory.//// Platform def CYGHWR_DEVS_ETH_INTEL_I82544_HAS_NO_EEPROM// removes all code for dealing with the EEPROM for those// targets where there is none fitted. Either an external// means to get ESAs should be used, or we must rely on// hard-wiring the ESA's into each executable by means of the// usual CDL configuration.//// Platform def CYGHWR_DEVS_ETH_INTEL_I82544_HAS_ONE_EEPROM// is for hardware with multiple devices, but only one with a// serial EEPROM installed. The 2nd device would get either// the same ESA - because they are certain to be on different// segment and internets - or the same ESA incremented by// CYGHWR_DEVS_ETH_INTEL_I82544_HAS_ONE_EEPROM_MAC_ADJUST.// CYGHWR_DEVS_ETH_INTEL_I82544_HAS_ONE_EEPROM should be the// number (0 or 1) of the device that does have the EEPROM.//// CYGHWR_DEVS_ETH_INTEL_I82544_PCIMEM_DISCONTIGUOUS enables// checking code for breaks in the physical address of PCI// window memory. This can happen on some boards where a// smaller SDRAM is fitted than the hardware allows, so some// higher-order address bits are ignored. We make SDRAM// contiguous in mapped memory, but what the i82544 sees// might be discontiguous. The checking code skips any// allocated chunk who appears to contain such a break, and// tries again.//// CYGHWR_DEVS_ETH_INTEL_I82544_RESET_TIMEOUT( int32 )// CYGHWR_DEVS_ETH_INTEL_I82544_TIMEOUT_FIRED( int32 ) if// both defined give the driver a means to detect that we// have been fixated on the same transmit operation for too// long - we missed an interrupt or the device crashed. The// int32 argument is used to hold a eg. the value of a// fast-running hardware timer.//// Platform def CYGHWR_DEVS_ETH_INTEL_I82544_USE_ASD is// used to select Auto Speed Detection for setting up the// link parameters.//// FIXME: replace -1/-2 return values with proper E-defines// FIXME: For 82557/8 compatibility i82544_configure() function// probably needs some tweaking - config bits differ// slightly but crucially.// FIXME: EEPROM code not tested on a BE system.////####DESCRIPTIONEND####////==========================================================================#include <pkgconf/system.h>#ifdef CYGPKG_IO_ETH_DRIVERS#include <pkgconf/io_eth_drivers.h>#endif#include <pkgconf/devs_eth_intel_i82544.h>#include <cyg/infra/cyg_type.h>#include <cyg/infra/cyg_ass.h>#include <cyg/hal/hal_arch.h>#include <cyg/hal/hal_intr.h>#include <cyg/infra/diag.h>#include <cyg/hal/hal_if.h>#include <cyg/hal/drv_api.h>#include <cyg/io/eth/netdev.h>#include <cyg/io/eth/eth_drv.h>#ifdef CYGPKG_NET#include <pkgconf/net.h>#include <net/if.h> /* Needed for struct ifnet */#endif#ifdef CYGPKG_IO_PCI#include <cyg/io/pci.h>// So we can check the validity of the PCI window against the MLTs opinion,// and thereby what the malloc heap consumes willy-nilly:#include CYGHWR_MEMORY_LAYOUT_H#else#error "Need PCI package here"#endif#include <cyg/devs/eth/i82544_info.h>#include CYGDAT_DEVS_ETH_INTEL_I82544_INL// ------------------------------------------------------------------------#ifdef CYGDBG_DEVS_ETH_INTEL_I82544_CHATTER#define DEBUG_82544 // This one prints stuff as packets come and go#define DEBUG // Startup printing mainly#define noDEBUG_EE // Some EEPROM specific retries &c#endif#ifdef CYGDBG_USE_ASSERTSstatic struct { int can_send; int deliver; int stats; int waitcmd_timeouts; int waitcmd_timeouts_cu; int lockup_timeouts; int bad_cu_idles;} missed_interrupt = { 0,0,0, 0,0, 0, 0 };#endif#ifndef CYGPKG_REDBOOT#define os_printf diag_printf#define db_printf diag_printf#elsestatic void os_printf( char *fmt, ... ){ extern int start_console(void); extern void end_console(int); va_list a; int old_console; va_start( a, fmt ); old_console = start_console(); diag_vprintf( fmt, a ); end_console(old_console); va_end( a );}#define db_printf os_printf#endif// ------------------------------------------------------------------------//// MEMORY ADDRESSING// // ------------------------------------------------------------------------// Macros for writing shared memory structures - no need for byte flipping#define READMEM8( _reg_, _val_ ) ((CYG_BYTE)(_val_) = *((volatile CYG_BYTE *)(_reg_)))#define WRITEMEM8( _reg_, _val_ ) (*((volatile CYG_BYTE *)(_reg_)) = (CYG_BYTE)(_val_))#define READMEM16( _reg_, _val_ ) ((CYG_WORD16)(_val_) = *((volatile CYG_WORD16 *)(_reg_)))#define WRITEMEM16( _reg_, _val_ ) (*((volatile CYG_WORD16 *)(_reg_)) = (CYG_WORD16)(_val_))#define READMEM32( _reg_, _val_ ) ((CYG_WORD32)(_val_) = *((volatile CYG_WORD32 *)(_reg_)))#define WRITEMEM32( _reg_, _val_ ) (*((volatile CYG_WORD32 *)(_reg_)) = (CYG_WORD32)(_val_))#define READMEM64( _reg_, _val_ ) ((CYG_WORD64)(_val_) = *((volatile CYG_WORD64 *)(_reg_)))#define WRITEMEM64( _reg_, _val_ ) (*((volatile CYG_WORD64 *)(_reg_)) = (CYG_WORD64)(_val_))#define OUTL( _v_, _a_ ) WRITEMEM32( _a_, _v_ )static inline cyg_uint32 INL(cyg_uint32 io_address) { cyg_uint32 _t_; READMEM32( io_address, _t_ ); return _t_; }// ------------------------------------------------------------------------// Map from CPU-view addresses to PCI-bus master's view - however that is:#ifdef CYGHWR_INTEL_I82544_PCI_VIRT_TO_BUS#define VIRT_TO_BUS( _x_ ) CYGHWR_INTEL_I82544_PCI_VIRT_TO_BUS( _x_ )#define BUS_TO_VIRT( _x_ ) CYGHWR_INTEL_I82544_PCI_BUS_TO_VIRT( _x_ )#else // use default mappings: get a physical address to give to the device#define VIRT_TO_BUS( _x_ ) virt_to_bus((cyg_uint32)(_x_))static inline cyg_uint32 virt_to_bus(cyg_uint32 p_memory){ return CYGARC_PHYSICAL_ADDRESS(p_memory); }#define BUS_TO_VIRT( _x_ ) bus_to_virt((cyg_uint32)(_x_))static inline cyg_uint32 bus_to_virt(cyg_uint32 p_bus){ return CYGARC_UNCACHED_ADDRESS(p_bus); }#endif // not defined CYGHWR_INTEL_I82544_PCI_VIRT_TO_BUS// ------------------------------------------------------------------------// // 82544 REGISTER OFFSETS// // ------------------------------------------------------------------------// General registers#define I82544_CTRL 0x00000#define I82544_STATUS 0x00008#define I82544_EECD 0x00010#define I82544_CTRL_EXT 0x00018#define I82544_MDIC 0x00020#define I82544_FCAL 0x00028#define I82544_FCAH 0x0002c#define I82544_FCT 0x00030#define I82544_VET 0x00038#define I82544_FCTTV 0x00170#define I82544_TXCW 0x00178#define I82544_RXCW 0x00180#define I82544_PBA 0x01000// Interrupt control registers#define I82544_ICR 0x000c0#define I82544_ICS 0x000c8#define I82544_IMS 0x000d0#define I82544_IMC 0x000d8// Receive registers#define I82544_RCTL 0x00100#define I82544_FCRTL 0x02160#define I82544_FCRTH 0x02168#define I82544_RDBAL 0x02800#define I82544_RDBAH 0x02804#define I82544_RDLEN 0x02808#define I82544_RDH 0x02810#define I82544_RDT 0x02818#define I82544_RDTR 0x02820#define I82544_RXDCTL 0x02828#define I82544_RXCSUM 0x05000#define I82544_MTA 0x05200#define I82544_RAT 0x05400#define I82544_VFTA 0x05600#define I82544_RCTL_EN (1<<1)#define I82544_RCTL_BAM (1<<15)// Transmit registers#define I82544_TCTL 0x00400#define I82544_TIPG 0x00410#define I82544_TBT 0x00448#define I82544_AIT 0x00458#define I82544_TXDMAC 0x03000#define I82544_TDBAL 0x03800#define I82544_TDBAH 0x03804#define I82544_TDLEN 0x03808#define I82544_TDH 0x03810#define I82544_TDT 0x03818#define I82544_TIDV 0x03820#define I82544_TXDCTL 0x03828#define I82544_TSPMT 0x03830#define I82544_TCTL_EN (1<<1)#define I82544_TCTL_PSP (1<<3)// ------------------------------------------------------------------------//// 82544 DEVICE CONTROL WORD DEFNITIONS//// ------------------------------------------------------------------------#define I82544_CTRL_FD (1<<0)#define I82544_CTRL_BEM (1<<1)#define I82544_CTRL_LRST (1<<3)#define I82544_CTRL_ASDE (1<<5)#define I82544_CTRL_SLU (1<<6)#define I82544_CTRL_ILOS (1<<7)#define I82544_CTRL_SPEED (3<<8)#define I82544_CTRL_FRCSPD (1<<11)#define I82544_CTRL_FRCDPLX (1<<12)#define I82544_CTRL_SWDPINSLO (15<<18)#define I82544_CTRL_SWDPINSIO (15<<22)#define I82544_CTRL_RST (1<<26)#define I82544_CTRL_RFCE (1<<27)#define I82544_CTRL_TFCE (1<<28)#define I82544_CTRL_VME (1<<30)#define I82544_CTRL_PHY_RST (1<<31)#define I82544_CTRL_PHY_RESET (1<<18)#define I82544_CTRL_PHY_RESET_DIR (1<<22)#define I82544_CTRL_MDIO (1<<20)#define I82544_CTRL_MDIO_DIR (1<<24)#define I82544_CTRL_MDC (1<<21)#define I82544_CTRL_MDC_DIR (1<<25)#define I82544_CTRL_EXT_PHY_RESET4 (1<<4)#define I82544_CTRL_EXT_PHY_RESET_DIR4 (1<<8)#define PHY_ADDRESS 1// ------------------------------------------------------------------------//// 82544 DEVICE STATUS WORD DEFNITIONS//// ------------------------------------------------------------------------#define I82544_STATUS_FD 0x0001#define I82544_STATUS_LU 0x0002#define I82544_STATUS_TXOFF 0x0010#define I82544_STATUS_TBIMODE 0x0020#define I82544_STATUS_SPEED 0x00C0#define I82544_STATUS_ASDV 0x0300#define I82544_STATUS_PCI_SPD 0x0800#define I82544_STATUS_BUS64 0x1000#define I82544_STATUS_PCIX_MODE 0x2000#define I82544_STATUS_PCIXSPD 0xC000// ------------------------------------------------------------------------//// 82544 EEPROM INTERFACE//// ------------------------------------------------------------------------// EEPROM_Ctrl bits.#define EE_SHIFT_CLK 0x01 // EEPROM shift clock.#define EE_CS 0x02 // EEPROM chip select.#define EE_DATA_WRITE 0x04 // EEPROM chip data in.#define EE_DATA_READ 0x08 // EEPROM chip data out.#define EE_REQ 0x40 // EEPROM request (82546 only)#define EE_GNT 0x80 // EEPROM grant (82546 only)#define EE_PRES 0x100 // EEPROM present (82546 only)#define EE_SIZE 0x200 // EEPROM size (82546 only)#define EE_ENB (0x10|EE_CS)// ------------------------------------------------------------------------//// RECEIVE DESCRIPTORS//// ------------------------------------------------------------------------#define I82544_RD_BUFFER 0#define I82544_RD_LENGTH 8#define I82544_RD_CSUM 10#define I82544_RD_STATUS 12#define I82544_RD_ERRORS 13#define I82544_RD_SPECIAL 14#define I82544_RD_SIZE 16#define I82544_RD_STATUS_DD (1<<0)#define I82544_RD_STATUS_EOP (1<<1)#define I82544_RD_STATUS_IXSM (1<<2)#define I82544_RD_STATUS_VP (1<<3)#define I82544_RD_STATUS_TCPCS (1<<5)#define I82544_RD_STATUS_IPCS (1<<6)#define I82544_RD_STATUS_PIF (1<<7)// ------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?