This is the mail archive of the ecos-patches@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

vmWare networking update


Here's un update of my wmWare-net.patch, which allows You to use eCos
networking under VMware 3 and 4.

Now it works even with WMware NAT networks, not only with the host only
and bridged.

Please try and test it. If anybody wishes to read more about it please
visit <http://www.elsis.si/ecos/>.

Jifl, who would know that VMware NAT network device wouldn't answer any
ARP-s if one does not have the exact MAC that WMvare wants. And who
would know that VMware doesn't support PCNet EEPROM, at least no MAC
data is in there. Instead, VMware prepares the MAC in CSR_PAR
registers...

Regards
Iztok

diff -C5 -N -P -r -x '.*' /ecoscvs/orig/ecos/packages/devs/eth/amd/lancepci/current/cdl/amd_lancepci_eth_drivers.cdl ./devs/eth/amd/lancepci/current/cdl/amd_lancepci_eth_drivers.cdl
*** /ecoscvs/orig/ecos/packages/devs/eth/amd/lancepci/current/cdl/amd_lancepci_eth_drivers.cdl	1970-01-01 01:00:00.000000000 +0100
--- ./devs/eth/amd/lancepci/current/cdl/amd_lancepci_eth_drivers.cdl	2004-02-25 13:27:18.000000000 +0100
***************
*** 0 ****
--- 1,96 ----
+ # ====================================================================
+ #
+ #      amd_lancepci_eth_drivers.cdl
+ #
+ #      Ethernet drivers - support for AMD LANCE PCI (vmWare) ethernet
+ #      controllers
+ #
+ # ====================================================================
+ #####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####
+ # ====================================================================
+ ######DESCRIPTIONBEGIN####
+ #
+ # Author(s):      gthomas
+ # Contributors:   gthomas, jskov, iz
+ # Date:           2002-07-17
+ #
+ #####DESCRIPTIONEND####
+ #
+ # ====================================================================
+ 
+ cdl_package CYGPKG_DEVS_ETH_AMD_LANCEPCI {
+     display       "AMD LANCE compatible ethernet driver"
+     description   "Ethernet driver for AMD PCI LANCE compatible controllers."
+ 
+     parent        CYGPKG_IO_ETH_DRIVERS
+     active_if	  CYGPKG_IO_ETH_DRIVERS
+ 
+     active_if     CYGINT_DEVS_ETH_AMD_LANCEPCI_REQUIRED
+ 
+     include_dir   .
+     include_files ; # none _exported_ whatsoever
+     compile       -library=libextras.a if_lancepci.c
+ 
+     define_proc {
+         puts $::cdl_header "#include <pkgconf/system.h>";
+         puts $::cdl_header "#include CYGDAT_DEVS_ETH_AMD_LANCEPCI_CFG";
+     }
+ 
+     cdl_option CYGNUM_DEVS_ETH_AMD_LANCEPCI_DEV_COUNT {
+ 	display "Number of supported interfaces."
+ 	calculated    { CYGINT_DEVS_ETH_AMD_LANCEPCI_REQUIRED }
+         flavor        data
+ 	description   "
+ 	    This option selects the number of PCI ethernet interfaces to
+             be supported by the driver."
+     }
+ 
+     cdl_component CYGPKG_DEVS_ETH_AMD_LANCEPCI_OPTIONS {
+         display "LANCEPCI ethernet driver build options"
+         flavor  none
+ 	no_define
+ 
+         cdl_option CYGPKG_DEVS_ETH_AMD_LANCEPCI_CFLAGS_ADD {
+             display "Additional compiler flags"
+             flavor  data
+             no_define
+             default_value { "-D_KERNEL -D__ECOS" }
+             description   "
+                 This option modifies the set of compiler flags for
+                 building the LANCEPCI ethernet driver package.
+                 These flags are used in addition
+                 to the set of global flags."
+         }
+     }
+ }
diff -C5 -N -P -r -x '.*' /ecoscvs/orig/ecos/packages/devs/eth/amd/lancepci/current/ChangeLog ./devs/eth/amd/lancepci/current/ChangeLog
*** /ecoscvs/orig/ecos/packages/devs/eth/amd/lancepci/current/ChangeLog	1970-01-01 01:00:00.000000000 +0100
--- ./devs/eth/amd/lancepci/current/ChangeLog	2004-02-27 17:12:14.000000000 +0100
***************
*** 0 ****
--- 1,61 ----
+ 2004-02-27  Iztok Zupet  <iz@elsis.si>
+ 	* if_lancepci.c: fetch ESA from chips registers instead 
+ 	EEPROM. There seems to be no usable data in the VMware
+ 	EEPROM emulation. But the data which comes in CSR_PAR 
+ 	registers seems OK.
+ 
+ 2003-01-26  Iztok Zupet  <iz@vsr.si>
+ 
+ 	* if_lancepci.c: added aditional delay (printf) to init
+ 	  function, to fix it under Vmware 4.
+ 
+ 2003-01-26  Iztok Zupet  <iz@vsr.si>
+ 
+ 	* if_lancepci.c: fixed buffer reset after start,
+ 	  added additional delays (50ms)after start and control
+ 	  function, to let Vmware get a tick so that it can
+ 	  service the virtual chip. Added an interrupt controled
+ 	  transmit busy flag (cpd->txbusyh), so that the stop/start
+ 	  function can wait for it, thus not stopping the chip 
+ 	  aburptly.
+ 
+ 	* amd_lance.h: additional items in cpd data structure. 
+ 
+ 2002-07-17  Iztok Zupet  <iz@vsr.si>
+ 
+ 	* all: Cloned from PCnet original 
+ 	
+ //===========================================================================
+ //####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####
+ //===========================================================================
diff -C5 -N -P -r -x '.*' /ecoscvs/orig/ecos/packages/devs/eth/amd/lancepci/current/src/amd_lance.h ./devs/eth/amd/lancepci/current/src/amd_lance.h
*** /ecoscvs/orig/ecos/packages/devs/eth/amd/lancepci/current/src/amd_lance.h	1970-01-01 01:00:00.000000000 +0100
--- ./devs/eth/amd/lancepci/current/src/amd_lance.h	2004-02-25 13:27:18.000000000 +0100
***************
*** 0 ****
--- 1,532 ----
+ #ifndef CYGONCE_DEVS_ETH_AMD_LANCE_H
+ #define CYGONCE_DEVS_ETH_AMD_LANCE_H
+ //==========================================================================
+ //
+ //      amd_lance.h
+ //
+ //      AMD Lance Ethernet chip
+ //
+ //==========================================================================
+ //####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):    jskov, iz
+ // Contributors: jskov, hmt, iz
+ // Date:         2002-07-17
+ // Purpose:      Hardware description of AMD Lance series.
+ // Description:  
+ //
+ //####DESCRIPTIONEND####
+ //
+ //==========================================================================
+ 
+ #include <cyg/hal/hal_io.h>
+ 
+ //------------------------------------------------------------------------
+ // Get macros from platform header
+ #define __WANT_CONFIG
+ #include CYGDAT_DEVS_ETH_AMD_LANCEPCI_INL
+ #undef  __WANT_CONFIG
+ 
+ //------------------------------------------------------------------------
+ // Set to perms of:
+ // 0 disables all debug output
+ // 1 for process debug output
+ // 2 for added data IO output: get_reg, put_reg
+ // 4 for packet allocation/free output
+ // 8 for only startup status, so we can tell we're installed OK
+ #define DEBUG 0x0
+ 
+ #if DEBUG & 1
+ #define DEBUG_FUNCTION() do { os_printf("%s\n", __FUNCTION__); } while (0)
+ #else
+ #define DEBUG_FUNCTION() do {} while(0)
+ #endif
+ 
+ // ------------------------------------------------------------------------
+ // Macros for keeping track of statistics
+ #if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
+ # define KEEP_STATISTICS
+ #endif
+ 
+ #ifdef KEEP_STATISTICS
+ # define INCR_STAT( _x_ )        (cpd->stats. _x_ ++)
+ #else
+ # define INCR_STAT( _x_ )        CYG_EMPTY_STATEMENT
+ #endif
+ 
+ //------------------------------------------------------------------------
+ // Cache translation
+ #ifndef CYGARC_UNCACHED_ADDRESS
+ # define CYGARC_UNCACHED_ADDRESS(x) (x)
+ #endif
+ 
+ //------------------------------------------------------------------------
+ // Address translation
+ #ifndef HAL_PCI_CPU_TO_BUS
+ # error "HAL PCI support must define translation macros"
+ #endif
+ 
+ // ------------------------------------------------------------------------
+ // Macros for accessing structure elements
+ 
+ #define _SU8( _base_, _offset_) \
+         *((cyg_uint8 *)((CYG_ADDRWORD)_base_+(_offset_)))
+ #define _SU16( _base_, _offset_) \
+         *((cyg_uint16 *)((CYG_ADDRWORD)_base_+(_offset_)))
+ #define _SU32( _base_, _offset_) \
+         *((cyg_uint32 *)((CYG_ADDRWORD)_base_+(_offset_)))
+ 
+ #define _SI8( _base_, _offset_) \
+         *((cyg_int8 *)((CYG_ADDRWORD)_base_+(_offset_)))
+ #define _SI16( _base_, _offset_) \
+         *((cyg_int16 *)((CYG_ADDRWORD)_base_+(_offset_)))
+ #define _SI32( _base_, _offset_) \
+         *((cyg_int32 *)((CYG_ADDRWORD)_base_+(_offset_)))
+ 
+ // ------------------------------------------------------------------------
+ // Macros for accessing controller registers
+ #ifndef HAL_PCI_IO_READ_UINT8
+ # define HAL_PCI_IO_READ_UINT8(addr, datum)   HAL_READ_UINT8(addr, datum)
+ # define HAL_PCI_IO_WRITE_UINT8(addr, datum)  HAL_WRITE_UINT8(addr, datum)
+ # define HAL_PCI_IO_READ_UINT16(addr, datum)  HAL_READ_UINT16(addr, datum)
+ # define HAL_PCI_IO_WRITE_UINT16(addr, datum) HAL_WRITE_UINT16(addr, datum)
+ # define HAL_PCI_IO_READ_UINT32(addr, datum)  HAL_READ_UINT32(addr, datum)
+ # define HAL_PCI_IO_WRITE_UINT32(addr, datum) HAL_WRITE_UINT32(addr, datum)
+ #endif
+ 
+ // ------------------------------------------------------------------------
+ // IO map registers
+ #define LANCE_IO_EEPROM   0x00
+ #define LANCE_IO_ID       0x0e
+ #define LANCE_IO_RDP      0x10
+ #define LANCE_IO_RAP      0x12
+ #define LANCE_IO_RESET    0x14
+ #define LANCE_IO_BDP      0x16
+ 
+ // The ID of the 79C790 is 0x5757 - that may be different in other
+ // (older) cards.
+ #define LANCE_IO_ID_KEY   0x5757
+ 
+ // ------------------------------------------------------------------------
+ // Controller registers come in three sets: CSR, BCR and ANR. Use
+ // high-bits do differentiate, make the put/get functions do the right
+ // thing depending the state of these bits.
+ #define LANCE_RAP_MASK    0x007f
+ //#define LANCE_CSR_FLAG  0x0000        // implied
+ #define LANCE_BCR_FLAG    0x0080
+ #define LANCE_ANR_FLAG    0x0100
+ 
+ 
+ // CSR registers
+ #define LANCE_CSR_CSCR    0
+ #define LANCE_CSR_IBA0    1
+ #define LANCE_CSR_IBA1    2
+ #define LANCE_CSR_IM      3
+ #define LANCE_CSR_TFC     4
+ #define LANCE_CSR_ECI     5
+ #define LANCE_CSR_LAR0    8
+ #define LANCE_CSR_LAR1    9
+ #define LANCE_CSR_LAR2    10
+ #define LANCE_CSR_LAR3    11
+ #define LANCE_CSR_PAR0    12
+ #define LANCE_CSR_PAR1    13
+ #define LANCE_CSR_PAR2    14
+ #define LANCE_CSR_MODE    15
+ #define LANCE_CSR_BARRL   24
+ #define LANCE_CSR_BARRU   25
+ #define LANCE_CSR_BATRL   30
+ #define LANCE_CSR_BATRU   31
+ #define LANCE_CSR_RRC     72
+ #define LANCE_CSR_TRC     74
+ #define LANCE_CSR_RRLEN   76
+ #define LANCE_CSR_TRLEN   78
+ #define LANCE_CSR_ID_LO   88
+ #define LANCE_CSR_ID_HI   89
+ 
+ 
+ #define LANCE_CSR_CSCR_ERR       0x8000
+ #define LANCE_CSR_CSCR_RES       0x4000
+ #define LANCE_CSR_CSCR_CERR      0x2000
+ #define LANCE_CSR_CSCR_MISS      0x1000
+ #define LANCE_CSR_CSCR_MERR      0x0800
+ #define LANCE_CSR_CSCR_RINT      0x0400
+ #define LANCE_CSR_CSCR_TINT      0x0200
+ #define LANCE_CSR_CSCR_IDON      0x0100
+ #define LANCE_CSR_CSCR_INTR      0x0080
+ #define LANCE_CSR_CSCR_IENA      0x0040
+ #define LANCE_CSR_CSCR_RXON      0x0020
+ #define LANCE_CSR_CSCR_TXON      0x0010
+ #define LANCE_CSR_CSCR_TDMD      0x0008
+ #define LANCE_CSR_CSCR_STOP      0x0004
+ #define LANCE_CSR_CSCR_STRT      0x0002
+ #define LANCE_CSR_CSCR_INIT      0x0001
+ 
+ #define LANCE_CSR_CSCR_EV_MASK   0x007f
+ 
+ #define LANCE_CSR_IM_MISSM       0x1000
+ #define LANCE_CSR_IM_MERRM       0x0800
+ #define LANCE_CSR_IM_RINTM       0x0400
+ #define LANCE_CSR_IM_TINTM       0x0200
+ #define LANCE_CSR_IM_IDONM       0x0100
+ #define LANCE_CSR_IM_DXSUFLO     0x0040
+ #define LANCE_CSR_IM_LAPPEN      0x0020
+ #define LANCE_CSR_IM_DXMT2PD     0x0010
+ #define LANCE_CSR_IM_EMBA        0x0008
+ #define LANCE_CSR_IM_BSWP        0x0004
+ 
+ #define LANCE_CSR_TFC_TXDPOLL    0x1000
+ #define LANCE_CSR_TFC_APAD_XMT   0x0800
+ #define LANCE_CSR_TFC_ASTRP_RCV  0x0400
+ #define LANCE_CSR_TFC_MFCO       0x0200
+ #define LANCE_CSR_TFC_MFCOM      0x0100
+ #define LANCE_CSR_TFC_UINTCMD    0x0080
+ #define LANCE_CSR_TFC_UINT       0x0040
+ #define LANCE_CSR_TFC_RCVCCO     0x0020
+ #define LANCE_CSR_TFC_RCVCCOM    0x0010
+ #define LANCE_CSR_TFC_TXSTRT     0x0008
+ #define LANCE_CSR_TFC_TXSTRTM    0x0004
+ 
+ #define LANCE_CSR_ECI_TOKINTD      0x8000
+ #define LANCE_CSR_ECI_LTINTEN      0x4000
+ #define LANCE_CSR_ECI_SINT         0x0800
+ #define LANCE_CSR_ECI_SINTE        0x0400
+ #define LANCE_CSR_ECI_EXDINT       0x0080
+ #define LANCE_CSR_ECI_EXDINTE      0x0040
+ #define LANCE_CSR_ECI_MPPLBA       0x0020
+ #define LANCE_CSR_ECI_MPINT        0x0010
+ #define LANCE_CSR_ECI_MPINTE       0x0008
+ #define LANCE_CSR_ECI_MPEN         0x0004
+ #define LANCE_CSR_ECI_MPMODE       0x0002
+ #define LANCE_CSR_ECI_SPND         0x0001
+ 
+ #define LANCE_CSR_MODE_PROM        0x8000
+ #define LANCE_CSR_MODE_DRCVBC      0x4000
+ #define LANCE_CSR_MODE_DRCVPA      0x2000
+ #define LANCE_CSR_MODE_PORTSEL     0x0180
+ #define LANCE_CSR_MODE_INTL        0x0040
+ #define LANCE_CSR_MODE_DRTY        0x0020
+ #define LANCE_CSR_MODE_FCOLL       0x0010
+ #define LANCE_CSR_MODE_DXMTFCS     0x0008
+ #define LANCE_CSR_MODE_LOOP        0x0004
+ #define LANCE_CSR_MODE_DTX         0x0002
+ #define LANCE_CSR_MODE_DRX         0x0001
+ 
+ // BCR registers
+ #define LANCE_BCR_SWSTYLE (20 |LANCE_BCR_FLAG)
+ #define LANCE_BCR_MIIADDR (33 |LANCE_BCR_FLAG)
+ #define LANCE_BCR_MIIDATA (34 |LANCE_BCR_FLAG)
+ 
+ #define LANCE_BCR_MIIADDR_PHYAD    0x03e0
+ 
+ 
+ //----------------------------------------------------------------------------
+ // Receive buffer Descriptor
+ #if 1
+ #define LANCE_RD_PTR       0x00        // 32 bit
+ #define LANCE_RD_BLEN      0x04        // 16 bit (2's complement, negative)
+ #define LANCE_RD_MLEN      0x06        // 16 bit
+ #define LANCE_RD_SIZE      0x08
+ 
+ #define LANCE_RD_PTR_OWN       0x80000000
+ #define LANCE_RD_PTR_ERR       0x40000000
+ #define LANCE_RD_PTR_FRAM      0x20000000
+ #define LANCE_RD_PTR_OFLO      0x10000000
+ #define LANCE_RD_PTR_CRC       0x08000000
+ #define LANCE_RD_PTR_BUFF      0x04000000
+ #define LANCE_RD_PTR_STP       0x02000000
+ #define LANCE_RD_PTR_ENP       0x01000000
+ #define LANCE_RD_PTR_MASK      0x00ffffff
+ #else
+ 
+ #define LANCE_RD_PTR       0x00
+ #define LANCE_RD_BLEN      0x04
+ #define LANCE_RD_MLEN      0x08
+ #define LANCE_RD_USER      0x0c
+ #define LANCE_RD_SIZE      0x10
+ 
+ #define LANCE_RD_BLEN_OWN       0x80000000
+ #define LANCE_RD_BLEN_ERR       0x40000000
+ #define LANCE_RD_BLEN_FRAM      0x20000000
+ #define LANCE_RD_BLEN_OFLO      0x10000000
+ #define LANCE_RD_BLEN_CRC       0x08000000
+ #define LANCE_RD_BLEN_BUFF      0x04000000
+ #define LANCE_RD_BLEN_STP       0x02000000
+ #define LANCE_RD_BLEN_ENP       0x01000000
+ #define LANCE_RD_BLEN_BPE       0x00800000
+ #define LANCE_RD_BLEN_PAM       0x00400000
+ #define LANCE_RD_BLEN_LAFM      0x00200000
+ #define LANCE_RD_BLEN_BAM       0x00100000
+ #define LANCE_RD_BLEN_MASK      0x0000ffff
+ #endif
+ 
+ // Transmit buffer Descriptor
+ #if 1
+ #define LANCE_TD_PTR       0x00        // 32 bit
+ #define LANCE_TD_LEN       0x04        // 16 bit (2's complement, negative)
+ #define LANCE_TD_MISC      0x06        // 16 bit
+ #define LANCE_TD_SIZE      0x08
+ 
+ #define LANCE_TD_PTR_OWN       0x80000000
+ #define LANCE_TD_PTR_ERR       0x40000000
+ #define LANCE_TD_PTR_ADD_FCS   0x20000000
+ #define LANCE_TD_PTR_MORE      0x10000000
+ #define LANCE_TD_PTR_ONE       0x08000000
+ #define LANCE_TD_PTR_DEF       0x04000000
+ #define LANCE_TD_PTR_STP       0x02000000
+ #define LANCE_TD_PTR_ENP       0x01000000
+ #define LANCE_TD_PTR_MASK      0x00ffffff
+ #else
+ #define LANCE_TD_PTR       0x00
+ #define LANCE_TD_LEN       0x04
+ #define LANCE_TD_MISC      0x08
+ #define LANCE_TD_USER      0x0c
+ #define LANCE_TD_SIZE      0x10
+ 
+ #define LANCE_TD_LEN_OWN       0x80000000
+ #define LANCE_TD_LEN_ERR       0x40000000
+ #define LANCE_TD_LEN_ADD_FCS   0x20000000
+ #define LANCE_TD_LEN_MORE      0x10000000
+ #define LANCE_TD_LEN_ONE       0x08000000
+ #define LANCE_TD_LEN_DEF       0x04000000
+ #define LANCE_TD_LEN_STP       0x02000000
+ #define LANCE_TD_LEN_ENP       0x01000000
+ #define LANCE_TD_LEN_BPE       0x00800000
+ #define LANCE_TD_LEN_MASK      0x0000ffff
+ 
+ #define LANCE_TD_FLAGS_BUFF     0x80000000
+ #define LANCE_TD_FLAGS_UFLO     0x40000000
+ #define LANCE_TD_FLAGS_EX_DEF   0x20000000
+ #define LANCE_TD_FLAGS_LCOL     0x10000000
+ #define LANCE_TD_FLAGS_LCAR     0x08000000
+ #define LANCE_TD_FLAGS_RTRY     0x04000000
+ #define LANCE_TD_FLAGS_TRC_MASK 0x0000000f
+ #endif
+ 
+ 
+ #define LANCE_TD_MISC_BUFF     0x8000
+ #define LANCE_TD_MISC_UFLO     0x4000
+ #define LANCE_TD_MISC_EXDEF    0x2000
+ #define LANCE_TD_MISC_LCOL     0x1000
+ #define LANCE_TD_MISC_LCAR     0x0800
+ #define LANCE_TD_MISC_RTRY     0x0400
+ #define LANCE_TD_MISC_TDR      0x03ff
+ 
+ // Initialization Buffer
+ #define LANCE_IB_MODE            0
+ #define LANCE_IB_PADR0           2
+ #define LANCE_IB_PADR1           4
+ #define LANCE_IB_PADR2           6
+ #define LANCE_IB_LADRF0          8
+ #define LANCE_IB_LADRF1          10
+ #define LANCE_IB_LADRF2          12
+ #define LANCE_IB_LADRF3          14
+ #define LANCE_IB_RDRA            16
+ #define LANCE_IB_TDRA            20
+ #define LANCE_IB_SIZE            24
+ 
+ #define LANCE_IB_TDRA_CNT_shift  29
+ #define LANCE_IB_TDRA_PTR_mask   0x00ffffff
+ #define LANCE_IB_RDRA_CNT_shift  29
+ #define LANCE_IB_RDRA_PTR_mask   0x00ffffff
+ 
+ // ------------------------------------------------------------------------
+ 
+ #ifdef KEEP_STATISTICS
+ struct amd_lancepci_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          ;
+ };
+ #endif
+ 
+ typedef struct lancepci_priv_data {
+     int index;
+     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
+         txbusy:1,                       // A packet has been sent
+         txbusyh:1,                      // A packet has been sent for HW
+         spare1:2; 
+ 
+     cyg_uint16 event;
+     
+     unsigned long txkey;                // Used to ack when packet sent
+     unsigned char* base;                // Base address of controller EPROM region
+     int interrupt;                      // Interrupt vector used by controller
+     unsigned char esa[6];            // Controller ESA
+     // Function to configure the ESA - may fetch ESA from EPROM or 
+     // RedBoot config option.
+     void (*config_esa)(struct lancepci_priv_data* cpd);
+     void *ndp;                          // Network Device Pointer
+ 
+     cyg_handle_t  interrupt_handle;
+     cyg_interrupt interrupt_object;
+     int devid;
+ 
+     cyg_uint8* rx_buffers;              // ptr to base of buffer mem
+     cyg_uint8* rx_ring;                 // ptr to base of rx ring memory
+     int rx_ring_cnt;                    // number of entries in ring
+     int rx_ring_log_cnt;                // log of above
+     int rx_ring_next;                   // index of next full ring entry
+ 
+     cyg_uint8* tx_buffers;
+     cyg_uint8* tx_ring;
+     int tx_ring_cnt;
+     int tx_ring_log_cnt;
+     int tx_ring_free;                   // index of next free ring entry
+     int tx_ring_alloc;                  // index of first controller owned ring
+     int tx_ring_owned;                  // number of controller owned ring entries
+ 
+     int rxpacket;
+ #ifdef KEEP_STATISTICS
+     struct amd_lancepci_stats stats;
+ #endif
+ #if DEBUG & 1
+     cyg_uint32 txd;
+ #endif
+     cyg_uint8* init_table;				// lance init table pointer
+ 
+ } lancepci_priv_data;
+ 
+ // ------------------------------------------------------------------------
+ 
+ static __inline__ cyg_uint16
+ get_reg(struct eth_drv_sc *sc, int regno)
+ {
+     struct lancepci_priv_data *cpd =
+         (struct lancepci_priv_data *)sc->driver_private;
+     cyg_uint16 val, addr;
+ 
+     if (regno & LANCE_ANR_FLAG) {
+         // We could do this with recursive calls to get/put reg
+         // functions, but might as well just do it directly.
+         // First set ANR address
+         HAL_PCI_IO_WRITE_UINT16(cpd->base+LANCE_IO_RAP, LANCE_BCR_MIIADDR & LANCE_RAP_MASK);
+         HAL_PCI_IO_READ_UINT16(cpd->base+LANCE_IO_BDP, addr);
+         addr &= LANCE_BCR_MIIADDR_PHYAD;
+         addr |= (regno & LANCE_RAP_MASK);
+         HAL_PCI_IO_WRITE_UINT16(cpd->base+LANCE_IO_BDP, addr);
+         // Then read ANR register data
+         HAL_PCI_IO_WRITE_UINT16(cpd->base+LANCE_IO_RAP, LANCE_BCR_MIIDATA & LANCE_RAP_MASK);
+         HAL_PCI_IO_READ_UINT16(cpd->base+LANCE_IO_BDP, val);
+     } else {
+         HAL_PCI_IO_WRITE_UINT16(cpd->base+LANCE_IO_RAP, regno & LANCE_RAP_MASK);
+         if (regno & LANCE_BCR_FLAG)
+             HAL_PCI_IO_READ_UINT16(cpd->base+LANCE_IO_BDP, val);
+         else
+             HAL_PCI_IO_READ_UINT16(cpd->base+LANCE_IO_RDP, val);
+     }
+ #if DEBUG & 2
+     os_printf("read %s reg %d val 0x%04x\n", 
+                 (regno & LANCE_ANR_FLAG) ? "anr" : (regno & LANCE_BCR_FLAG) ? "bcr" : "csr", 
+                 regno & LANCE_RAP_MASK, val);
+ #endif
+     return val;
+ }
+ 
+ static __inline__ void
+ put_reg(struct eth_drv_sc *sc, int regno, cyg_uint16 val)
+ {
+     struct lancepci_priv_data *cpd =
+         (struct lancepci_priv_data *)sc->driver_private;
+     cyg_uint16 addr;
+ 
+     if (regno & LANCE_ANR_FLAG) {
+         // We could do this with recursive calls to get/put reg
+         // functions, but might as well just do it directly.
+         // First set ANR address
+         HAL_PCI_IO_WRITE_UINT16(cpd->base+LANCE_IO_RAP, LANCE_BCR_MIIADDR & LANCE_RAP_MASK);
+         HAL_PCI_IO_READ_UINT16(cpd->base+LANCE_IO_BDP, addr);
+         addr &= LANCE_BCR_MIIADDR_PHYAD;
+         addr |= (regno & LANCE_RAP_MASK);
+         HAL_PCI_IO_WRITE_UINT16(cpd->base+LANCE_IO_BDP, addr);
+         // Then write ANR register data
+         HAL_PCI_IO_WRITE_UINT16(cpd->base+LANCE_IO_RAP, LANCE_BCR_MIIDATA & LANCE_RAP_MASK);
+         HAL_PCI_IO_WRITE_UINT16(cpd->base+LANCE_IO_BDP, val);
+     } else {
+         HAL_PCI_IO_WRITE_UINT16(cpd->base+LANCE_IO_RAP, regno & LANCE_RAP_MASK);
+         if (regno & LANCE_BCR_FLAG)
+             HAL_PCI_IO_WRITE_UINT16(cpd->base+LANCE_IO_BDP, val);
+         else
+             HAL_PCI_IO_WRITE_UINT16(cpd->base+LANCE_IO_RDP, val);
+     }
+ 
+ #if DEBUG & 2
+     os_printf("write %s reg %d val 0x%04x\n", 
+                 (regno & LANCE_ANR_FLAG) ? "anr" : (regno & LANCE_BCR_FLAG) ? "bcr" : "csr", 
+                 regno & LANCE_RAP_MASK, val);
+ #endif
+ }
+ 
+ // ------------------------------------------------------------------------
+ #endif // CYGONCE_DEVS_ETH_AMD_LANCE_H
+ // EOF amd_lance.h
diff -C5 -N -P -r -x '.*' /ecoscvs/orig/ecos/packages/devs/eth/amd/lancepci/current/src/if_lancepci.c ./devs/eth/amd/lancepci/current/src/if_lancepci.c
*** /ecoscvs/orig/ecos/packages/devs/eth/amd/lancepci/current/src/if_lancepci.c	1970-01-01 01:00:00.000000000 +0100
--- ./devs/eth/amd/lancepci/current/src/if_lancepci.c	2004-02-27 16:34:32.000000000 +0100
***************
*** 0 ****
--- 1,1323 ----
+ //==========================================================================
+ //
+ //      dev/if_lancepci.c
+ //
+ //      Ethernet device driver for AMD PCI Lance (for instance vmWare VLANCE)
+ //      compatible controllers
+ //
+ //==========================================================================
+ //####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):    jskov, based on lan91cxx driver by hmt & jskov, iz
+ // Contributors: gthomas, jskov, hmt, iz
+ // Date:         2002-07-17, 2003-01-26
+ // Purpose:
+ // Description:  hardware driver for AMD Lance PCI (and possibly PCnet)
+ //               and wmWare VLANCE ethernet
+ // Notes:        The controller is used in its 16bit mode. That means that
+ //               all addresses are 24bit only - and that all controller
+ //               accessed memory must be within the same 16MB region
+ //               (starting at 0 on older controllers).
+ //
+ //               The KEEP_STATISTICS code is not implemented yet. Look
+ //               for FIXME macro.
+ //
+ //####DESCRIPTIONEND####
+ //
+ //==========================================================================
+ //#####VMWAREDESCRIPTIONBEGIN####
+ //
+ // Notes:        The vmWare VLACNCE virtual controller does not seem to do
+ //               anything about SUSPEND  and seems it must be reinitialized after
+ //               every STOP. In addition it lacks some registers.
+ //
+ //		 Sometimes, the driver must wait to let Vmware get a tick, to
+ //		 process the chip initialization and control functions!!!
+ //
+ //		 That's the reason for not patching the PCnet driver
+ //		 but cloning a special one from it.
+ //
+ //
+ //####VMWAREDESCRIPTIONEND####
+ //==========================================================================
+ 
+ #include <pkgconf/system.h>
+ #include <pkgconf/devs_eth_amd_lancepci.h>
+ #include <pkgconf/io_eth_drivers.h>
+ 
+ #include <cyg/infra/cyg_type.h>
+ #include <cyg/hal/hal_arch.h>
+ #include <cyg/hal/hal_intr.h>
+ #include <cyg/infra/cyg_ass.h>
+ #include <cyg/infra/diag.h>
+ #include <cyg/hal/drv_api.h>
+ #include <cyg/hal/hal_if.h>             // delays
+ #include <string.h>
+ #include <cyg/io/eth/netdev.h>
+ #include <cyg/io/eth/eth_drv.h>
+ #ifdef CYGPKG_NET
+ #include <pkgconf/net.h>
+ #include <cyg/kernel/kapi.h>
+ #include <net/if.h>  			// Needed for struct ifnet
+ #include <pkgconf/io_eth_drivers.h>
+ #endif
+ #include CYGHWR_MEMORY_LAYOUT_H
+ 
+ #ifdef CYGPKG_IO_PCI
+ #include <cyg/io/pci.h>
+ #else
+ #error "Need PCI package here"
+ #endif
+ 
+ #define FIXME 0
+ 
+ #define _BUF_SIZE 1544
+ 
+ #ifdef CYGPKG_INFRA_DEBUG
+ // Then we log, OOI, the number of times we get a bad packet number
+ // from the tx done fifo.
+ int lancepci_txfifo_good = 0;
+ int lancepci_txfifo_bad = 0;
+ #endif
+ 
+ #include "amd_lance.h"
+ #define __WANT_DEVS
+ #include CYGDAT_DEVS_ETH_AMD_LANCEPCI_INL
+ #undef  __WANT_DEVS
+ 
+ //#define DEBUG 0xff
+ 
+ #if defined(CYGPKG_REDBOOT)
+ 
+ static void db_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 );
+ }
+ 
+ #else
+ 
+ #define db_printf diag_printf
+ 
+ #endif
+ 
+ 
+ static struct eth_drv_sc *oursc;	//a dummy sc pointer
+ 
+ static void lancepci_poll(struct eth_drv_sc *sc);
+ 
+ 
+ // This ISR is called when the ethernet interrupt occurs
+ static cyg_uint32
+ lancepci_isr(cyg_vector_t vector, cyg_addrword_t data)
+ {
+     struct lancepci_priv_data *cpd = (struct lancepci_priv_data *)data;
+ 
+     DEBUG_FUNCTION();
+ 
+     INCR_STAT( interrupts );
+     cpd->event = get_reg(oursc, LANCE_CSR_CSCR);
+     if (cpd->event & LANCE_CSR_CSCR_TINT)
+         cpd->txbusyh=0;				// take care of HW txbusy flag
+     cyg_drv_interrupt_mask(cpd->interrupt);
+     cyg_drv_interrupt_acknowledge(cpd->interrupt);
+     return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR);  // Run the DSR
+ }
+ 
+ static void
+ lancepci_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+ {
+     // This conditioning out is necessary because of explicit calls to this
+     // DSR - which would not ever be called in the case of a polled mode
+     // usage ie. in RedBoot.
+ #ifdef CYGPKG_IO_ETH_DRIVERS_NET
+     struct lancepci_priv_data* cpd = (struct lancepci_priv_data *)data;
+     struct cyg_netdevtab_entry *ndp = (struct cyg_netdevtab_entry *)(cpd->ndp);
+     struct eth_drv_sc *sc = (struct eth_drv_sc *)(ndp->device_instance);
+ 
+     // but here, it must be a *sc:
+     eth_drv_dsr( vector, count, (cyg_addrword_t)sc );
+ #else
+ # ifndef CYGPKG_REDBOOT
+ #  error Empty lancepci ethernet DSR is compiled.  Is this what you want?
+ # endif
+ #endif
+ }
+ 
+ 
+ // The deliver function (ex-DSR)  handles the ethernet [logical] processing
+ static void
+ lancepci_deliver(struct eth_drv_sc *sc)
+ {
+     struct lancepci_priv_data *cpd =
+         (struct lancepci_priv_data *)sc->driver_private;
+ 
+     DEBUG_FUNCTION();
+ 
+     // Service the interrupt:
+     lancepci_poll(sc);
+     // Allow interrupts to happen again
+     cyg_drv_interrupt_unmask(cpd->interrupt);
+ }
+ 
+ static int
+ lancepci_int_vector(struct eth_drv_sc *sc)
+ {
+     struct lancepci_priv_data *cpd =
+         (struct lancepci_priv_data *)sc->driver_private;
+ 
+     return (cpd->interrupt);
+ }
+ 
+ // ------------------------------------------------------------------------
+ // Memory management
+ //
+ // Simply carve off from the front of the PCI mapped window into real memory
+ static cyg_uint32 lancepci_heap_size;
+ static cyg_uint8 *lancepci_heap_base;
+ static cyg_uint8 *lancepci_heap_free;
+ 
+ static void*
+ pciwindow_mem_alloc(int size)
+ {
+     void *p_memory;
+     int _size = size;
+ 
+     CYG_ASSERT(
+         (CYGHWR_AMD_LANCEPCI_PCI_MEM_MAP_BASE <= (int)lancepci_heap_free)
+         &&
+         ((CYGHWR_AMD_LANCEPCI_PCI_MEM_MAP_BASE +
+           CYGHWR_AMD_LANCEPCI_PCI_MEM_MAP_SIZE) > (int)lancepci_heap_free)
+         &&
+         (0 < lancepci_heap_size)
+         &&
+         (CYGHWR_AMD_LANCEPCI_PCI_MEM_MAP_SIZE >= lancepci_heap_size)
+         &&
+         (CYGHWR_AMD_LANCEPCI_PCI_MEM_MAP_BASE == (int)lancepci_heap_base),
+         "Heap variables corrupted" );
+ 
+     p_memory = (void *)0;
+     size = (size + 3) & ~3;
+     if ( (lancepci_heap_free+size) < (lancepci_heap_base+lancepci_heap_size) ) {
+         cyg_uint32 *p;
+         p_memory = (void *)lancepci_heap_free;
+         lancepci_heap_free += size;
+         for ( p = (cyg_uint32 *)p_memory; _size > 0; _size -= 4 )
+             *p++ = 0;
+     }
+ 
+ #if DEBUG & 9
+     db_printf("Allocated %d bytes at 0x%08x\n", size, p_memory);
+ #endif
+ 
+     return p_memory;
+ }
+ 
+ static cyg_pci_match_func find_lancepci_match_func;
+ 
+ static cyg_bool
+ find_lancepci_match_func( cyg_uint16 v, cyg_uint16 d, cyg_uint32 c, void *p )
+ {
+ #if DEBUG & 9
+     db_printf("PCI match vendor 0x%04x device 0x%04x\n", v, d);
+ #endif
+     return (0x1022 == v) && (0x2000 == d);
+ }
+ 
+ static int
+ pci_init_find_lancepci( void )
+ {
+     cyg_pci_device_id devid;
+     cyg_pci_device dev_info;
+     cyg_uint16 cmd;
+     int device_index;
+     int found_devices = 0;
+ 
+     DEBUG_FUNCTION();
+ 
+ #ifdef CYGARC_UNCACHED_ADDRESS
+     CYG_ASSERT( CYGARC_UNCACHED_ADDRESS((CYG_ADDRWORD)CYGMEM_SECTION_pci_window) ==
+                 CYGHWR_AMD_LANCEPCI_PCI_MEM_MAP_BASE,
+       "PCI window configured does not match PCI memory section base" );
+ #else
+     CYG_ASSERT( (CYG_ADDRWORD)CYGMEM_SECTION_pci_window ==
+                 CYGHWR_AMD_LANCEPCI_PCI_MEM_MAP_BASE,
+       "PCI window configured does not match PCI memory section base" );
+ #endif
+     CYG_ASSERT( CYGMEM_SECTION_pci_window_SIZE ==
+                 CYGHWR_AMD_LANCEPCI_PCI_MEM_MAP_SIZE,
+         "PCI window configured does not match PCI memory section size" );
+ 
+     if (
+ #ifdef CYGARC_UNCACHED_ADDRESS
+          CYGARC_UNCACHED_ADDRESS((CYG_ADDRWORD)CYGMEM_SECTION_pci_window) !=
+ #else
+          (CYG_ADDRWORD)CYGMEM_SECTION_pci_window !=
+ #endif
+          CYGHWR_AMD_LANCEPCI_PCI_MEM_MAP_BASE
+          ||
+          CYGMEM_SECTION_pci_window_SIZE !=
+          CYGHWR_AMD_LANCEPCI_PCI_MEM_MAP_SIZE ) {
+ #if DEBUG & 8
+         db_printf("pci_init_find_lancepci(): PCI window misconfigured\n");
+ #endif
+         return 0;
+     }
+ 
+     // First initialize the heap in PCI window'd memory
+     lancepci_heap_size = CYGHWR_AMD_LANCEPCI_PCI_MEM_MAP_SIZE;
+     lancepci_heap_base = (cyg_uint8 *)CYGHWR_AMD_LANCEPCI_PCI_MEM_MAP_BASE;
+     lancepci_heap_free = lancepci_heap_base;
+ #if DEBUG & 9
+     db_printf("pcimem : 0x%08x size: 0x%08x\n", lancepci_heap_base, lancepci_heap_size);
+ #endif
+ 
+     cyg_pci_init();
+ #if DEBUG & 8
+     db_printf("Finished cyg_pci_init();\n");
+ #endif
+ 
+     devid = CYG_PCI_NULL_DEVID;
+ 
+     for (device_index = 0;
+          device_index < CYGNUM_DEVS_ETH_AMD_LANCEPCI_DEV_COUNT;
+          device_index++) {
+         struct lancepci_priv_data* cpd = lancepci_priv_array[device_index];
+ 
+         cpd->index = device_index;
+ 
+         // See above for find_lancepci_match_func - it selects any of several
+         // variants.  This is necessary in case we have multiple mixed-type
+         // devices on one board in arbitrary orders.
+         if (cyg_pci_find_matching( &find_lancepci_match_func, NULL, &devid )) {
+ #if DEBUG & 8
+             db_printf("eth%d = lancepci\n", device_index);
+ #endif
+             cyg_pci_get_device_info(devid, &dev_info);
+ 
+             cpd->interrupt_handle = 0; // Flag not attached.
+             if (cyg_pci_translate_interrupt(&dev_info, &cpd->interrupt)) {
+ #if DEBUG & 8
+                 db_printf(" Wired to HAL vector %d\n", cpd->interrupt);
+ #endif
+                 cyg_drv_interrupt_create(
+                     cpd->interrupt,
+                     1,                  // Priority - unused
+                     (cyg_addrword_t)cpd,// Data item passed to ISR & DSR
+                     lancepci_isr,          // ISR
+                     lancepci_dsr,          // DSR
+                     &cpd->interrupt_handle, // handle to intr obj
+                     &cpd->interrupt_object ); // space for int obj
+ 
+                 cyg_drv_interrupt_attach(cpd->interrupt_handle);
+ 
+                 // Don't unmask the interrupt yet, that could get us into a
+                 // race.
+             }
+             else {
+                 cpd->interrupt = 0;
+ #if DEBUG & 8
+                 db_printf(" Does not generate interrupts.\n");
+ #endif
+             }
+ 
+             if (cyg_pci_configure_device(&dev_info)) {
+ #if DEBUG & 8
+                 int i;
+                 db_printf("Found device on bus %d, devfn 0x%02x:\n",
+                           CYG_PCI_DEV_GET_BUS(devid),
+                           CYG_PCI_DEV_GET_DEVFN(devid));
+ 
+                 if (dev_info.command & CYG_PCI_CFG_COMMAND_ACTIVE) {
+                     db_printf(" Note that board is active. Probed"
+                               " sizes and CPU addresses invalid!\n");
+                 }
+                 db_printf(" Vendor    0x%04x", dev_info.vendor);
+                 db_printf("\n Device    0x%04x", dev_info.device);
+                 db_printf("\n Command   0x%04x, Status 0x%04x\n",
+                           dev_info.command, dev_info.status);
+ 
+                 db_printf(" Class/Rev 0x%08x", dev_info.class_rev);
+                 db_printf("\n Header 0x%02x\n", dev_info.header_type);
+ 
+                 db_printf(" SubVendor 0x%04x, Sub ID 0x%04x\n",
+                           dev_info.header.normal.sub_vendor,
+                           dev_info.header.normal.sub_id);
+ 
+                 for(i = 0; i < CYG_PCI_MAX_BAR; i++) {
+                     db_printf(" BAR[%d]    0x%08x /", i, dev_info.base_address[i]);
+                     db_printf(" probed size 0x%08x / CPU addr 0x%08x\n",
+                               dev_info.base_size[i], dev_info.base_map[i]);
+                 }
+                 db_printf(" eth%d configured\n", device_index);
+ #endif
+                 found_devices++;
+                 cpd->found = 1;
+                 cpd->active = 0;
+                 cpd->devid = devid;
+                 cpd->base = (unsigned char*) dev_info.base_map[0];
+ #if DEBUG & 8
+                 db_printf(" I/O address = 0x%08x\n", cpd->base);
+ #endif
+ 
+                 // Don't use cyg_pci_set_device_info since it clears
+                 // some of the fields we want to print out below.
+                 cyg_pci_read_config_uint16(dev_info.devid,
+                                            CYG_PCI_CFG_COMMAND, &cmd);
+                 cmd |= (CYG_PCI_CFG_COMMAND_IO         // enable I/O space
+                         | CYG_PCI_CFG_COMMAND_MEMORY   // enable memory space
+                         | CYG_PCI_CFG_COMMAND_MASTER); // enable bus master
+                 cyg_pci_write_config_uint16(dev_info.devid,
+                                             CYG_PCI_CFG_COMMAND, cmd);
+ 
+                 // This is the indicator for "uses an interrupt"
+                 if (cpd->interrupt_handle != 0) {
+                     cyg_drv_interrupt_acknowledge(cpd->interrupt);
+                     cyg_drv_interrupt_unmask(cpd->interrupt);
+ #if DEBUG & 8
+                     db_printf(" Enabled interrupt %d\n", cpd->interrupt);
+ #endif
+                 }
+ #if DEBUG & 8
+                 db_printf(" **** Device enabled for I/O and Memory "
+                             "and Bus Master\n");
+ #endif
+             }
+             else {
+                 cpd->found = 0;
+                 cpd->active = 0;
+ #if DEBUG & 8
+                 db_printf("Failed to configure device %d\n", device_index);
+ #endif
+             }
+         }
+         else {
+             cpd->found = 0;
+             cpd->active = 0;
+ #if DEBUG & 8
+             db_printf("eth%d not found\n", device_index);
+ #endif
+         }
+     }
+ 
+     if (0 == found_devices)
+         return 0;
+ 
+     return 1;
+ }
+ 
+ 
+ static bool
+ amd_lancepci_init(struct cyg_netdevtab_entry *tab)
+ {
+     static int initialized = 0; // only probe PCI et al *once*
+     struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
+     struct lancepci_priv_data *cpd =
+         (struct lancepci_priv_data *)sc->driver_private;
+     cyg_uint16 val;
+     cyg_uint32 b;
+     cyg_uint8* p;
+     cyg_uint8* d;
+     int i;
+ 
+     DEBUG_FUNCTION();
+ 
+     if ( 0 == initialized++ ) {
+         // then this is the first time ever:
+         if ( ! pci_init_find_lancepci() ) {
+ #if DEBUG & 8
+             db_printf( "pci_init_find_lancepci failed" );
+ #endif
+             return false;
+         }
+     }
+ 
+     // If this device is not present, exit
+     if (0 == cpd->found)
+         return 0;
+ 
+ #if DEBUG & 8
+     db_printf("lancepci at base 0x%08x, EEPROM key 0x%04x\n",
+                 cpd->base, _SU16(cpd->base, LANCE_IO_ID));
+ #endif
+ 
+ #if 0
+     // FIXME: Doesn't work with non-conforming EEPROMS
+     if (LANCE_IO_ID_KEY != _SU16(cpd->base, LANCE_IO_ID) ) {
+         db_printf("Lance EPROM key not found\n");
+         return false;
+     }
+ #endif
+ 
+ #if DEBUG & 9
+     db_printf("pcimem : %08x size: %08x\n", lancepci_heap_base, lancepci_heap_size);
+ #endif
+ 
+     // Prepare ESA
+     if (!cpd->hardwired_esa) {
+         // Don't use the address from the EEPROM for VMware
+         // Use the address that VMware prepares in CSR_PAR registers
+         // if You want to be able to use NAT networking. (iz@elsis.si Feb 27 04)
+         //
+         // p = cpd->base + LANCE_IO_EEPROM;
+         // for (i = 0; i < 6; i++)
+         // cpd->esa[i] = *p++;
+         put_reg(sc, LANCE_CSR_CSCR, LANCE_CSR_CSCR_STOP);
+         for (i = 0;  i < sizeof(cpd->esa);  i += 2) {
+             cyg_uint16 z = get_reg(sc, LANCE_CSR_PAR0+i/2 );
+             cpd->esa[i] =   (cyg_uint8)(0xff & z);
+             cpd->esa[i+1] = (cyg_uint8)(0xff & (z >> 8));
+       }
+ 
+     }
+ #if DEBUG & 9
+     db_printf("Lance - %s ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+                 (cpd->hardwired_esa) ? "static" : "eeprom",
+                 cpd->esa[0], cpd->esa[1], cpd->esa[2],
+                 cpd->esa[3], cpd->esa[4], cpd->esa[5] );
+ #endif
+ 
+ 
+     // Prepare RX and TX rings
+     p = cpd->rx_ring = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc((1<<cpd->rx_ring_log_cnt)*LANCE_RD_SIZE));
+     memset(cpd->rx_ring,0,(1<<cpd->rx_ring_log_cnt)*LANCE_RD_SIZE);
+ 
+     d = cpd->rx_buffers = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc(_BUF_SIZE*cpd->rx_ring_cnt));
+     memset(cpd->rx_buffers,0,_BUF_SIZE*cpd->rx_ring_cnt);
+ 
+     for (i = 0; i < cpd->rx_ring_cnt; i++) {
+         HAL_PCI_CPU_TO_BUS(d, b);
+         _SU32(p, LANCE_RD_PTR) = (b & LANCE_RD_PTR_MASK) | LANCE_RD_PTR_OWN;
+         _SU16(p, LANCE_RD_BLEN) = (-_BUF_SIZE);
+         p += LANCE_RD_SIZE;
+         d += _BUF_SIZE;
+     }
+     cpd->rx_ring_next = 0;
+ 
+     p = cpd->tx_ring = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc((1<<cpd->tx_ring_log_cnt)*LANCE_TD_SIZE));
+     memset(cpd->tx_ring,0,(1<<cpd->tx_ring_log_cnt)*LANCE_TD_SIZE);
+ 
+     d = cpd->tx_buffers = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc(_BUF_SIZE*cpd->tx_ring_cnt));
+     for (i = 0; i < cpd->tx_ring_cnt; i++) {
+         HAL_PCI_CPU_TO_BUS(d, b);
+         _SU32(p, LANCE_RD_PTR) = b & LANCE_TD_PTR_MASK;
+         p += LANCE_TD_SIZE;
+         d += _BUF_SIZE;
+     }
+     cpd->tx_ring_free = cpd->tx_ring_alloc = cpd->tx_ring_owned = 0;
+ 
+     // Initialization table
+     cpd->init_table = (cyg_uint8*)CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc(LANCE_IB_SIZE));
+     _SU16(cpd->init_table, LANCE_IB_MODE) = 0x0000;
+     for (i = 0; i < 6; i++)
+         _SU8(cpd->init_table, LANCE_IB_PADR0+i) = cpd->esa[i];
+     for (i = 0; i < 8; i++)
+         _SU8(cpd->init_table, LANCE_IB_LADRF0+i) = 0;
+ 
+     HAL_PCI_CPU_TO_BUS(cpd->rx_ring, b);
+     _SU32(cpd->init_table, LANCE_IB_RDRA) = ((b & LANCE_IB_RDRA_PTR_mask)
+                                         | (cpd->rx_ring_log_cnt << LANCE_IB_RDRA_CNT_shift));
+     HAL_PCI_CPU_TO_BUS(cpd->tx_ring, b);
+     _SU32(cpd->init_table, LANCE_IB_TDRA) = ((b & LANCE_IB_TDRA_PTR_mask)
+                                         | (cpd->tx_ring_log_cnt << LANCE_IB_TDRA_CNT_shift));
+ 
+ #if DEBUG & 9
+     db_printf("Loading up lance controller from table at 0x%08x\n", cpd->init_table);
+     db_printf(" Mode 0x%04x\n", _SU16(cpd->init_table, LANCE_IB_MODE));
+     db_printf(" PADR %02x:%02x:%02x:%02x:%02x:%02x ",
+                 _SU8(cpd->init_table, LANCE_IB_PADR0+0), _SU8(cpd->init_table, LANCE_IB_PADR0+1),
+                 _SU8(cpd->init_table, LANCE_IB_PADR0+2), _SU8(cpd->init_table, LANCE_IB_PADR0+3),
+                 _SU8(cpd->init_table, LANCE_IB_PADR0+4), _SU8(cpd->init_table, LANCE_IB_PADR0+5));
+     db_printf("LADR %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+                 _SU8(cpd->init_table, LANCE_IB_LADRF0+0), _SU8(cpd->init_table, LANCE_IB_LADRF0+1),
+                 _SU8(cpd->init_table, LANCE_IB_LADRF0+2), _SU8(cpd->init_table, LANCE_IB_LADRF0+3),
+                 _SU8(cpd->init_table, LANCE_IB_LADRF0+4), _SU8(cpd->init_table, LANCE_IB_LADRF0+5),
+                 _SU8(cpd->init_table, LANCE_IB_LADRF0+5), _SU8(cpd->init_table, LANCE_IB_LADRF0+7));
+     db_printf(" RX 0x%08x (len %d) TX 0x%08x (len %d)\n",
+                 _SU32(cpd->init_table, LANCE_IB_RDRA) & 0x1fffffff,
+                 (_SU32(cpd->init_table, LANCE_IB_RDRA) >> LANCE_IB_RDRA_CNT_shift) & 7,
+                 _SU32(cpd->init_table, LANCE_IB_TDRA) & 0x1fffffff,
+                 (_SU32(cpd->init_table, LANCE_IB_TDRA) >> LANCE_IB_TDRA_CNT_shift) & 7);
+ #endif
+ 
+     // Reset chip
+     HAL_PCI_IO_READ_UINT16(cpd->base+LANCE_IO_RESET, val);
+ 
+     // Load up chip with buffers.
+     // Note: There is a 16M limit on the addresses used by the driver
+     // since the top 8 bits of the init_table address is appended to
+     // all other addresses used by the controller.
+     HAL_PCI_CPU_TO_BUS(cpd->init_table, b);
+     put_reg(sc, LANCE_CSR_IBA0, (b >>  0) & 0xffff);
+     put_reg(sc, LANCE_CSR_IBA1, (b >> 16) & 0xffff);
+     // Disable automatic TX polling (_send will force a poll), pad
+     // XT frames to legal length, mask status interrupts.
+     put_reg(sc, LANCE_CSR_TFC, (LANCE_CSR_TFC_TXDPOLL | LANCE_CSR_TFC_APAD_XMT
+                                 | LANCE_CSR_TFC_MFCOM | LANCE_CSR_TFC_RCVCCOM
+                                 | LANCE_CSR_TFC_TXSTRTM));
+     // Recover after TX FIFO underflow
+     put_reg(sc, LANCE_CSR_IM, LANCE_CSR_IM_DXSUFLO);
+     // Initialize controller - load up init_table
+     put_reg(sc, LANCE_CSR_CSCR, LANCE_CSR_CSCR_INIT);
+     while (0 == (get_reg(sc, LANCE_CSR_CSCR) & LANCE_CSR_CSCR_IDON));
+ 
+     // Stop controller
+     put_reg(sc, LANCE_CSR_CSCR, LANCE_CSR_CSCR_STOP);
+ 
+ #if DEBUG & 9
+     db_printf("lancepci controller state is now:\n");
+     db_printf(" Mode 0x%04x  TFC 0x%04x\n", _SU16(cpd->init_table, LANCE_IB_MODE), get_reg(sc, LANCE_CSR_TFC));
+     db_printf(" PADR %04x:%04x:%04x ",
+                 get_reg(sc, LANCE_CSR_PAR0),
+                 get_reg(sc, LANCE_CSR_PAR1),
+                 get_reg(sc, LANCE_CSR_PAR2));
+     db_printf("LADR %04x:%04x:%04x:%04x\n",
+                 get_reg(sc, LANCE_CSR_LAR0),
+                 get_reg(sc, LANCE_CSR_LAR1),
+                 get_reg(sc, LANCE_CSR_LAR2),
+                 get_reg(sc, LANCE_CSR_LAR3));
+     db_printf(" RX 0x%04x%04x (len 0x%04x) TX 0x%04x%04x (len 0x%04x)\n",
+                 get_reg(sc, LANCE_CSR_BARRU), get_reg(sc, LANCE_CSR_BARRL),
+                 get_reg(sc, LANCE_CSR_RRLEN),
+                 get_reg(sc, LANCE_CSR_BATRU), get_reg(sc, LANCE_CSR_BATRL),
+                 get_reg(sc, LANCE_CSR_TRLEN));
+ 
+     val = get_reg(sc, LANCE_CSR_ID_LO);
+     db_printf("lancepci ID 0x%04x (%s) ",
+                 val,
+                 (0x5003 == val) ? "Am79C973" : (0x7003 == val) ? "Am79C975" :
+ 		        (0x1003 == val) ? "Am79C900 or wmWare VLANCE" : "Unknown");
+     val = get_reg(sc, LANCE_CSR_ID_HI);
+     db_printf("Part IDU 0x%03x Silicon rev %d\n",
+                 val & 0x0fff, (val >> 12) & 0xf);
+ #endif
+     // and record the net dev pointer
+     cpd->ndp = (void *)tab;
+     cpd->active = 0;
+     oursc=sc;
+ 
+     // Initialize upper level driver
+     (sc->funs->eth_drv->init)(sc, cpd->esa);
+     cpd->txbusyh=cpd->txbusy=0;
+     cpd->event=0;
+     db_printf("Lancepci driver loaded and Init Done\n");
+     return true;
+ }
+ 
+ static void
+ lancepci_stop(struct eth_drv_sc *sc)
+ {
+     cyg_uint32 b;
+     struct lancepci_priv_data *cpd =
+         (struct lancepci_priv_data *)sc->driver_private;
+ 
+     DEBUG_FUNCTION();
+     if (!cpd->active)
+         return;
+     if (cpd->txbusyh) {
+ #if DEBUG & 9
+         db_printf("Lancepci-stop:waiting for tx empty\n");
+ #endif
+         b=100;
+         while (cpd->txbusyh && b) {
+ 	    CYGACC_CALL_IF_DELAY_US(200);
+ 	    b--;
+ 	 }
+     }
+     put_reg(sc, LANCE_CSR_CSCR, LANCE_CSR_CSCR_STOP);
+     cpd->active = 0;
+ #if DEBUG & 9
+     db_printf("Lancepci-stop:done\n");
+ #endif
+ }
+ 
+ //
+ // This function is called to "start up" the interface.  It may be called
+ // multiple times, even when the hardware is already running.  It will be
+ // called whenever something "hardware oriented" changes and should leave
+ // the hardware ready to send/receive packets.
+ //
+ static void
+ lancepci_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
+ {
+     cyg_uint16 reg;
+     cyg_uint32 b;
+     struct lancepci_priv_data *cpd =
+         (struct lancepci_priv_data *)sc->driver_private;
+ #ifdef CYGPKG_NET
+     struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+ #endif
+     DEBUG_FUNCTION();
+ 
+     // If device is already active, stop it
+ #if DEBUG & 9
+ 	db_printf("Lancepci-start:entered\n");
+ #endif
+     if (cpd->active)
+      {
+         if (cpd->txbusyh) {
+ #if DEBUG & 9
+ 	    db_printf("Lancepci-start:waiting for tx empty\n");
+ #endif
+ 	    b=100;
+      	    while (cpd->txbusyh && b) {
+ 	        CYGACC_CALL_IF_DELAY_US(200);
+ 		b--;
+ 	    }
+ 	}
+     	put_reg(sc, LANCE_CSR_CSCR, LANCE_CSR_CSCR_STOP);
+     	cpd->active = 0;
+ #if DEBUG & 9
+     	db_printf("Lancepci-start:stopped\n");
+ #endif
+     }
+     CYGACC_CALL_IF_DELAY_US(200);
+ 
+ #ifdef CYGPKG_NET
+     if (( 0
+ #ifdef ETH_DRV_FLAGS_PROMISC_MODE
+          != (flags & ETH_DRV_FLAGS_PROMISC_MODE)
+ #endif
+         ) || (ifp->if_flags & IFF_PROMISC)
+         ) {
+         // Then we select promiscuous mode.
+     	_SU16(cpd->init_table, LANCE_IB_MODE) = 0x0000|LANCE_CSR_MODE_PROM;
+ #if DEBUG & 9
+ 	db_printf("Promisc MODE!");
+ #endif
+     }
+     else _SU16(cpd->init_table, LANCE_IB_MODE) = 0x0000;
+ #endif
+     cpd->rx_ring_next = 0;
+     cpd->tx_ring_free = cpd->tx_ring_alloc = cpd->tx_ring_owned = 0;
+     // Init the chip again
+     HAL_PCI_CPU_TO_BUS(cpd->init_table, b);
+     put_reg(sc, LANCE_CSR_IBA0, (b >>  0) & 0xffff);
+     put_reg(sc, LANCE_CSR_IBA1, (b >> 16) & 0xffff);
+     // Disable automatic TX polling (_send will force a poll), pad
+     // XT frames to legal length, mask status interrupts.
+     put_reg(sc, LANCE_CSR_TFC, (LANCE_CSR_TFC_TXDPOLL | LANCE_CSR_TFC_APAD_XMT
+                                 | LANCE_CSR_TFC_MFCOM | LANCE_CSR_TFC_RCVCCOM
+                                 | LANCE_CSR_TFC_TXSTRTM));
+     // Recover after TX FIFO underflow
+     put_reg(sc, LANCE_CSR_IM, LANCE_CSR_IM_DXSUFLO);
+     // Initialize controller - load up init_table
+     put_reg(sc, LANCE_CSR_CSCR, LANCE_CSR_CSCR_INIT);
+     while (0 == (get_reg(sc, LANCE_CSR_CSCR) & LANCE_CSR_CSCR_IDON));
+ 	reg=get_reg(sc,LANCE_CSR_CSCR);
+     put_reg(sc, LANCE_CSR_CSCR, (reg|(LANCE_CSR_CSCR_IENA | LANCE_CSR_CSCR_STRT))&~LANCE_CSR_CSCR_INIT);
+ #if DEBUG & 9
+ 	reg=get_reg(sc,LANCE_CSR_CSCR);
+ 	db_printf("CSR after start = %4x\n",reg);
+ #endif
+     cpd->active = 1; cpd->txbusy=0; cpd->txbusyh=0;
+     // delay is necessary for Vmware to get a tick !!!
+     CYGACC_CALL_IF_DELAY_US(50000);
+ }
+ 
+ //
+ // This routine is called to perform special "control" opertions
+ //
+ static int
+ lancepci_control(struct eth_drv_sc *sc, unsigned long key,
+                void *data, int data_length)
+ {
+     cyg_uint8 *esa = (cyg_uint8 *)data;
+     int i, res;
+     cyg_uint16 reg;
+     struct lancepci_priv_data *cpd =
+         (struct lancepci_priv_data *)sc->driver_private;
+ 
+     DEBUG_FUNCTION();
+ 
+ #if DEBUG & 9
+ 	db_printf("Lancepci-control:entered\n");
+ #endif
+     res = 0;                            // expect success
+     switch (key) {
+         case ETH_DRV_SET_MAC_ADDRESS:
+ #if 9 & DEBUG
+             db_printf("PCNET - set ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+                 esa[0], esa[1], esa[2], esa[3], esa[4], esa[5] );
+ #endif // DEBUG
+             for ( i = 0; i < sizeof(cpd->esa);  i++ )
+                 cpd->esa[i] = esa[i];
+             for (i = 0;  i < sizeof(cpd->esa);  i += 2) {
+                 reg = cpd->esa[i] | (cpd->esa[i+1] << 8);
+                 put_reg(sc, LANCE_CSR_PAR0+i/2, reg );
+             }
+             for (i = 0; i < 6; i++)	// in case of later restart
+                 _SU8(cpd->init_table, LANCE_IB_PADR0+i) = cpd->esa[i];
+             break;
+ #ifdef ETH_DRV_GET_MAC_ADDRESS
+         case ETH_DRV_GET_MAC_ADDRESS:
+             // Extract the MAC address that is in the chip, and tell the
+             // system about it.
+             for (i = 0;  i < sizeof(cpd->esa);  i += 2) {
+                 cyg_uint16 z = get_reg(sc, LANCE_CSR_PAR0+i/2 );
+                 esa[i] =   (cyg_uint8)(0xff & z);
+                 esa[i+1] = (cyg_uint8)(0xff & (z >> 8));
+             }
+             break;
+ #endif
+ #ifdef ETH_DRV_GET_IF_STATS_UD
+         case ETH_DRV_GET_IF_STATS_UD: // UD == UPDATE
+ #endif
+         // drop through
+ #ifdef ETH_DRV_GET_IF_STATS
+         case ETH_DRV_GET_IF_STATS:
+ #endif
+ 
+ #if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
+         {
+             struct ether_drv_stats *p = (struct ether_drv_stats *)data;
+             // Chipset entry is no longer supported; RFC1573.
+             for ( i = 0; i < SNMP_CHIPSET_LEN; i++ )
+                 p->snmp_chipset[i] = 0;
+ 
+             // This perhaps should be a config opt, so you can make up your own
+             // description, or supply it from the instantiation.
+             strcpy( p->description, "AMD LancePCI" );
+             // CYG_ASSERT( 48 > strlen(p->description), "Description too long" );
+ 
+             p->operational = 3;         // LINK UP
+             p->duplex = 2;              // 2 = SIMPLEX
+             p->speed = 10 * 1000000;
+ 
+ #if FIXME
+ #ifdef KEEP_STATISTICS
+             {
+                 struct amd_lancepci_stats *ps = &(cpd->stats);
+ 
+                 // Admit to it...
+                 p->supports_dot3        = true;
+ 
+                 p->tx_good              = ps->tx_good             ;
+                 p->tx_max_collisions    = ps->tx_max_collisions   ;
+                 p->tx_late_collisions   = ps->tx_late_collisions  ;
+                 p->tx_underrun          = ps->tx_underrun         ;
+                 p->tx_carrier_loss      = ps->tx_carrier_loss     ;
+                 p->tx_deferred          = ps->tx_deferred         ;
+                 p->tx_sqetesterrors     = ps->tx_sqetesterrors    ;
+                 p->tx_single_collisions = ps->tx_single_collisions;
+                 p->tx_mult_collisions   = ps->tx_mult_collisions  ;
+                 p->tx_total_collisions  = ps->tx_total_collisions ;
+                 p->rx_good              = ps->rx_good             ;
+                 p->rx_crc_errors        = ps->rx_crc_errors       ;
+                 p->rx_align_errors      = ps->rx_align_errors     ;
+                 p->rx_resource_errors   = ps->rx_resource_errors  ;
+                 p->rx_overrun_errors    = ps->rx_overrun_errors   ;
+                 p->rx_collisions        = ps->rx_collisions       ;
+                 p->rx_short_frames      = ps->rx_short_frames     ;
+                 p->rx_too_long_frames   = ps->rx_too_long_frames  ;
+                 p->rx_symbol_errors     = ps->rx_symbol_errors    ;
+ 
+                 p->interrupts           = ps->interrupts          ;
+                 p->rx_count             = ps->rx_count            ;
+                 p->rx_deliver           = ps->rx_deliver          ;
+                 p->rx_resource          = ps->rx_resource         ;
+                 p->rx_restart           = ps->rx_restart          ;
+                 p->tx_count             = ps->tx_count            ;
+                 p->tx_complete          = ps->tx_complete         ;
+                 p->tx_dropped           = ps->tx_dropped          ;
+             }
+ #endif // KEEP_STATISTICS
+ #endif // FIXME
+ 
+             p->tx_queue_len = 1;
+             break;
+         }
+ #endif
+         default:
+             res = 1;
+             break;
+     }
+ #if DEBUG & 9
+     db_printf("Lancepci-control:done\n");
+ #endif
+     CYGACC_CALL_IF_DELAY_US(50000);	// let VMware get a tick
+     return res;
+ }
+ 
+ //
+ // This routine is called to see if it is possible to send another packet.
+ // It will return non-zero if a transmit is possible, zero otherwise.
+ //
+ static int
+ lancepci_can_send(struct eth_drv_sc *sc)
+ {
+     struct lancepci_priv_data *cpd =
+         (struct lancepci_priv_data *)sc->driver_private;
+ 
+     DEBUG_FUNCTION();
+ 
+     return (0 == cpd->txbusy);
+ }
+ 
+ //
+ // This routine is called to send data to the hardware.
+ static void
+ lancepci_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
+             int total_len, unsigned long key)
+ {
+     struct lancepci_priv_data *cpd =
+         (struct lancepci_priv_data *)sc->driver_private;
+     int i, len, plen, ring_entry;
+ 
+     cyg_uint8* sdata = NULL;
+     cyg_uint8 *d, *buf, *txd;
+     cyg_uint16 ints;
+     cyg_uint32 b;
+ 
+     DEBUG_FUNCTION();
+ 
+     INCR_STAT( tx_count );
+ 
+     cpd->txbusy = 1; cpd->txbusyh=1;
+     cpd->txkey = key;
+ 
+     // Find packet length
+     plen = 0;
+     for (i = 0;  i < sg_len;  i++)
+         plen += sg_list[i].len;
+ 
+     CYG_ASSERT( plen == total_len, "sg data length mismatch" );
+ 
+     // Get next TX descriptor
+     ring_entry = cpd->tx_ring_free;
+     do {
+         if (cpd->tx_ring_owned == cpd->tx_ring_cnt) {
+             // Is this a dead end? Probably is.
+ #if DEBUG & 1
+             db_printf("%s: Allocation failed! Retrying...\n", __FUNCTION__ );
+ #endif
+             continue;
+         }
+ 
+         cpd->tx_ring_free++;
+         cpd->tx_ring_owned++;
+         if (cpd->tx_ring_free == cpd->tx_ring_cnt)
+             cpd->tx_ring_free = 0;
+     } while (0);
+ 
+     txd = cpd->tx_ring + ring_entry*LANCE_TD_SIZE;
+     buf = cpd->tx_buffers + ring_entry*_BUF_SIZE;
+     CYG_ASSERT(0 == (_SU32(txd, LANCE_TD_PTR) & LANCE_TD_PTR_OWN),
+                "TX descriptor not free");
+ 
+ #if DEBUG & 4
+     db_printf("#####Tx descriptor 0x%08x buffer 0x%08x\n",
+                 txd, buf);
+ #endif
+ 
+     // Put data into buffer
+     d = buf;
+     for (i = 0;  i < sg_len;  i++) {
+         sdata = (cyg_uint8 *)sg_list[i].buf;
+         len = sg_list[i].len;
+ 
+         CYG_ASSERT( sdata, "No sg data pointer here" );
+         while(len--)
+             *d++ = *sdata++;
+     }
+     CYG_ASSERT( sdata, "No sg data pointer outside" );
+ 
+ #if DEBUG & 1
+     db_printf("CSCR %04x\n", get_reg(sc, LANCE_CSR_CSCR));
+ #endif
+     _SU16(txd, LANCE_TD_LEN) = (-plen);
+     _SU16(txd, LANCE_TD_MISC) = 0;
+     HAL_PCI_CPU_TO_BUS(buf, b);
+     _SU32(txd, LANCE_TD_PTR) = ((b & LANCE_TD_PTR_MASK)
+                                 | LANCE_TD_PTR_OWN | LANCE_TD_PTR_STP | LANCE_TD_PTR_ENP);
+ 
+ #if DEBUG & 1
+     db_printf("Last TX: LEN %04x MISC %04x PTR %08x\n",
+                 _SU16(txd, LANCE_TD_LEN),
+                 _SU16(txd, LANCE_TD_MISC),
+                 _SU32(txd, LANCE_TD_PTR));
+ #endif
+ 
+     // This delay seems to be necessary on some platforms
+     // (Malta 5kc for example).
+     // Why it is needed is not clear, but removing it or
+     // reducing it cause transmission failures in RedBoot (at least).
+     CYGACC_CALL_IF_DELAY_US(100);
+ 
+ 
+     // Set transmit demand
+     ints = get_reg(sc, LANCE_CSR_CSCR);
+     ints &= LANCE_CSR_CSCR_EV_MASK;
+     ints |= LANCE_CSR_CSCR_TDMD;
+     put_reg(sc, LANCE_CSR_CSCR, ints);
+ 
+ #if DEBUG & 1
+     ints = get_reg(sc, LANCE_CSR_CSCR);
+     db_printf("%s:END: ints at TX: 0x%04x\n", __FUNCTION__, ints);
+ #endif
+ 
+     // This is another mystery delay like the one above. This one is
+     // even stranger, since waiting here at the _end_ of the function
+     // should have no effect.
+     CYGACC_CALL_IF_DELAY_US(200);
+ }
+ 
+ static void
+ lancepci_TxEvent(struct eth_drv_sc *sc, int stat)
+ {
+      struct lancepci_priv_data *cpd =
+         (struct lancepci_priv_data *)sc->driver_private;
+     int success = 1;
+     cyg_uint8 *txd;
+     cyg_uint16 ints;
+     cyg_uint32 pkt_stat;
+ 
+     DEBUG_FUNCTION();
+ 
+     if (0 == cpd->tx_ring_owned) {
+ #if DEBUG & 1
+         db_printf("%s: got TX completion when no outstanding packets\n", __FUNCTION__);
+ #endif
+         return;
+     }
+ 
+     INCR_STAT( tx_complete );
+ 
+     txd = cpd->tx_ring + cpd->tx_ring_alloc*LANCE_TD_SIZE;
+     pkt_stat = _SU32(txd, LANCE_TD_PTR);
+     if (pkt_stat & LANCE_TD_PTR_OWN) {
+ #if DEBUG & 1
+         db_printf("%s: got TX completion when buffer is still owned\n", __FUNCTION__);
+ #endif
+         // first dirty ring entry not freed - wtf?
+     }
+ 
+     if (pkt_stat & LANCE_TD_PTR_ERR) {
+         // We had an error. Tell the stack.
+         success = 0;
+ #if DEBUG & 1
+         db_printf("%s: TX failure, retrying...\n", __FUNCTION__);
+ #endif
+     }
+ 
+     cpd->tx_ring_alloc++;
+     if (cpd->tx_ring_alloc == cpd->tx_ring_cnt)
+         cpd->tx_ring_alloc = 0;
+     cpd->tx_ring_owned--;
+ 
+ #if FIXME
+ #ifdef KEEP_STATISTICS
+     {
+         cyg_uint16 reg;
+ 
+         reg = get_reg( sc, LANCE_CSR_CSCR );
+ 
+         // Covering each bit in turn...
+         if ( reg & LANCE_STATUS_TX_UNRN   ) INCR_STAT( tx_underrun );
+         //if ( reg & LANCE_STATUS_LINK_OK ) INCR_STAT(  );
+         //if ( reg & LANCE_STATUS_CTR_ROL ) INCR_STAT(  );
+         //if ( reg & LANCE_STATUS_EXC_DEF ) INCR_STAT(  );
+         if ( reg & LANCE_STATUS_LOST_CARR ) INCR_STAT( tx_carrier_loss );
+         if ( reg & LANCE_STATUS_LATCOL    ) INCR_STAT( tx_late_collisions );
+         //if ( reg & LANCE_STATUS_WAKEUP  ) INCR_STAT(  );
+         if ( reg & LANCE_STATUS_TX_DEFR   ) INCR_STAT( tx_deferred );
+         //if ( reg & LANCE_STATUS_LTX_BRD ) INCR_STAT(  );
+         if ( reg & LANCE_STATUS_SQET      ) INCR_STAT( tx_sqetesterrors );
+         if ( reg & LANCE_STATUS_16COL     ) INCR_STAT( tx_max_collisions );
+         //if ( reg & LANCE_STATUS_LTX_MULT) INCR_STAT(  );
+         if ( reg & LANCE_STATUS_MUL_COL   ) INCR_STAT( tx_mult_collisions );
+         if ( reg & LANCE_STATUS_SNGL_COL  ) INCR_STAT( tx_single_collisions );
+         if ( reg & LANCE_STATUS_TX_SUC    ) INCR_STAT( tx_good );
+ 
+         cpd->stats.tx_total_collisions =
+             cpd->stats.tx_late_collisions +
+             cpd->stats.tx_max_collisions +
+             cpd->stats.tx_mult_collisions +
+             cpd->stats.tx_single_collisions;
+ 
+         // We do not need to look in the Counter Register (LANCE_COUNTER)
+         // because it just mimics the info we already have above.
+     }
+ #endif // KEEP_STATISTICS
+ #endif // FIXME
+ 
+     // Ack the TX int which clears the packet from the TX completion
+     // queue.
+     ints = get_reg(sc, LANCE_CSR_CSCR);
+     ints |= LANCE_CSR_CSCR_TINT;
+     put_reg(sc, LANCE_CSR_CSCR, ints);
+ 
+ #if DEBUG & 4
+     db_printf("#####Tx packet freed 0x%08x\n", txd );
+ #endif
+ 
+     if ( cpd->txbusy ) {
+         cpd->txbusy = 0;
+         (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, success);
+     }
+ }
+ 
+ 
+ //
+ // This function is called when a packet has been received.  Its job is
+ // to prepare to unload the packet from the hardware.  Once the length of
+ // the packet is known, the upper layer of the driver can be told.  When
+ // the upper layer is ready to unload the packet, the internal function
+ // 'lancepci_recv' will be called to actually fetch it from the hardware.
+ //
+ static void
+ lancepci_RxEvent(struct eth_drv_sc *sc)
+ {
+     struct lancepci_priv_data *cpd =
+         (struct lancepci_priv_data *)sc->driver_private;
+     cyg_uint8 *rxd;
+     cyg_uint32 rstat;
+     cyg_uint16 ints, len;
+ 
+     DEBUG_FUNCTION();
+ 
+     ints = get_reg(sc, LANCE_CSR_CSCR);
+ #if DEBUG & 1
+     db_printf("RxEvent - CSR: 0x%04x\n", ints);
+ #endif
+ 
+     while (1) {
+         // Get state of next (supposedly) full ring entry
+         cpd->rxpacket = cpd->rx_ring_next;
+         rxd = cpd->rx_ring + cpd->rxpacket*LANCE_RD_SIZE;
+         rstat = _SU32(rxd, LANCE_RD_PTR);
+ 
+         // Keep going until we hit an entry that is owned by the
+         // controller.
+         if (rstat & LANCE_RD_PTR_OWN) {
+ #if DEBUG & 1
+             int i;
+             for (i = 0; i < cpd->rx_ring_cnt; i++) {
+                 rxd = cpd->rx_ring + i*LANCE_RD_SIZE;
+                 rstat = _SU32(rxd, LANCE_RD_PTR);
+ 
+                 if (!(rstat & LANCE_RD_PTR_OWN)) {
+                     int i;
+                     cyg_uint32 rstat;
+                     cyg_uint16 mlen, blen;
+                     cyg_uint8* rxd;
+ 
+                     db_printf("%s: Inconsistent RX state\n", __FUNCTION__);
+                     for (i = 0; i < cpd->rx_ring_cnt; i++) {
+                         rxd = cpd->rx_ring + i*LANCE_RD_SIZE;
+ 
+                         rstat = _SU32(rxd, LANCE_RD_PTR);
+                         blen = _SU16(rxd, LANCE_RD_BLEN);
+                         mlen = _SU16(rxd, LANCE_RD_MLEN);
+                         db_printf(" %02d: 0x%08x:0x%04x:0x%04x\n", i, rstat, blen, mlen);
+                     }
+                 }
+             }
+ #endif
+             break;
+         }
+ 
+ #if DEBUG & 4
+         db_printf("#####Rx packet at index %d\n", cpd->rxpacket);
+ #endif
+ 
+         // Increment counts
+         INCR_STAT( rx_count );
+         cpd->rx_ring_next++;
+         if (cpd->rx_ring_next == cpd->rx_ring_cnt) cpd->rx_ring_next = 0;
+ 
+         len = _SU16(rxd, LANCE_RD_MLEN);
+ 
+ #ifdef KEEP_STATISTICS
+         //if ( rstat & LANCE_RD_PTR_FRAM ) INCR_STAT( rx_frame_errors );
+         //if ( rstat & LANCE_RD_PTR_OFLO ) INCR_STAT(  );
+         if ( rstat & LANCE_RD_PTR_CRC ) INCR_STAT( rx_crc_errors );
+         //if ( rstat & LANCE_RD_PTR_BUFF ) INCR_STAT(  );
+ #endif // KEEP_STATISTICS
+ 
+         if (0 == (rstat & LANCE_RD_PTR_ERR)) {
+             // It's OK
+             INCR_STAT( rx_good );
+ 
+ #if DEBUG & 1
+             db_printf("RxEvent good rx - stat: 0x%08x, len: 0x%04x\n", rstat, len);
+ #endif
+             // Check for bogusly short packets; can happen in promisc
+             // mode: Asserted against and checked by upper layer
+             // driver.
+ #ifdef CYGPKG_NET
+             if ( len > sizeof( struct ether_header ) )
+                 // then it is acceptable; offer the data to the network stack
+ #endif
+                 (sc->funs->eth_drv->recv)(sc, len);
+         } else {
+             // Not OK for one reason or another...
+ #if DEBUG & 1
+             db_printf("RxEvent - No RX bit: stat: 0x%08x, len: 0x%04x\n",
+                         rstat, len);
+ #endif
+         }
+ 
+         // Free packet (clear all status flags, and set OWN)
+         _SU32(rxd, LANCE_RD_PTR) &= LANCE_RD_PTR_MASK;
+         _SU32(rxd, LANCE_RD_PTR) |= LANCE_RD_PTR_OWN;
+     }
+ 
+     // Ack RX interrupt set
+     ints = get_reg(sc, LANCE_CSR_CSCR);
+     ints &= LANCE_CSR_CSCR_EV_MASK;
+     ints |= LANCE_CSR_CSCR_RINT;
+     put_reg(sc, LANCE_CSR_CSCR, ints);
+ }
+ 
+ //
+ // This function is called as a result of the "eth_drv_recv()" call above.
+ // Its job is to actually fetch data for a packet from the hardware once
+ // memory buffers have been allocated for the packet.  Note that the buffers
+ // may come in pieces, using a scatter-gather list.  This allows for more
+ // efficient processing in the upper layers of the stack.
+ //
+ static void
+ lancepci_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
+ {
+     struct lancepci_priv_data *cpd =
+         (struct lancepci_priv_data *)sc->driver_private;
+     int i, mlen=0, plen;
+     cyg_uint8 *data, *rxd, *buf;
+ 
+     DEBUG_FUNCTION();
+ 
+     rxd = cpd->rx_ring + cpd->rxpacket*LANCE_RD_SIZE;
+     buf = cpd->rx_buffers + cpd->rxpacket*_BUF_SIZE;
+ 
+     INCR_STAT( rx_deliver );
+ 
+     plen = _SU16(rxd, LANCE_RD_MLEN);
+ 
+     for (i = 0;  i < sg_len;  i++) {
+         data = (cyg_uint8*)sg_list[i].buf;
+         mlen = sg_list[i].len;
+ 
+ #if DEBUG & 1
+         db_printf("%s : mlen %x, plen %x\n", __FUNCTION__, mlen, plen);
+ #endif
+         if (data) {
+             while (mlen > 0) {
+                 *data++ = *buf++;
+                 mlen--;
+                 plen--;
+             }
+         }
+     }
+ }
+ 
+ static void
+ lancepci_poll(struct eth_drv_sc *sc)
+ {
+     cyg_uint16 event;
+     struct lancepci_priv_data *cpd =
+         (struct lancepci_priv_data *)sc->driver_private;
+ 
+ //  DEBUG_FUNCTION();
+ 
+     while (1) {
+         // Get the (unmasked) requests
+ 	if (cpd->event) {
+ 	    event=cpd->event;
+ 	    cpd->event=0;
+ 	}
+ 	else
+             event = get_reg(sc, LANCE_CSR_CSCR);
+         if (!((LANCE_CSR_CSCR_ERR|LANCE_CSR_CSCR_INTR) & event))
+             break;
+ 
+         if (event & LANCE_CSR_CSCR_RINT) {
+             lancepci_RxEvent(sc);
+         }
+         else if (event & LANCE_CSR_CSCR_TINT) {
+ 	    cpd->txbusyh=0;		// again , for polled mode
+             lancepci_TxEvent(sc, event);
+         }
+         else if (event & LANCE_CSR_CSCR_MISS) {
+ #if DEBUG & 1
+             int i;
+             cyg_uint32 rstat;
+             cyg_uint16 mlen, blen;
+             cyg_uint8* rxd;
+             struct lancepci_priv_data *cpd =
+                 (struct lancepci_priv_data *)sc->driver_private;
+ 
+             db_printf("%s: Ran out of RX buffers (%04x)\n", __FUNCTION__, event);
+             for (i = 0; i < cpd->rx_ring_cnt; i++) {
+                 rxd = cpd->rx_ring + i*LANCE_TD_SIZE;
+ 
+                 rstat = _SU32(rxd, LANCE_RD_PTR);
+                 blen = _SU16(rxd, LANCE_RD_BLEN);
+                 mlen = _SU16(rxd, LANCE_RD_MLEN);
+                 db_printf(" %02d: 0x%08x:0x%04x:0x%04x\n", i, rstat, blen, mlen);
+             }
+ #endif
+             event &= LANCE_CSR_CSCR_EV_MASK;
+             event |= LANCE_CSR_CSCR_MISS;
+             put_reg(sc, LANCE_CSR_CSCR, event);
+         }
+         else {
+ #if DEBUG & 1
+             db_printf("%s: Unknown interrupt: 0x%04x\n", __FUNCTION__, event);
+ #endif
+             put_reg(sc, LANCE_CSR_CSCR, event);
+         }
+     }
+ }
+ 
+ // EOF if_lancepci.c
diff -C5 -N -P -r -x '.*' /ecoscvs/orig/ecos/packages/devs/eth/i386/pc/lancepci/current/cdl/i386_pc_lancepci_eth_drivers.cdl ./devs/eth/i386/pc/lancepci/current/cdl/i386_pc_lancepci_eth_drivers.cdl
*** /ecoscvs/orig/ecos/packages/devs/eth/i386/pc/lancepci/current/cdl/i386_pc_lancepci_eth_drivers.cdl	1970-01-01 01:00:00.000000000 +0100
--- ./devs/eth/i386/pc/lancepci/current/cdl/i386_pc_lancepci_eth_drivers.cdl	2004-02-25 13:27:18.000000000 +0100
***************
*** 0 ****
--- 1,129 ----
+ # ====================================================================
+ #
+ #      pc_lancepci_eth_drivers.cdl
+ #
+ #      Ethernet drivers - support for AMD Lance PCI ethernet controller
+ #      on the i386 PC (also wmWare)
+ #
+ # ====================================================================
+ #####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####
+ # ====================================================================
+ ######DESCRIPTIONBEGIN####
+ #
+ # Author(s):      iz
+ # Contributors:
+ # Date:           2002-07-17
+ #
+ #####DESCRIPTIONEND####
+ #
+ # ====================================================================
+ 
+ cdl_package CYGPKG_DEVS_ETH_I386_PC_LANCEPCI {
+     display       "PC Lance PCI board ethernet driver"
+     description   "Ethernet driver for PCI Lance."
+ 
+     parent        CYGPKG_IO_ETH_DRIVERS
+     active_if	  CYGPKG_IO_ETH_DRIVERS
+ 
+     include_dir   cyg/io
+ 
+     # FIXME: This really belongs in the AMD_LANCEPCI package
+     cdl_interface CYGINT_DEVS_ETH_AMD_LANCEPCI_REQUIRED {
+         display   "AMD Lance PCI ethernet driver required"
+     }
+ 
+     define_proc {
+         puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+         puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_AMD_LANCEPCI_INL <cyg/io/devs_eth_i386_pc_lancepci.inl>"
+         puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_AMD_LANCEPCI_CFG <pkgconf/devs_eth_i386_pc_lancepci.h>"
+         puts $::cdl_system_header "/*****  ethernet driver proc output end  *****/"
+     }
+ 
+     cdl_component CYGPKG_DEVS_ETH_I386_PC_LANCEPCI_ETH0 {
+         display       "Lance PCI ethernet port 0 driver"
+         flavor        bool
+         default_value 1
+         description   "
+             This option includes the ethernet device driver for the
+             PC (vmWare) Lance PCI port 0."
+ 
+         implements CYGHWR_NET_DRIVERS
+         implements CYGHWR_NET_DRIVER_ETH0
+         implements CYGINT_DEVS_ETH_AMD_LANCEPCI_REQUIRED
+ 
+         cdl_option CYGNUM_DEVS_ETH_I386_PC_LANCEPCI_ETH0_RX_RING_SIZE {
+             display       "Size of RX ring for ETH0"
+             flavor        data
+             default_value 4
+             legal_values  { 4 8 16 32 64 128 }
+             description   "
+                 This option sets the size of the RX ring."
+         }
+ 
+         cdl_option CYGNUM_DEVS_ETH_I386_PC_LANCEPCI_ETH0_TX_RING_SIZE {
+             display       "Size of TX ring for ETH0"
+             flavor        data
+             default_value 4
+             legal_values  { 4 8 16 32 64 128 }
+             description   "
+                 This option sets the size of the TX ring."
+         }
+ 
+         cdl_option CYGDAT_DEVS_ETH_I386_PC_LANCEPCI_ETH0_NAME {
+             display       "Device name for the ETH0 ethernet port 0 driver"
+             flavor        data
+             default_value {"\"eth0\""}
+             description   "
+                 This option sets the name of the ethernet device for the
+                 PC Lance port 0."
+         }
+ 
+         cdl_component CYGSEM_DEVS_ETH_I386_PC_LANCEPCI_ETH0_SET_ESA {
+             display       "Set the ethernet station address"
+             flavor        bool
+             default_value   0
+             description   "Enabling this option will allow the ethernet
+             station address to be forced to the value set by the
+             configuration.  This may be required if the hardware does
+             not include a serial EEPROM for the ESA."
+ 
+             cdl_option CYGDAT_DEVS_ETH_I386_PC_LANCEPCI_ETH0_ESA {
+                 display       "The ethernet station address"
+                 flavor        data
+                 default_value {"{0x08, 0x88, 0x12, 0x34, 0x56, 0x78}"}
+                 description   "The ethernet station address"
+             }
+         }
+     }
+ }
diff -C5 -N -P -r -x '.*' /ecoscvs/orig/ecos/packages/devs/eth/i386/pc/lancepci/current/ChangeLog ./devs/eth/i386/pc/lancepci/current/ChangeLog
*** /ecoscvs/orig/ecos/packages/devs/eth/i386/pc/lancepci/current/ChangeLog	1970-01-01 01:00:00.000000000 +0100
--- ./devs/eth/i386/pc/lancepci/current/ChangeLog	2004-02-25 13:27:18.000000000 +0100
***************
*** 0 ****
--- 1,39 ----
+ 2002-07-17  Iztok Zupet  <iz@vsr.si>
+ 
+ 	* all: Platform specific information to use generic AMD Lance
+ 	PCI driver for the PC platform
+ 
+ //===========================================================================
+ //####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####
+ //===========================================================================
diff -C5 -N -P -r -x '.*' /ecoscvs/orig/ecos/packages/devs/eth/i386/pc/lancepci/current/include/devs_eth_i386_pc_lancepci.inl ./devs/eth/i386/pc/lancepci/current/include/devs_eth_i386_pc_lancepci.inl
*** /ecoscvs/orig/ecos/packages/devs/eth/i386/pc/lancepci/current/include/devs_eth_i386_pc_lancepci.inl	1970-01-01 01:00:00.000000000 +0100
--- ./devs/eth/i386/pc/lancepci/current/include/devs_eth_i386_pc_lancepci.inl	2004-02-25 13:27:18.000000000 +0100
***************
*** 0 ****
--- 1,111 ----
+ //==========================================================================
+ //
+ //      devs/eth/i386/pc/include/devs_eth_i386_pc_lancepci.inl
+ //
+ //      PC Lance PCI ethernet I/O definitions.
+ //
+ //==========================================================================
+ //####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####
+ //==========================================================================
+ //#####DESCRIPTIONBEGIN####
+ //
+ // Author(s):   iz
+ // Contributors:
+ // Date:        2002-07-17
+ // Purpose:     PC Lance PCI (VLANCE device in vmWare) ethernet defintions
+ //####DESCRIPTIONEND####
+ //==========================================================================
+ 
+ #include <cyg/hal/hal_intr.h>           // CYGNUM_HAL_INTERRUPT_ETHR
+ 
+ #ifdef __WANT_CONFIG
+ #define CYGHWR_AMD_LANCEPCI_PCI_MEM_MAP_BASE (CYGARC_UNCACHED_ADDRESS(CYGMEM_SECTION_pci_window))
+ #define CYGHWR_AMD_LANCEPCI_PCI_MEM_MAP_SIZE CYGMEM_SECTION_pci_window_SIZE
+ #define HAL_PCI_CPU_TO_BUS(__cpu_addr, __bus_addr)   \
+     CYG_MACRO_START                                  \
+     (__bus_addr) = CYGARC_PHYSICAL_ADDRESS(__cpu_addr);   \
+     CYG_MACRO_END
+ #endif // __WANT_CONFIG
+ 
+ 
+ #ifdef __WANT_DEVS
+ 
+ #ifdef CYGPKG_DEVS_ETH_I386_PC_LANCEPCI_ETH0
+ 
+ static lancepci_priv_data amd_lancepci_eth0_priv_data = {
+ #ifdef CYGSEM_DEVS_ETH_I386_PC_LANCEPCI_ETH0_SET_ESA
+     esa : CYGDAT_DEVS_ETH_I386_PC_LANCEPCI_ETH0_ESA,
+     hardwired_esa : true,
+ #else
+     hardwired_esa : false,
+ #endif
+     config_esa : NULL,             // rely on the hardwired address for now
+     rx_ring : NULL,
+     rx_ring_cnt : CYGNUM_DEVS_ETH_I386_PC_LANCEPCI_ETH0_RX_RING_SIZE,
+     rx_ring_log_cnt : 2,
+     tx_ring : NULL,
+     tx_ring_cnt : CYGNUM_DEVS_ETH_I386_PC_LANCEPCI_ETH0_TX_RING_SIZE,
+     tx_ring_log_cnt : 2,
+ };
+ 
+ ETH_DRV_SC(amd_lancepci_sc,
+            &amd_lancepci_eth0_priv_data, // Driver specific data
+            CYGDAT_DEVS_ETH_I386_PC_LANCEPCI_ETH0_NAME,
+            lancepci_start,
+            lancepci_stop,
+            lancepci_control,
+            lancepci_can_send,
+            lancepci_send,
+            lancepci_recv,
+            lancepci_deliver,     // "pseudoDSR" called from fast net thread
+            lancepci_poll,        // poll function, encapsulates ISR and DSR
+            lancepci_int_vector);
+ 
+ NETDEVTAB_ENTRY(lancepci_netdev,
+                 "lancepci_" CYGDAT_DEVS_ETH_I386_PC_LANCEPCI_ETH0_NAME,
+                 amd_lancepci_init,
+                 &amd_lancepci_sc);
+ #endif // CYGPKG_DEVS_ETH_I386_PC_LANCEPCI_ETH0
+ 
+ // These arrays are used for sanity checking of pointers
+ struct lancepci_priv_data *
+ lancepci_priv_array[CYGNUM_DEVS_ETH_AMD_LANCEPCI_DEV_COUNT] = {
+ #ifdef CYGPKG_DEVS_ETH_I386_PC_LANCEPCI_ETH0
+     &amd_lancepci_eth0_priv_data,
+ #endif
+ };
+ 
+ #endif // __WANT_DEVS
+ 
+ // EOF devs_eth_pc_lancepci.inl
diff -C5 -N -P -r -x '.*' /ecoscvs/orig/ecos/packages/ecos.db ./ecos.db
*** /ecoscvs/orig/ecos/packages/ecos.db	2004-02-20 11:27:14.000000000 +0100
--- ./ecos.db	2004-02-25 13:27:18.000000000 +0100
***************
*** 1362,1371 ****
--- 1362,1379 ----
  	directory	devs/eth/amd/pcnet
  	script		amd_pcnet_eth_drivers.cdl
          description     "Ethernet driver for AMD PCNET controller."
  }
  
