This is the mail archive of the
ecos-patches@sources.redhat.com
mailing list for the eCos project.
PC Vmware networking
- From: Iztok Zupet <iztok dot zupet at vsr dot si>
- To: ecos-patches at sources dot redhat dot com
- Date: Wed, 29 Jan 2003 13:40:36 +0100
- Subject: PC Vmware networking
- Organization: VSR d.o.o.
- Reply-to: iztok dot zupet at vsr dot si
Hello,
As promised to Jifl, tidied up and changelogs done. The assignment has
already been sent to Red Hat.
Regards
Iztok
diff -C5 -N -P -r -x '.*' /ecoscvs/orig/ecos/packages/ChangeLog ./ChangeLog
*** /ecoscvs/orig/ecos/packages/ChangeLog 2003-01-27 17:33:05.000000000 +0100
--- ./ChangeLog 2003-01-29 13:17:57.000000000 +0100
***************
*** 1,5 ****
--- 1,10 ----
+ 2003-01-26 Iztok Zupet <iz@vsr.si>
+
+ * ecos.db: Add packages for LancePCI (Vmware) eth driver.
+ Add new target pc_vmWare for use under Vmware virtual machine.
+
2003-01-24 Knud Woehler <knud.woehler@microplex.de>
2003-01-24 Mark Salter <msalter@redhat.com>
* ecos.db: Add packages for XScale PXA2x0/MPC50.
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 2003-01-29 09:03:46.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 2003-01-29 13:19:41.000000000 +0100
***************
*** 0 ****
--- 1,50 ----
+ 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 2003-01-29 09:04:29.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 2003-01-29 09:04:43.000000000 +0100
***************
*** 0 ****
--- 1,1313 ----
+ //==========================================================================
+ //
+ // 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
+
+ #if defined(CYGPKG_REDBOOT) && DEBUG
+
+ 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) {
+ // Use the address from the serial EEPROM
+ p = cpd->base + LANCE_IO_EEPROM;
+ for (i = 0; i < 6; i++)
+ cpd->esa[i] = *p++;
+ }
+ #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;
+ #if DEBUG & 9
+ db_printf("Init Done\n");
+ #endif
+ 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 2003-01-29 09:06:16.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 2002-10-24 20:19:36.000000000 +0200
***************
*** 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 2003-01-29 09:06:41.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 2003-01-27 17:33:05.000000000 +0100
--- ./ecos.db 2003-01-27 18:31:37.000000000 +0100
***************
*** 1146,1155 ****
--- 1146,1163 ----
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
***************
*** 1360,1369 ****
--- 1368,1386 ----
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
***************
*** 3719,3728 ****
--- 3736,3764 ----
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