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 + -
显示快捷键?