if_i21143.c
来自「eCos操作系统源码」· C语言 代码 · 共 1,953 行 · 第 1/5 页
C
1,953 行
//==========================================================================//// if_i21143.c//// Intel 21143 ethernet driver////==========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 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// Contributors: // Date: 2000-09-17// Purpose: // Description: hardware driver for 21143 Intel PRO/100+ ethernet////####DESCRIPTIONEND####////==========================================================================#include <pkgconf/system.h>#ifdef CYGPKG_IO_ETH_DRIVERS#include <pkgconf/io_eth_drivers.h>#endif#include <pkgconf/devs_eth_intel_i21143.h>// Config for the instantiating package:#include CYGDAT_DEVS_ETH_INTEL_I21143_CFG#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/hal/hal_cache.h> // HAL_DCACHE_STORE#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>#include CYGHWR_MEMORY_LAYOUT_H#else#error "Need PCI package here"#endif// ------------------------------------------------------------------------// Exported statistics and the like// defined in <cyg/io/eth/eth_drv_stats.h> - already included.#define KEEP_STATISTICS#ifdef KEEP_STATISTICS# define INCR_STAT( _x_ ) (p_i21143->stats. _x_ ++)#else# define INCR_STAT( _x_ ) CYG_EMPTY_STATEMENT#endif// ------------------------------------------------------------------------//// DEVICES AND PACKET QUEUES//// ------------------------------------------------------------------------#define RX_DESCRIPTORS (4) // 4 packets.#define RX_BUFFERS RX_DESCRIPTORS#define TX_DESCRIPTORS MAX_ETH_DRV_SG // Enough for one tx, even if fragmented#define MAX_RX_PACKET_SIZE 1536 // maximum Rx packet size#define MAX_TX_PACKET_SIZE 1536 // maximum Tx packet size// ------------------------------------------------------------------------typedef struct buffer_descriptor { volatile cyg_uint32 des0; volatile cyg_uint32 des1; volatile cyg_uint32 buf1; volatile cyg_uint32 buf2;} BUFDES;typedef struct i21143 { cyg_uint8 // (split up for atomic byte access) found:1, // was hardware discovered? mac_addr_ok:1, // can we bring up? active:1, // has this if been brung up? hardwired_esa:1, // set if ESA is hardwired via CDL spare1:4; cyg_uint8 tx_endbuf; // transmit in progress flag too#define NO_TX_IN_PROGRESS (255) cyg_uint8 index; // 0 or 1 or whatever cyg_uint8 line_status; // line status when last inspected cyg_uint32 devid; // PCI device id cyg_uint32 io_address; // memory mapped I/O address cyg_uint8 mac_address[6]; // mac (hardware) address cyg_uint16 phy_autoneg_remote; // remote link status cache void *ndp; // Network Device Pointer int next_rx_descriptor; // descriptor index for buffers volatile BUFDES *rx_ring; // location of Rx descriptors volatile BUFDES *tx_ring; // location of Tx descriptors unsigned long tx_keys[1]; // keys for tx q management // Interrupt handling stuff cyg_vector_t vector; // interrupt vector cyg_handle_t interrupt_handle; // handle for int.handler cyg_interrupt interrupt_object; // Refer to following items only though uncached addresses from the // tx_ring and rxring pointers: volatile BUFDES _tx[TX_DESCRIPTORS]; volatile BUFDES _rx[RX_DESCRIPTORS]; cyg_uint8 _rxbufs[ RX_BUFFERS ] [ MAX_RX_PACKET_SIZE ] ;#ifdef KEEP_STATISTICS struct stats { unsigned int tx_good; unsigned int tx_max_collisions; unsigned int tx_late_collisions; unsigned int tx_underrun; unsigned int tx_carrier_loss; unsigned int tx_deferred; unsigned int tx_sqetesterrors; unsigned int tx_single_collisions; unsigned int tx_mult_collisions; unsigned int tx_total_collisions; unsigned int rx_good; unsigned int rx_crc_errors; unsigned int rx_align_errors; unsigned int rx_resource_errors;// unsigned int rx_overrun_errors; unsigned int rx_collisions; unsigned int rx_short_frames; unsigned int rx_too_long_frames; unsigned int rx_symbol_errors; unsigned int interrupts; unsigned int rx_count; unsigned int rx_deliver; unsigned int rx_resource; unsigned int rx_restart; unsigned int tx_count; unsigned int tx_complete; unsigned int tx_dropped; } stats;#endif // KEEP_STATISTICS} I21143;// ------------------------------------------------------------------------// After defining that, now we can instantiate the device(s):#include CYGDAT_DEVS_ETH_INTEL_I21143_INL// ------------------------------------------------------------------------// Access to cached/uncached/physical memory, to map from CPU-view// addresses to PCI-bus master's view - however that is:// // We'll use these macros, so that different platforms can define them// externally:// o CYGHWR_PCI_VIRT_TO_BUS( x )// - address for the PCI device to use// o CYGHWR_CACHED_TO_UNCACHED( x )// - access to memory that the PCI device will look at// o CYGHWR_BUS_TO_UNCACHED( x )// - back from an address in the PCI structures to one for us to look at// to see what it said.#ifndef CYGHWR_PCI_VIRT_TO_BUS# ifdef CYGARC_PHYSICAL_ADDRESS# define CYGHWR_PCI_VIRT_TO_BUS( _x_ ) CYGARC_PHYSICAL_ADDRESS( (_x_) )# else# error No CYGHWR_PCI_VIRT_TO_BUS() defined!//#define CYGHWR_PCI_VIRT_TO_BUS( _x_ ) (_x_)# endif#endif#ifndef CYGHWR_CACHED_TO_UNCACHED# ifdef CYGARC_UNCACHED_ADDRESS# define CYGHWR_CACHED_TO_UNCACHED( _x_ ) CYGARC_UNCACHED_ADDRESS( (_x_) )# else # define CYGHWR_CACHED_TO_UNCACHED( _x_ ) (_x_)# endif#endif#ifndef CYGHWR_BUS_TO_UNCACHED# ifdef CYGARC_UNCACHED_ADDRESS# define CYGHWR_BUS_TO_UNCACHED( _x_ ) CYGARC_UNCACHED_ADDRESS( (_x_) )# else # define CYGHWR_BUS_TO_UNCACHED( _x_ ) (_x_)# endif#endif// ------------------------------------------------------------------------// Prototypes and declarationsstatic int pci_init_find_21143s( void );static int i21143_configure(struct i21143* p_i21143, int promisc);static void i21143_reset(struct i21143* p_i21143);static void InitTxRing(struct i21143* p_i21143);static void InitRxRing(struct i21143* p_i21143);static void eth_set_mac_address( struct i21143* p_i21143, cyg_uint8 *addr );static void mii_write_register( int ioaddr, int regnum, int value );static int mii_read_register( int ioaddr, int regnum );static int get_eeprom_size( int ioaddr );static int read_eeprom_word( int ioaddr, int addrbits, int address );// ------------------------------------------------------------------------//// 21143 GENERAL STATUS REGISTER//// ------------------------------------------------------------------------#define GEN_STATUS_FDX 0x04 // 1 = full duplex, 0 = half#define GEN_STATUS_100MBPS 0x02 // 1 = 100 Mbps, 0 = 10 Mbps#define GEN_STATUS_LINK 0x01 // 1 = link up, 0 = link down// returns status in terms of the above:static int i21143_status( struct i21143* p_i21143 );// A cheap check for changes: true if changed, is all:static int i21143_status_changed( struct i21143* p_i21143 );// ------------------------------------------------------------------------#define CYGDAT_DEVS_ETH_DESCRIPTION "Intel i21143 10/100 Ethernet [DEC]"#define ETH_DEV_DOT3STATSETHERCHIPSET 1,3,6,1,2,1,10,7,8,2,5// ------------------------------------------------------------------------#ifdef CYGDBG_DEVS_ETH_INTEL_I21143_CHATTER#define nDEBUG_TRAFFIC // This one prints stuff as packets come and go#define DEBUG // Startup printing mainly#define nDEBUG_EE // Some EEPROM specific retries &c#define nDEBUG_TRAFFIC_TXDETAILS // tx bufs layout#define nDEBUG_DUMP_REGS#define nDEBUG_MAC#define nDEBUG_STARTSTOPRESET#endif// ------------------------------------------------------------------------// I/O access macros as inlines for type safety#if (CYG_BYTEORDER == CYG_MSBFIRST)#define HAL_CTOLE32(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) | (((x) & 0xff0000) >> 8) | (((x) >> 24) & 0xff))#define HAL_LE32TOC(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) | (((x) & 0xff0000) >> 8) | (((x) >> 24) & 0xff))#define HAL_CTOLE16(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))#define HAL_LE16TOC(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))//static inline void OUTB(cyg_uint8 value, cyg_uint32 io_address)//{// HAL_WRITE_UINT8( io_address, value);//}////static inline void OUTW(cyg_uint16 value, cyg_uint32 io_address)//{// HAL_WRITE_UINT16( io_address, (((value & 0xff) << 8) | ((value & 0xff00) >> 8)) );//}static inline void OUTL(cyg_uint32 value, cyg_uint32 io_address){ HAL_WRITE_UINT32( io_address, ((((value) & 0xff) << 24) | (((value) & 0xff00) << 8) | (((value) & 0xff0000) >> 8) | (((value) >> 24) & 0xff)) );}//static inline cyg_uint8 INB(cyg_uint32 io_address)//{ // cyg_uint8 d;// HAL_READ_UINT8( io_address, d );// return d;//}////static inline cyg_uint16 INW(cyg_uint32 io_address)//{// cyg_uint16 d;// HAL_READ_UINT16( io_address, d );// return (((d & 0xff) << 8) | ((d & 0xff00) >> 8));//}static inline cyg_uint32 INL(cyg_uint32 io_address){ cyg_uint32 d; HAL_READ_UINT32( io_address, d ); return ((((d) & 0xff) << 24) | (((d) & 0xff00) << 8) | (((d) & 0xff0000) >> 8) | (((d) >> 24) & 0xff));}#else// Maintaining the same styleee as above...#define HAL_CTOLE32(x) ((((x))))#define HAL_LE32TOC(x) ((((x))))#define HAL_CTOLE16(x) ((((x))))#define HAL_LE16TOC(x) ((((x))))//static inline void OUTB(cyg_uint8 value, cyg_uint32 io_address)//{ HAL_WRITE_UINT8( io_address, value ); }////static inline void OUTW(cyg_uint16 value, cyg_uint32 io_address)//{ HAL_WRITE_UINT16( io_address, value ); }static inline void OUTL(cyg_uint32 value, cyg_uint32 io_address){ HAL_WRITE_UINT32( io_address, value ); }//static inline cyg_uint8 INB(cyg_uint32 io_address)// { cyg_uint8 _t_; HAL_READ_UINT8( io_address, _t_ ); return _t_; }////static inline cyg_uint16 INW(cyg_uint32 io_address)// { cyg_uint16 _t_; HAL_READ_UINT16( io_address, _t_ ); return _t_; }static inline cyg_uint32 INL(cyg_uint32 io_address) { cyg_uint32 _t_; HAL_READ_UINT32( io_address, _t_ ); return _t_; }#endif // byteorder// ------------------------------------------------------------------------static inline void udelay(int delay){ CYGACC_CALL_IF_DELAY_US(delay);}// ------------------------------------------------------------------------#ifdef DEBUG_DUMP_REGS#define MII 1#define ETH 2#define BOTH 3void debug_dump_regs( cyg_uint32 ioaddr, int which ){ int i; if ( MII & which ) for ( i = 0; i <= 0x19 ; i++ ) { int v; if ( 0x08 == i ) i = 0x10;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?