summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTill Straumann <strauman@slac.stanford.edu>2009-04-22 22:06:58 +0000
committerTill Straumann <strauman@slac.stanford.edu>2009-04-22 22:06:58 +0000
commita8bf95d0249565f4210ccab5c13232d501ce0c2d (patch)
treee01f2eca98add8dba13eec23a95fa22120638890
parenta90d1ed6c9cbdf2f899d13178fd589f80c5ab0e6 (diff)
downloadlibbsdport-a8bf95d0249565f4210ccab5c13232d501ce0c2d.tar.bz2
- importing updated version from SLAC as of 20090422
-rwxr-xr-xbootstrap45
-rw-r--r--bsd_eth_drivers/ChangeLog20
-rw-r--r--bsd_eth_drivers/Makefile11
-rw-r--r--bsd_eth_drivers/Makefile.am2
-rw-r--r--bsd_eth_drivers/if_em/LICENSE31
-rw-r--r--bsd_eth_drivers/if_em/Makefile158
-rw-r--r--bsd_eth_drivers/if_em/README.rtems66
-rw-r--r--bsd_eth_drivers/if_em/freebsd_cvs_status291
-rw-r--r--bsd_eth_drivers/if_le/Makefile152
-rw-r--r--bsd_eth_drivers/if_le/README.rtems80
-rw-r--r--bsd_eth_drivers/if_le/am7990.c627
-rw-r--r--bsd_eth_drivers/if_le/if_le_cbus.c451
-rw-r--r--bsd_eth_drivers/if_le/if_le_isa.c509
-rw-r--r--bsd_eth_drivers/if_le/if_le_lebuffer.c408
-rw-r--r--bsd_eth_drivers/if_le/if_le_ledma.c490
-rw-r--r--bsd_eth_drivers/if_le/lebuffer_sbus.c300
-rw-r--r--bsd_eth_drivers/if_pcn/Makefile143
-rw-r--r--bsd_eth_drivers/if_pcn/README.rtems73
-rw-r--r--bsd_eth_drivers/libbsdport/Makefile116
-rw-r--r--bsd_eth_drivers/libbsdport/Makefile.am3
-rw-r--r--bsd_eth_drivers/libbsdport/alldrv.c1
-rw-r--r--bsd_eth_drivers/libbsdport/bus.h40
-rw-r--r--bsd_eth_drivers/libbsdport/devicet.c2
-rw-r--r--bsd_eth_drivers/libbsdport/libbsdport.h7
-rw-r--r--bsd_eth_drivers/libbsdport/libbsdport_api.h2
-rw-r--r--bsd_eth_drivers/libbsdport/modini.c100
-rw-r--r--bsd_eth_drivers/libbsdport/sysbus.c12
-rw-r--r--bsd_eth_drivers/libbsdport/taskqueue.h2
-rw-r--r--configure.ac12
-rw-r--r--m4/acinclude.m416
-rw-r--r--m4/multilib-fix.m478
-rw-r--r--m4/multilib-installdir.m421
-rw-r--r--m4/rtems-bsp-postlink.m432
-rw-r--r--m4/rtems-isml.m411
-rw-r--r--m4/rtems-ismultibsp.m423
-rw-r--r--m4/rtems-multilib.m428
-rw-r--r--rtems-pre.am2
37 files changed, 4293 insertions, 72 deletions
diff --git a/bootstrap b/bootstrap
new file mode 100755
index 0000000..d0762ad
--- /dev/null
+++ b/bootstrap
@@ -0,0 +1,45 @@
+#!/bin/sh
+
+localhack=
+while getopts "lf" theopt ; do
+ case $theopt in
+ l)
+ localhack=yes
+ ;;
+ f)
+ force=--force
+ ;;
+ *)
+ ;;
+ esac
+done
+
+if test -d cexp ; then
+ (cd cexp; make src)
+fi
+
+for val in cexp/binutils* binutils* ; do
+ if test -d "$val" ; then
+ echo "*************** ERROR Found $val;"
+ echo "You must run `basename $0` before unpacking 'binutils';"
+ echo "Please move the 'binutils' directory temporarily out of the source tree,"
+ echo "run `basename $0` and then move binutils back"
+ exit 1
+ fi
+done
+
+if test "$localhack" = "yes" ; then
+# for some strange reason it is not
+# possible to pass autoreconf an option
+# directing it to search directories
+# for '.m4' files for aclocal. The '-I/-B'
+# options don't seem to work. We hack
+# around this by setting ACLOCAL
+ if test "${ACLOCAL+set}" = "set" ; then
+ echo "Warning: ACLOCAL is already set; I add a -I option";
+ else
+ ACLOCAL=aclocal
+ fi
+ export ACLOCAL="$ACLOCAL -I `(cd \`dirname $0\`; pwd)`/autognu"
+fi
+autoreconf -i $force
diff --git a/bsd_eth_drivers/ChangeLog b/bsd_eth_drivers/ChangeLog
new file mode 100644
index 0000000..33cb584
--- /dev/null
+++ b/bsd_eth_drivers/ChangeLog
@@ -0,0 +1,20 @@
+ 2008/03/22 (TS)
+ - silence more compiler warnings:
+ * make DMA address void* instead of caddr_t to avoid strict-aliasing violation
+ * add dummy statement to silence 'unused variable' warning.
+ - added header with RTEMS version checking macro. Unfortunately, many small
+ details of the RTEMS APIs change with versions :-( [e.g., changed type
+ from unsigned -> uint32_t in st_le32()]. Individual files can include
+ the new <rtems_verscheck.h> and test for RTEMS version to switch conditional
+ compilation (aaargh).
+ - header clash; <queue.h> (and others) are present in newlib and in RTEMS/bsdnet
+ but they use a different multiple-inclusion guard :-(. Must pick the right one...
+ 2007/11/07 (TS)
+ - added ChangeLog
+ - moved arp_ifinit from libbsdport.h to libbsdport_post.h
+ - replaced inport_xxx/outport_xxx by in_xxx/out_xxx and _IO_BASE
+ - bookE has not mftb instruction :-( we must use mfspr
+ (but that wouldn't work on classic ppc if we were not
+ in supervisory mode).
+ - type adaptions in libbsdport.h to protect us against
+ alias rule and to silence warnings.
diff --git a/bsd_eth_drivers/Makefile b/bsd_eth_drivers/Makefile
new file mode 100644
index 0000000..175dea6
--- /dev/null
+++ b/bsd_eth_drivers/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile.dir,v 1.4 2000/06/12 15:00:14 joel Exp
+#
+
+include $(RTEMS_MAKEFILE_PATH)/Makefile.inc
+
+include $(RTEMS_CUSTOM)
+include $(RTEMS_ROOT)/make/directory.cfg
+
+SUBDIRS=libbsdport if_em if_pcn if_le
+
diff --git a/bsd_eth_drivers/Makefile.am b/bsd_eth_drivers/Makefile.am
index 4495d4a..347eb90 100644
--- a/bsd_eth_drivers/Makefile.am
+++ b/bsd_eth_drivers/Makefile.am
@@ -1,3 +1,3 @@
AUTOMAKE_OPTIONS=foreign
-SUBDIRS=libbsdport if_pcn if_le if_em re
+SUBDIRS=libbsdport if_pcn if_le if_em
diff --git a/bsd_eth_drivers/if_em/LICENSE b/bsd_eth_drivers/if_em/LICENSE
new file mode 100644
index 0000000..7e13aa1
--- /dev/null
+++ b/bsd_eth_drivers/if_em/LICENSE
@@ -0,0 +1,31 @@
+$FreeBSD: src/sys/dev/em/LICENSE,v 1.6 2007/05/04 00:00:11 jfv Exp $
+
+ Copyright (c) 2001-2007, Intel Corporation
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/bsd_eth_drivers/if_em/Makefile b/bsd_eth_drivers/if_em/Makefile
new file mode 100644
index 0000000..ea0d776
--- /dev/null
+++ b/bsd_eth_drivers/if_em/Makefile
@@ -0,0 +1,158 @@
+#
+# Makefile.leaf,v 1.7 2002/07/22 22:56:09 joel Exp
+#
+# Templates/Makefile.leaf
+# Template leaf node Makefile
+#
+#
+LIBNAME=libif_em.a
+
+ENBL_82542_SUPPORT=NO
+ENBL_ICH8LAN_SUPPORT=YES
+
+CPPFLAGS_82542_SUPPORT_NO=-DNO_82542_SUPPORT
+C_PIECES_82542_SUPPORT_YES=e1000_82542
+CPPFLAGS_ICH8LAN_SUPPORT_NO=-DNO_ICH8LAN_SUPPORT
+C_PIECES_ICH8LAN_SUPPORT_YES=e1000_ich8lan
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=
+
+C_PIECES+=e1000_80003es2lan
+C_PIECES+=e1000_82540
+C_PIECES+=e1000_82541
+C_PIECES+=$(C_PIECES_82542_SUPPORT_$(ENBL_82542_SUPPORT))
+C_PIECES+=e1000_82543
+C_PIECES+=e1000_82571
+C_PIECES+=e1000_82575
+C_PIECES+=e1000_api
+C_PIECES+=$(C_PIECES_ICH8LAN_SUPPORT_$(ENBL_ICH8LAN_SUPPORT))
+C_PIECES+=e1000_mac
+C_PIECES+=e1000_manage
+C_PIECES+=e1000_nvm
+C_PIECES+=e1000_phy
+
+C_PIECES+=if_em
+
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+# C++ source names, if any, go here -- minus the .cc
+CC_PIECES=
+CC_FILES=$(CC_PIECES:%=%.cc)
+CC_O_FILES=$(CC_PIECES:%=${ARCH}/%.o)
+
+H_FILES=
+
+# Assembly source names, if any, go here -- minus the .S
+S_PIECES=
+S_FILES=$(S_PIECES:%=%.S)
+S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o)
+
+SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
+OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
+
+# If your PGMS target has the '.exe' extension, a statically
+# linked application is generated.
+# If it has a '.obj' extension, a loadable module is built.
+#
+#
+ifdef LIBNAME
+LIB=${ARCH}/${LIBNAME}
+else
+PGMS=${ARCH}/if_em.obj
+endif
+
+# List of RTEMS Classic API Managers to be included in the application
+# goes here. Use:
+# MANAGERS=all
+# to include all RTEMS Classic API Managers in the application or
+# something like this to include a specific set of managers.
+# MANAGERS=io event message rate_monotonic semaphore timer
+#
+# UNUSED for loadable modules
+MANAGERS=ALL
+
+ifndef RTEMS_MAKEFILE_PATH
+$(error you need to set the RTEMS_MAKEFILE_PATH environment variable)
+endif
+
+include $(RTEMS_MAKEFILE_PATH)/Makefile.inc
+
+include $(RTEMS_CUSTOM)
+ifdef LIBNAME
+include $(RTEMS_ROOT)/make/lib.cfg
+else
+include $(RTEMS_ROOT)/make/leaf.cfg
+endif
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES +=
+CPPFLAGS += -I. -I../libbsdport -I../libbsdport/dummyheaders
+CPPFLAGS += $(CPPFLAGS_82542_SUPPORT_$(ENBL_82542_SUPPORT))
+CPPFLAGS += $(CPPFLAGS_ICH8LAN_SUPPORT_$(ENBL_ICH8LAN_SUPPORT))
+CFLAGS +=
+
+#
+# CFLAGS_DEBUG_V are used when the `make debug' target is built.
+# To link your application with the non-optimized RTEMS routines,
+# uncomment the following line:
+# CFLAGS_DEBUG_V += -qrtems_debug
+#
+
+LD_PATHS +=
+LD_LIBS +=
+LDFLAGS +=
+
+#
+# Add your list of files to delete here. The config files
+# already know how to delete some stuff, so you may want
+# to just run 'make clean' first to see what gets missed.
+# 'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+all: ${ARCH} $(SRCS) $(PGMS) ${LIB}
+
+#How to make a relocatable object
+$(filter %.obj, $(PGMS)): ${OBJS}
+ $(make-obj)
+
+#How to make an executable (statically linked)
+$(filter %.exe,$(PGMS)): ${LINK_FILES}
+ $(make-exe)
+ifdef ELFEXT
+ifdef XSYMS
+ $(XSYMS) $(@:%.exe=%.$(ELFEXT)) $(@:%.exe=%.sym)
+endif
+endif
+
+$(LIB): ${OBJS}
+ $(make-library)
+
+ifndef RTEMS_SITE_INSTALLDIR
+RTEMS_SITE_INSTALLDIR = $(PROJECT_RELEASE)
+endif
+
+${RTEMS_SITE_INSTALLDIR}/include \
+${RTEMS_SITE_INSTALLDIR}/lib \
+${RTEMS_SITE_INSTALLDIR}/bin:
+ test -d $@ || mkdir -p $@
+# Install the program(s), appending _g or _p as appropriate.
+# for include files, just use $(INSTALL_CHANGE)
+#
+# - Some BSPs might generate bootable executables in yet another
+# format (such as .srec) and you might need to extend the rule
+# below so the essential files get installed. YMMV.
+ifdef LIBNAME
+install: all $(RTEMS_SITE_INSTALLDIR)/lib
+ $(INSTALL_VARIANT) -m 644 ${LIB} ${RTEMS_SITE_INSTALLDIR}/lib
+else
+install: all $(RTEMS_SITE_INSTALLDIR)/bin
+ $(INSTALL_VARIANT) -m 555 ${PGMS} ${PGMS:%.exe=%.bin} ${PGMS:%.exe=%.sym} ${RTEMS_SITE_INSTALLDIR}/bin
+endif
diff --git a/bsd_eth_drivers/if_em/README.rtems b/bsd_eth_drivers/if_em/README.rtems
new file mode 100644
index 0000000..88fa2fb
--- /dev/null
+++ b/bsd_eth_drivers/if_em/README.rtems
@@ -0,0 +1,66 @@
+RTEMS PORT OF THE 'em' ETHERNET DRIVER
+======================================
+
+This is a port of the intel / FreeBSD 'em' driver as of
+2007/7/4 (checked out from FreeBSD/head on that date).
+
+SUPPORTED BSPs:
+- you need 'libbsdport' which in turn needs 'libbspExt'
+ These work for i386/pc386 and powerpc/new-exception-processing
+ BSPs, i.e., the BSP must implement <rtems/pci.h> and <rtems/irq.h>.
+
+USAGE:
+- to attach this driver:
+ * define a NULL terminated list with all libbsdport supported
+ drivers you want to include with your application:
+
+ extern driver_t libbsdport_em_driver;
+
+ driver_t *libbsdport_netdriver_table[] = {
+ &libbsdport_em_driver,
+ /* other drivers here or upstream of 'em' if they support
+ * the same hardware but are preferred.
+ */
+ 0
+ };
+
+ * specify libbsdport_netdriver_attach for the 'attach' function
+ pointer in struct rtems_bsdnet_ifconfig.
+
+ * use the 'name' field in struct rtems_bsdnet_ifconfig to filter
+ drivers and device instances:
+
+ <driver_name><instance>
+
+ either may be omitted which means that the next available
+ driver/hardware device is to be used. Here are a few examples:
+
+ "" /* use first device found supported by any driver in the
+ * libbsdport_driver_table[].
+ */
+
+ "em2" /* use second device supported by the 'em' driver */
+
+ Notes: Counting instances begins with 1 (not 0).
+ Consult libbsdport/README for more information.
+
+
+KNOWN ISSUES:
+- 'ignore_broadcast' and 'mtu' settings from
+ struct rtems_bsdnet_ifconfig are ignored. I haven't seen
+ many drivers that honour 'ignore_broadcast' and 'mtu' can be
+ set using a ioctl(). I'm trying to keep changes to BSD sources
+ minimal...
+- ring sizes are restricted (driver validates sizes and uses
+ defaults if requested sizes don't meet requirements).
+
+TESTED WITH:
+ 82544 on motorola MVME5500 (PPC MVE board)
+ 82573 on concurrent technologies PP410 (intel x86) board
+
+TESTED ON:
+ rtems-4.7
+ powerpc/beatnik (motorola MVME5500)
+ i386/pc686 (concurrent technologies PP410 compact PCI)
+
+T.S, 200707
diff --git a/bsd_eth_drivers/if_em/freebsd_cvs_status b/bsd_eth_drivers/if_em/freebsd_cvs_status
new file mode 100644
index 0000000..da6f8b8
--- /dev/null
+++ b/bsd_eth_drivers/if_em/freebsd_cvs_status
@@ -0,0 +1,291 @@
+FreeBSD checkout at 2007-07-04 00:49 PDT
+
+? freebsd_cvs_status
+===================================================================
+File: LICENSE Status: Up-to-date
+
+ Working revision: 1.6
+ Repository revision: 1.6 /home/ncvs/src/sys/dev/em/LICENSE,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: README Status: Up-to-date
+
+ Working revision: 1.15
+ Repository revision: 1.15 /home/ncvs/src/sys/dev/em/README,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: e1000_80003es2lan.c Status: Up-to-date
+
+ Working revision: 1.3
+ Repository revision: 1.3 /home/ncvs/src/sys/dev/em/e1000_80003es2lan.c,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: e1000_80003es2lan.h Status: Up-to-date
+
+ Working revision: 1.3
+ Repository revision: 1.3 /home/ncvs/src/sys/dev/em/e1000_80003es2lan.h,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: e1000_82540.c Status: Up-to-date
+
+ Working revision: 1.3
+ Repository revision: 1.3 /home/ncvs/src/sys/dev/em/e1000_82540.c,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: e1000_82541.c Status: Up-to-date
+
+ Working revision: 1.3
+ Repository revision: 1.3 /home/ncvs/src/sys/dev/em/e1000_82541.c,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: e1000_82541.h Status: Up-to-date
+
+ Working revision: 1.3
+ Repository revision: 1.3 /home/ncvs/src/sys/dev/em/e1000_82541.h,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: e1000_82542.c Status: Up-to-date
+
+ Working revision: 1.3
+ Repository revision: 1.3 /home/ncvs/src/sys/dev/em/e1000_82542.c,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: e1000_82543.c Status: Up-to-date
+
+ Working revision: 1.3
+ Repository revision: 1.3 /home/ncvs/src/sys/dev/em/e1000_82543.c,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: e1000_82543.h Status: Up-to-date
+
+ Working revision: 1.3
+ Repository revision: 1.3 /home/ncvs/src/sys/dev/em/e1000_82543.h,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: e1000_82571.c Status: Up-to-date
+
+ Working revision: 1.3
+ Repository revision: 1.3 /home/ncvs/src/sys/dev/em/e1000_82571.c,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: e1000_82571.h Status: Up-to-date
+
+ Working revision: 1.3
+ Repository revision: 1.3 /home/ncvs/src/sys/dev/em/e1000_82571.h,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: e1000_82575.c Status: Up-to-date
+
+ Working revision: 1.3
+ Repository revision: 1.3 /home/ncvs/src/sys/dev/em/e1000_82575.c,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: e1000_82575.h Status: Up-to-date
+
+ Working revision: 1.3
+ Repository revision: 1.3 /home/ncvs/src/sys/dev/em/e1000_82575.h,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: e1000_api.c Status: Up-to-date
+
+ Working revision: 1.3
+ Repository revision: 1.3 /home/ncvs/src/sys/dev/em/e1000_api.c,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: e1000_api.h Status: Up-to-date
+
+ Working revision: 1.3
+ Repository revision: 1.3 /home/ncvs/src/sys/dev/em/e1000_api.h,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: e1000_defines.h Status: Up-to-date
+
+ Working revision: 1.3
+ Repository revision: 1.3 /home/ncvs/src/sys/dev/em/e1000_defines.h,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: e1000_hw.h Status: Up-to-date
+
+ Working revision: 1.3
+ Repository revision: 1.3 /home/ncvs/src/sys/dev/em/e1000_hw.h,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: e1000_ich8lan.c Status: Up-to-date
+
+ Working revision: 1.3
+ Repository revision: 1.3 /home/ncvs/src/sys/dev/em/e1000_ich8lan.c,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: e1000_ich8lan.h Status: Up-to-date
+
+ Working revision: 1.3
+ Repository revision: 1.3 /home/ncvs/src/sys/dev/em/e1000_ich8lan.h,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: e1000_mac.c Status: Up-to-date
+
+ Working revision: 1.3
+ Repository revision: 1.3 /home/ncvs/src/sys/dev/em/e1000_mac.c,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: e1000_mac.h Status: Up-to-date
+
+ Working revision: 1.3
+ Repository revision: 1.3 /home/ncvs/src/sys/dev/em/e1000_mac.h,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: e1000_manage.c Status: Up-to-date
+
+ Working revision: 1.3
+ Repository revision: 1.3 /home/ncvs/src/sys/dev/em/e1000_manage.c,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: e1000_manage.h Status: Up-to-date
+
+ Working revision: 1.3
+ Repository revision: 1.3 /home/ncvs/src/sys/dev/em/e1000_manage.h,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: e1000_nvm.c Status: Up-to-date
+
+ Working revision: 1.3
+ Repository revision: 1.3 /home/ncvs/src/sys/dev/em/e1000_nvm.c,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: e1000_nvm.h Status: Up-to-date
+
+ Working revision: 1.3
+ Repository revision: 1.3 /home/ncvs/src/sys/dev/em/e1000_nvm.h,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: e1000_osdep.h Status: Up-to-date
+
+ Working revision: 1.3
+ Repository revision: 1.3 /home/ncvs/src/sys/dev/em/e1000_osdep.h,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: e1000_phy.c Status: Up-to-date
+
+ Working revision: 1.3
+ Repository revision: 1.3 /home/ncvs/src/sys/dev/em/e1000_phy.c,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: e1000_phy.h Status: Up-to-date
+
+ Working revision: 1.3
+ Repository revision: 1.3 /home/ncvs/src/sys/dev/em/e1000_phy.h,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: e1000_regs.h Status: Up-to-date
+
+ Working revision: 1.3
+ Repository revision: 1.3 /home/ncvs/src/sys/dev/em/e1000_regs.h,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: if_em.c Status: Up-to-date
+
+ Working revision: 1.181
+ Repository revision: 1.181 /home/ncvs/src/sys/dev/em/if_em.c,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: if_em.h Status: Up-to-date
+
+ Working revision: 1.61
+ Repository revision: 1.61 /home/ncvs/src/sys/dev/em/if_em.h,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
diff --git a/bsd_eth_drivers/if_le/Makefile b/bsd_eth_drivers/if_le/Makefile
new file mode 100644
index 0000000..ab71264
--- /dev/null
+++ b/bsd_eth_drivers/if_le/Makefile
@@ -0,0 +1,152 @@
+#
+# Makefile.leaf,v 1.7 2002/07/22 22:56:09 joel Exp
+#
+# Templates/Makefile.leaf
+# Template leaf node Makefile
+#
+#
+LIBNAME=libif_le.a
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=
+
+C_PIECES+=lance am79900 if_le_pci
+
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+# C++ source names, if any, go here -- minus the .cc
+CC_PIECES=
+CC_FILES=$(CC_PIECES:%=%.cc)
+CC_O_FILES=$(CC_PIECES:%=${ARCH}/%.o)
+
+H_FILES=
+
+LINKS+=dev/le/lancereg.h
+LINKS+=dev/le/lancevar.h
+LINKS+=dev/le/am79900reg.h
+LINKS+=dev/le/am79900var.h
+
+# Assembly source names, if any, go here -- minus the .S
+S_PIECES=
+S_FILES=$(S_PIECES:%=%.S)
+S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o)
+
+SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
+OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
+
+# If your PGMS target has the '.exe' extension, a statically
+# linked application is generated.
+# If it has a '.obj' extension, a loadable module is built.
+#
+#
+ifdef LIBNAME
+LIB=${ARCH}/${LIBNAME}
+else
+PGMS=${ARCH}/if_pcn.obj
+endif
+
+# List of RTEMS Classic API Managers to be included in the application
+# goes here. Use:
+# MANAGERS=all
+# to include all RTEMS Classic API Managers in the application or
+# something like this to include a specific set of managers.
+# MANAGERS=io event message rate_monotonic semaphore timer
+#
+# UNUSED for loadable modules
+MANAGERS=ALL
+
+all:
+
+depend: ${LINKS}
+
+ifndef RTEMS_MAKEFILE_PATH
+$(error you need to set the RTEMS_MAKEFILE_PATH environment variable)
+endif
+
+include $(RTEMS_MAKEFILE_PATH)/Makefile.inc
+
+include $(RTEMS_CUSTOM)
+ifdef LIBNAME
+include $(RTEMS_ROOT)/make/lib.cfg
+else
+include $(RTEMS_ROOT)/make/leaf.cfg
+endif
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+#DEFINES += -DLEDEBUG
+CPPFLAGS += -I. -I../libbsdport -I../libbsdport/dummyheaders
+CPPFLAGS += $(CPPFLAGS_82542_SUPPORT_$(ENBL_82542_SUPPORT))
+CFLAGS +=
+
+#
+# CFLAGS_DEBUG_V are used when the `make debug' target is built.
+# To link your application with the non-optimized RTEMS routines,
+# uncomment the following line:
+# CFLAGS_DEBUG_V += -qrtems_debug
+#
+
+LD_PATHS +=
+LD_LIBS +=
+LDFLAGS +=
+
+#
+# Add your list of files to delete here. The config files
+# already know how to delete some stuff, so you may want
+# to just run 'make clean' first to see what gets missed.
+# 'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS += $(sort $(foreach n,$(LINKS),$(firstword $(subst /, ,$(n)))))
+
+all: ${LINKS} ${ARCH} $(SRCS) $(PGMS) ${LIB}
+
+#How to make a relocatable object
+$(filter %.obj, $(PGMS)): ${OBJS}
+ $(make-obj)
+
+#How to make an executable (statically linked)
+$(filter %.exe,$(PGMS)): ${LINK_FILES}
+ $(make-exe)
+ifdef ELFEXT
+ifdef XSYMS
+ $(XSYMS) $(@:%.exe=%.$(ELFEXT)) $(@:%.exe=%.sym)
+endif
+endif
+
+$(LIB): ${OBJS}
+ $(make-library)
+
+ifndef RTEMS_SITE_INSTALLDIR
+RTEMS_SITE_INSTALLDIR = $(PROJECT_RELEASE)
+endif
+
+# for each name listed in LINKS, create parent directories (if needed)
+# and a symlink to file in .
+# E.g., LINKS=a/b/c.h
+# creates a/b/c.h -> ../../c.h
+$(LINKS):
+ @if [ ! -d $(dir $@) ] ; then mkdir -p $(dir $@); fi
+ @ln -s `echo $@ | sed -e 's%[^/]\+[/]\+%../%g'` $@
+
+${RTEMS_SITE_INSTALLDIR}/include \
+${RTEMS_SITE_INSTALLDIR}/lib \
+${RTEMS_SITE_INSTALLDIR}/bin:
+ test -d $@ || mkdir -p $@
+# Install the program(s), appending _g or _p as appropriate.
+# for include files, just use $(INSTALL_CHANGE)
+#
+# - Some BSPs might generate bootable executables in yet another
+# format (such as .srec) and you might need to extend the rule
+# below so the essential files get installed. YMMV.
+ifdef LIBNAME
+install: all $(RTEMS_SITE_INSTALLDIR)/lib
+ $(INSTALL_VARIANT) -m 644 ${LIB} ${RTEMS_SITE_INSTALLDIR}/lib
+else
+install: all $(RTEMS_SITE_INSTALLDIR)/bin
+ $(INSTALL_VARIANT) -m 555 ${PGMS} ${PGMS:%.exe=%.bin} ${PGMS:%.exe=%.sym} ${RTEMS_SITE_INSTALLDIR}/bin
+endif
diff --git a/bsd_eth_drivers/if_le/README.rtems b/bsd_eth_drivers/if_le/README.rtems
new file mode 100644
index 0000000..829e1d8
--- /dev/null
+++ b/bsd_eth_drivers/if_le/README.rtems
@@ -0,0 +1,80 @@
+RTEMS PORT OF THE 'le' ETHERNET DRIVER
+======================================
+
+This is a port of the FreeBSD 'le' driver as of
+2007/7/21 (checked out from FreeBSD/head on that date).
+
+SUPPORTED BSPs:
+- you need 'libbsdport' which in turn needs 'libbspExt'
+ These work for i386/pc386 and powerpc/new-exception-processing
+ BSPs, i.e., the BSP must implement <rtems/pci.h> and <rtems/irq.h>.
+
+USAGE:
+- to attach this driver:
+ * define a NULL terminated list with all libbsdport supported
+ drivers you want to include with your application:
+
+ extern driver_t libbsdport_le_pci_driver;
+
+ driver_t *libbsdport_netdriver_table[] = {
+ &libbsdport_le_pci_driver,
+ /* other drivers here or upstream of 'le' if they support
+ * the same hardware but are preferred.
+ */
+ 0
+ };
+
+ * specify libbsdport_netdriver_attach for the 'attach' function
+ pointer in struct rtems_bsdnet_ifconfig.
+
+ * use the 'name' field in struct rtems_bsdnet_ifconfig to filter
+ drivers and device instances:
+
+ <driver_name><instance>
+
+ either may be omitted which means that the next available
+ driver/hardware device is to be used. Here are a few examples:
+
+ "" /* use first device found supported by any driver in the
+ * libbsdport_driver_table[].
+ */
+
+ "le1" /* use first device supported by the 'le' driver */
+
+ Notes: Counting instances begins with 1 (not 0).
+ Consult libbsdport/README for more information.
+
+
+KNOWN ISSUES:
+- only the PCI module has been ported, so far. No ISA (yet).
+ This means that only the
+ am79900*.*
+ lance*.*
+ if_le_pci.c
+ files are really used. Other files are left here for reference.
+- media status (SIOCGIFMEDIA) doesn't work. sc_mediastatus
+ is not set so the media is always reported as 0.
+- 'ignore_broadcast' and 'mtu' settings from
+ struct rtems_bsdnet_ifconfig are ignored. I haven't seen
+ many drivers that honour 'ignore_broadcast' and 'mtu' can be
+ set using a ioctl(). I'm trying to keep changes to BSD sources
+ minimal...
+- ring sizes are restricted to powers of 2.
+
+OTHER NOTES:
+- you can use the 'pcn' driver for 79C971 and upwards
+ chips. 'pcn' supposedly uses more advanced features
+ of those chips.
+- 'le' works with qemu's 'pcnet32' Am79C970A emulation :-)
+
+TESTED WITH:
+ Technobox 10/100-TX Ethernet PMC (AMD Am79C973 chip)
+ qemu 'pcnet32' emulation
+
+TESTED ON:
+ rtems-4.7
+ powerpc/beatnik (motorola MVME5500 and MVME6100 VME boards)
+ i386/pc686 (concurrent technologies PP410 compact PCI)
+ qemu emulator
+
+T.S, 200707
diff --git a/bsd_eth_drivers/if_le/am7990.c b/bsd_eth_drivers/if_le/am7990.c
new file mode 100644
index 0000000..9768dd8
--- /dev/null
+++ b/bsd_eth_drivers/if_le/am7990.c
@@ -0,0 +1,627 @@
+/* $NetBSD: am7990.c,v 1.68 2005/12/11 12:21:25 christos Exp $ */
+
+/*-
+ * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
+ * Simulation Facility, NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell and Rick Macklem.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)if_le.c 8.2 (Berkeley) 11/16/93
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/sys/dev/le/am7990.c,v 1.4 2006/12/06 02:14:31 marius Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/lock.h>
+#include <sys/mbuf.h>
+#include <sys/mutex.h>
+#include <sys/socket.h>
+
+#include <net/bpf.h>
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_var.h>
+
+#include <machine/bus.h>
+
+#include <dev/le/lancereg.h>
+#include <dev/le/lancevar.h>
+#include <dev/le/am7990reg.h>
+#include <dev/le/am7990var.h>
+
+static void am7990_meminit(struct lance_softc *);
+static void am7990_rint(struct lance_softc *);
+static void am7990_tint(struct lance_softc *);
+static void am7990_start_locked(struct lance_softc *sc);
+
+#ifdef LEDEBUG
+static void am7990_recv_print(struct lance_softc *, int);
+static void am7990_xmit_print(struct lance_softc *, int);
+#endif
+
+int
+am7990_config(struct am7990_softc *sc, const char* name, int unit)
+{
+ int error, mem;
+
+ sc->lsc.sc_meminit = am7990_meminit;
+ sc->lsc.sc_start_locked = am7990_start_locked;
+
+ error = lance_config(&sc->lsc, name, unit);
+ if (error != 0)
+ return (error);
+
+ mem = 0;
+ sc->lsc.sc_initaddr = mem;
+ mem += sizeof(struct leinit);
+ sc->lsc.sc_rmdaddr = mem;
+ mem += sizeof(struct lermd) * sc->lsc.sc_nrbuf;
+ sc->lsc.sc_tmdaddr = mem;
+ mem += sizeof(struct letmd) * sc->lsc.sc_ntbuf;
+ sc->lsc.sc_rbufaddr = mem;
+ mem += LEBLEN * sc->lsc.sc_nrbuf;
+ sc->lsc.sc_tbufaddr = mem;
+ mem += LEBLEN * sc->lsc.sc_ntbuf;
+
+ if (mem > sc->lsc.sc_memsize)
+ panic("%s: memsize", __func__);
+
+ lance_attach(&sc->lsc);
+
+ return (0);
+}
+
+void
+am7990_detach(struct am7990_softc *sc)
+{
+
+ lance_detach(&sc->lsc);
+}
+
+/*
+ * Set up the initialization block and the descriptor rings.
+ */
+static void
+am7990_meminit(struct lance_softc *sc)
+{
+ struct ifnet *ifp = sc->sc_ifp;
+ struct leinit init;
+ struct lermd rmd;
+ struct letmd tmd;
+ u_long a;
+ int bix;
+
+ LE_LOCK_ASSERT(sc, MA_OWNED);
+
+ if (ifp->if_flags & IFF_PROMISC)
+ init.init_mode = LE_MODE_NORMAL | LE_MODE_PROM;
+ else
+ init.init_mode = LE_MODE_NORMAL;
+
+ init.init_padr[0] = (sc->sc_enaddr[1] << 8) | sc->sc_enaddr[0];
+ init.init_padr[1] = (sc->sc_enaddr[3] << 8) | sc->sc_enaddr[2];
+ init.init_padr[2] = (sc->sc_enaddr[5] << 8) | sc->sc_enaddr[4];
+ lance_setladrf(sc, init.init_ladrf);
+
+ sc->sc_last_rd = 0;
+ sc->sc_first_td = sc->sc_last_td = sc->sc_no_td = 0;
+
+ a = sc->sc_addr + LE_RMDADDR(sc, 0);
+ init.init_rdra = a;
+ init.init_rlen = (a >> 16) | ((ffs(sc->sc_nrbuf) - 1) << 13);
+
+ a = sc->sc_addr + LE_TMDADDR(sc, 0);
+ init.init_tdra = a;
+ init.init_tlen = (a >> 16) | ((ffs(sc->sc_ntbuf) - 1) << 13);
+
+ (*sc->sc_copytodesc)(sc, &init, LE_INITADDR(sc), sizeof(init));
+
+ /*
+ * Set up receive ring descriptors.
+ */
+ for (bix = 0; bix < sc->sc_nrbuf; bix++) {
+ a = sc->sc_addr + LE_RBUFADDR(sc, bix);
+ rmd.rmd0 = a;
+ rmd.rmd1_hadr = a >> 16;
+ rmd.rmd1_bits = LE_R1_OWN;
+ rmd.rmd2 = -LEBLEN | LE_XMD2_ONES;
+ rmd.rmd3 = 0;
+ (*sc->sc_copytodesc)(sc, &rmd, LE_RMDADDR(sc, bix),
+ sizeof(rmd));
+ }
+
+ /*
+ * Set up transmit ring descriptors.
+ */
+ for (bix = 0; bix < sc->sc_ntbuf; bix++) {
+ a = sc->sc_addr + LE_TBUFADDR(sc, bix);
+ tmd.tmd0 = a;
+ tmd.tmd1_hadr = a >> 16;
+ tmd.tmd1_bits = 0;
+ tmd.tmd2 = LE_XMD2_ONES;
+ tmd.tmd3 = 0;
+ (*sc->sc_copytodesc)(sc, &tmd, LE_TMDADDR(sc, bix),
+ sizeof(tmd));
+ }
+}
+
+static void
+am7990_rint(struct lance_softc *sc)
+{
+ struct ifnet *ifp = sc->sc_ifp;
+ struct mbuf *m;
+ struct lermd rmd;
+ int bix, rp;
+#if defined(LANCE_REVC_BUG)
+ struct ether_header *eh;
+ /* Make sure this is short-aligned, for ether_cmp(). */
+ static uint16_t bcast_enaddr[3] = { ~0, ~0, ~0 };
+#endif
+
+ bix = sc->sc_last_rd;
+
+ /* Process all buffers with valid data. */
+ for (;;) {
+ rp = LE_RMDADDR(sc, bix);
+ (*sc->sc_copyfromdesc)(sc, &rmd, rp, sizeof(rmd));
+
+ if (rmd.rmd1_bits & LE_R1_OWN)
+ break;
+
+ m = NULL;
+ if ((rmd.rmd1_bits & (LE_R1_ERR | LE_R1_STP | LE_R1_ENP)) !=
+ (LE_R1_STP | LE_R1_ENP)) {
+ if (rmd.rmd1_bits & LE_R1_ERR) {
+#ifdef LEDEBUG
+ if (rmd.rmd1_bits & LE_R1_ENP) {
+ if ((rmd.rmd1_bits & LE_R1_OFLO) == 0) {
+ if (rmd.rmd1_bits & LE_R1_FRAM)
+ if_printf(ifp,
+ "framing error\n");
+ if (rmd.rmd1_bits & LE_R1_CRC)
+ if_printf(ifp,
+ "crc mismatch\n");
+ }
+ } else
+ if (rmd.rmd1_bits & LE_R1_OFLO)
+ if_printf(ifp, "overflow\n");
+#endif
+ if (rmd.rmd1_bits & LE_R1_BUFF)
+ if_printf(ifp,
+ "receive buffer error\n");
+ } else if ((rmd.rmd1_bits & (LE_R1_STP | LE_R1_ENP)) !=
+ (LE_R1_STP | LE_R1_ENP))
+ if_printf(ifp, "dropping chained buffer\n");
+ } else {
+#ifdef LEDEBUG
+ if (sc->sc_flags & LE_DEBUG)
+ am7990_recv_print(sc, bix);
+#endif
+ /* Pull the packet off the interface. */
+ m = lance_get(sc, LE_RBUFADDR(sc, bix),
+ (int)rmd.rmd3 - ETHER_CRC_LEN);
+ }
+
+ rmd.rmd1_bits = LE_R1_OWN;
+ rmd.rmd2 = -LEBLEN | LE_XMD2_ONES;
+ rmd.rmd3 = 0;
+ (*sc->sc_copytodesc)(sc, &rmd, rp, sizeof(rmd));
+
+ if (++bix == sc->sc_nrbuf)
+ bix = 0;
+
+ if (m != NULL) {
+ ifp->if_ipackets++;
+
+#ifdef LANCE_REVC_BUG
+ /*
+ * The old LANCE (Rev. C) chips have a bug which
+ * causes garbage to be inserted in front of the
+ * received packet. The workaround is to ignore
+ * packets with an invalid destination address
+ * (garbage will usually not match).
+ * Of course, this precludes multicast support...
+ */
+ eh = mtod(m, struct ether_header *);
+ if (ether_cmp(eh->ether_dhost, sc->sc_enaddr) &&
+ ether_cmp(eh->ether_dhost, bcast_enaddr)) {
+ m_freem(m);
+ continue;
+ }
+#endif
+
+ /* Pass the packet up. */
+ LE_UNLOCK(sc);
+ (*ifp->if_input)(ifp, m);
+ LE_LOCK(sc);
+ } else
+ ifp->if_ierrors++;
+ }
+
+ sc->sc_last_rd = bix;
+}
+
+static void
+am7990_tint(struct lance_softc *sc)
+{
+ struct ifnet *ifp = sc->sc_ifp;
+ struct letmd tmd;
+ int bix;
+
+ bix = sc->sc_first_td;
+
+ for (;;) {
+ if (sc->sc_no_td <= 0)
+ break;
+
+ (*sc->sc_copyfromdesc)(sc, &tmd, LE_TMDADDR(sc, bix),
+ sizeof(tmd));
+
+#ifdef LEDEBUG
+ if (sc->sc_flags & LE_DEBUG)
+ if_printf(ifp, "trans tmd: "
+ "ladr %04x, hadr %02x, flags %02x, "
+ "bcnt %04x, mcnt %04x\n",
+ tmd.tmd0, tmd.tmd1_hadr, tmd.tmd1_bits,
+ tmd.tmd2, tmd.tmd3);
+#endif
+
+ if (tmd.tmd1_bits & LE_T1_OWN)
+ break;
+
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+
+ if (tmd.tmd1_bits & LE_T1_ERR) {
+ if (tmd.tmd3 & LE_T3_BUFF)
+ if_printf(ifp, "transmit buffer error\n");
+ else if (tmd.tmd3 & LE_T3_UFLO)
+ if_printf(ifp, "underflow\n");
+ if (tmd.tmd3 & (LE_T3_BUFF | LE_T3_UFLO)) {
+ lance_init_locked(sc);
+ return;
+ }
+ if (tmd.tmd3 & LE_T3_LCAR) {
+ if (sc->sc_flags & LE_CARRIER)
+ if_link_state_change(ifp,
+ LINK_STATE_DOWN);
+ sc->sc_flags &= ~LE_CARRIER;
+ if (sc->sc_nocarrier)
+ (*sc->sc_nocarrier)(sc);
+ else
+ if_printf(ifp, "lost carrier\n");
+ }
+ if (tmd.tmd3 & LE_T3_LCOL)
+ ifp->if_collisions++;
+ if (tmd.tmd3 & LE_T3_RTRY) {
+#ifdef LEDEBUG
+ if_printf(ifp, "excessive collisions, tdr %d\n",
+ tmd.tmd3 & LE_T3_TDR_MASK);
+#endif
+ ifp->if_collisions += 16;
+ }
+ ifp->if_oerrors++;
+ } else {
+ if (tmd.tmd1_bits & LE_T1_ONE)
+ ifp->if_collisions++;
+ else if (tmd.tmd1_bits & LE_T1_MORE)
+ /* Real number is unknown. */
+ ifp->if_collisions += 2;
+ ifp->if_opackets++;
+ }
+
+ if (++bix == sc->sc_ntbuf)
+ bix = 0;
+
+ --sc->sc_no_td;
+ }
+
+ sc->sc_first_td = bix;
+
+ sc->sc_wdog_timer = sc->sc_no_td > 0 ? 5 : 0;
+}
+
+/*
+ * Controller interrupt
+ */
+void
+am7990_intr(void *arg)
+{
+ struct lance_softc *sc = arg;
+ struct ifnet *ifp = sc->sc_ifp;
+ uint16_t isr;
+
+ LE_LOCK(sc);
+
+ if (sc->sc_hwintr && (*sc->sc_hwintr)(sc) == -1) {
+ ifp->if_ierrors++;
+ lance_init_locked(sc);
+ LE_UNLOCK(sc);
+ return;
+ }
+
+ isr = (*sc->sc_rdcsr)(sc, LE_CSR0);
+#if defined(LEDEBUG) && LEDEBUG > 1
+ if (sc->sc_flags & LE_DEBUG)
+ if_printf(ifp, "%s: entering with isr=%04x\n", __func__, isr);
+#endif
+ if ((isr & LE_C0_INTR) == 0) {
+ LE_UNLOCK(sc);
+ return;
+ }
+
+ /*
+ * Clear interrupt source flags and turn off interrupts. If we
+ * don't clear these flags before processing their sources we
+ * could completely miss some interrupt events as the NIC can
+ * change these flags while we're in this handler. We turn off
+ * interrupts so we don't get another RX interrupt while still
+ * processing the previous one in ifp->if_input() with the
+ * driver lock dropped.
+ */
+ (*sc->sc_wrcsr)(sc, LE_CSR0, isr & ~(LE_C0_INEA | LE_C0_TDMD |
+ LE_C0_STOP | LE_C0_STRT | LE_C0_INIT));
+
+ if (isr & LE_C0_ERR) {
+ if (isr & LE_C0_BABL) {
+#ifdef LEDEBUG
+ if_printf(ifp, "babble\n");
+#endif
+ ifp->if_oerrors++;
+ }
+#if 0
+ if (isr & LE_C0_CERR) {
+ if_printf(ifp, "collision error\n");
+ ifp->if_collisions++;
+ }
+#endif
+ if (isr & LE_C0_MISS) {
+#ifdef LEDEBUG
+ if_printf(ifp, "missed packet\n");
+#endif
+ ifp->if_ierrors++;
+ }
+ if (isr & LE_C0_MERR) {
+ if_printf(ifp, "memory error\n");
+ lance_init_locked(sc);
+ LE_UNLOCK(sc);
+ return;
+ }
+ }
+
+ if ((isr & LE_C0_RXON) == 0) {
+ if_printf(ifp, "receiver disabled\n");
+ ifp->if_ierrors++;
+ lance_init_locked(sc);
+ LE_UNLOCK(sc);
+ return;
+ }
+ if ((isr & LE_C0_TXON) == 0) {
+ if_printf(ifp, "transmitter disabled\n");
+ ifp->if_oerrors++;
+ lance_init_locked(sc);
+ LE_UNLOCK(sc);
+ return;
+ }
+
+ /*
+ * Pretend we have carrier; if we don't this will be cleared shortly.
+ */
+ if (!(sc->sc_flags & LE_CARRIER))
+ if_link_state_change(ifp, LINK_STATE_UP);
+ sc->sc_flags |= LE_CARRIER;
+
+ if (isr & LE_C0_RINT)
+ am7990_rint(sc);
+ if (isr & LE_C0_TINT)
+ am7990_tint(sc);
+
+ /* Enable interrupts again. */
+ (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INEA);
+
+ if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+ am7990_start_locked(sc);
+
+ LE_UNLOCK(sc);
+}
+
+/*
+ * Set up output on interface.
+ * Get another datagram to send off of the interface queue, and map it to the
+ * interface before starting the output.
+ */
+static void
+am7990_start_locked(struct lance_softc *sc)
+{
+ struct ifnet *ifp = sc->sc_ifp;
+ struct letmd tmd;
+ struct mbuf *m;
+ int bix, enq, len, rp;
+
+ LE_LOCK_ASSERT(sc, MA_OWNED);
+
+ if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
+ IFF_DRV_RUNNING)
+ return;
+
+ bix = sc->sc_last_td;
+ enq = 0;
+
+ for (; sc->sc_no_td < sc->sc_ntbuf &&
+ !IFQ_DRV_IS_EMPTY(&ifp->if_snd);) {
+ rp = LE_TMDADDR(sc, bix);
+ (*sc->sc_copyfromdesc)(sc, &tmd, rp, sizeof(tmd));
+
+ if (tmd.tmd1_bits & LE_T1_OWN) {
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ if_printf(ifp,
+ "missing buffer, no_td = %d, last_td = %d\n",
+ sc->sc_no_td, sc->sc_last_td);
+ }
+
+ IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
+ if (m == 0)
+ break;
+
+ /*
+ * If BPF is listening on this interface, let it see the packet
+ * before we commit it to the wire.
+ */
+ BPF_MTAP(ifp, m);
+
+ /*
+ * Copy the mbuf chain into the transmit buffer.
+ */
+ len = lance_put(sc, LE_TBUFADDR(sc, bix), m);
+
+#ifdef LEDEBUG
+ if (len > ETHERMTU + ETHER_HDR_LEN)
+ if_printf(ifp, "packet length %d\n", len);
+#endif
+
+ /*
+ * Init transmit registers, and set transmit start flag.
+ */
+ tmd.tmd1_bits = LE_T1_OWN | LE_T1_STP | LE_T1_ENP;
+ tmd.tmd2 = -len | LE_XMD2_ONES;
+ tmd.tmd3 = 0;
+
+ (*sc->sc_copytodesc)(sc, &tmd, rp, sizeof(tmd));
+
+#ifdef LEDEBUG
+ if (sc->sc_flags & LE_DEBUG)
+ am7990_xmit_print(sc, bix);
+#endif
+
+ (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INEA | LE_C0_TDMD);
+ enq++;
+
+ if (++bix == sc->sc_ntbuf)
+ bix = 0;
+
+ if (++sc->sc_no_td == sc->sc_ntbuf) {
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ break;
+ }
+ }
+
+ sc->sc_last_td = bix;
+
+ if (enq > 0)
+ sc->sc_wdog_timer = 5;
+}
+
+#ifdef LEDEBUG
+static void
+am7990_recv_print(struct lance_softc *sc, int no)
+{
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ether_header eh;
+ struct lermd rmd;
+ uint16_t len;
+
+ (*sc->sc_copyfromdesc)(sc, &rmd, LE_RMDADDR(sc, no), sizeof(rmd));
+ len = rmd.rmd3;
+ if_printf(ifp, "receive buffer %d, len = %d\n", no, len);
+ if_printf(ifp, "status %04x\n", (*sc->sc_rdcsr)(sc, LE_CSR0));
+ if_printf(ifp,
+ "ladr %04x, hadr %02x, flags %02x, bcnt %04x, mcnt %04x\n",
+ rmd.rmd0, rmd.rmd1_hadr, rmd.rmd1_bits, rmd.rmd2, rmd.rmd3);
+ if (len - ETHER_CRC_LEN >= sizeof(eh)) {
+ (*sc->sc_copyfrombuf)(sc, &eh, LE_RBUFADDR(sc, no), sizeof(eh));
+ if_printf(ifp, "dst %s", ether_sprintf(eh.ether_dhost));
+ printf(" src %s type %04x\n", ether_sprintf(eh.ether_shost),
+ ntohs(eh.ether_type));
+ }
+}
+
+static void
+am7990_xmit_print(struct lance_softc *sc, int no)
+{
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ether_header eh;
+ struct letmd tmd;
+ uint16_t len;
+
+ (*sc->sc_copyfromdesc)(sc, &tmd, LE_TMDADDR(sc, no), sizeof(tmd));
+ len = -tmd.tmd2;
+ if_printf(ifp, "transmit buffer %d, len = %d\n", no, len);
+ if_printf(ifp, "status %04x\n", (*sc->sc_rdcsr)(sc, LE_CSR0));
+ if_printf(ifp,
+ "ladr %04x, hadr %02x, flags %02x, bcnt %04x, mcnt %04x\n",
+ tmd.tmd0, tmd.tmd1_hadr, tmd.tmd1_bits, tmd.tmd2, tmd.tmd3);
+ if (len >= sizeof(eh)) {
+ (*sc->sc_copyfrombuf)(sc, &eh, LE_TBUFADDR(sc, no), sizeof(eh));
+ if_printf(ifp, "dst %s", ether_sprintf(eh.ether_dhost));
+ printf(" src %s type %04x\n", ether_sprintf(eh.ether_shost),
+ ntohs(eh.ether_type));
+ }
+}
+#endif /* LEDEBUG */
diff --git a/bsd_eth_drivers/if_le/if_le_cbus.c b/bsd_eth_drivers/if_le/if_le_cbus.c
new file mode 100644
index 0000000..40d0e19
--- /dev/null
+++ b/bsd_eth_drivers/if_le/if_le_cbus.c
@@ -0,0 +1,451 @@
+/*-
+ * Copyright (c) 1994-2000
+ * Paul Richards. All rights reserved.
+ *
+ * PC-98 port by Chiharu Shibata & FreeBSD(98) porting team.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * verbatim and that no modifications are made prior to this
+ * point in the file.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name Paul Richards may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY PAUL RICHARDS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL PAUL RICHARDS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: FreeBSD: src/sys/dev/lnc/if_lnc_cbus.c,v 1.12 2005/11/12 19:14:21
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/sys/dev/le/if_le_cbus.c,v 1.5 2007/02/23 12:18:45 piso Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/socket.h>
+
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_media.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <isa/isavar.h>
+
+#include <dev/le/lancereg.h>
+#include <dev/le/lancevar.h>
+#include <dev/le/am7990var.h>
+
+#define LE_CBUS_MEMSIZE (16*1024)
+#define CNET98S_IOSIZE 32
+#define CNET98S_RDP 0x10
+#define CNET98S_RAP 0x12
+#define CNET98S_RESET 0x14
+#define CNET98S_BDP 0x16
+
+struct le_cbus_softc {
+ struct am7990_softc sc_am7990; /* glue to MI code */
+
+ int sc_rrid;
+ struct resource *sc_rres;
+ bus_space_tag_t sc_regt;
+ bus_space_handle_t sc_regh;
+
+ int sc_irid;
+ struct resource *sc_ires;
+ void *sc_ih;
+
+ bus_dma_tag_t sc_pdmat;
+ bus_dma_tag_t sc_dmat;
+ bus_dmamap_t sc_dmam;
+};
+
+static device_probe_t le_cbus_probe;
+static device_attach_t le_cbus_attach;
+static device_detach_t le_cbus_detach;
+static device_resume_t le_cbus_resume;
+static device_suspend_t le_cbus_suspend;
+
+static device_method_t le_cbus_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, le_cbus_probe),
+ DEVMETHOD(device_attach, le_cbus_attach),
+ DEVMETHOD(device_detach, le_cbus_detach),
+ /* We can just use the suspend method here. */
+ DEVMETHOD(device_shutdown, le_cbus_suspend),
+ DEVMETHOD(device_suspend, le_cbus_suspend),
+ DEVMETHOD(device_resume, le_cbus_resume),
+
+ { 0, 0 }
+};
+
+DEFINE_CLASS_0(le, le_cbus_driver, le_cbus_methods, sizeof(struct le_cbus_softc));
+DRIVER_MODULE(le, isa, le_cbus_driver, le_devclass, 0, 0);
+MODULE_DEPEND(le, ether, 1, 1, 1);
+
+static bus_addr_t le_ioaddr_cnet98s[CNET98S_IOSIZE] = {
+ 0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007,
+ 0x008, 0x009, 0x00a, 0x00b, 0x00c, 0x00d, 0x00e, 0x00f,
+ 0x400, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407,
+ 0x408, 0x409, 0x40a, 0x40b, 0x40c, 0x40d, 0x40e, 0x40f,
+};
+
+static void le_cbus_wrbcr(struct lance_softc *, uint16_t, uint16_t);
+#ifdef LEDEBUG
+static uint16_t le_cbus_rdbcr(struct lance_softc *, uint16_t);
+#endif
+static void le_cbus_wrcsr(struct lance_softc *, uint16_t, uint16_t);
+static uint16_t le_cbus_rdcsr(struct lance_softc *, uint16_t);
+static void le_cbus_hwreset(struct lance_softc *);
+static bus_dmamap_callback_t le_cbus_dma_callback;
+
+static void
+le_cbus_wrbcr(struct lance_softc *sc, uint16_t port, uint16_t val)
+{
+ struct le_cbus_softc *lesc = (struct le_cbus_softc *)sc;
+
+ bus_space_write_2(lesc->sc_regt, lesc->sc_regh, CNET98S_RAP, port);
+ bus_space_barrier(lesc->sc_regt, lesc->sc_regh, CNET98S_RAP, 2,
+ BUS_SPACE_BARRIER_WRITE);
+ bus_space_write_2(lesc->sc_regt, lesc->sc_regh, CNET98S_BDP, val);
+}
+
+#ifdef LEDEBUG
+static uint16_t
+le_cbus_rdbcr(struct lance_softc *sc, uint16_t port)
+{
+ struct le_cbus_softc *lesc = (struct le_cbus_softc *)sc;
+
+ bus_space_write_2(lesc->sc_regt, lesc->sc_regh, CNET98S_RAP, port);
+ bus_space_barrier(lesc->sc_regt, lesc->sc_regh, CNET98S_RAP, 2,
+ BUS_SPACE_BARRIER_WRITE);
+ return (bus_space_read_2(lesc->sc_regt, lesc->sc_regh, CNET98S_BDP));
+}
+#endif
+
+static void
+le_cbus_wrcsr(struct lance_softc *sc, uint16_t port, uint16_t val)
+{
+ struct le_cbus_softc *lesc = (struct le_cbus_softc *)sc;
+
+ bus_space_write_2(lesc->sc_regt, lesc->sc_regh, CNET98S_RAP, port);
+ bus_space_barrier(lesc->sc_regt, lesc->sc_regh, CNET98S_RAP, 2,
+ BUS_SPACE_BARRIER_WRITE);
+ bus_space_write_2(lesc->sc_regt, lesc->sc_regh, CNET98S_RDP, val);
+}
+
+static uint16_t
+le_cbus_rdcsr(struct lance_softc *sc, uint16_t port)
+{
+ struct le_cbus_softc *lesc = (struct le_cbus_softc *)sc;
+
+ bus_space_write_2(lesc->sc_regt, lesc->sc_regh, CNET98S_RAP, port);
+ bus_space_barrier(lesc->sc_regt, lesc->sc_regh, CNET98S_RAP, 2,
+ BUS_SPACE_BARRIER_WRITE);
+ return (bus_space_read_2(lesc->sc_regt, lesc->sc_regh, CNET98S_RDP));
+}
+
+static void
+le_cbus_hwreset(struct lance_softc *sc)
+{
+ struct le_cbus_softc *lesc = (struct le_cbus_softc *)sc;
+
+ /*
+ * NB: These are Contec C-NET(98)S only.
+ */
+
+ /* Reset the chip. */
+ bus_space_write_2(lesc->sc_regt, lesc->sc_regh, CNET98S_RESET,
+ bus_space_read_2(lesc->sc_regt, lesc->sc_regh, CNET98S_RESET));
+ DELAY(500);
+
+ /* ISA bus configuration */
+ /* ISACSR0 - set Master Mode Read Active time to 300ns. */
+ le_cbus_wrbcr(sc, LE_BCR0, 0x0006);
+ /* ISACSR1 - set Master Mode Write Active time to 300ns. */
+ le_cbus_wrbcr(sc, LE_BCR1, 0x0006);
+#ifdef LEDEBUG
+ device_printf(dev, "ISACSR2=0x%x\n", le_cbus_rdbcr(sc, LE_BCR2));
+#endif
+ /* ISACSR5 - LED1 */
+ le_cbus_wrbcr(sc, LE_BCR5, LE_B4_PSE | LE_B4_XMTE);
+ /* ISACSR6 - LED2 */
+ le_cbus_wrbcr(sc, LE_BCR6, LE_B4_PSE | LE_B4_RCVE);
+ /* ISACSR7 - LED3 */
+ le_cbus_wrbcr(sc, LE_BCR7, LE_B4_PSE | LE_B4_COLE);
+}
+
+static void
+le_cbus_dma_callback(void *xsc, bus_dma_segment_t *segs, int nsegs, int error)
+{
+ struct lance_softc *sc = (struct lance_softc *)xsc;
+
+ if (error != 0)
+ return;
+ KASSERT(nsegs == 1, ("%s: bad DMA segment count", __func__));
+ sc->sc_addr = segs[0].ds_addr;
+}
+
+static int
+le_cbus_probe(device_t dev)
+{
+ struct le_cbus_softc *lesc;
+ struct lance_softc *sc;
+ int error;
+
+ /*
+ * Skip PnP devices as some wedge when trying to probe them as
+ * C-NET(98)S.
+ */
+ if (isa_get_vendorid(dev))
+ return (ENXIO);
+
+ lesc = device_get_softc(dev);
+ sc = &lesc->sc_am7990.lsc;
+
+ lesc->sc_rrid = 0;
+ lesc->sc_rres = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &lesc->sc_rrid,
+ le_ioaddr_cnet98s, CNET98S_IOSIZE, RF_ACTIVE);
+ if (lesc->sc_rres == NULL)
+ return (ENXIO);
+ isa_load_resourcev(lesc->sc_rres, le_ioaddr_cnet98s, CNET98S_IOSIZE);
+ lesc->sc_regt = rman_get_bustag(lesc->sc_rres);
+ lesc->sc_regh = rman_get_bushandle(lesc->sc_rres);
+
+ /* Reset the chip. */
+ bus_space_write_2(lesc->sc_regt, lesc->sc_regh, CNET98S_RESET,
+ bus_space_read_2(lesc->sc_regt, lesc->sc_regh, CNET98S_RESET));
+ DELAY(500);
+
+ /* Stop the chip and put it in a known state. */
+ le_cbus_wrcsr(sc, LE_CSR0, LE_C0_STOP);
+ DELAY(100);
+ if (le_cbus_rdcsr(sc, LE_CSR0) != LE_C0_STOP) {
+ error = ENXIO;
+ goto fail;
+ }
+ le_cbus_wrcsr(sc, LE_CSR3, 0);
+ device_set_desc(dev, "C-NET(98)S");
+ error = BUS_PROBE_DEFAULT;
+
+ fail:
+ bus_release_resource(dev, SYS_RES_IOPORT, lesc->sc_rrid, lesc->sc_rres);
+ return (error);
+}
+
+static int
+le_cbus_attach(device_t dev)
+{
+ struct le_cbus_softc *lesc;
+ struct lance_softc *sc;
+ int error, i;
+
+ lesc = device_get_softc(dev);
+ sc = &lesc->sc_am7990.lsc;
+
+ LE_LOCK_INIT(sc, device_get_nameunit(dev));
+
+ lesc->sc_rrid = 0;
+ lesc->sc_rres = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &lesc->sc_rrid,
+ le_ioaddr_cnet98s, CNET98S_IOSIZE, RF_ACTIVE);
+ if (lesc->sc_rres == NULL) {
+ device_printf(dev, "cannot allocate registers\n");
+ error = ENXIO;
+ goto fail_mtx;
+ }
+ isa_load_resourcev(lesc->sc_rres, le_ioaddr_cnet98s, CNET98S_IOSIZE);
+ lesc->sc_regt = rman_get_bustag(lesc->sc_rres);
+ lesc->sc_regh = rman_get_bushandle(lesc->sc_rres);
+
+ lesc->sc_irid = 0;
+ if ((lesc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ,
+ &lesc->sc_irid, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
+ device_printf(dev, "cannot allocate interrupt\n");
+ error = ENXIO;
+ goto fail_rres;
+ }
+
+ error = bus_dma_tag_create(
+ bus_get_dma_tag(dev), /* parent */
+ 1, 0, /* alignment, boundary */
+ BUS_SPACE_MAXADDR_24BIT, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ BUS_SPACE_MAXSIZE_32BIT, /* maxsize */
+ 0, /* nsegments */
+ BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
+ 0, /* flags */
+ NULL, NULL, /* lockfunc, lockarg */
+ &lesc->sc_pdmat);
+ if (error != 0) {
+ device_printf(dev, "cannot allocate parent DMA tag\n");
+ goto fail_ires;
+ }
+
+ sc->sc_memsize = LE_CBUS_MEMSIZE;
+ /*
+ * For Am79C90, Am79C961 and Am79C961A the init block must be 2-byte
+ * aligned and the ring descriptors must be 8-byte aligned.
+ */
+ error = bus_dma_tag_create(
+ lesc->sc_pdmat, /* parent */
+ 8, 0, /* alignment, boundary */
+ BUS_SPACE_MAXADDR_24BIT, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ sc->sc_memsize, /* maxsize */
+ 1, /* nsegments */
+ sc->sc_memsize, /* maxsegsize */
+ 0, /* flags */
+ NULL, NULL, /* lockfunc, lockarg */
+ &lesc->sc_dmat);
+ if (error != 0) {
+ device_printf(dev, "cannot allocate buffer DMA tag\n");
+ goto fail_pdtag;
+ }
+
+ error = bus_dmamem_alloc(lesc->sc_dmat, (void **)&sc->sc_mem,
+ BUS_DMA_WAITOK | BUS_DMA_COHERENT, &lesc->sc_dmam);
+ if (error != 0) {
+ device_printf(dev, "cannot allocate DMA buffer memory\n");
+ goto fail_dtag;
+ }
+
+ sc->sc_addr = 0;
+ error = bus_dmamap_load(lesc->sc_dmat, lesc->sc_dmam, sc->sc_mem,
+ sc->sc_memsize, le_cbus_dma_callback, sc, 0);
+ if (error != 0 || sc->sc_addr == 0) {
+ device_printf(dev, "cannot load DMA buffer map\n");
+ goto fail_dmem;
+ }
+
+ sc->sc_flags = 0;
+ sc->sc_conf3 = 0;
+
+ /*
+ * Extract the physical MAC address from the ROM.
+ */
+ for (i = 0; i < sizeof(sc->sc_enaddr); i++)
+ sc->sc_enaddr[i] = bus_space_read_1(lesc->sc_regt,
+ lesc->sc_regh, i * 2);
+
+ sc->sc_copytodesc = lance_copytobuf_contig;
+ sc->sc_copyfromdesc = lance_copyfrombuf_contig;
+ sc->sc_copytobuf = lance_copytobuf_contig;
+ sc->sc_copyfrombuf = lance_copyfrombuf_contig;
+ sc->sc_zerobuf = lance_zerobuf_contig;
+
+ sc->sc_rdcsr = le_cbus_rdcsr;
+ sc->sc_wrcsr = le_cbus_wrcsr;
+ sc->sc_hwreset = le_cbus_hwreset;
+ sc->sc_hwinit = NULL;
+ sc->sc_hwintr = NULL;
+ sc->sc_nocarrier = NULL;
+ sc->sc_mediachange = NULL;
+ sc->sc_mediastatus = NULL;
+ sc->sc_supmedia = NULL;
+
+ error = am7990_config(&lesc->sc_am7990, device_get_name(dev),
+ device_get_unit(dev));
+ if (error != 0) {
+ device_printf(dev, "cannot attach Am7990\n");
+ goto fail_dmap;
+ }
+
+ error = bus_setup_intr(dev, lesc->sc_ires, INTR_TYPE_NET | INTR_MPSAFE,
+ NULL, am7990_intr, sc, &lesc->sc_ih);
+ if (error != 0) {
+ device_printf(dev, "cannot set up interrupt\n");
+ goto fail_am7990;
+ }
+
+ return (0);
+
+ fail_am7990:
+ am7990_detach(&lesc->sc_am7990);
+ fail_dmap:
+ bus_dmamap_unload(lesc->sc_dmat, lesc->sc_dmam);
+ fail_dmem:
+ bus_dmamem_free(lesc->sc_dmat, sc->sc_mem, lesc->sc_dmam);
+ fail_dtag:
+ bus_dma_tag_destroy(lesc->sc_dmat);
+ fail_pdtag:
+ bus_dma_tag_destroy(lesc->sc_pdmat);
+ fail_ires:
+ bus_release_resource(dev, SYS_RES_IRQ, lesc->sc_irid, lesc->sc_ires);
+ fail_rres:
+ bus_release_resource(dev, SYS_RES_IOPORT, lesc->sc_rrid, lesc->sc_rres);
+ fail_mtx:
+ LE_LOCK_DESTROY(sc);
+ return (error);
+}
+
+static int
+le_cbus_detach(device_t dev)
+{
+ struct le_cbus_softc *lesc;
+ struct lance_softc *sc;
+
+ lesc = device_get_softc(dev);
+ sc = &lesc->sc_am7990.lsc;
+
+ bus_teardown_intr(dev, lesc->sc_ires, lesc->sc_ih);
+ am7990_detach(&lesc->sc_am7990);
+ bus_dmamap_unload(lesc->sc_dmat, lesc->sc_dmam);
+ bus_dmamem_free(lesc->sc_dmat, sc->sc_mem, lesc->sc_dmam);
+ bus_dma_tag_destroy(lesc->sc_dmat);
+ bus_dma_tag_destroy(lesc->sc_pdmat);
+ bus_release_resource(dev, SYS_RES_IRQ, lesc->sc_irid, lesc->sc_ires);
+ bus_release_resource(dev, SYS_RES_IOPORT, lesc->sc_rrid, lesc->sc_rres);
+ LE_LOCK_DESTROY(sc);
+
+ return (0);
+}
+
+static int
+le_cbus_suspend(device_t dev)
+{
+ struct le_cbus_softc *lesc;
+
+ lesc = device_get_softc(dev);
+
+ lance_suspend(&lesc->sc_am7990.lsc);
+
+ return (0);
+}
+
+static int
+le_cbus_resume(device_t dev)
+{
+ struct le_cbus_softc *lesc;
+
+ lesc = device_get_softc(dev);
+
+ lance_resume(&lesc->sc_am7990.lsc);
+
+ return (0);
+}
diff --git a/bsd_eth_drivers/if_le/if_le_isa.c b/bsd_eth_drivers/if_le/if_le_isa.c
new file mode 100644
index 0000000..9299943
--- /dev/null
+++ b/bsd_eth_drivers/if_le/if_le_isa.c
@@ -0,0 +1,509 @@
+/* $NetBSD: if_le_isa.c,v 1.41 2005/12/24 20:27:41 perry Exp $ */
+
+/*-
+ * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
+ * Simulation Facility, NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell and Rick Macklem.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)if_le.c 8.2 (Berkeley) 11/16/93
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/sys/dev/le/if_le_isa.c,v 1.4 2007/02/23 12:18:45 piso Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/socket.h>
+
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_media.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <isa/isavar.h>
+
+#include <dev/le/lancereg.h>
+#include <dev/le/lancevar.h>
+#include <dev/le/am7990var.h>
+
+#define LE_ISA_MEMSIZE (16*1024)
+#define PCNET_RDP 0x10
+#define PCNET_RAP 0x12
+
+struct le_isa_softc {
+ struct am7990_softc sc_am7990; /* glue to MI code */
+
+ bus_size_t sc_rap; /* offsets to LANCE... */
+ bus_size_t sc_rdp; /* ...registers */
+
+ int sc_rrid;
+ struct resource *sc_rres;
+ bus_space_tag_t sc_regt;
+ bus_space_handle_t sc_regh;
+
+ int sc_drid;
+ struct resource *sc_dres;
+
+ int sc_irid;
+ struct resource *sc_ires;
+ void *sc_ih;
+
+ bus_dma_tag_t sc_pdmat;
+ bus_dma_tag_t sc_dmat;
+ bus_dmamap_t sc_dmam;
+};
+
+static device_probe_t le_isa_probe;
+static device_attach_t le_isa_attach;
+static device_detach_t le_isa_detach;
+static device_resume_t le_isa_resume;
+static device_suspend_t le_isa_suspend;
+
+static device_method_t le_isa_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, le_isa_probe),
+ DEVMETHOD(device_attach, le_isa_attach),
+ DEVMETHOD(device_detach, le_isa_detach),
+ /* We can just use the suspend method here. */
+ DEVMETHOD(device_shutdown, le_isa_suspend),
+ DEVMETHOD(device_suspend, le_isa_suspend),
+ DEVMETHOD(device_resume, le_isa_resume),
+
+ { 0, 0 }
+};
+
+DEFINE_CLASS_0(le, le_isa_driver, le_isa_methods, sizeof(struct le_isa_softc));
+DRIVER_MODULE(le, isa, le_isa_driver, le_devclass, 0, 0);
+MODULE_DEPEND(le, ether, 1, 1, 1);
+
+struct le_isa_param {
+ const char *name;
+ u_long iosize;
+ bus_size_t rap;
+ bus_size_t rdp;
+ bus_size_t macstart;
+ int macstride;
+} static const le_isa_params[] = {
+ { "BICC Isolan", 24, 0xe, 0xc, 0, 2 },
+ { "Novell NE2100", 16, 0x12, 0x10, 0, 1 }
+};
+
+static struct isa_pnp_id le_isa_ids[] = {
+ { 0x0322690e, "Cabletron E2200 Single Chip" }, /* CSI2203 */
+ { 0x0110490a, "Boca LANCard Combo" }, /* BRI1001 */
+ { 0x0100a60a, "Melco Inc. LGY-IV" }, /* BUF0001 */
+ { 0xd880d041, "Novell NE2100" }, /* PNP80D8 */
+ { 0x0082d041, "Cabletron E2100 Series DNI" }, /* PNP8200 */
+ { 0x3182d041, "AMD AM1500T/AM2100" }, /* PNP8231 */
+ { 0x8c82d041, "AMD PCnet-ISA" }, /* PNP828C */
+ { 0x8d82d041, "AMD PCnet-32" }, /* PNP828D */
+ { 0xcefaedfe, "Racal InterLan EtherBlaster" }, /* _WMFACE */
+ { 0, NULL }
+};
+
+static void le_isa_wrcsr(struct lance_softc *, uint16_t, uint16_t);
+static uint16_t le_isa_rdcsr(struct lance_softc *, uint16_t);
+static bus_dmamap_callback_t le_isa_dma_callback;
+static int le_isa_probe_legacy(device_t, const struct le_isa_param *);
+
+static void
+le_isa_wrcsr(struct lance_softc *sc, uint16_t port, uint16_t val)
+{
+ struct le_isa_softc *lesc = (struct le_isa_softc *)sc;
+
+ bus_space_write_2(lesc->sc_regt, lesc->sc_regh, lesc->sc_rap, port);
+ bus_space_barrier(lesc->sc_regt, lesc->sc_regh, lesc->sc_rap, 2,
+ BUS_SPACE_BARRIER_WRITE);
+ bus_space_write_2(lesc->sc_regt, lesc->sc_regh, lesc->sc_rdp, val);
+}
+
+static uint16_t
+le_isa_rdcsr(struct lance_softc *sc, uint16_t port)
+{
+ struct le_isa_softc *lesc = (struct le_isa_softc *)sc;
+
+ bus_space_write_2(lesc->sc_regt, lesc->sc_regh, lesc->sc_rap, port);
+ bus_space_barrier(lesc->sc_regt, lesc->sc_regh, lesc->sc_rap, 2,
+ BUS_SPACE_BARRIER_WRITE);
+ return (bus_space_read_2(lesc->sc_regt, lesc->sc_regh, lesc->sc_rdp));
+}
+
+static void
+le_isa_dma_callback(void *xsc, bus_dma_segment_t *segs, int nsegs, int error)
+{
+ struct lance_softc *sc = (struct lance_softc *)xsc;
+
+ if (error != 0)
+ return;
+ KASSERT(nsegs == 1, ("%s: bad DMA segment count", __func__));
+ sc->sc_addr = segs[0].ds_addr;
+}
+
+static int
+le_isa_probe_legacy(device_t dev, const struct le_isa_param *leip)
+{
+ struct le_isa_softc *lesc;
+ struct lance_softc *sc;
+ int error;
+
+ lesc = device_get_softc(dev);
+ sc = &lesc->sc_am7990.lsc;
+
+ lesc->sc_rrid = 0;
+ lesc->sc_rres = bus_alloc_resource(dev, SYS_RES_IOPORT, &lesc->sc_rrid,
+ 0, ~0, leip->iosize, RF_ACTIVE);
+ if (lesc->sc_rres == NULL)
+ return (ENXIO);
+ lesc->sc_regt = rman_get_bustag(lesc->sc_rres);
+ lesc->sc_regh = rman_get_bushandle(lesc->sc_rres);
+ lesc->sc_rap = leip->rap;
+ lesc->sc_rdp = leip->rdp;
+
+ /* Stop the chip and put it in a known state. */
+ le_isa_wrcsr(sc, LE_CSR0, LE_C0_STOP);
+ DELAY(100);
+ if (le_isa_rdcsr(sc, LE_CSR0) != LE_C0_STOP) {
+ error = ENXIO;
+ goto fail;
+ }
+ le_isa_wrcsr(sc, LE_CSR3, 0);
+ error = 0;
+
+ fail:
+ bus_release_resource(dev, SYS_RES_IOPORT, lesc->sc_rrid, lesc->sc_rres);
+ return (error);
+}
+
+static int
+le_isa_probe(device_t dev)
+{
+ int i;
+
+ switch (ISA_PNP_PROBE(device_get_parent(dev), dev, le_isa_ids)) {
+ case 0:
+ return (BUS_PROBE_DEFAULT);
+ case ENOENT:
+ for (i = 0; i < sizeof(le_isa_params) /
+ sizeof(le_isa_params[0]); i++) {
+ if (le_isa_probe_legacy(dev, &le_isa_params[i]) == 0) {
+ device_set_desc(dev, le_isa_params[i].name);
+ return (BUS_PROBE_DEFAULT);
+ }
+ }
+ /* FALLTHROUGH */
+ case ENXIO:
+ default:
+ return (ENXIO);
+ }
+}
+
+static int
+le_isa_attach(device_t dev)
+{
+ struct le_isa_softc *lesc;
+ struct lance_softc *sc;
+ bus_size_t macstart, rap, rdp;
+ int error, i, macstride;
+
+ lesc = device_get_softc(dev);
+ sc = &lesc->sc_am7990.lsc;
+
+ LE_LOCK_INIT(sc, device_get_nameunit(dev));
+
+ lesc->sc_rrid = 0;
+ switch (ISA_PNP_PROBE(device_get_parent(dev), dev, le_isa_ids)) {
+ case 0:
+ lesc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
+ &lesc->sc_rrid, RF_ACTIVE);
+ rap = PCNET_RAP;
+ rdp = PCNET_RDP;
+ macstart = 0;
+ macstride = 1;
+ break;
+ case ENOENT:
+ for (i = 0; i < sizeof(le_isa_params) /
+ sizeof(le_isa_params[0]); i++) {
+ if (le_isa_probe_legacy(dev, &le_isa_params[i]) == 0) {
+ lesc->sc_rres = bus_alloc_resource(dev,
+ SYS_RES_IOPORT, &lesc->sc_rrid, 0, ~0,
+ le_isa_params[i].iosize, RF_ACTIVE);
+ rap = le_isa_params[i].rap;
+ rdp = le_isa_params[i].rdp;
+ macstart = le_isa_params[i].macstart;
+ macstride = le_isa_params[i].macstride;
+ goto found;
+ }
+ }
+ /* FALLTHROUGH */
+ case ENXIO:
+ default:
+ device_printf(dev, "cannot determine chip\n");
+ error = ENXIO;
+ goto fail_mtx;
+ }
+
+ found:
+ if (lesc->sc_rres == NULL) {
+ device_printf(dev, "cannot allocate registers\n");
+ error = ENXIO;
+ goto fail_mtx;
+ }
+ lesc->sc_regt = rman_get_bustag(lesc->sc_rres);
+ lesc->sc_regh = rman_get_bushandle(lesc->sc_rres);
+ lesc->sc_rap = rap;
+ lesc->sc_rdp = rdp;
+
+ lesc->sc_drid = 0;
+ if ((lesc->sc_dres = bus_alloc_resource_any(dev, SYS_RES_DRQ,
+ &lesc->sc_drid, RF_ACTIVE)) == NULL) {
+ device_printf(dev, "cannot allocate DMA channel\n");
+ error = ENXIO;
+ goto fail_rres;
+ }
+
+ lesc->sc_irid = 0;
+ if ((lesc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ,
+ &lesc->sc_irid, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
+ device_printf(dev, "cannot allocate interrupt\n");
+ error = ENXIO;
+ goto fail_dres;
+ }
+
+ error = bus_dma_tag_create(
+ bus_get_dma_tag(dev), /* parent */
+ 1, 0, /* alignment, boundary */
+ BUS_SPACE_MAXADDR_24BIT, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ BUS_SPACE_MAXSIZE_32BIT, /* maxsize */
+ 0, /* nsegments */
+ BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
+ 0, /* flags */
+ NULL, NULL, /* lockfunc, lockarg */
+ &lesc->sc_pdmat);
+ if (error != 0) {
+ device_printf(dev, "cannot allocate parent DMA tag\n");
+ goto fail_ires;
+ }
+
+ sc->sc_memsize = LE_ISA_MEMSIZE;
+ /*
+ * For Am79C90, Am79C961 and Am79C961A the init block must be 2-byte
+ * aligned and the ring descriptors must be 8-byte aligned.
+ */
+ error = bus_dma_tag_create(
+ lesc->sc_pdmat, /* parent */
+ 8, 0, /* alignment, boundary */
+ BUS_SPACE_MAXADDR_24BIT, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ sc->sc_memsize, /* maxsize */
+ 1, /* nsegments */
+ sc->sc_memsize, /* maxsegsize */
+ 0, /* flags */
+ NULL, NULL, /* lockfunc, lockarg */
+ &lesc->sc_dmat);
+ if (error != 0) {
+ device_printf(dev, "cannot allocate buffer DMA tag\n");
+ goto fail_pdtag;
+ }
+
+ error = bus_dmamem_alloc(lesc->sc_dmat, (void **)&sc->sc_mem,
+ BUS_DMA_WAITOK | BUS_DMA_COHERENT, &lesc->sc_dmam);
+ if (error != 0) {
+ device_printf(dev, "cannot allocate DMA buffer memory\n");
+ goto fail_dtag;
+ }
+
+ sc->sc_addr = 0;
+ error = bus_dmamap_load(lesc->sc_dmat, lesc->sc_dmam, sc->sc_mem,
+ sc->sc_memsize, le_isa_dma_callback, sc, 0);
+ if (error != 0 || sc->sc_addr == 0) {
+ device_printf(dev, "cannot load DMA buffer map\n");
+ goto fail_dmem;
+ }
+
+ isa_dmacascade(rman_get_start(lesc->sc_dres));
+
+ sc->sc_flags = 0;
+ sc->sc_conf3 = 0;
+
+ /*
+ * Extract the physical MAC address from the ROM.
+ */
+ for (i = 0; i < sizeof(sc->sc_enaddr); i++)
+ sc->sc_enaddr[i] = bus_space_read_1(lesc->sc_regt,
+ lesc->sc_regh, macstart + i * macstride);
+
+ sc->sc_copytodesc = lance_copytobuf_contig;
+ sc->sc_copyfromdesc = lance_copyfrombuf_contig;
+ sc->sc_copytobuf = lance_copytobuf_contig;
+ sc->sc_copyfrombuf = lance_copyfrombuf_contig;
+ sc->sc_zerobuf = lance_zerobuf_contig;
+
+ sc->sc_rdcsr = le_isa_rdcsr;
+ sc->sc_wrcsr = le_isa_wrcsr;
+ sc->sc_hwreset = NULL;
+ sc->sc_hwinit = NULL;
+ sc->sc_hwintr = NULL;
+ sc->sc_nocarrier = NULL;
+ sc->sc_mediachange = NULL;
+ sc->sc_mediastatus = NULL;
+ sc->sc_supmedia = NULL;
+
+ error = am7990_config(&lesc->sc_am7990, device_get_name(dev),
+ device_get_unit(dev));
+ if (error != 0) {
+ device_printf(dev, "cannot attach Am7990\n");
+ goto fail_dmap;
+ }
+
+ error = bus_setup_intr(dev, lesc->sc_ires, INTR_TYPE_NET | INTR_MPSAFE,
+ NULL, am7990_intr, sc, &lesc->sc_ih);
+ if (error != 0) {
+ device_printf(dev, "cannot set up interrupt\n");
+ goto fail_am7990;
+ }
+
+ return (0);
+
+ fail_am7990:
+ am7990_detach(&lesc->sc_am7990);
+ fail_dmap:
+ bus_dmamap_unload(lesc->sc_dmat, lesc->sc_dmam);
+ fail_dmem:
+ bus_dmamem_free(lesc->sc_dmat, sc->sc_mem, lesc->sc_dmam);
+ fail_dtag:
+ bus_dma_tag_destroy(lesc->sc_dmat);
+ fail_pdtag:
+ bus_dma_tag_destroy(lesc->sc_pdmat);
+ fail_ires:
+ bus_release_resource(dev, SYS_RES_IRQ, lesc->sc_irid, lesc->sc_ires);
+ fail_dres:
+ bus_release_resource(dev, SYS_RES_DRQ, lesc->sc_drid, lesc->sc_dres);
+ fail_rres:
+ bus_release_resource(dev, SYS_RES_IOPORT, lesc->sc_rrid, lesc->sc_rres);
+ fail_mtx:
+ LE_LOCK_DESTROY(sc);
+ return (error);
+}
+
+static int
+le_isa_detach(device_t dev)
+{
+ struct le_isa_softc *lesc;
+ struct lance_softc *sc;
+
+ lesc = device_get_softc(dev);
+ sc = &lesc->sc_am7990.lsc;
+
+ bus_teardown_intr(dev, lesc->sc_ires, lesc->sc_ih);
+ am7990_detach(&lesc->sc_am7990);
+ bus_dmamap_unload(lesc->sc_dmat, lesc->sc_dmam);
+ bus_dmamem_free(lesc->sc_dmat, sc->sc_mem, lesc->sc_dmam);
+ bus_dma_tag_destroy(lesc->sc_dmat);
+ bus_dma_tag_destroy(lesc->sc_pdmat);
+ bus_release_resource(dev, SYS_RES_IRQ, lesc->sc_irid, lesc->sc_ires);
+ bus_release_resource(dev, SYS_RES_DRQ, lesc->sc_drid, lesc->sc_dres);
+ bus_release_resource(dev, SYS_RES_IOPORT, lesc->sc_rrid, lesc->sc_rres);
+ LE_LOCK_DESTROY(sc);
+
+ return (0);
+}
+
+static int
+le_isa_suspend(device_t dev)
+{
+ struct le_isa_softc *lesc;
+
+ lesc = device_get_softc(dev);
+
+ lance_suspend(&lesc->sc_am7990.lsc);
+
+ return (0);
+}
+
+static int
+le_isa_resume(device_t dev)
+{
+ struct le_isa_softc *lesc;
+
+ lesc = device_get_softc(dev);
+
+ lance_resume(&lesc->sc_am7990.lsc);
+
+ return (0);
+}
diff --git a/bsd_eth_drivers/if_le/if_le_lebuffer.c b/bsd_eth_drivers/if_le/if_le_lebuffer.c
new file mode 100644
index 0000000..5ad8d31
--- /dev/null
+++ b/bsd_eth_drivers/if_le/if_le_lebuffer.c
@@ -0,0 +1,408 @@
+/*-
+ * Copyright (c) 2006 Marius Strobl <marius@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/sys/dev/le/if_le_lebuffer.c,v 1.2 2007/02/23 12:18:45 piso Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/socket.h>
+
+#include <dev/ofw/ofw_bus.h>
+
+#include <machine/bus.h>
+#include <machine/ofw_machdep.h>
+#include <machine/resource.h>
+
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_media.h>
+
+#include <dev/le/lancereg.h>
+#include <dev/le/lancevar.h>
+#include <dev/le/am7990reg.h>
+#include <dev/le/am7990var.h>
+
+/*
+ * LANCE registers
+ */
+#define LEREG1_RDP 0 /* Register Data port */
+#define LEREG1_RAP 2 /* Register Address port */
+
+struct le_lebuffer_softc {
+ struct am7990_softc sc_am7990; /* glue to MI code */
+
+ int sc_brid;
+ struct resource *sc_bres;
+ bus_space_tag_t sc_buft;
+ bus_space_handle_t sc_bufh;
+
+ int sc_rrid;
+ struct resource *sc_rres;
+ bus_space_tag_t sc_regt;
+ bus_space_handle_t sc_regh;
+
+ int sc_irid;
+ struct resource *sc_ires;
+ void *sc_ih;
+};
+
+static devclass_t le_lebuffer_devclass;
+
+static device_probe_t le_lebuffer_probe;
+static device_attach_t le_lebuffer_attach;
+static device_detach_t le_lebuffer_detach;
+static device_resume_t le_buffer_resume;
+static device_suspend_t le_buffer_suspend;
+
+static device_method_t le_lebuffer_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, le_lebuffer_probe),
+ DEVMETHOD(device_attach, le_lebuffer_attach),
+ DEVMETHOD(device_detach, le_lebuffer_detach),
+ /* We can just use the suspend method here. */
+ DEVMETHOD(device_shutdown, le_buffer_suspend),
+ DEVMETHOD(device_suspend, le_buffer_suspend),
+ DEVMETHOD(device_resume, le_buffer_resume),
+
+ { 0, 0 }
+};
+
+DEFINE_CLASS_0(le, le_lebuffer_driver, le_lebuffer_methods,
+ sizeof(struct le_lebuffer_softc));
+DRIVER_MODULE(le, lebuffer, le_lebuffer_driver, le_lebuffer_devclass, 0, 0);
+MODULE_DEPEND(le, ether, 1, 1, 1);
+
+/*
+ * Media types supported
+ */
+static const int le_lebuffer_media[] = {
+ IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, 0)
+};
+#define NLEMEDIA \
+ (sizeof(le_lebuffer_media) / sizeof(le_lebuffer_media[0]))
+
+static void le_lebuffer_wrcsr(struct lance_softc *, uint16_t, uint16_t);
+static uint16_t le_lebuffer_rdcsr(struct lance_softc *, uint16_t);
+static void le_lebuffer_copytodesc(struct lance_softc *, void *, int, int);
+static void le_lebuffer_copyfromdesc(struct lance_softc *, void *, int, int);
+static void le_lebuffer_copytobuf(struct lance_softc *, void *, int, int);
+static void le_lebuffer_copyfrombuf(struct lance_softc *, void *, int, int);
+static void le_lebuffer_zerobuf(struct lance_softc *, int, int);
+
+static void
+le_lebuffer_wrcsr(struct lance_softc *sc, uint16_t port, uint16_t val)
+{
+ struct le_lebuffer_softc *lesc = (struct le_lebuffer_softc *)sc;
+
+ bus_space_write_2(lesc->sc_regt, lesc->sc_regh, LEREG1_RAP, port);
+ bus_space_barrier(lesc->sc_regt, lesc->sc_regh, LEREG1_RAP, 2,
+ BUS_SPACE_BARRIER_WRITE);
+ bus_space_write_2(lesc->sc_regt, lesc->sc_regh, LEREG1_RDP, val);
+}
+
+static uint16_t
+le_lebuffer_rdcsr(struct lance_softc *sc, uint16_t port)
+{
+ struct le_lebuffer_softc *lesc = (struct le_lebuffer_softc *)sc;
+
+ bus_space_write_2(lesc->sc_regt, lesc->sc_regh, LEREG1_RAP, port);
+ bus_space_barrier(lesc->sc_regt, lesc->sc_regh, LEREG1_RAP, 2,
+ BUS_SPACE_BARRIER_WRITE);
+ return (bus_space_read_2(lesc->sc_regt, lesc->sc_regh, LEREG1_RDP));
+}
+
+/*
+ * It turns out that using bus_space(9) to access the buffers and the
+ * descriptors yields way more throughput than accessing them via the
+ * KVA returned by rman_get_virtual(9). The descriptor rings can be
+ * accessed using 8-bit up to 64-bit operations while the buffers can
+ * be only accessed using 8-bit and 16-bit operations.
+ * NB: For whatever reason setting LE_C3_BSWP has no effect with at
+ * least the 501-2981 (although their 'busmaster-regval' property
+ * indicates to set LE_C3_BSWP also for these cards), so we need
+ * to manually byte swap access to the buffers, i.e. the accesses
+ * going through the RX/TX FIFOs.
+ */
+
+static void
+le_lebuffer_copytodesc(struct lance_softc *sc, void *fromv, int off, int len)
+{
+ struct le_lebuffer_softc *lesc = (struct le_lebuffer_softc *)sc;
+ caddr_t from = fromv;
+
+ for (; len >= 8; len -= 8, off += 8, from += 8)
+ bus_space_write_8(lesc->sc_buft, lesc->sc_bufh, off,
+ be64dec(from));
+ for (; len >= 4; len -= 4, off += 4, from += 4)
+ bus_space_write_4(lesc->sc_buft, lesc->sc_bufh, off,
+ be32dec(from));
+ for (; len >= 2; len -= 2, off += 2, from += 2)
+ bus_space_write_2(lesc->sc_buft, lesc->sc_bufh, off,
+ be16dec(from));
+ if (len == 1)
+ bus_space_write_1(lesc->sc_buft, lesc->sc_bufh, off,
+ *from);
+}
+
+static void
+le_lebuffer_copyfromdesc(struct lance_softc *sc, void *tov, int off, int len)
+{
+ struct le_lebuffer_softc *lesc = (struct le_lebuffer_softc *)sc;
+ caddr_t to = tov;
+
+ for (; len >= 8; len -= 8, off += 8, to += 8)
+ be64enc(to,
+ bus_space_read_8(lesc->sc_buft, lesc->sc_bufh, off));
+ for (; len >= 4; len -= 4, off += 4, to += 4)
+ be32enc(to,
+ bus_space_read_4(lesc->sc_buft, lesc->sc_bufh, off));
+ for (; len >= 2; len -= 2, off += 2, to += 2)
+ be16enc(to,
+ bus_space_read_2(lesc->sc_buft, lesc->sc_bufh, off));
+ if (len == 1)
+ *to =
+ bus_space_read_1(lesc->sc_buft, lesc->sc_bufh, off);
+}
+
+static void
+le_lebuffer_copytobuf(struct lance_softc *sc, void *fromv, int off, int len)
+{
+ struct le_lebuffer_softc *lesc = (struct le_lebuffer_softc *)sc;
+ caddr_t from = fromv;
+
+ for (; len >= 2; len -= 2, off += 2, from += 2)
+ bus_space_write_2(lesc->sc_buft, lesc->sc_bufh, off,
+ le16dec(from));
+ if (len == 1)
+ bus_space_write_1(lesc->sc_buft, lesc->sc_bufh, off + 1,
+ *from);
+}
+
+static void
+le_lebuffer_copyfrombuf(struct lance_softc *sc, void *tov, int off, int len)
+{
+ struct le_lebuffer_softc *lesc = (struct le_lebuffer_softc *)sc;
+ caddr_t to = tov;
+
+ for (; len >= 2; len -= 2, off += 2, to += 2)
+ le16enc(to,
+ bus_space_read_2(lesc->sc_buft, lesc->sc_bufh, off));
+ if (len == 1)
+ *to =
+ bus_space_read_1(lesc->sc_buft, lesc->sc_bufh, off + 1);
+}
+
+static void
+le_lebuffer_zerobuf(struct lance_softc *sc, int off, int len)
+{
+ struct le_lebuffer_softc *lesc = (struct le_lebuffer_softc *)sc;
+
+ for (; len >= 2; len -= 2, off += 2)
+ bus_space_write_2(lesc->sc_buft, lesc->sc_bufh, off, 0);
+ if (len == 1)
+ bus_space_write_1(lesc->sc_buft, lesc->sc_bufh, off + 1, 0);
+}
+
+static int
+le_lebuffer_probe(device_t dev)
+{
+
+ if (strcmp(ofw_bus_get_name(dev), "le") == 0) {
+ device_set_desc(dev, "LANCE Ethernet");
+ return (BUS_PROBE_DEFAULT);
+ }
+ return (ENXIO);
+}
+
+static int
+le_lebuffer_attach(device_t dev)
+{
+ struct le_lebuffer_softc *lesc;
+ struct lance_softc *sc;
+ int error;
+
+ lesc = device_get_softc(dev);
+ sc = &lesc->sc_am7990.lsc;
+
+ LE_LOCK_INIT(sc, device_get_nameunit(dev));
+
+ /*
+ * The "register space" of the parent is just a buffer where the
+ * the LANCE descriptor rings and the RX/TX buffers can be stored.
+ */
+ lesc->sc_brid = 0;
+ lesc->sc_bres = bus_alloc_resource_any(device_get_parent(dev),
+ SYS_RES_MEMORY, &lesc->sc_brid, RF_ACTIVE);
+ if (lesc->sc_bres == NULL) {
+ device_printf(dev, "cannot allocate LANCE buffer\n");
+ error = ENXIO;
+ goto fail_mtx;
+ }
+ lesc->sc_buft = rman_get_bustag(lesc->sc_bres);
+ lesc->sc_bufh = rman_get_bushandle(lesc->sc_bres);
+
+ /* Allocate LANCE registers. */
+ lesc->sc_rrid = 0;
+ lesc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+ &lesc->sc_rrid, RF_ACTIVE);
+ if (lesc->sc_rres == NULL) {
+ device_printf(dev, "cannot allocate LANCE registers\n");
+ error = ENXIO;
+ goto fail_bres;
+ }
+ lesc->sc_regt = rman_get_bustag(lesc->sc_rres);
+ lesc->sc_regh = rman_get_bushandle(lesc->sc_rres);
+
+ /* Allocate LANCE interrupt. */
+ lesc->sc_irid = 0;
+ if ((lesc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ,
+ &lesc->sc_irid, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
+ device_printf(dev, "cannot allocate interrupt\n");
+ error = ENXIO;
+ goto fail_rres;
+ }
+
+ /*
+ * LANCE view is offset by buffer location.
+ * Note that we don't use sc->sc_mem.
+ */
+ sc->sc_addr = 0;
+ sc->sc_memsize = rman_get_size(lesc->sc_bres);
+ sc->sc_flags = 0;
+
+ /* That old black magic... */
+ if (OF_getprop(ofw_bus_get_node(dev), "busmaster-regval",
+ &sc->sc_conf3, sizeof(sc->sc_conf3)) == -1)
+ sc->sc_conf3 = LE_C3_ACON | LE_C3_BCON;
+ /*
+ * Make sure LE_C3_BSWP is cleared so that for cards where
+ * that flag actually works le_lebuffer_copy{from,to}buf()
+ * don't fail...
+ */
+ sc->sc_conf3 &= ~LE_C3_BSWP;
+
+ OF_getetheraddr(dev, sc->sc_enaddr);
+
+ sc->sc_copytodesc = le_lebuffer_copytodesc;
+ sc->sc_copyfromdesc = le_lebuffer_copyfromdesc;
+ sc->sc_copytobuf = le_lebuffer_copytobuf;
+ sc->sc_copyfrombuf = le_lebuffer_copyfrombuf;
+ sc->sc_zerobuf = le_lebuffer_zerobuf;
+
+ sc->sc_rdcsr = le_lebuffer_rdcsr;
+ sc->sc_wrcsr = le_lebuffer_wrcsr;
+ sc->sc_hwreset = NULL;
+ sc->sc_hwinit = NULL;
+ sc->sc_hwintr = NULL;
+ sc->sc_nocarrier = NULL;
+ sc->sc_mediachange = NULL;
+ sc->sc_mediastatus = NULL;
+ sc->sc_supmedia = le_lebuffer_media;
+ sc->sc_nsupmedia = NLEMEDIA;
+ sc->sc_defaultmedia = le_lebuffer_media[0];
+
+ error = am7990_config(&lesc->sc_am7990, device_get_name(dev),
+ device_get_unit(dev));
+ if (error != 0) {
+ device_printf(dev, "cannot attach Am7990\n");
+ goto fail_ires;
+ }
+
+ error = bus_setup_intr(dev, lesc->sc_ires, INTR_TYPE_NET | INTR_MPSAFE,
+ NULL, am7990_intr, sc, &lesc->sc_ih);
+ if (error != 0) {
+ device_printf(dev, "cannot set up interrupt\n");
+ goto fail_am7990;
+ }
+
+ return (0);
+
+ fail_am7990:
+ am7990_detach(&lesc->sc_am7990);
+ fail_ires:
+ bus_release_resource(dev, SYS_RES_IRQ, lesc->sc_irid, lesc->sc_ires);
+ fail_rres:
+ bus_release_resource(dev, SYS_RES_MEMORY, lesc->sc_rrid, lesc->sc_rres);
+ fail_bres:
+ bus_release_resource(device_get_parent(dev), SYS_RES_MEMORY,
+ lesc->sc_brid, lesc->sc_bres);
+ fail_mtx:
+ LE_LOCK_DESTROY(sc);
+ return (error);
+}
+
+static int
+le_lebuffer_detach(device_t dev)
+{
+ struct le_lebuffer_softc *lesc;
+ struct lance_softc *sc;
+
+ lesc = device_get_softc(dev);
+ sc = &lesc->sc_am7990.lsc;
+
+ bus_teardown_intr(dev, lesc->sc_ires, lesc->sc_ih);
+ am7990_detach(&lesc->sc_am7990);
+ bus_release_resource(dev, SYS_RES_IRQ, lesc->sc_irid, lesc->sc_ires);
+ bus_release_resource(dev, SYS_RES_MEMORY, lesc->sc_rrid, lesc->sc_rres);
+ bus_release_resource(device_get_parent(dev), SYS_RES_MEMORY,
+ lesc->sc_brid, lesc->sc_bres);
+ LE_LOCK_DESTROY(sc);
+
+ return (0);
+}
+
+static int
+le_buffer_suspend(device_t dev)
+{
+ struct le_lebuffer_softc *lesc;
+
+ lesc = device_get_softc(dev);
+
+ lance_suspend(&lesc->sc_am7990.lsc);
+
+ return (0);
+}
+
+static int
+le_buffer_resume(device_t dev)
+{
+ struct le_lebuffer_softc *lesc;
+
+ lesc = device_get_softc(dev);
+
+ lance_resume(&lesc->sc_am7990.lsc);
+
+ return (0);
+}
diff --git a/bsd_eth_drivers/if_le/if_le_ledma.c b/bsd_eth_drivers/if_le/if_le_ledma.c
new file mode 100644
index 0000000..248b8a0
--- /dev/null
+++ b/bsd_eth_drivers/if_le/if_le_ledma.c
@@ -0,0 +1,490 @@
+/* $NetBSD: if_le_ledma.c,v 1.26 2005/12/11 12:23:44 christos Exp $ */
+
+/*-
+ * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles M. Hannum; Jason R. Thorpe of the Numerical Aerospace
+ * Simulation Facility, NASA Ames Research Center; Paul Kranenburg.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/sys/dev/le/if_le_ledma.c,v 1.4 2007/02/23 12:18:45 piso Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/socket.h>
+
+#include <dev/ofw/ofw_bus.h>
+
+#include <machine/bus.h>
+#include <machine/ofw_machdep.h>
+#include <machine/resource.h>
+
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_media.h>
+
+#include <sparc64/sbus/lsi64854reg.h>
+#include <sparc64/sbus/lsi64854var.h>
+
+#include <dev/le/lancereg.h>
+#include <dev/le/lancevar.h>
+#include <dev/le/am7990var.h>
+
+#define LEDMA_ALIGNMENT 8 /* ring desc. alignmet for NCR92C990 */
+#define LEDMA_BOUNDARY (16*1024*1024) /* must not cross 16MB boundary */
+#define LEDMA_MEMSIZE (16*1024) /* LANCE memory size */
+#define LEREG1_RDP 0 /* Register Data Port */
+#define LEREG1_RAP 2 /* Register Address Port */
+
+struct le_dma_softc {
+ struct am7990_softc sc_am7990; /* glue to MI code */
+
+ int sc_rrid;
+ struct resource *sc_rres;
+ bus_space_tag_t sc_regt;
+ bus_space_handle_t sc_regh;
+
+ int sc_irid;
+ struct resource *sc_ires;
+ void *sc_ih;
+
+ bus_dma_tag_t sc_dmat;
+ bus_dmamap_t sc_dmam;
+ bus_addr_t sc_laddr; /* LANCE DMA address */
+
+ struct lsi64854_softc *sc_dma; /* pointer to DMA engine */
+};
+
+static device_probe_t le_dma_probe;
+static device_attach_t le_dma_attach;
+static device_detach_t le_dma_detach;
+static device_resume_t le_dma_resume;
+static device_suspend_t le_dma_suspend;
+
+static device_method_t le_dma_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, le_dma_probe),
+ DEVMETHOD(device_attach, le_dma_attach),
+ DEVMETHOD(device_detach, le_dma_detach),
+ /* We can just use the suspend method here. */
+ DEVMETHOD(device_shutdown, le_dma_suspend),
+ DEVMETHOD(device_suspend, le_dma_suspend),
+ DEVMETHOD(device_resume, le_dma_resume),
+
+ { 0, 0 }
+};
+
+DEFINE_CLASS_0(le, le_dma_driver, le_dma_methods, sizeof(struct le_dma_softc));
+DRIVER_MODULE(le, dma, le_dma_driver, le_devclass, 0, 0);
+MODULE_DEPEND(le, ether, 1, 1, 1);
+
+/*
+ * Media types supported
+ */
+static const int le_dma_supmedia[] = {
+ IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, 0),
+ IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, 0),
+ IFM_MAKEWORD(IFM_ETHER, IFM_10_5, 0, 0)
+};
+
+static void le_dma_wrcsr(struct lance_softc *, uint16_t, uint16_t);
+static uint16_t le_dma_rdcsr(struct lance_softc *, uint16_t);
+static void le_dma_setutp(struct lance_softc *);
+static void le_dma_setaui(struct lance_softc *);
+static int le_dma_supmediachange(struct lance_softc *);
+static void le_dma_supmediastatus(struct lance_softc *, struct ifmediareq *);
+static void le_dma_hwreset(struct lance_softc *);
+static int le_dma_hwintr(struct lance_softc *);
+static void le_dma_nocarrier(struct lance_softc *);
+static bus_dmamap_callback_t le_dma_dma_callback;
+
+static void
+le_dma_wrcsr(struct lance_softc *sc, uint16_t port, uint16_t val)
+{
+ struct le_dma_softc *lesc = (struct le_dma_softc *)sc;
+
+ bus_space_write_2(lesc->sc_regt, lesc->sc_regh, LEREG1_RAP, port);
+ bus_space_barrier(lesc->sc_regt, lesc->sc_regh, LEREG1_RAP, 2,
+ BUS_SPACE_BARRIER_WRITE);
+ bus_space_write_2(lesc->sc_regt, lesc->sc_regh, LEREG1_RDP, val);
+}
+
+static uint16_t
+le_dma_rdcsr(struct lance_softc *sc, uint16_t port)
+{
+ struct le_dma_softc *lesc = (struct le_dma_softc *)sc;
+
+ bus_space_write_2(lesc->sc_regt, lesc->sc_regh, LEREG1_RAP, port);
+ bus_space_barrier(lesc->sc_regt, lesc->sc_regh, LEREG1_RAP, 2,
+ BUS_SPACE_BARRIER_WRITE);
+ return (bus_space_read_2(lesc->sc_regt, lesc->sc_regh, LEREG1_RDP));
+}
+
+static void
+le_dma_setutp(struct lance_softc *sc)
+{
+ struct lsi64854_softc *dma = ((struct le_dma_softc *)sc)->sc_dma;
+
+ L64854_SCSR(dma, L64854_GCSR(dma) | E_TP_AUI);
+ DELAY(20000); /* We must not touch the LANCE chip for 20ms. */
+}
+
+static void
+le_dma_setaui(struct lance_softc *sc)
+{
+ struct lsi64854_softc *dma = ((struct le_dma_softc *)sc)->sc_dma;
+
+ L64854_SCSR(dma, L64854_GCSR(dma) & ~E_TP_AUI);
+ DELAY(20000); /* We must not touch the LANCE chip for 20ms. */
+}
+
+static int
+le_dma_supmediachange(struct lance_softc *sc)
+{
+ struct ifmedia *ifm = &sc->sc_media;
+
+ if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
+ return (EINVAL);
+
+ /*
+ * Switch to the selected media. If autoselect is set, we don't
+ * really have to do anything. We'll switch to the other media
+ * when we detect loss of carrier.
+ */
+ switch (IFM_SUBTYPE(ifm->ifm_media)) {
+ case IFM_10_T:
+ le_dma_setutp(sc);
+ break;
+
+ case IFM_10_5:
+ le_dma_setaui(sc);
+ break;
+
+ case IFM_AUTO:
+ break;
+
+ default:
+ return (EINVAL);
+ }
+
+ return (0);
+}
+
+static void
+le_dma_supmediastatus(struct lance_softc *sc, struct ifmediareq *ifmr)
+{
+ struct lsi64854_softc *dma = ((struct le_dma_softc *)sc)->sc_dma;
+
+ /*
+ * Notify the world which media we're currently using.
+ */
+ if (L64854_GCSR(dma) & E_TP_AUI)
+ ifmr->ifm_active = IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, 0);
+ else
+ ifmr->ifm_active = IFM_MAKEWORD(IFM_ETHER, IFM_10_5, 0, 0);
+}
+
+static void
+le_dma_hwreset(struct lance_softc *sc)
+{
+ struct le_dma_softc *lesc = (struct le_dma_softc *)sc;
+ struct lsi64854_softc *dma = lesc->sc_dma;
+ uint32_t aui_bit, csr;
+
+ /*
+ * Reset DMA channel.
+ */
+ csr = L64854_GCSR(dma);
+ aui_bit = csr & E_TP_AUI;
+ DMA_RESET(dma);
+
+ /* Write bits 24-31 of Lance address. */
+ bus_space_write_4(dma->sc_regt, dma->sc_regh, L64854_REG_ENBAR,
+ lesc->sc_laddr & 0xff000000);
+
+ DMA_ENINTR(dma);
+
+ /*
+ * Disable E-cache invalidates on chip writes.
+ * Retain previous cable selection bit.
+ */
+ csr = L64854_GCSR(dma);
+ csr |= (E_DSBL_WR_INVAL | aui_bit);
+ L64854_SCSR(dma, csr);
+ DELAY(20000); /* We must not touch the LANCE chip for 20ms. */
+}
+
+static int
+le_dma_hwintr(struct lance_softc *sc)
+{
+ struct le_dma_softc *lesc = (struct le_dma_softc *)sc;
+ struct lsi64854_softc *dma = lesc->sc_dma;
+
+ return (DMA_INTR(dma));
+}
+
+static void
+le_dma_nocarrier(struct lance_softc *sc)
+{
+ struct le_dma_softc *lesc = (struct le_dma_softc *)sc;
+
+ /*
+ * Check if the user has requested a certain cable type, and
+ * if so, honor that request.
+ */
+
+ if (L64854_GCSR(lesc->sc_dma) & E_TP_AUI) {
+ switch (IFM_SUBTYPE(sc->sc_media.ifm_media)) {
+ case IFM_10_5:
+ case IFM_AUTO:
+ if_printf(sc->sc_ifp, "lost carrier on UTP port, "
+ "switching to AUI port\n");
+ le_dma_setaui(sc);
+ }
+ } else {
+ switch (IFM_SUBTYPE(sc->sc_media.ifm_media)) {
+ case IFM_10_T:
+ case IFM_AUTO:
+ if_printf(sc->sc_ifp, "lost carrier on AUI port, "
+ "switching to UTP port\n");
+ le_dma_setutp(sc);
+ }
+ }
+}
+
+static void
+le_dma_dma_callback(void *xsc, bus_dma_segment_t *segs, int nsegs, int error)
+{
+ struct le_dma_softc *lesc = (struct le_dma_softc *)xsc;
+
+ if (error != 0)
+ return;
+ KASSERT(nsegs == 1, ("%s: bad DMA segment count", __func__));
+ lesc->sc_laddr = segs[0].ds_addr;
+}
+
+static int
+le_dma_probe(device_t dev)
+{
+
+ if (strcmp(ofw_bus_get_name(dev), "le") == 0) {
+ device_set_desc(dev, "LANCE Ethernet");
+ return (BUS_PROBE_DEFAULT);
+ }
+ return (ENXIO);
+}
+
+static int
+le_dma_attach(device_t dev)
+{
+ struct le_dma_softc *lesc;
+ struct lsi64854_softc *dma;
+ struct lance_softc *sc;
+ int error;
+
+ lesc = device_get_softc(dev);
+ sc = &lesc->sc_am7990.lsc;
+
+ LE_LOCK_INIT(sc, device_get_nameunit(dev));
+
+ /*
+ * Establish link to `ledma' device.
+ * XXX hackery.
+ */
+ dma = (struct lsi64854_softc *)device_get_softc(device_get_parent(dev));
+ lesc->sc_dma = dma;
+ lesc->sc_dma->sc_client = lesc;
+
+ lesc->sc_rrid = 0;
+ lesc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+ &lesc->sc_rrid, RF_ACTIVE);
+ if (lesc->sc_rres == NULL) {
+ device_printf(dev, "cannot allocate registers\n");
+ error = ENXIO;
+ goto fail_mtx;
+ }
+ lesc->sc_regt = rman_get_bustag(lesc->sc_rres);
+ lesc->sc_regh = rman_get_bushandle(lesc->sc_rres);
+
+ lesc->sc_irid = 0;
+ if ((lesc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ,
+ &lesc->sc_irid, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
+ device_printf(dev, "cannot allocate interrupt\n");
+ error = ENXIO;
+ goto fail_rres;
+ }
+
+ sc->sc_memsize = LEDMA_MEMSIZE;
+ error = bus_dma_tag_create(
+ dma->sc_parent_dmat, /* parent */
+ LEDMA_ALIGNMENT, /* alignment */
+ LEDMA_BOUNDARY, /* boundary */
+ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ sc->sc_memsize, /* maxsize */
+ 1, /* nsegments */
+ sc->sc_memsize, /* maxsegsize */
+ 0, /* flags */
+ NULL, NULL, /* lockfunc, lockarg */
+ &lesc->sc_dmat);
+ if (error != 0) {
+ device_printf(dev, "cannot allocate buffer DMA tag\n");
+ goto fail_ires;
+ }
+
+ error = bus_dmamem_alloc(lesc->sc_dmat, (void **)&sc->sc_mem,
+ BUS_DMA_WAITOK | BUS_DMA_COHERENT, &lesc->sc_dmam);
+ if (error != 0) {
+ device_printf(dev, "cannot allocate DMA buffer memory\n");
+ goto fail_dtag;
+ }
+
+ lesc->sc_laddr = 0;
+ error = bus_dmamap_load(lesc->sc_dmat, lesc->sc_dmam, sc->sc_mem,
+ sc->sc_memsize, le_dma_dma_callback, lesc, 0);
+ if (error != 0 || lesc->sc_laddr == 0) {
+ device_printf(dev, "cannot load DMA buffer map\n");
+ goto fail_dmem;
+ }
+
+ sc->sc_addr = lesc->sc_laddr & 0xffffff;
+ sc->sc_flags = 0;
+ sc->sc_conf3 = LE_C3_BSWP | LE_C3_ACON | LE_C3_BCON;
+
+ sc->sc_mediachange = le_dma_supmediachange;
+ sc->sc_mediastatus = le_dma_supmediastatus;
+ sc->sc_supmedia = le_dma_supmedia;
+ sc->sc_nsupmedia = sizeof(le_dma_supmedia) / sizeof(le_dma_supmedia[0]);
+ sc->sc_defaultmedia = le_dma_supmedia[0];
+
+ OF_getetheraddr(dev, sc->sc_enaddr);
+
+ sc->sc_copytodesc = lance_copytobuf_contig;
+ sc->sc_copyfromdesc = lance_copyfrombuf_contig;
+ sc->sc_copytobuf = lance_copytobuf_contig;
+ sc->sc_copyfrombuf = lance_copyfrombuf_contig;
+ sc->sc_zerobuf = lance_zerobuf_contig;
+
+ sc->sc_rdcsr = le_dma_rdcsr;
+ sc->sc_wrcsr = le_dma_wrcsr;
+ sc->sc_hwreset = le_dma_hwreset;
+ sc->sc_hwintr = le_dma_hwintr;
+ sc->sc_nocarrier = le_dma_nocarrier;
+
+ error = am7990_config(&lesc->sc_am7990, device_get_name(dev),
+ device_get_unit(dev));
+ if (error != 0) {
+ device_printf(dev, "cannot attach Am7990\n");
+ goto fail_dmap;
+ }
+
+ error = bus_setup_intr(dev, lesc->sc_ires, INTR_TYPE_NET | INTR_MPSAFE,
+ NULL, am7990_intr, sc, &lesc->sc_ih);
+ if (error != 0) {
+ device_printf(dev, "cannot set up interrupt\n");
+ goto fail_am7990;
+ }
+
+ return (0);
+
+ fail_am7990:
+ am7990_detach(&lesc->sc_am7990);
+ fail_dmap:
+ bus_dmamap_unload(lesc->sc_dmat, lesc->sc_dmam);
+ fail_dmem:
+ bus_dmamem_free(lesc->sc_dmat, sc->sc_mem, lesc->sc_dmam);
+ fail_dtag:
+ bus_dma_tag_destroy(lesc->sc_dmat);
+ fail_ires:
+ bus_release_resource(dev, SYS_RES_IRQ, lesc->sc_irid, lesc->sc_ires);
+ fail_rres:
+ bus_release_resource(dev, SYS_RES_MEMORY, lesc->sc_rrid, lesc->sc_rres);
+ fail_mtx:
+ LE_LOCK_DESTROY(sc);
+ return (error);
+}
+
+static int
+le_dma_detach(device_t dev)
+{
+ struct le_dma_softc *lesc;
+ struct lance_softc *sc;
+
+ lesc = device_get_softc(dev);
+ sc = &lesc->sc_am7990.lsc;
+
+ bus_teardown_intr(dev, lesc->sc_ires, lesc->sc_ih);
+ am7990_detach(&lesc->sc_am7990);
+ bus_dmamap_unload(lesc->sc_dmat, lesc->sc_dmam);
+ bus_dmamem_free(lesc->sc_dmat, sc->sc_mem, lesc->sc_dmam);
+ bus_dma_tag_destroy(lesc->sc_dmat);
+ bus_release_resource(dev, SYS_RES_IRQ, lesc->sc_irid, lesc->sc_ires);
+ bus_release_resource(dev, SYS_RES_MEMORY, lesc->sc_rrid, lesc->sc_rres);
+ LE_LOCK_DESTROY(sc);
+
+ return (0);
+}
+
+static int
+le_dma_suspend(device_t dev)
+{
+ struct le_dma_softc *lesc;
+
+ lesc = device_get_softc(dev);
+
+ lance_suspend(&lesc->sc_am7990.lsc);
+
+ return (0);
+}
+
+static int
+le_dma_resume(device_t dev)
+{
+ struct le_dma_softc *lesc;
+
+ lesc = device_get_softc(dev);
+
+ lance_resume(&lesc->sc_am7990.lsc);
+
+ return (0);
+}
diff --git a/bsd_eth_drivers/if_le/lebuffer_sbus.c b/bsd_eth_drivers/if_le/lebuffer_sbus.c
new file mode 100644
index 0000000..b9414f2
--- /dev/null
+++ b/bsd_eth_drivers/if_le/lebuffer_sbus.c
@@ -0,0 +1,300 @@
+/*-
+ * Copyright (c) 2006 Marius Strobl <marius@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/sys/dev/le/lebuffer_sbus.c,v 1.1 2007/01/20 12:53:30 marius Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/bus_common.h>
+#include <machine/resource.h>
+
+#include <sparc64/sbus/ofw_sbus.h>
+#include <sparc64/sbus/sbusreg.h>
+#include <sparc64/sbus/sbusvar.h>
+
+struct lebuffer_devinfo {
+ struct ofw_bus_devinfo ldi_obdinfo;
+ struct resource_list ldi_rl;
+};
+
+static devclass_t lebuffer_devclass;
+
+static device_probe_t lebuffer_probe;
+static device_attach_t lebuffer_attach;
+static device_detach_t lebuffer_detach;
+static bus_print_child_t lebuffer_print_child;
+static bus_probe_nomatch_t lebuffer_probe_nomatch;
+static bus_get_resource_list_t lebuffer_get_resource_list;
+static ofw_bus_get_devinfo_t lebuffer_get_devinfo;
+
+static struct lebuffer_devinfo *lebuffer_setup_dinfo(device_t, phandle_t);
+static void lebuffer_destroy_dinfo(struct lebuffer_devinfo *);
+static int lebuffer_print_res(struct lebuffer_devinfo *);
+
+static device_method_t lebuffer_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, lebuffer_probe),
+ DEVMETHOD(device_attach, lebuffer_attach),
+ DEVMETHOD(device_detach, lebuffer_detach),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, lebuffer_print_child),
+ DEVMETHOD(bus_probe_nomatch, lebuffer_probe_nomatch),
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+ DEVMETHOD(bus_alloc_resource, bus_generic_rl_alloc_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_get_resource_list, lebuffer_get_resource_list),
+ DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
+
+ /* ofw_bus interface */
+ DEVMETHOD(ofw_bus_get_devinfo, lebuffer_get_devinfo),
+ DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat),
+ DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model),
+ DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name),
+ DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node),
+ DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type),
+
+ { 0, 0 }
+};
+
+DEFINE_CLASS_0(lebuffer, lebuffer_driver, lebuffer_methods, 1);
+DRIVER_MODULE(lebuffer, sbus, lebuffer_driver, lebuffer_devclass, 0, 0);
+
+static int
+lebuffer_probe(device_t dev)
+{
+ const char *name;
+
+ name = ofw_bus_get_name(dev);
+ if (strcmp(name, "lebuffer") == 0) {
+ device_set_desc_copy(dev, name);
+ return (0);
+ }
+ return (ENXIO);
+}
+
+static int
+lebuffer_attach(device_t dev)
+{
+ struct lebuffer_devinfo *ldi;
+ device_t cdev;
+ phandle_t child;
+ int children;
+
+ children = 0;
+ for (child = OF_child(ofw_bus_get_node(dev)); child != 0;
+ child = OF_peer(child)) {
+ if ((ldi = lebuffer_setup_dinfo(dev, child)) == NULL)
+ continue;
+ if (children != 0) {
+ device_printf(dev,
+ "<%s>: only one child per buffer supported\n",
+ ldi->ldi_obdinfo.obd_name);
+ lebuffer_destroy_dinfo(ldi);
+ continue;
+ }
+ if ((cdev = device_add_child(dev, NULL, -1)) == NULL) {
+ device_printf(dev, "<%s>: device_add_child failed\n",
+ ldi->ldi_obdinfo.obd_name);
+ lebuffer_destroy_dinfo(ldi);
+ continue;
+ }
+ device_set_ivars(cdev, ldi);
+ children++;
+ }
+ return (bus_generic_attach(dev));
+}
+
+static int
+lebuffer_detach(device_t dev)
+{
+ device_t *children;
+ int i, nchildren;
+
+ bus_generic_detach(dev);
+ if (device_get_children(dev, &children, &nchildren) == 0) {
+ for (i = 0; i < nchildren; i++) {
+ lebuffer_destroy_dinfo(device_get_ivars(children[i]));
+ device_delete_child(dev, children[i]);
+ }
+ free(children, M_TEMP);
+ }
+ return (0);
+}
+
+static struct lebuffer_devinfo *
+lebuffer_setup_dinfo(device_t dev, phandle_t node)
+{
+ struct lebuffer_devinfo *ldi;
+ struct sbus_regs *reg;
+ uint32_t base, iv, *intr;
+ int i, nreg, nintr, slot, rslot;
+
+ ldi = malloc(sizeof(*ldi), M_DEVBUF, M_WAITOK | M_ZERO);
+ if (ofw_bus_gen_setup_devinfo(&ldi->ldi_obdinfo, node) != 0) {
+ free(ldi, M_DEVBUF);
+ return (NULL);
+ }
+ resource_list_init(&ldi->ldi_rl);
+ slot = -1;
+ nreg = OF_getprop_alloc(node, "reg", sizeof(*reg), (void **)&reg);
+ if (nreg == -1) {
+ device_printf(dev, "<%s>: incomplete\n",
+ ldi->ldi_obdinfo.obd_name);
+ goto fail;
+ }
+ for (i = 0; i < nreg; i++) {
+ base = reg[i].sbr_offset;
+ if (SBUS_ABS(base)) {
+ rslot = SBUS_ABS_TO_SLOT(base);
+ base = SBUS_ABS_TO_OFFSET(base);
+ } else
+ rslot = reg[i].sbr_slot;
+ if (slot != -1 && slot != rslot) {
+ device_printf(dev, "<%s>: multiple slots\n",
+ ldi->ldi_obdinfo.obd_name);
+ free(reg, M_OFWPROP);
+ goto fail;
+ }
+ slot = rslot;
+
+ resource_list_add(&ldi->ldi_rl, SYS_RES_MEMORY, i, base,
+ base + reg[i].sbr_size, reg[i].sbr_size);
+ }
+ free(reg, M_OFWPROP);
+ if (slot != sbus_get_slot(dev)) {
+ device_printf(dev, "<%s>: parent and child slot do not match\n",
+ ldi->ldi_obdinfo.obd_name);
+ goto fail;
+ }
+
+ /*
+ * The `interrupts' property contains the SBus interrupt level.
+ */
+ nintr = OF_getprop_alloc(node, "interrupts", sizeof(*intr),
+ (void **)&intr);
+ if (nintr != -1) {
+ for (i = 0; i < nintr; i++) {
+ iv = intr[i];
+ /*
+ * SBus card devices need the slot number encoded into
+ * the vector as this is generally not done.
+ */
+ if ((iv & INTMAP_OBIO_MASK) == 0)
+ iv |= slot << 3;
+ /* Set the IGN as appropriate. */
+ iv |= sbus_get_ign(dev) << INTMAP_IGN_SHIFT;
+ resource_list_add(&ldi->ldi_rl, SYS_RES_IRQ, i,
+ iv, iv, 1);
+ }
+ free(intr, M_OFWPROP);
+ }
+ return (ldi);
+
+ fail:
+ lebuffer_destroy_dinfo(ldi);
+ return (NULL);
+}
+
+static void
+lebuffer_destroy_dinfo(struct lebuffer_devinfo *dinfo)
+{
+
+ resource_list_free(&dinfo->ldi_rl);
+ ofw_bus_gen_destroy_devinfo(&dinfo->ldi_obdinfo);
+ free(dinfo, M_DEVBUF);
+}
+
+static int
+lebuffer_print_child(device_t dev, device_t child)
+{
+ int rv;
+
+ rv = bus_print_child_header(dev, child);
+ rv += lebuffer_print_res(device_get_ivars(child));
+ rv += bus_print_child_footer(dev, child);
+ return (rv);
+}
+
+static void
+lebuffer_probe_nomatch(device_t dev, device_t child)
+{
+ const char *type;
+
+ device_printf(dev, "<%s>", ofw_bus_get_name(child));
+ lebuffer_print_res(device_get_ivars(child));
+ type = ofw_bus_get_type(child);
+ printf(" type %s (no driver attached)\n",
+ type != NULL ? type : "unknown");
+}
+
+static struct resource_list *
+lebuffer_get_resource_list(device_t dev, device_t child)
+{
+ struct lebuffer_devinfo *ldi;
+
+ ldi = device_get_ivars(child);
+ return (&ldi->ldi_rl);
+}
+
+static const struct ofw_bus_devinfo *
+lebuffer_get_devinfo(device_t bus, device_t child)
+{
+ struct lebuffer_devinfo *ldi;
+
+ ldi = device_get_ivars(child);
+ return (&ldi->ldi_obdinfo);
+}
+
+static int
+lebuffer_print_res(struct lebuffer_devinfo *ldi)
+{
+ int rv;
+
+ rv = 0;
+ rv += resource_list_print_type(&ldi->ldi_rl, "mem", SYS_RES_MEMORY,
+ "%#lx");
+ rv += resource_list_print_type(&ldi->ldi_rl, "irq", SYS_RES_IRQ, "%ld");
+ return (rv);
+}
diff --git a/bsd_eth_drivers/if_pcn/Makefile b/bsd_eth_drivers/if_pcn/Makefile
new file mode 100644
index 0000000..7e52001
--- /dev/null
+++ b/bsd_eth_drivers/if_pcn/Makefile
@@ -0,0 +1,143 @@
+#
+# Makefile.leaf,v 1.7 2002/07/22 22:56:09 joel Exp
+#
+# Templates/Makefile.leaf
+# Template leaf node Makefile
+#
+#
+LIBNAME=libif_pcn.a
+
+LINKS=pci/if_pcnreg.h
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=
+
+C_PIECES+=if_pcn
+
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+# C++ source names, if any, go here -- minus the .cc
+CC_PIECES=
+CC_FILES=$(CC_PIECES:%=%.cc)
+CC_O_FILES=$(CC_PIECES:%=${ARCH}/%.o)
+
+H_FILES=
+
+# Assembly source names, if any, go here -- minus the .S
+S_PIECES=
+S_FILES=$(S_PIECES:%=%.S)
+S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o)
+
+SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
+OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
+
+# If your PGMS target has the '.exe' extension, a statically
+# linked application is generated.
+# If it has a '.obj' extension, a loadable module is built.
+#
+#
+ifdef LIBNAME
+LIB=${ARCH}/${LIBNAME}
+else
+PGMS=${ARCH}/if_pcn.obj
+endif
+
+# List of RTEMS Classic API Managers to be included in the application
+# goes here. Use:
+# MANAGERS=all
+# to include all RTEMS Classic API Managers in the application or
+# something like this to include a specific set of managers.
+# MANAGERS=io event message rate_monotonic semaphore timer
+#
+# UNUSED for loadable modules
+MANAGERS=ALL
+
+ifndef RTEMS_MAKEFILE_PATH
+$(error you need to set the RTEMS_MAKEFILE_PATH environment variable)
+endif
+
+all:
+
+depend: ${LINKS}
+
+include $(RTEMS_MAKEFILE_PATH)/Makefile.inc
+
+include $(RTEMS_CUSTOM)
+ifdef LIBNAME
+include $(RTEMS_ROOT)/make/lib.cfg
+else
+include $(RTEMS_ROOT)/make/leaf.cfg
+endif
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+#DEFINES += -DPCN_DEBUG
+CPPFLAGS += -I. -I../libbsdport -I../libbsdport/dummyheaders
+CFLAGS +=
+
+#
+# CFLAGS_DEBUG_V are used when the `make debug' target is built.
+# To link your application with the non-optimized RTEMS routines,
+# uncomment the following line:
+# CFLAGS_DEBUG_V += -qrtems_debug
+#
+
+LD_PATHS +=
+LD_LIBS +=
+LDFLAGS +=
+
+#
+# Add your list of files to delete here. The config files
+# already know how to delete some stuff, so you may want
+# to just run 'make clean' first to see what gets missed.
+# 'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS += pci
+
+all: ${LINKS} ${ARCH} $(SRCS) $(PGMS) ${LIB}
+
+pci/%:%
+ if [ ! -d pci ]; then mkdir -p pci; fi ; ln -s ../$^ $@
+
+#How to make a relocatable object
+$(filter %.obj, $(PGMS)): ${OBJS}
+ $(make-obj)
+
+#How to make an executable (statically linked)
+$(filter %.exe,$(PGMS)): ${LINK_FILES}
+ $(make-exe)
+ifdef ELFEXT
+ifdef XSYMS
+ $(XSYMS) $(@:%.exe=%.$(ELFEXT)) $(@:%.exe=%.sym)
+endif
+endif
+
+$(LIB): ${OBJS}
+ $(make-library)
+
+ifndef RTEMS_SITE_INSTALLDIR
+RTEMS_SITE_INSTALLDIR = $(PROJECT_RELEASE)
+endif
+
+${RTEMS_SITE_INSTALLDIR}/include \
+${RTEMS_SITE_INSTALLDIR}/lib \
+${RTEMS_SITE_INSTALLDIR}/bin:
+ test -d $@ || mkdir -p $@
+# Install the program(s), appending _g or _p as appropriate.
+# for include files, just use $(INSTALL_CHANGE)
+#
+# - Some BSPs might generate bootable executables in yet another
+# format (such as .srec) and you might need to extend the rule
+# below so the essential files get installed. YMMV.
+ifdef LIBNAME
+install: all $(RTEMS_SITE_INSTALLDIR)/lib
+ $(INSTALL_VARIANT) -m 644 ${LIB} ${RTEMS_SITE_INSTALLDIR}/lib
+else
+install: all $(RTEMS_SITE_INSTALLDIR)/bin
+ $(INSTALL_VARIANT) -m 555 ${PGMS} ${PGMS:%.exe=%.bin} ${PGMS:%.exe=%.sym} ${RTEMS_SITE_INSTALLDIR}/bin
+endif
diff --git a/bsd_eth_drivers/if_pcn/README.rtems b/bsd_eth_drivers/if_pcn/README.rtems
new file mode 100644
index 0000000..ab8ba09
--- /dev/null
+++ b/bsd_eth_drivers/if_pcn/README.rtems
@@ -0,0 +1,73 @@
+RTEMS PORT OF THE 'pcn' ETHERNET DRIVER
+=======================================
+
+This is a port of the FreeBSD 'pcn' driver as of
+2007/7/17 (checked out from FreeBSD/head on that date).
+
+SUPPORTED BSPs:
+- you need 'libbsdport' which in turn needs 'libbspExt'
+ These work for i386/pc386 and powerpc/new-exception-processing
+ BSPs, i.e., the BSP must implement <rtems/pci.h> and <rtems/irq.h>.
+
+USAGE:
+- to attach this driver:
+ * define a NULL terminated list with all libbsdport supported
+ drivers you want to include with your application:
+
+ extern driver_t libbsdport_pcn_driver;
+
+ driver_t *libbsdport_netdriver_table[] = {
+ &libbsdport_pcn_driver,
+ /* other drivers here or upstream of 'pcn' if they support
+ * the same hardware but are preferred.
+ */
+ 0
+ };
+
+ * specify libbsdport_netdriver_attach for the 'attach' function
+ pointer in struct rtems_bsdnet_ifconfig.
+
+ * use the 'name' field in struct rtems_bsdnet_ifconfig to filter
+ drivers and device instances:
+
+ <driver_name><instance>
+
+ either may be omitted which means that the next available
+ driver/hardware device is to be used. Here are a few examples:
+
+ "" /* use first device found supported by any driver in the
+ * libbsdport_driver_table[].
+ */
+
+ "pcn2" /* use second device supported by the 'pcn' driver */
+
+ Notes: Counting instances begins with 1 (not 0).
+ Consult libbsdport/README for more information.
+
+KNOWN ISSUES:
+- 'ignore_broadcast' and 'mtu' settings from
+ struct rtems_bsdnet_ifconfig are ignored. I haven't seen
+ many drivers that honour 'ignore_broadcast' and 'mtu' can be
+ set using a ioctl(). I'm trying to keep changes to BSD sources
+ minimal...
+- ring sizes are restricted fixed to hardcoded size.
+- Only the internal phy of the 973/975 chips are supported
+ and will allow SIOCGIFMEDIA/SIOCSIFMEDIA to work. I don't know
+ what happens with other chips or external phys.
+ Probably, the factory-default setup should work with autonegotiation
+ but the ioctls wont. YMMV.
+
+OTHER NOTES:
+- you can use the (more generic) 'le' driver for the 79C971
+ and upwards chips, too, but 'pcn' supposedly uses more advanced
+ features of these chips.
+
+TESTED WITH:
+ Technobox 10/100-TX Ethernet PMC (AMD Am79C973 chip)
+
+TESTED ON:
+ rtems-4.7
+ powerpc/beatnik (motorola MVME5500 and MVME6100 VME boards)
+ i386/pc686 (concurrent technologies PP410 compact PCI)
+
+T.S, 200707
diff --git a/bsd_eth_drivers/libbsdport/Makefile b/bsd_eth_drivers/libbsdport/Makefile
new file mode 100644
index 0000000..fbf9f35
--- /dev/null
+++ b/bsd_eth_drivers/libbsdport/Makefile
@@ -0,0 +1,116 @@
+#
+# Makefile.lib,v 1.5 2000/06/12 15:00:14 joel Exp
+#
+# Templates/Makefile.lib
+# Template library Makefile
+#
+
+LIBNAME=libbsdport.a
+LIB=${ARCH}/${LIBNAME}
+
+# C and C++ source names, if any, go here -- minus the .c or .cc
+C_PIECES=rtems_callout rtems_taskqueue rtems_udelay ifstuff devicet alldrv
+C_PIECES+=contigmalloc sysbus malloc ifmedia
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+CC_PIECES=
+CC_FILES=$(CC_PIECES:%=%.cc)
+CC_O_FILES=$(CC_PIECES:%=${ARCH}/%.o)
+
+H_FILES=libbsdport_api.h rtems_verscheck.h
+
+LINKS+=sys/taskqueue.h
+LINKS+=sys/bus.h
+LINKS+=sys/mutex.h
+LINKS+=bsp/rtems_verscheck.h
+
+DUMMYHEADERS+=dummyheaders/machine/bus.h
+DUMMYHEADERS+=dummyheaders/machine/resource.h
+DUMMYHEADERS+=dummyheaders/dev/pci/pcivar.h
+DUMMYHEADERS+=dummyheaders/dev/pci/pcireg.h
+DUMMYHEADERS+=dummyheaders/dev/mii/miivar.h
+DUMMYHEADERS+=dummyheaders/sys/module.h
+DUMMYHEADERS+=dummyheaders/sys/rman.h
+DUMMYHEADERS+=dummyheaders/sys/kthread.h
+DUMMYHEADERS+=dummyheaders/sys/endian.h
+DUMMYHEADERS+=dummyheaders/net/if_vlan_var.h
+DUMMYHEADERS+=dummyheaders/netinet/ip6.h
+DUMMYHEADERS+=dummyheaders/vm/pmap.h
+DUMMYHEADERS+=dummyheaders/miibus_if.h
+
+# Assembly source names, if any, go here -- minus the .S
+S_PIECES=
+S_FILES=$(S_PIECES:%=%.S)
+S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o)
+
+SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
+OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
+
+all:
+
+depend: ${LINKS}
+
+include $(RTEMS_MAKEFILE_PATH)/Makefile.inc
+
+include $(RTEMS_CUSTOM)
+include $(RTEMS_ROOT)/make/lib.cfg
+
+#
+# Add local stuff here using +=
+#
+
+DEFINES +=
+CPPFLAGS += -I.
+CFLAGS +=
+
+#
+# Add your list of files to delete here. The config files
+# already know how to delete some stuff, so you may want
+# to just run 'make clean' first to see what gets missed.
+# 'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS += dummyheaders
+CLOBBER_ADDITIONS += $(sort $(foreach n,$(LINKS),$(firstword $(subst /, ,$(n)))))
+
+all: ${DUMMYHEADERS} ${LINKS} ${ARCH} $(SRCS) $(LIB)
+
+$(LIB): ${OBJS}
+ $(make-library)
+
+dummyheaders/%:
+ @if [ ! -d `dirname $@` ] ; then mkdir -p `dirname $@`; fi
+ @touch $@
+
+# for each name listed in LINKS, create parent directories (if needed)
+# and a symlink to file in .
+# E.g., LINKS=a/b/c.h
+# creates a/b/c.h -> ../../c.h
+$(LINKS):
+ @if [ ! -d $(dir $@) ] ; then mkdir -p $(dir $@); fi
+ @ln -s `echo $@ | sed -e 's%[^/]\+[/]\+%../%g'` $@
+
+ifndef RTEMS_SITE_INSTALLDIR
+RTEMS_SITE_INSTALLDIR = $(PROJECT_RELEASE)
+endif
+
+ifndef RTEMS_SITE_BSP_INSTALLDIR
+RTEMS_SITE_BSP_INSTALLDIR = $(RTEMS_SITE_INSTALLDIR)
+endif
+
+${RTEMS_SITE_INSTALLDIR}/include/bsp \
+${RTEMS_SITE_INSTALLDIR}/lib \
+${RTEMS_SITE_INSTALLDIR}/bin:
+ test -d $@ || mkdir -p $@
+
+# Install the program(s), appending _g or _p as appropriate.
+# for include files, just use $(INSTALL_CHANGE)
+#
+
+install: all $(RTEMS_SITE_INSTALLDIR)/lib $(RTEMS_SITE_INSTALLDIR)/include/bsp
+ $(INSTALL_VARIANT) -m 644 ${LIB} ${RTEMS_SITE_INSTALLDIR}/lib
+ $(INSTALL_CHANGE) -m 644 ${H_FILES} ${RTEMS_SITE_INSTALLDIR}/include/bsp
+
+
diff --git a/bsd_eth_drivers/libbsdport/Makefile.am b/bsd_eth_drivers/libbsdport/Makefile.am
index 44096b5..e6e31cd 100644
--- a/bsd_eth_drivers/libbsdport/Makefile.am
+++ b/bsd_eth_drivers/libbsdport/Makefile.am
@@ -38,9 +38,6 @@ DUMMYHEADERS+=dummyheaders/netinet/ip6.h
DUMMYHEADERS+=dummyheaders/vm/pmap.h
DUMMYHEADERS+=dummyheaders/miibus_if.h
-DUMMYHEADERS+=dummyheaders/miidevs.h
-DUMMYHEADERS+=dummyheaders/dev/mii/brgphyreg.h
-
BUILT_SOURCES=
include ../links.am
diff --git a/bsd_eth_drivers/libbsdport/alldrv.c b/bsd_eth_drivers/libbsdport/alldrv.c
index 0738179..f81b95a 100644
--- a/bsd_eth_drivers/libbsdport/alldrv.c
+++ b/bsd_eth_drivers/libbsdport/alldrv.c
@@ -5,7 +5,6 @@ driver_t *libbsdport_netdriver_table_all[] = {
&libbsdport_em_driver,
&libbsdport_pcn_driver,
&libbsdport_le_pci_driver,
- &libbsdport_re_driver,
0
};
diff --git a/bsd_eth_drivers/libbsdport/bus.h b/bsd_eth_drivers/libbsdport/bus.h
index 76d78a8..19cb24f 100644
--- a/bsd_eth_drivers/libbsdport/bus.h
+++ b/bsd_eth_drivers/libbsdport/bus.h
@@ -156,10 +156,6 @@ bus_setup_intr(device_t dev, struct resource *r, int flags, driver_filter_t filt
/* Flags currently ignored... */
#define INTR_MPSAFE 0
#define INTR_TYPE_NET 0
-/* INTR_FAST indicates that a 'handler' is actually
- * a 'fast' handler which already uses taskqueues
- */
-#define INTR_FAST 1
int
bus_teardown_intr(device_t dev, struct resource *r, void *cookiep);
@@ -196,16 +192,6 @@ rman_get_bustag(struct resource *r);
#define BUS_DMA_COHERENT 0
#endif
-#ifndef BUS_DMA_ZERO
-/* ignored anyways */
-#define BUS_DMA_ZERO 0
-#endif
-
-#ifndef BUS_DMA_ALLOCNOW
-/* ignored anyways */
-#define BUS_DMA_ALLOCNOW 0
-#endif
-
/* unused */
#ifndef BUS_SPACE_MAXADDR
#define BUS_SPACE_MAXADDR 0xdeadbeef
@@ -279,10 +265,10 @@ bus_get_dma_tag(device_t dev)
return 0;
}
-typedef void bus_dmamap_callback_t (void *arg, bus_dma_segment_t *segs, int nseg, int error);
+typedef void bus_dmamap_callback_t (void *, bus_dma_segment_t *, int, int);
static inline int
-bus_dmamap_load(bus_dma_tag_t tag, bus_dmamap_t map, caddr_t vaddr, bus_size_t size, bus_dmamap_callback_t cb, void *arg, unsigned flags)
+bus_dmamap_load(bus_dma_tag_t tag, bus_dmamap_t map, caddr_t vaddr, bus_size_t size, void (*cb)(void *arg, bus_dma_segment_t *segs, int nseg, int error), void *arg, unsigned flags)
{
bus_dma_segment_t segs[1];
segs[0].ds_addr = CPU2BUSADDR(vaddr);
@@ -291,28 +277,6 @@ bus_dma_segment_t segs[1];
return 0;
}
-typedef void bus_dmamap_callback2_t (void *arg, bus_dma_segment_t *segs, int nsegs, bus_size_t mapsize, int error);
-
-static inline int
-bus_dmamap_load_mbuf(bus_dma_tag_t tag, bus_dmamap_t map, struct mbuf *m_head, bus_dmamap_callback2_t cb, void *arg, unsigned flags)
-{
-/* hopefully there's enough stack ... */
-bus_dma_segment_t segs[tag->maxsegs];
-struct mbuf *m;
-int n;
-bus_size_t sz;
- for ( m=m_head, sz=0, n=0; m; m=m->m_next, n++ ) {
- if ( n >= tag->maxsegs ) {
- cb(arg, segs, n, sz, EFBIG);
- return EFBIG;
- }
- segs[n].ds_addr = CPU2BUSADDR(mtod(m, unsigned));
- sz += (segs[n].ds_len = m->m_len);
- }
- cb(arg, segs, n, sz, 0);
- return 0;
-}
-
#define bus_dmamap_unload(tag, map) do {} while (0)
/* should we do something if we have no HW snooping ? */
diff --git a/bsd_eth_drivers/libbsdport/devicet.c b/bsd_eth_drivers/libbsdport/devicet.c
index 48ddd9a..f197da4 100644
--- a/bsd_eth_drivers/libbsdport/devicet.c
+++ b/bsd_eth_drivers/libbsdport/devicet.c
@@ -12,7 +12,7 @@
#include <sys/bus.h>
#include "libbsdport_api.h"
-#define DEBUG
+#undef DEBUG
extern void real_libc_free(void*);
diff --git a/bsd_eth_drivers/libbsdport/libbsdport.h b/bsd_eth_drivers/libbsdport/libbsdport.h
index 8b88784..0fdd4a4 100644
--- a/bsd_eth_drivers/libbsdport/libbsdport.h
+++ b/bsd_eth_drivers/libbsdport/libbsdport.h
@@ -31,10 +31,6 @@
#include <rtems_udelay.h>
-#ifndef bswap32
-#define bswap32(_x) CPU_swap_u32(_x)
-#endif
-
#if defined(__LITTLE_ENDIAN__) || defined(__i386__)
static inline uint16_t htole16(uint16_t v) { return v; }
static inline uint32_t htole32(uint32_t v) { return v; }
@@ -191,9 +187,6 @@ static inline void membarrier_w() { asm volatile("eieio":::"memory"); }
#define PCIY_PMG 0x01
#endif
-#ifndef PCI_RF_DENSE
-#define PCI_RF_DENSE 0
-#endif
static inline uint32_t
pci_read_config(device_t dev, unsigned reg, int width)
diff --git a/bsd_eth_drivers/libbsdport/libbsdport_api.h b/bsd_eth_drivers/libbsdport/libbsdport_api.h
index ba3e54e..73b54b0 100644
--- a/bsd_eth_drivers/libbsdport/libbsdport_api.h
+++ b/bsd_eth_drivers/libbsdport/libbsdport_api.h
@@ -24,8 +24,6 @@ extern driver_t *libbsdport_netdriver_table[];
extern driver_t libbsdport_em_driver;
/* AMD 79C971..976 pcnet PCI */
extern driver_t libbsdport_pcn_driver;
-/* RealTek RTL8139, 8168, 8169, 8169S, 8110, 8101E, and 8111 PCI */
-extern driver_t libbsdport_re_driver;
/* AMD/Lance older (and later) chips; this driver also supports what 'pcn'
* does but might not be as efficient.
* NOTE: The 'le_pci' driver works with the pcnet32 (79C970A) emulation
diff --git a/bsd_eth_drivers/libbsdport/modini.c b/bsd_eth_drivers/libbsdport/modini.c
new file mode 100644
index 0000000..3156c16
--- /dev/null
+++ b/bsd_eth_drivers/libbsdport/modini.c
@@ -0,0 +1,100 @@
+#include "devicet.h"
+#include <rtems/rtems_bsdnet.h>
+
+struct {
+ struct device dev;
+ struct {
+ char space[4096];
+ } softc;
+} thele = {
+ {
+ bushdr: {
+/* mvme5500 { x, x, x } */
+/* qemu */ { 0, 3, 0 }
+ },
+ type: DEV_TYPE_PCI,
+ name: "le",
+ nameunit: { 'l', 'e', '1', 0},
+ unit: 1,
+ },
+ {
+ { 0, }
+ }
+};
+
+void *thelesoftc = &thele.softc;
+
+
+struct {
+ struct device dev;
+ struct {
+ char space[4096];
+ } softc;
+} theem = {
+ {
+ bushdr: {
+/* mvme5500 { 2, 0xa, 0 } */
+/* cpci */ { 7, 0, 0 }
+ },
+ type: DEV_TYPE_PCI,
+ name: "em",
+ nameunit: { 'e', 'm', '1', 0},
+ unit: 1,
+ },
+ {
+ { 0, }
+ }
+};
+
+void *theemsoftc = &theem.softc;
+
+struct {
+ struct device dev;
+ struct {
+ char space[4096];
+ } softc;
+} thepcn = {
+ {
+ bushdr: {
+/* mvme5500 { x, 0xx, x } */
+/* cpci */ { 4, 6, 0 }
+ },
+ type: DEV_TYPE_PCI,
+ name: "pcn",
+ nameunit: { 'p', 'c', 'n', '1', 0},
+ unit: 1,
+ },
+ {
+ { 0, }
+ }
+};
+
+void *thepcnsoftc = &thepcn.softc;
+
+extern driver_t rtems_em_driver;
+extern driver_t rtems_le_pci_driver;
+extern driver_t rtems_pcn_driver;
+
+driver_t *rtems_netdriver_table[] = {
+ &rtems_em_driver,
+ &rtems_le_pci_driver,
+ &rtems_pcn_driver,
+ 0
+};
+
+struct rtems_bsdnet_ifconfig pcncfg = {
+ name: "pcn",
+ rbuf_count:20,
+ xbuf_count:3,
+};
+
+#ifdef DEBUG_MODULAR
+void
+_cexpModuleInitialize(void *unused)
+{
+extern void * rtems_callout_initialize();
+extern void * rtems_taskqueue_initialize();
+ rtems_callout_initialize();
+ rtems_taskqueue_initialize();
+}
+#endif
diff --git a/bsd_eth_drivers/libbsdport/sysbus.c b/bsd_eth_drivers/libbsdport/sysbus.c
index fc0ae0b..fcd3aac 100644
--- a/bsd_eth_drivers/libbsdport/sysbus.c
+++ b/bsd_eth_drivers/libbsdport/sysbus.c
@@ -143,17 +143,12 @@ bus_setup_intr(device_t dev, struct resource *r, int flags, driver_filter_t filt
int rval;
struct irq_cookie *info = 0;
+
+
if ( filter && handler ) {
rtems_panic("bus_setup_intr for both: filter & handler not implemented\n");
}
- if ( (flags & INTR_FAST) && filter ) {
- rtems_panic("bus_setup_intr for both: filter & INTR_FAST not implemented\n");
- /* handler is a fast handler already */
- filter = (driver_filter_t) handler;
- handler = 0;
- }
-
if ( handler ) {
if ( !dev->drv ) {
device_printf(dev, "bus_setup_intr: device has no driver attached\n");
@@ -192,8 +187,7 @@ struct irq_cookie *info = 0;
return rval;
}
- if ( cookiep )
- *cookiep = info;
+ *cookiep = info;
return rval;
}
diff --git a/bsd_eth_drivers/libbsdport/taskqueue.h b/bsd_eth_drivers/libbsdport/taskqueue.h
index d700edf..a341ec1 100644
--- a/bsd_eth_drivers/libbsdport/taskqueue.h
+++ b/bsd_eth_drivers/libbsdport/taskqueue.h
@@ -31,8 +31,6 @@ taskqueue_create_fast(const char *name, int mflags, tq_enq_fn, void *ctxt);
int
taskqueue_enqueue(struct taskqueue *tq, struct task *ta);
-#define taskqueue_enqueue_fast(_q,_t) taskqueue_enqueue(_q,_t)
-
void
taskqueue_thread_enqueue(void *ctxt);
diff --git a/configure.ac b/configure.ac
index e4a5e53..df29fd2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_PREREQ(2.63)
+AC_PREREQ(2.62)
m4_include(./m4/cvstag.m4)
@@ -296,23 +296,21 @@ TILLAC_M4_IF_PRESENT([bsd_eth_drivers],
[if test -d $srcdir/bsd_eth_drivers ; then
AC_CONFIG_FILES([bsd_eth_drivers/Makefile])
AC_CONFIG_FILES([bsd_eth_drivers/libbsdport/Makefile])
- AC_CONFIG_FILES([bsd_eth_drivers/bge/Makefile])
AC_CONFIG_FILES([bsd_eth_drivers/if_pcn/Makefile])
AC_CONFIG_FILES([bsd_eth_drivers/if_le/Makefile])
AC_CONFIG_FILES([bsd_eth_drivers/if_em/Makefile])
- AC_CONFIG_FILES([bsd_eth_drivers/re/Makefile])
all_subdirs="${all_subdirs} bsd_eth_drivers"
if test "$ac_cv_func_pci_find_device" = "yes" ; then
-## if test "${host_cpu}" = i386 && test ! "${have_bspext}" = yes ; then
-## AC_MSG_NOTICE([Not building bsd_eth_drivers; on i386 you need libbspExt])
-## else
+ if test "${host_cpu}" = i386 && test ! "${have_bspext}" = yes ; then
+ AC_MSG_NOTICE([Not building bsd_eth_drivers; on i386 you need libbspExt])
+ else
#FIXME: make these configurable options
ENBL_82542_SUPPORT=NO
ENBL_ICH8LAN_SUPPORT=YES
AC_SUBST([ENBL_82542_SUPPORT])
AC_SUBST([ENBL_ICH8LAN_SUPPORT])
enable_subdirs="${enable_subdirs} bsd_eth_drivers"
-## fi
+ fi
fi
fi]dnl
)
diff --git a/m4/acinclude.m4 b/m4/acinclude.m4
new file mode 100644
index 0000000..130276e
--- /dev/null
+++ b/m4/acinclude.m4
@@ -0,0 +1,16 @@
+dnl m4_syscmd is executed when aclocal is run
+m4_syscmd([cat - > makefile.top.am <<'EOF_'
+AUTOMAKE_OPTIONS=foreign
+SUBDIRS=@the_subdirs@
+# When making a distribution we only want to
+# recurse into (any) one single BSP subdir.
+DIST_SUBDIRS=@the_distsub@
+
+# The dist-hook then removes this extra
+# directory level again.
+dist-hook:
+ if test "$(PACKAGE_VERSION)" = "untagged" ; then echo "Need tagged version to cut distribution"; exit 1; fi
+ cp -frl $(distdir)/$(DIST_SUBDIRS)/* $(distdir)
+ rm -fr $(distdir)/$(DIST_SUBDIRS)
+EOF_
+])
diff --git a/m4/multilib-fix.m4 b/m4/multilib-fix.m4
new file mode 100644
index 0000000..d822a79
--- /dev/null
+++ b/m4/multilib-fix.m4
@@ -0,0 +1,78 @@
+# Automake-1.10's AM_ENABLE_MULTILIB is buggy - it
+# does not properly preserve quoting when copying
+# ac_configure_args to the 'config.status' it creates.
+# I guess one level of quoting is removed when the
+# copying happens (by means of a 'here'-document in
+# AC_OUTPUT_COMMANDS).
+#
+# Note that we cannot use a different name since
+# automake 'knows' about AM_ENABLE_MULTILIB and
+# behaves differently if we would, e.g., name the
+# modified macro 'MY_ENABLE_MULTILIB'.
+# Hence we hope that we can override automake/aclocal's
+# definition.
+#
+# Below (look at the 'sed' code) we replace all occurrences
+# of '$' by '\$' so that 'config.status' again says '$'.
+#
+# This is important if we want to pass e.g.,
+#
+# --exec-prefix='${prefix}/xxx'
+#
+# correctly to the multisubdir configurations.
+#
+# AM_ENABLE_MULTILIB([MAKEFILE], [REL-TO-TOP-SRCDIR])
+# ---------------------------------------------------
+# Add --enable-multilib to configure.
+AC_DEFUN([AM_ENABLE_MULTILIB],
+[# Default to --enable-multilib
+AC_ARG_ENABLE(multilib,
+[ --enable-multilib build many library versions (default)],
+[case "$enableval" in
+ yes) multilib=yes ;;
+ no) multilib=no ;;
+ *) AC_MSG_ERROR([bad value $enableval for multilib option]) ;;
+ esac],
+ [multilib=yes])
+
+# We may get other options which we leave undocumented:
+# --with-target-subdir, --with-multisrctop, --with-multisubdir
+# See config-ml.in if you want the gory details.
+
+if test "$srcdir" = "."; then
+ if test "$with_target_subdir" != "."; then
+ multi_basedir="$srcdir/$with_multisrctop../$2"
+ else
+ multi_basedir="$srcdir/$with_multisrctop$2"
+ fi
+else
+ multi_basedir="$srcdir/$2"
+fi
+AC_SUBST(multi_basedir)
+
+# Even if the default multilib is not a cross compilation,
+# it may be that some of the other multilibs are.
+if test $cross_compiling = no && test $multilib = yes \
+ && test "x${with_multisubdir}" != x ; then
+ cross_compiling=maybe
+fi
+
+AC_OUTPUT_COMMANDS([
+# Only add multilib support code if we just rebuilt the top-level
+# Makefile.
+case " $CONFIG_FILES " in
+ *" ]m4_default([$1],Makefile)[ "*)
+ ac_file=]m4_default([$1],Makefile)[ . ${multi_basedir}/config-ml.in
+ ;;
+esac],
+ [
+srcdir="$srcdir"
+host="$host"
+target="$target"
+with_multisubdir="$with_multisubdir"
+with_multisrctop="$with_multisrctop"
+with_target_subdir="$with_target_subdir"
+ac_configure_args="${multilib_arg} `echo ${ac_configure_args} | sed -e 's/[$]/\\\\$/g'`"
+multi_basedir="$multi_basedir"
+CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+CC="$CC"])])dnl
diff --git a/m4/multilib-installdir.m4 b/m4/multilib-installdir.m4
new file mode 100644
index 0000000..68ac591
--- /dev/null
+++ b/m4/multilib-installdir.m4
@@ -0,0 +1,21 @@
+# TILLAM_MULTISUB_INSTALLDIR
+#
+# tweak 'libdir' so that libraries are
+# installed in proper multisubdir.
+#
+# For use by 'sub-packages', i.e., from
+# configure.ac in a subdir of a main
+# package. Only the toplevel configure.ac
+# should say AM_ENABLE_MULTILIB
+#
+AC_DEFUN([TILLAM_MULTISUB_INSTALLDIR],
+[# Install multilib into proper multisubdir
+if test "${with_multisubdir+set}" = "set" ; then
+ the_multisubdir="/${with_multisubdir}"
+else
+ the_multisubdir=
+fi
+AC_SUBST(libdir,[${libdir}${the_multisubdir}])])dnl
+
+
+])dnl
diff --git a/m4/rtems-bsp-postlink.m4 b/m4/rtems-bsp-postlink.m4
new file mode 100644
index 0000000..c2007d4
--- /dev/null
+++ b/m4/rtems-bsp-postlink.m4
@@ -0,0 +1,32 @@
+# Define 'postlink' commands based on BSP family
+#
+# NOTE: This is NOT extracted from the RTEMS makefiles but
+# essentially a copy of what rtems-4.9.0 does.
+# It would be too hard to figure this one out ;-(
+#
+AC_DEFUN([TILLAC_RTEMS_BSP_POSTLINK_CMDS],
+ [AC_ARG_VAR([RTEMS_BSP_POSTLINK_CMDS],[Command sequence to convert ELF file into downloadable executable])
+ AC_MSG_NOTICE([Setting RTEMS_BSP_POSTLINK_CMDS based on RTEMS_BSP_FAMILY])
+ case "$RTEMS_BSP_FAMILY" in
+ svgm|beatnik|mvme5500|mvme3100|uC5282|mvme167|mvme162)
+# convert ELF -> pure binary
+ RTEMS_BSP_POSTLINK_CMDS='$(OBJCOPY) -Obinary -R .comment -S $(basename $[@])$(APPEXEEXT) $[@]'
+ ;;
+ motorola_powerpc)
+# convert ELF -> special PREP bootloader
+ RTEMS_BSP_POSTLINK_CMDS=\
+'$(OBJCOPY) -O binary -R .comment -S $(basename $[@])$(APPEXEEXT) rtems ;'\
+'gzip -vf9 rtems ; '\
+'$(LD) -o $(basename $[@])$(DOWNEXT) $(RTEMS_BSP_INSTTOP)/lib/bootloader.o '\
+'--just-symbols=$(basename $[@])$(APPEXEEXT) '\
+'-b binary rtems.gz -T $(RTEMS_BSP_INSTTOP)/lib/ppcboot.lds '\
+'-Map $(basename $[@]).map && chmod 755 $(basename $[@])$(DOWNEXT) ; '\
+'rm -f rtems.gz'
+ ;;
+# default: empty command
+ *)
+ ;;
+ esac
+ AC_MSG_NOTICE([RTEMS_BSP_POSTLINK_CMDS: "$RTEMS_BSP_POSTLINK_CMDS"])
+ AM_CONDITIONAL([HAVE_BSP_POSTLINK_CMDS], [test ! "$RTEMS_BSP_POSTLINK_CMDS"xx = "xx" ])]dnl
+)
diff --git a/m4/rtems-isml.m4 b/m4/rtems-isml.m4
new file mode 100644
index 0000000..1a4f62e
--- /dev/null
+++ b/m4/rtems-isml.m4
@@ -0,0 +1,11 @@
+# Find out if this is a multilibbed RTEMS installation
+#
+# Result is exit status, i.e., this macro can e.g., be used
+# in a 'if MACRO ; then list; fi' statement.
+#
+# TILLAC_RTEMS_CPUKIT_MULTILIB
+AC_DEFUN([TILLAC_RTEMS_CPUKIT_MULTILIB],
+ [AC_REQUIRE([AC_CANONICAL_HOST])
+ AC_REQUIRE([TILLAC_RTEMS_OPTIONS])
+ test -d ${with_rtems_top}/${host_cpu}-${host_os}/include]dnl
+)
diff --git a/m4/rtems-ismultibsp.m4 b/m4/rtems-ismultibsp.m4
new file mode 100644
index 0000000..63e8805
--- /dev/null
+++ b/m4/rtems-ismultibsp.m4
@@ -0,0 +1,23 @@
+#
+# Check if the 'enable_rtemsbsp' variable lists a single
+# or multiple BSPs and set exit status accordingly:
+#
+# Result is exit status, i.e., this macro can e.g., be used
+# in a 'if MACRO ; then list; fi' statement.
+#
+# true - if enable_rtembsp lists more than one BSP
+# false - otherwise
+#
+# if TILLAC_RTEMS_CHECK_MULTI_BSPS ; then list ; fi
+AC_DEFUN([TILLAC_RTEMS_CHECK_MULTI_BSPS],
+ [AC_REQUIRE([TILLAC_RTEMS_CHECK_BSPS])
+ ( _tillac_rtems_multi_bsps=no
+ for _tillac_rtems_bspcand in $enable_rtemsbsp ; do
+ if test "$_tillac_rtems_multi_bsps" = "no" ; then
+ _tillac_rtems_multi_bsps=maybe
+ else
+ _tillac_rtems_multi_bsps=yes
+ fi
+ done
+ test "$_tillac_rtems_multi_bsps" = "yes")]dnl
+)
diff --git a/m4/rtems-multilib.m4 b/m4/rtems-multilib.m4
new file mode 100644
index 0000000..25be9d4
--- /dev/null
+++ b/m4/rtems-multilib.m4
@@ -0,0 +1,28 @@
+#
+# Prepare for a multilibbed build
+# - check for presence of 'config-ml.in'
+# - expand AM_ENABLE_MULTILIB(MAKEFILE, REL-TO-TOP-SRCDIR)
+# - expand TILLAM_MULTISUB_INSTALLDIR (workaround so that
+# multilibs are installed into proper subdir.
+# - make sure 'enable_multilib' is set to 'no' if it was initially
+# unset; yet another little workaround...
+#
+# TILLAC_RTEMS_MULTILIB([MAKEFILE], [REL-TO-TOP-SRCDIR])
+AC_DEFUN([TILLAC_RTEMS_MULTILIB],
+ [if test -f ${srcdir}/config-ml.in || test -f $(srcdir)/../config-ml.in ; then
+ AM_ENABLE_MULTILIB([$1],[$2])
+ # install multilibs into MULTISUBDIR
+ TILLAM_MULTISUB_INSTALLDIR
+dnl AC_SUBST(libdir,[${libdir}'$(MULTISUBDIR)'])
+ # in order to properly build multilibs in sub-libraries it seems we
+ # must pass the --enable-multilibs arg to sub-configures or multilibs
+ # are not built there.
+ # To work around, we simply set the default to 'no' so the user must
+ # say --enable-multilib to get them.
+ if test ! "${enable_multilib+set}" = "set" ; then
+ multilib=no
+ fi
+ else
+ enable_multilib=no
+ fi]dnl
+)
diff --git a/rtems-pre.am b/rtems-pre.am
index 07d85fa..219e2bd 100644
--- a/rtems-pre.am
+++ b/rtems-pre.am
@@ -1,4 +1,4 @@
-AM_CPPFLAGS = -Wall -D__BSD_VISIBLE
+AM_CPPFLAGS = -Wall
AM_CFLAGS = -Wall
AM_CXXFLAGS = -Wall
AM_CCASFLAGS =