+ package CYGPKG_DEVS_ETH_AMD_LANCEPCI {
+ 	alias 		{ "AMD Lance PCI ethernet driver" lancepci_eth_driver }
+ 	hardware
+ 	directory	devs/eth/amd/lancepci
+ 	script		amd_lancepci_eth_drivers.cdl
+         description     "Ethernet driver for AMD Lance PCI controller (vmWare)."
+ }
+ 
  package CYGPKG_DEVS_ETH_MIPS_MIPS32_MALTA {
  	alias 		{ "MIPS Malta board ethernet driver" malta_eth_driver }
  	hardware
  	directory	devs/eth/mips/malta
  	script		mips_mips32_malta_eth_drivers.cdl
***************
*** 1629,1638 ****
--- 1637,1655 ----
  	directory	devs/eth/i386/pc/i82544
  	script		i386_pc_i82544_eth_drivers.cdl
          description     "Ethernet driver for standard PC with Intel 82544 Gigabit NIC."
  }
  
+ package CYGPKG_DEVS_ETH_I386_PC_LANCEPCI {
+ 	alias 		{ "Standard PC with AMD Lance PCI device"
+ 			   devs_eth_i386_pc_lancepci pc_ether_lancepci }
+ 	hardware
+ 	directory	devs/eth/i386/pc/lancepci
+ 	script		i386_pc_lancepci_eth_drivers.cdl
+         description     "Ethernet driver for standard PC with AMD Lance NIC (vmWare)."
+ }
+ 
  package CYGPKG_DEVS_ETH_MIPS_ATLAS {
  	alias 		{ "MIPS Atlas with onboard SAA9730 ethernet driver"
  			   devs_eth_mips_atlas atlas_eth_driver }
  	hardware
  	directory	devs/eth/mips/atlas
***************
*** 4380,4389 ****
--- 4397,4425 ----
      	    The pc target provides the packages needed to run eCos binaries
              on a standard i386 PC motherboard with an Intel 82543/82544 based
              Gigabit ethernet interface."
  }
  
+ target pc_vmWare {
+         alias		{ "i386 PC target (vmWare)" }
+ 	packages        { CYGPKG_HAL_I386
+                           CYGPKG_HAL_I386_GENERIC
+                           CYGPKG_HAL_I386_PC
+                           CYGPKG_HAL_I386_PCMB
+ 			  CYGPKG_IO_PCI
+                           CYGPKG_IO_SERIAL_GENERIC_16X5X
+ 	                  CYGPKG_IO_SERIAL_I386_PC
+ 			  CYGPKG_DEVS_ETH_AMD_LANCEPCI
+ 			  CYGPKG_DEVS_ETH_I386_PC_LANCEPCI
+                           CYGPKG_DEVICES_WALLCLOCK_DALLAS_DS12887
+                           CYGPKG_DEVICES_WALLCLOCK_I386_PC
+         }
+         description "
+     	    The pc target provides the packages needed to run eCos binaries
+             on a standard i386 PC under wmWare."
+ }
+ 
  # --------------------------------------------------------------------------
  # Synthetic targets.
  target linux {
          alias		{ "Linux synthetic target" i386linux }
  	packages        { CYGPKG_HAL_SYNTH

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]