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