forked from Imagelibrary/rtems
Modification from Emmanuel Raguet <raguet@crf.canon.fr> to merge the
dec21140 drivers from the i386/pc386 and powerpc/mcp750 (all Motorola PowerPC boards) and move the network driver to libchip. This driver should work on all PCI based uses of this chip.
This commit is contained in:
@@ -19,7 +19,8 @@ include $(RTEMS_ROOT)/make/directory.cfg
|
|||||||
INSTALL_CHANGE = @INSTALL_CHANGE@
|
INSTALL_CHANGE = @INSTALL_CHANGE@
|
||||||
|
|
||||||
# We only build the Network library if HAS_NETWORKING was defined
|
# We only build the Network library if HAS_NETWORKING was defined
|
||||||
NETWORK_yes_V = dec21140 ne2000 wd8003 3c509
|
# dec21140 is supported via libchip
|
||||||
|
NETWORK_yes_V = ne2000 wd8003 3c509
|
||||||
NETWORK = $(NETWORK_$(HAS_NETWORKING)_V)
|
NETWORK = $(NETWORK_$(HAS_NETWORKING)_V)
|
||||||
|
|
||||||
# wrapup is the one that actually builds and installs the library
|
# wrapup is the one that actually builds and installs the library
|
||||||
|
|||||||
5
c/src/lib/libbsp/i386/pc386/README.dec21140
Normal file
5
c/src/lib/libbsp/i386/pc386/README.dec21140
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#
|
||||||
|
# $Id$
|
||||||
|
#
|
||||||
|
|
||||||
|
The dec21140 network driver is found in libchip/networking.
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
#
|
|
||||||
# $Id$
|
|
||||||
#
|
|
||||||
|
|
||||||
@SET_MAKE@
|
|
||||||
srcdir = @srcdir@
|
|
||||||
top_srcdir = @top_srcdir@
|
|
||||||
top_builddir = ../../..
|
|
||||||
subdir = i386/pc386/dec21140
|
|
||||||
|
|
||||||
RTEMS_ROOT = @RTEMS_ROOT@
|
|
||||||
PROJECT_ROOT = @PROJECT_ROOT@
|
|
||||||
|
|
||||||
VPATH = @srcdir@
|
|
||||||
|
|
||||||
PGM = ${ARCH}/dec21140.rel
|
|
||||||
|
|
||||||
# C source names, if any, go here -- minus the .c
|
|
||||||
C_PIECES = dec21140
|
|
||||||
C_FILES = $(C_PIECES:%=%.c)
|
|
||||||
C_O_FILES = $(C_PIECES:%=${ARCH}/%.o)
|
|
||||||
|
|
||||||
H_FILES =
|
|
||||||
|
|
||||||
SRCS = $(C_FILES) $(H_FILES)
|
|
||||||
OBJS = $(C_O_FILES)
|
|
||||||
|
|
||||||
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
|
|
||||||
include $(RTEMS_ROOT)/make/leaf.cfg
|
|
||||||
|
|
||||||
INSTALL_CHANGE = @INSTALL_CHANGE@
|
|
||||||
|
|
||||||
#
|
|
||||||
# (OPTIONAL) Add local stuff here using +=
|
|
||||||
#
|
|
||||||
|
|
||||||
DEFINES += -D__INSIDE_RTEMS_BSD_TCPIP_STACK__
|
|
||||||
CPPFLAGS +=
|
|
||||||
CFLAGS +=
|
|
||||||
|
|
||||||
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 +=
|
|
||||||
|
|
||||||
$(PGM): ${OBJS}
|
|
||||||
$(make-rel)
|
|
||||||
|
|
||||||
all: ${ARCH} $(SRCS) $(PGM)
|
|
||||||
|
|
||||||
# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
|
|
||||||
install: all
|
|
||||||
|
|
||||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
|
||||||
cd $(top_builddir) \
|
|
||||||
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
|
||||||
@@ -14,7 +14,8 @@ PROJECT_ROOT = @PROJECT_ROOT@
|
|||||||
VPATH = @srcdir@
|
VPATH = @srcdir@
|
||||||
|
|
||||||
# We only build the Network library if HAS_NETWORKING was defined
|
# We only build the Network library if HAS_NETWORKING was defined
|
||||||
NETWORK_yes_V = dec21140 ne2000 wd8003 3c509
|
# dec21140 is supported via libchip
|
||||||
|
NETWORK_yes_V = ne2000 wd8003 3c509
|
||||||
NETWORK = $(NETWORK_$(HAS_NETWORKING)_V)
|
NETWORK = $(NETWORK_$(HAS_NETWORKING)_V)
|
||||||
|
|
||||||
BSP_PIECES = startup clock console timer $(NETWORK)
|
BSP_PIECES = startup clock console timer $(NETWORK)
|
||||||
|
|||||||
@@ -22,14 +22,10 @@ SRCS = README
|
|||||||
|
|
||||||
all: $(SRCS)
|
all: $(SRCS)
|
||||||
|
|
||||||
# We only build the Network library if HAS_NETWORKING was defined
|
|
||||||
NETWORK_yes_V = dec21140
|
|
||||||
NETWORK = $(NETWORK_$(HAS_NETWORKING)_V)
|
|
||||||
|
|
||||||
# wrapup is the one that actually builds and installs the library
|
# wrapup is the one that actually builds and installs the library
|
||||||
# from the individual .rel files built in other directories
|
# from the individual .rel files built in other directories
|
||||||
SUBDIRS = clock console include pci residual openpic irq vectors start \
|
SUBDIRS = clock console include pci residual openpic irq vectors start \
|
||||||
startup bootloader $(NETWORK) motorola wrapup
|
startup bootloader motorola wrapup
|
||||||
|
|
||||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||||
cd $(top_builddir) \
|
cd $(top_builddir) \
|
||||||
|
|||||||
5
c/src/lib/libbsp/powerpc/mcp750/README.dec21140
Normal file
5
c/src/lib/libbsp/powerpc/mcp750/README.dec21140
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#
|
||||||
|
# $Id$
|
||||||
|
#
|
||||||
|
|
||||||
|
The dec21140 network driver is found in libchip/networking.
|
||||||
@@ -13,12 +13,7 @@ PROJECT_ROOT = @PROJECT_ROOT@
|
|||||||
|
|
||||||
VPATH = @srcdir@
|
VPATH = @srcdir@
|
||||||
|
|
||||||
# We only build the Network library if HAS_NETWORKING was defined
|
BSP_PIECES = clock console irq openpic pci residual startup vectors motorola
|
||||||
NETWORK_yes_V = dec21140
|
|
||||||
NETWORK = $(NETWORK_$(HAS_NETWORKING)_V)
|
|
||||||
|
|
||||||
BSP_PIECES = clock console irq openpic pci residual startup $(NETWORK) \
|
|
||||||
vectors motorola
|
|
||||||
GENERIC_PIECES =
|
GENERIC_PIECES =
|
||||||
|
|
||||||
# bummer; have to use $foreach since % pattern subst rules only replace 1x
|
# bummer; have to use $foreach since % pattern subst rules only replace 1x
|
||||||
|
|||||||
@@ -22,14 +22,10 @@ SRCS = README
|
|||||||
|
|
||||||
all: $(SRCS)
|
all: $(SRCS)
|
||||||
|
|
||||||
# We only build the Network library if HAS_NETWORKING was defined
|
|
||||||
NETWORK_yes_V = dec21140
|
|
||||||
NETWORK = $(NETWORK_$(HAS_NETWORKING)_V)
|
|
||||||
|
|
||||||
# wrapup is the one that actually builds and installs the library
|
# wrapup is the one that actually builds and installs the library
|
||||||
# from the individual .rel files built in other directories
|
# from the individual .rel files built in other directories
|
||||||
SUBDIRS = clock console include pci residual openpic irq vectors start \
|
SUBDIRS = clock console include pci residual openpic irq vectors start \
|
||||||
startup bootloader $(NETWORK) motorola wrapup
|
startup bootloader motorola wrapup
|
||||||
|
|
||||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||||
cd $(top_builddir) \
|
cd $(top_builddir) \
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
#
|
||||||
|
# $Id$
|
||||||
|
#
|
||||||
|
|
||||||
|
The dec21140 network driver is found in libchip/networking.
|
||||||
@@ -13,12 +13,7 @@ PROJECT_ROOT = @PROJECT_ROOT@
|
|||||||
|
|
||||||
VPATH = @srcdir@
|
VPATH = @srcdir@
|
||||||
|
|
||||||
# We only build the Network library if HAS_NETWORKING was defined
|
BSP_PIECES = clock console irq openpic pci residual startup vectors motorola
|
||||||
NETWORK_yes_V = dec21140
|
|
||||||
NETWORK = $(NETWORK_$(HAS_NETWORKING)_V)
|
|
||||||
|
|
||||||
BSP_PIECES = clock console irq openpic pci residual startup $(NETWORK) \
|
|
||||||
vectors motorola
|
|
||||||
GENERIC_PIECES =
|
GENERIC_PIECES =
|
||||||
|
|
||||||
# bummer; have to use $foreach since % pattern subst rules only replace 1x
|
# bummer; have to use $foreach since % pattern subst rules only replace 1x
|
||||||
|
|||||||
117
c/src/libchip/network/README.dec21140
Normal file
117
c/src/libchip/network/README.dec21140
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
#
|
||||||
|
# $Id$
|
||||||
|
#
|
||||||
|
|
||||||
|
This TULIP driver can be used on BSPs that support PCI bus.
|
||||||
|
|
||||||
|
It can handle any DEC21140 based Ethernet controller.
|
||||||
|
|
||||||
|
It works on big or little endian target.
|
||||||
|
|
||||||
|
It has been tested with powerpc/mcp750 BSP (OnBoard Ethernet
|
||||||
|
controller) and i386/pc386 BSP (D-Link DFE-500TX Ethernet board).
|
||||||
|
|
||||||
|
|
||||||
|
*****************************************************************
|
||||||
|
******** ***************
|
||||||
|
******** tests with ttcp benchmark for DEC driver ***************
|
||||||
|
******** optimization ***************
|
||||||
|
******** ***************
|
||||||
|
*****************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
LINUX -> LINUX-ix86
|
||||||
|
|
||||||
|
Transmitter :
|
||||||
|
|
||||||
|
ttcp-t: buflen=8192, nbuf=2048, align=16384/0, port=5001 tcp -> genesis
|
||||||
|
ttcp-t: 16777216 bytes in 1.87 real seconds = 8775.25 KB/sec +++
|
||||||
|
ttcp-t: 2048 I/O calls, msec/call = 0.93, calls/sec = 1096.91
|
||||||
|
ttcp-t: 0.0user 0.9sys 0:01real 51% 0i+0d 0maxrss 0+2pf 0+0csw
|
||||||
|
|
||||||
|
Receiver :
|
||||||
|
|
||||||
|
ttcp-r: buflen=8192, nbuf=2048, align=16384/0, port=5001 tcp
|
||||||
|
ttcp-r: 16777216 bytes in 1.88 real seconds = 8706.53 KB/sec +++
|
||||||
|
ttcp-r: 10802 I/O calls, msec/call = 0.18, calls/sec = 5740.23
|
||||||
|
ttcp-r: 0.0user 0.2sys 0:01real 13% 0i+0d 0maxrss 0+2pf 0+0csw
|
||||||
|
|
||||||
|
==============================================================
|
||||||
|
==============================================================
|
||||||
|
==============================================================
|
||||||
|
|
||||||
|
LINUX -> RTEMS-ix86 with tulip driver from pc386 bsp
|
||||||
|
|
||||||
|
Transmitter :
|
||||||
|
|
||||||
|
ttcp-t: buflen=8192, nbuf=2048, align=16384/0, port=5001 tcp -> neil-young-100
|
||||||
|
ttcp-t: 16777216 bytes in 1.98 real seconds = 8294.76 KB/sec +++
|
||||||
|
ttcp-t: 2048 I/O calls, msec/call = 0.99, calls/sec = 1036.85
|
||||||
|
ttcp-t: 0.0user 0.1sys 0:01real 9% 0i+0d 0maxrss 0+2pf 0+0csw
|
||||||
|
|
||||||
|
Receiver :
|
||||||
|
|
||||||
|
ttcp-r: buflen=8192, nbuf=2048, align=16384/0, port=5001 tcp
|
||||||
|
ttcp-r: 16777216 bytes in 2.03 real seconds = 8065.14 KB/sec +++
|
||||||
|
ttcp-r: 3088 I/O calls, msec/call = 0.67, calls/sec = 1520.09
|
||||||
|
ttcp-r: 0.0user 2.0sys 0:02real 100% 0i+0d 0maxrss 0+0pf 0+0csw
|
||||||
|
|
||||||
|
==============================================================
|
||||||
|
==============================================================
|
||||||
|
==============================================================
|
||||||
|
|
||||||
|
RTEMS-ix86 with tulip driver from pc386 bsp -> LINUX
|
||||||
|
|
||||||
|
Transmitter :
|
||||||
|
|
||||||
|
ttcp-t: buflen=8192, nbuf=2048, align=16384/0, port=5001 tcp -> 194.2.81.126
|
||||||
|
ttcp-t: 16777216 bytes in 2.76 real seconds = 5938.77 KB/sec +++
|
||||||
|
ttcp-t: 2048 I/O calls, msec/call = 1.38, calls/sec = 742.35
|
||||||
|
ttcp-t: 0.0user 2.5sys 0:02real 100% 0i+0d 0maxrss 0+0pf 0+0csw
|
||||||
|
|
||||||
|
Receiver :
|
||||||
|
|
||||||
|
ttcp-r: buflen=8192, nbuf=2048, align=16384/0, port=5001 tcp
|
||||||
|
ttcp-r: 16777216 bytes in 2.75 real seconds = 5948.53 KB/sec +++
|
||||||
|
ttcp-r: 11349 I/O calls, msec/call = 0.25, calls/sec = 4120.48
|
||||||
|
ttcp-r: 0.0user 0.1sys 0:02real 6% 0i+0d 0maxrss 0+2pf 0+0csw
|
||||||
|
|
||||||
|
==============================================================
|
||||||
|
==============================================================
|
||||||
|
==============================================================
|
||||||
|
|
||||||
|
LINUX -> RTEMS-ix86 with optimized tulip driver
|
||||||
|
|
||||||
|
Transmitter :
|
||||||
|
|
||||||
|
ttcp-t: buflen=8192, nbuf=2048, align=16384/0, port=5001 tcp -> neil-young-100
|
||||||
|
ttcp-t: 16777216 bytes in 1.73 real seconds = 9470.13 KB/sec +++
|
||||||
|
ttcp-t: 2048 I/O calls, msec/call = 0.87, calls/sec = 1183.77
|
||||||
|
ttcp-t: 0.0user 0.1sys 0:01real 6% 0i+0d 0maxrss 0+2pf 0+0csw
|
||||||
|
|
||||||
|
Receiver :
|
||||||
|
|
||||||
|
ttcp-r: buflen=8192, nbuf=2048, align=16384/0, port=5001 tcp
|
||||||
|
ttcp-r: 16777216 bytes in 1.76 real seconds = 9315.33 KB/sec +++
|
||||||
|
ttcp-r: 4558 I/O calls, msec/call = 0.40, calls/sec = 2591.51
|
||||||
|
ttcp-r: 0.0user 1.7sys 0:01real 100% 0i+0d 0maxrss 0+0pf 0+0csw
|
||||||
|
|
||||||
|
==============================================================
|
||||||
|
==============================================================
|
||||||
|
==============================================================
|
||||||
|
|
||||||
|
RTEMS-ix86 with optimized tulip driver -> LINUX
|
||||||
|
|
||||||
|
Transmitter :
|
||||||
|
|
||||||
|
ttcp-t: buflen=8192, nbuf=2048, align=16384/0, port=5001 tcp -> 194.2.81.126
|
||||||
|
ttcp-t: 16777216 bytes in 2.09 real seconds = 7847.80 KB/sec +++
|
||||||
|
ttcp-t: 2048 I/O calls, msec/call = 1.04, calls/sec = 980.98
|
||||||
|
ttcp-t: 0.0user 2.0sys 0:02real 100% 0i+0d 0maxrss 0+0pf 0+0csw
|
||||||
|
|
||||||
|
Receiver :
|
||||||
|
|
||||||
|
ttcp-r: buflen=8192, nbuf=2048, align=16384/0, port=5001 tcp
|
||||||
|
ttcp-r: 16777216 bytes in 2.08 real seconds = 7874.23 KB/sec +++
|
||||||
|
ttcp-r: 11404 I/O calls, msec/call = 0.19, calls/sec = 5480.82
|
||||||
|
ttcp-r: 0.0user 0.1sys 0:02real 8% 0i+0d 0maxrss 0+2pf 0+0csw
|
||||||
@@ -1,11 +1,24 @@
|
|||||||
/*
|
/*
|
||||||
* RTEMS driver for TULIP based Ethernet Controller
|
* RTEMS driver for TULIP based Ethernet Controller
|
||||||
*
|
*
|
||||||
* $Header$
|
* Copyright (C) 1999 Emmanuel Raguet. raguet@crf.canon.fr
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.OARcorp.com/rtems/license.html.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <bsp.h>
|
#include <bsp.h>
|
||||||
|
#if defined(i386)
|
||||||
#include <pcibios.h>
|
#include <pcibios.h>
|
||||||
|
#endif
|
||||||
|
#if defined(__PPC)
|
||||||
|
#include <bsp/pci.h>
|
||||||
|
#include <libcpu/byteorder.h>
|
||||||
|
#include <libcpu/io.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -24,7 +37,12 @@
|
|||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netinet/if_ether.h>
|
#include <netinet/if_ether.h>
|
||||||
|
|
||||||
|
#if defined(i386)
|
||||||
#include <irq.h>
|
#include <irq.h>
|
||||||
|
#endif
|
||||||
|
#if defined(__PPC)
|
||||||
|
#include <bsp/irq.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef malloc
|
#ifdef malloc
|
||||||
#undef malloc
|
#undef malloc
|
||||||
@@ -33,11 +51,15 @@
|
|||||||
#undef free
|
#undef free
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define DEC_DEBUG
|
||||||
|
|
||||||
|
#define PCI_INVALID_VENDORDEVICEID 0xffffffff
|
||||||
#define PCI_VENDOR_ID_DEC 0x1011
|
#define PCI_VENDOR_ID_DEC 0x1011
|
||||||
#define PCI_DEVICE_ID_DEC_TULIP_FAST 0x0009
|
#define PCI_DEVICE_ID_DEC_TULIP_FAST 0x0009
|
||||||
|
|
||||||
#define IO_MASK 0x3
|
#define IO_MASK 0x3
|
||||||
#define MEM_MASK 0xF
|
#define MEM_MASK 0xF
|
||||||
|
#define MASK_OFFSET 0xF
|
||||||
|
|
||||||
/* command and status registers, 32-bit access, only if IO-ACCESS */
|
/* command and status registers, 32-bit access, only if IO-ACCESS */
|
||||||
#define ioCSR0 0x00 /* bus mode register */
|
#define ioCSR0 0x00 /* bus mode register */
|
||||||
@@ -78,27 +100,35 @@
|
|||||||
#define DEC_REGISTER_SIZE 0x100 /* to reserve virtual memory */
|
#define DEC_REGISTER_SIZE 0x100 /* to reserve virtual memory */
|
||||||
|
|
||||||
#define RESET_CHIP 0x00000001
|
#define RESET_CHIP 0x00000001
|
||||||
#define CSR0_MODE 0x01a08000 /* 01a08000 */
|
#if defined(__PPC)
|
||||||
|
#define CSR0_MODE 0x0030e002 /* 01b08000 */
|
||||||
|
#else
|
||||||
|
#define CSR0_MODE 0x0020e002 /* 01b08000 */
|
||||||
|
#endif
|
||||||
#define ROM_ADDRESS 0x00004800
|
#define ROM_ADDRESS 0x00004800
|
||||||
#define CSR6_INIT 0x020c0000 /* 020c0000 */
|
#define CSR6_INIT 0x022cc000 /* 022c0000 020c0000 */
|
||||||
#define CSR6_TX 0x00002000
|
#define CSR6_TX 0x00002000
|
||||||
#define CSR6_TXRX 0x00002002
|
#define CSR6_TXRX 0x00002002
|
||||||
#define IT_SETUP 0x00010040 /* 0001ebef */
|
#define IT_SETUP 0x000100c0 /* 000100e0 */
|
||||||
#define CLEAR_IT 0xFFFFFFFF
|
#define CLEAR_IT 0xFFFFFFFF
|
||||||
#define NO_IT 0x00000000
|
#define NO_IT 0x00000000
|
||||||
|
|
||||||
#define NRXBUFS 7 /* number of receive buffers */
|
#define NRXBUFS 32 /* number of receive buffers */
|
||||||
#define NTXBUFS 1 /* number of transmit buffers */
|
#define NTXBUFS 16 /* number of transmit buffers */
|
||||||
|
|
||||||
/* message descriptor entry */
|
/* message descriptor entry */
|
||||||
struct MD {
|
struct MD {
|
||||||
volatile unsigned long status;
|
/* used by hardware */
|
||||||
volatile unsigned long counts;
|
volatile unsigned32 status;
|
||||||
unsigned long buf1, buf2;
|
volatile unsigned32 counts;
|
||||||
|
unsigned32 buf1, buf2;
|
||||||
|
/* used by software */
|
||||||
|
volatile struct mbuf *m;
|
||||||
|
volatile struct MD *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Number of WDs supported by this driver
|
* Number of DECs supported by this driver
|
||||||
*/
|
*/
|
||||||
#define NDECDRIVER 1
|
#define NDECDRIVER 1
|
||||||
|
|
||||||
@@ -121,6 +151,28 @@ struct MD {
|
|||||||
*/
|
*/
|
||||||
#define START_TRANSMIT_EVENT RTEMS_EVENT_2
|
#define START_TRANSMIT_EVENT RTEMS_EVENT_2
|
||||||
|
|
||||||
|
#if defined(__PPC)
|
||||||
|
#define phys_to_bus(address) ((unsigned int)(address) + PREP_PCI_DRAM_OFFSET)
|
||||||
|
#define bus_to_phys(address) ((unsigned int)(address) - PREP_PCI_DRAM_OFFSET)
|
||||||
|
#define CPU_CACHE_ALIGNMENT_FOR_BUFFER PPC_CACHE_ALIGNMENT
|
||||||
|
#else
|
||||||
|
#define phys_to_bus(address) address
|
||||||
|
#define bus_to_phys(address) address
|
||||||
|
#define delay_in_bus_cycles(cycle) Wait_X_ms( cycle/100 )
|
||||||
|
#define CPU_CACHE_ALIGNMENT_FOR_BUFFER PG_SIZE
|
||||||
|
|
||||||
|
inline void st_le32(volatile unsigned32 *addr, unsigned32 value)
|
||||||
|
{
|
||||||
|
*(addr)=value ;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline unsigned32 ld_le32(volatile unsigned32 *addr)
|
||||||
|
{
|
||||||
|
return(*addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#if (MCLBYTES < RBUF_SIZE)
|
#if (MCLBYTES < RBUF_SIZE)
|
||||||
# error "Driver must have MCLBYTES > RBUF_SIZE"
|
# error "Driver must have MCLBYTES > RBUF_SIZE"
|
||||||
#endif
|
#endif
|
||||||
@@ -129,19 +181,24 @@ struct MD {
|
|||||||
* Per-device data
|
* Per-device data
|
||||||
*/
|
*/
|
||||||
struct dec21140_softc {
|
struct dec21140_softc {
|
||||||
struct arpcom arpcom;
|
|
||||||
rtems_irq_connect_data irqInfo;
|
struct arpcom arpcom;
|
||||||
struct MD *MDbase;
|
|
||||||
char *bufferBase;
|
rtems_irq_connect_data irqInfo;
|
||||||
int acceptBroadcast;
|
|
||||||
int rxBdCount;
|
volatile struct MD *MDbase;
|
||||||
int txBdCount;
|
volatile unsigned char *bufferBase;
|
||||||
rtems_id rxDaemonTid;
|
int acceptBroadcast;
|
||||||
rtems_id txDaemonTid;
|
rtems_id rxDaemonTid;
|
||||||
|
rtems_id txDaemonTid;
|
||||||
|
|
||||||
|
volatile struct MD *TxMD;
|
||||||
|
volatile struct MD *SentTxMD;
|
||||||
|
int PendingTxCount;
|
||||||
|
int TxSuspended;
|
||||||
|
|
||||||
unsigned int port;
|
unsigned int port;
|
||||||
unsigned int *base;
|
volatile unsigned int *base;
|
||||||
unsigned long bpar;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Statistics
|
* Statistics
|
||||||
@@ -174,27 +231,26 @@ static struct dec21140_softc dec21140_softc[NDECDRIVER];
|
|||||||
static rtems_isr
|
static rtems_isr
|
||||||
dec21140Enet_interrupt_handler (rtems_vector_number v)
|
dec21140Enet_interrupt_handler (rtems_vector_number v)
|
||||||
{
|
{
|
||||||
unsigned int *tbase;
|
volatile unsigned32 *tbase;
|
||||||
unsigned long status;
|
unsigned32 status;
|
||||||
|
struct dec21140_softc *sc;
|
||||||
|
|
||||||
unsigned int sc;
|
sc = &dec21140_softc[0];
|
||||||
|
tbase = (unsigned32 *)(sc->base) ;
|
||||||
tbase = dec21140_softc[0].base ;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read status
|
* Read status
|
||||||
*/
|
*/
|
||||||
*(tbase+memCSR7) = NO_IT;
|
status = ld_le32(tbase+memCSR5);
|
||||||
status = *(tbase+memCSR5);
|
st_le32((tbase+memCSR5), status); /* clear the bits we've read */
|
||||||
*(tbase+memCSR5) = CLEAR_IT;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Frame received?
|
* Frame received?
|
||||||
*/
|
*/
|
||||||
if (status & 0x00000040){
|
if (status & 0x000000c0){
|
||||||
dec21140_softc[0].rxInterrupts++;
|
sc->rxInterrupts++;
|
||||||
sc = rtems_event_send (dec21140_softc[0].rxDaemonTid, INTERRUPT_EVENT);
|
rtems_event_send (sc->rxDaemonTid, INTERRUPT_EVENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nopOn(const rtems_irq_connect_data* notUsed)
|
static void nopOn(const rtems_irq_connect_data* notUsed)
|
||||||
@@ -210,93 +266,6 @@ static int dec21140IsOn(const rtems_irq_connect_data* irq)
|
|||||||
return BSP_irq_enabled_at_i8259s (irq->name);
|
return BSP_irq_enabled_at_i8259s (irq->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Read and write the MII registers using software-generated serial
|
|
||||||
* MDIO protocol.
|
|
||||||
*/
|
|
||||||
#define MDIO_SHIFT_CLK 0x10000
|
|
||||||
#define MDIO_DATA_WRITE0 0x00000
|
|
||||||
#define MDIO_DATA_WRITE1 0x20000
|
|
||||||
#define MDIO_ENB 0x00000
|
|
||||||
#define MDIO_ENB_IN 0x40000
|
|
||||||
#define MDIO_DATA_READ 0x80000
|
|
||||||
|
|
||||||
static int mdio_read(unsigned int *ioaddr, int phy_id, int location)
|
|
||||||
{
|
|
||||||
int i, i3;
|
|
||||||
int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
|
|
||||||
unsigned short retval = 0;
|
|
||||||
|
|
||||||
/* Establish sync by sending at least 32 logic ones. */
|
|
||||||
for (i = 32; i >= 0; i--) {
|
|
||||||
*ioaddr = MDIO_ENB | MDIO_DATA_WRITE1;
|
|
||||||
for(i3=0; i3<1000; i3++);
|
|
||||||
*ioaddr = MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK;
|
|
||||||
for(i3=0; i3<1000; i3++);
|
|
||||||
}
|
|
||||||
/* Shift the read command bits out. */
|
|
||||||
for (i = 17; i >= 0; i--) {
|
|
||||||
int dataval = (read_cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
|
|
||||||
*ioaddr = dataval;
|
|
||||||
for(i3=0; i3<1000; i3++);
|
|
||||||
*ioaddr = dataval | MDIO_SHIFT_CLK;
|
|
||||||
for(i3=0; i3<1000; i3++);
|
|
||||||
*ioaddr = dataval;
|
|
||||||
for(i3=0; i3<1000; i3++);
|
|
||||||
}
|
|
||||||
*ioaddr = MDIO_ENB_IN | MDIO_SHIFT_CLK;
|
|
||||||
for(i3=0; i3<1000; i3++);
|
|
||||||
*ioaddr = MDIO_ENB_IN;
|
|
||||||
|
|
||||||
for (i = 16; i > 0; i--) {
|
|
||||||
*ioaddr = MDIO_ENB_IN | MDIO_SHIFT_CLK;
|
|
||||||
for(i3=0; i3<1000; i3++);
|
|
||||||
retval = (retval << 1) | ((*ioaddr & MDIO_DATA_READ) ? 1 : 0);
|
|
||||||
*ioaddr = MDIO_ENB_IN;
|
|
||||||
for(i3=0; i3<1000; i3++);
|
|
||||||
}
|
|
||||||
/* Clear out extra bits. */
|
|
||||||
for (i = 16; i > 0; i--) {
|
|
||||||
*ioaddr = MDIO_ENB_IN | MDIO_SHIFT_CLK;
|
|
||||||
for(i3=0; i3<1000; i3++);
|
|
||||||
*ioaddr = MDIO_ENB_IN;
|
|
||||||
for(i3=0; i3<1000; i3++);
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mdio_write(unsigned int *ioaddr, int phy_id, int location, int value)
|
|
||||||
{
|
|
||||||
int i, i3;
|
|
||||||
int cmd = (0x5002 << 16) | (phy_id << 23) | (location << 18) | value;
|
|
||||||
|
|
||||||
/* Establish sync by sending at least 32 logic ones. */
|
|
||||||
for (i = 32; i >= 0; i--) {
|
|
||||||
*ioaddr = MDIO_ENB | MDIO_DATA_WRITE1;
|
|
||||||
for(i3=0; i3<1000; i3++);
|
|
||||||
*ioaddr = MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK;
|
|
||||||
for(i3=0; i3<1000; i3++);
|
|
||||||
}
|
|
||||||
/* Shift the read command bits out. */
|
|
||||||
for (i = 31; i >= 0; i--) {
|
|
||||||
int dataval = (cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
|
|
||||||
*ioaddr = dataval;
|
|
||||||
for(i3=0; i3<1000; i3++);
|
|
||||||
*ioaddr = dataval | MDIO_SHIFT_CLK;
|
|
||||||
for(i3=0; i3<1000; i3++);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear out extra bits. */
|
|
||||||
for (i = 2; i > 0; i--) {
|
|
||||||
*ioaddr = MDIO_ENB_IN;
|
|
||||||
for(i3=0; i3<1000; i3++);
|
|
||||||
*ioaddr = MDIO_ENB_IN | MDIO_SHIFT_CLK;
|
|
||||||
for(i3=0; i3<1000; i3++);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This routine reads a word (16 bits) from the serial EEPROM.
|
* This routine reads a word (16 bits) from the serial EEPROM.
|
||||||
@@ -315,38 +284,38 @@ static int mdio_write(unsigned int *ioaddr, int phy_id, int location, int value)
|
|||||||
#define EE_READ_CMD (6 << 6)
|
#define EE_READ_CMD (6 << 6)
|
||||||
#define EE_ERASE_CMD (7 << 6)
|
#define EE_ERASE_CMD (7 << 6)
|
||||||
|
|
||||||
static int eeget16(unsigned int *ioaddr, int location)
|
static int eeget16(volatile unsigned int *ioaddr, int location)
|
||||||
{
|
{
|
||||||
int i, i3;
|
int i;
|
||||||
unsigned short retval = 0;
|
unsigned short retval = 0;
|
||||||
int read_cmd = location | EE_READ_CMD;
|
int read_cmd = location | EE_READ_CMD;
|
||||||
|
|
||||||
*ioaddr = EE_ENB & ~EE_CS;
|
st_le32(ioaddr, EE_ENB & ~EE_CS);
|
||||||
*ioaddr = EE_ENB;
|
st_le32(ioaddr, EE_ENB);
|
||||||
|
|
||||||
/* Shift the read command bits out. */
|
/* Shift the read command bits out. */
|
||||||
for (i = 10; i >= 0; i--) {
|
for (i = 10; i >= 0; i--) {
|
||||||
short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
|
short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
|
||||||
*ioaddr = EE_ENB | dataval;
|
st_le32(ioaddr, EE_ENB | dataval);
|
||||||
for (i3=0; i3<1000; i3++) ;
|
delay_in_bus_cycles(200);
|
||||||
*ioaddr = EE_ENB | dataval | EE_SHIFT_CLK;
|
st_le32(ioaddr, EE_ENB | dataval | EE_SHIFT_CLK);
|
||||||
for (i3=0; i3<1000; i3++) ;
|
delay_in_bus_cycles(200);
|
||||||
*ioaddr = EE_ENB | dataval; /* Finish EEPROM a clock tick. */
|
st_le32(ioaddr, EE_ENB | dataval); /* Finish EEPROM a clock tick. */
|
||||||
for (i3=0; i3<1000; i3++) ;
|
delay_in_bus_cycles(200);
|
||||||
}
|
}
|
||||||
*ioaddr = EE_ENB;
|
st_le32(ioaddr, EE_ENB);
|
||||||
|
|
||||||
for (i = 16; i > 0; i--) {
|
for (i = 16; i > 0; i--) {
|
||||||
*ioaddr = EE_ENB | EE_SHIFT_CLK;
|
st_le32(ioaddr, EE_ENB | EE_SHIFT_CLK);
|
||||||
for (i3=0; i3<1000; i3++) ;
|
delay_in_bus_cycles(200);
|
||||||
retval = (retval << 1) | ((*ioaddr & EE_DATA_READ) ? 1 : 0);
|
retval = (retval << 1) | ((ld_le32(ioaddr) & EE_DATA_READ) ? 1 : 0);
|
||||||
*ioaddr = EE_ENB;
|
st_le32(ioaddr, EE_ENB);
|
||||||
for (i3=0; i3<1000; i3++) ;
|
delay_in_bus_cycles(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Terminate the EEPROM access. */
|
/* Terminate the EEPROM access. */
|
||||||
*ioaddr = EE_ENB & ~EE_CS;
|
st_le32(ioaddr, EE_ENB & ~EE_CS);
|
||||||
return retval;
|
return ( ((retval<<8)&0xff00) | ((retval>>8)&0xff) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -356,96 +325,110 @@ static void
|
|||||||
dec21140Enet_initialize_hardware (struct dec21140_softc *sc)
|
dec21140Enet_initialize_hardware (struct dec21140_softc *sc)
|
||||||
{
|
{
|
||||||
rtems_status_code st;
|
rtems_status_code st;
|
||||||
unsigned int *tbase;
|
volatile unsigned int *tbase;
|
||||||
union {char c[64]; unsigned short s[32];} rombuf;
|
union {char c[64]; unsigned short s[32];} rombuf;
|
||||||
int i, i2, i3;
|
int i;
|
||||||
char *cp, direction, *setup_frm, *eaddrs;
|
volatile unsigned char *cp, *setup_frm, *eaddrs;
|
||||||
unsigned long csr12_val, mii_reg0;
|
volatile unsigned char *buffer;
|
||||||
unsigned char *buffer;
|
volatile struct MD *rmd;
|
||||||
struct MD *rmd;
|
|
||||||
|
|
||||||
|
|
||||||
tbase = sc->base;
|
tbase = sc->base;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* WARNING : First write in CSR6
|
* WARNING : First write in CSR6
|
||||||
* Then Reset the chip ( 1 in CSR0)
|
* Then Reset the chip ( 1 in CSR0)
|
||||||
*/
|
*/
|
||||||
|
st_le32( (tbase+memCSR6), CSR6_INIT);
|
||||||
*(tbase+memCSR6) = CSR6_INIT;
|
st_le32( (tbase+memCSR0), RESET_CHIP);
|
||||||
*(tbase+memCSR0) = RESET_CHIP;
|
delay_in_bus_cycles(200);
|
||||||
for(i3=0; i3<1000; i3++);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Init CSR0
|
* Init CSR0
|
||||||
*/
|
*/
|
||||||
*(tbase+memCSR0) = CSR0_MODE;
|
st_le32( (tbase+memCSR0), CSR0_MODE);
|
||||||
|
|
||||||
csr12_val = *(tbase+memCSR8);
|
/* csr12_val = ld_le32( (tbase+memCSR8) );*/
|
||||||
|
|
||||||
for (i=0; i<32; i++)
|
for (i=0; i<32; i++){
|
||||||
rombuf.s[i] = eeget16(tbase+memCSR9, i);
|
rombuf.s[i] = eeget16(tbase+memCSR9, i);
|
||||||
|
}
|
||||||
memcpy (sc->arpcom.ac_enaddr, rombuf.c+20, ETHER_ADDR_LEN);
|
memcpy (sc->arpcom.ac_enaddr, rombuf.c+20, ETHER_ADDR_LEN);
|
||||||
|
|
||||||
|
|
||||||
mii_reg0 = mdio_read(tbase+memCSR9, 0, 0);
|
|
||||||
mdio_write(tbase+memCSR9, 0, 0, mii_reg0 | 0x1000);
|
|
||||||
|
|
||||||
#ifdef DEC_DEBUG
|
#ifdef DEC_DEBUG
|
||||||
printk("DC21140 %x:%x:%x:%x:%x:%x IRQ %d IO %x M %x .........\n",
|
printk("DC21140 %x:%x:%x:%x:%x:%x IRQ %d IO %x M %x .........\n",
|
||||||
sc->arpcom.ac_enaddr[0], sc->arpcom.ac_enaddr[1],
|
sc->arpcom.ac_enaddr[0], sc->arpcom.ac_enaddr[1],
|
||||||
sc->arpcom.ac_enaddr[2], sc->arpcom.ac_enaddr[3],
|
sc->arpcom.ac_enaddr[2], sc->arpcom.ac_enaddr[3],
|
||||||
sc->arpcom.ac_enaddr[4], sc->arpcom.ac_enaddr[5],
|
sc->arpcom.ac_enaddr[4], sc->arpcom.ac_enaddr[5],
|
||||||
sc->irqInfo.name, sc->port, sc->base);
|
sc->irqInfo.name, sc->port, (unsigned) sc->base);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Init RX ring
|
* Init RX ring
|
||||||
*/
|
*/
|
||||||
sc->rxBdCount = 0;
|
cp = (volatile unsigned char *)malloc(((NRXBUFS+NTXBUFS)*sizeof(struct MD))
|
||||||
|
+ (NTXBUFS*RBUF_SIZE)
|
||||||
cp = (char *)malloc((NRXBUFS+NTXBUFS)*(sizeof(struct MD)+ RBUF_SIZE) + PG_SIZE);
|
+ CPU_CACHE_ALIGNMENT_FOR_BUFFER);
|
||||||
sc->bufferBase = cp;
|
sc->bufferBase = cp;
|
||||||
cp += (PG_SIZE - (int)cp) & MASK_OFFSET;
|
cp += (CPU_CACHE_ALIGNMENT_FOR_BUFFER - (int)cp)
|
||||||
|
& (CPU_CACHE_ALIGNMENT_FOR_BUFFER - 1);
|
||||||
|
#if defined(__i386)
|
||||||
#ifdef PCI_BRIDGE_DOES_NOT_ENSURE_CACHE_COHERENCY_FOR_DMA
|
#ifdef PCI_BRIDGE_DOES_NOT_ENSURE_CACHE_COHERENCY_FOR_DMA
|
||||||
if (_CPU_is_paging_enabled())
|
if (_CPU_is_paging_enabled())
|
||||||
_CPU_change_memory_mapping_attribute
|
_CPU_change_memory_mapping_attribute
|
||||||
(NULL, cp,
|
(NULL, cp,
|
||||||
(NRXBUFS+NTXBUFS)*(sizeof(struct MD)+ RBUF_SIZE),
|
((NRXBUFS+NTXBUFS)*sizeof(struct MD))
|
||||||
|
+ (NTXBUFS*RBUF_SIZE),
|
||||||
PTE_CACHE_DISABLE | PTE_WRITABLE);
|
PTE_CACHE_DISABLE | PTE_WRITABLE);
|
||||||
#endif
|
#endif
|
||||||
rmd = (struct MD*)cp;
|
#endif
|
||||||
|
rmd = (volatile struct MD*)cp;
|
||||||
sc->MDbase = rmd;
|
sc->MDbase = rmd;
|
||||||
buffer = cp + ((NRXBUFS+NTXBUFS)*sizeof(struct MD));
|
buffer = cp + ((NRXBUFS+NTXBUFS)*sizeof(struct MD));
|
||||||
|
st_le32( (tbase+memCSR3), (long)(phys_to_bus((long)(sc->MDbase))));
|
||||||
*(tbase+memCSR3) = (long)(sc->MDbase);
|
|
||||||
for (i=0 ; i<NRXBUFS; i++){
|
for (i=0 ; i<NRXBUFS; i++){
|
||||||
rmd->buf2 = 0;
|
struct mbuf *m;
|
||||||
rmd->buf1 = (unsigned long)(buffer + (i*RBUF_SIZE));
|
|
||||||
if (i == NRXBUFS-1)
|
/* allocate an mbuf for each receive descriptor */
|
||||||
rmd->counts = 0xfec00000 | (RBUF_SIZE);
|
MGETHDR (m, M_WAIT, MT_DATA);
|
||||||
else
|
MCLGET (m, M_WAIT);
|
||||||
rmd->counts = 0xfcc00000 | (RBUF_SIZE);
|
m->m_pkthdr.rcvif = &sc->arpcom.ac_if;
|
||||||
|
rmd->m = m;
|
||||||
|
|
||||||
|
rmd->buf2 = phys_to_bus(rmd+1);
|
||||||
|
rmd->buf1 = phys_to_bus(mtod(m, void *));
|
||||||
|
rmd->counts = 0xfdc00000 | (RBUF_SIZE);
|
||||||
rmd->status = 0x80000000;
|
rmd->status = 0x80000000;
|
||||||
|
rmd->next = rmd + 1;
|
||||||
rmd++;
|
rmd++;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* mark last RX buffer.
|
||||||
|
*/
|
||||||
|
sc->MDbase [NRXBUFS-1].counts = 0xfec00000 | (RBUF_SIZE);
|
||||||
|
sc->MDbase [NRXBUFS-1].next = sc->MDbase;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Init TX ring
|
* Init TX ring
|
||||||
*/
|
*/
|
||||||
sc->txBdCount = 0;
|
st_le32( (tbase+memCSR4), (long)(phys_to_bus((long)(rmd))) );
|
||||||
*(tbase+memCSR4) = (long)(rmd);
|
for (i=0 ; i<NTXBUFS; i++){
|
||||||
rmd->buf2 = 0;
|
(rmd+i)->buf2 = phys_to_bus(rmd+i+1);
|
||||||
rmd->buf1 = (unsigned long)(buffer + (NRXBUFS*RBUF_SIZE));
|
(rmd+i)->buf1 = phys_to_bus(buffer + (i*RBUF_SIZE));
|
||||||
rmd->counts = 0x62000000;
|
(rmd+i)->counts = 0x01000000;
|
||||||
rmd->status = 0x0;
|
(rmd+i)->status = 0x0;
|
||||||
|
(rmd+i)->next = rmd+i+1;
|
||||||
|
(rmd+i)->m = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mark last TX buffer.
|
||||||
|
*/
|
||||||
|
(rmd+NTXBUFS-1)->buf2 = phys_to_bus(rmd);
|
||||||
|
(rmd+NTXBUFS-1)->next = rmd;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up interrupts
|
* Set up interrupts
|
||||||
*/
|
*/
|
||||||
*(tbase+memCSR5) = IT_SETUP;
|
|
||||||
*(tbase+memCSR7) = IT_SETUP;
|
|
||||||
|
|
||||||
sc->irqInfo.hdl = (rtems_irq_hdl)dec21140Enet_interrupt_handler;
|
sc->irqInfo.hdl = (rtems_irq_hdl)dec21140Enet_interrupt_handler;
|
||||||
sc->irqInfo.on = nopOn;
|
sc->irqInfo.on = nopOn;
|
||||||
sc->irqInfo.off = nopOn;
|
sc->irqInfo.off = nopOn;
|
||||||
@@ -455,72 +438,61 @@ dec21140Enet_initialize_hardware (struct dec21140_softc *sc)
|
|||||||
rtems_panic ("Can't attach DEC21140 interrupt handler for irq %d\n",
|
rtems_panic ("Can't attach DEC21140 interrupt handler for irq %d\n",
|
||||||
sc->irqInfo.name);
|
sc->irqInfo.name);
|
||||||
|
|
||||||
/*
|
st_le32( (tbase+memCSR7), NO_IT);
|
||||||
* Start TX for setup frame
|
|
||||||
*/
|
|
||||||
*(tbase+memCSR6) = CSR6_INIT | CSR6_TX;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Build setup frame
|
* Build setup frame
|
||||||
*/
|
*/
|
||||||
setup_frm = (char *)(rmd->buf1);
|
setup_frm = (volatile unsigned char *)(bus_to_phys(rmd->buf1));
|
||||||
eaddrs = (char *)(sc->arpcom.ac_enaddr);
|
eaddrs = (char *)(sc->arpcom.ac_enaddr);
|
||||||
/* Fill the buffer with our physical address. */
|
/* Fill the buffer with our physical address. */
|
||||||
for (i = 1; i < 16; i++) {
|
for (i = 1; i < 16; i++) {
|
||||||
*setup_frm++ = eaddrs[0];
|
*setup_frm++ = eaddrs[0];
|
||||||
*setup_frm++ = eaddrs[1];
|
*setup_frm++ = eaddrs[1];
|
||||||
setup_frm += 2;
|
*setup_frm++ = eaddrs[0];
|
||||||
|
*setup_frm++ = eaddrs[1];
|
||||||
|
*setup_frm++ = eaddrs[2];
|
||||||
|
*setup_frm++ = eaddrs[3];
|
||||||
*setup_frm++ = eaddrs[2];
|
*setup_frm++ = eaddrs[2];
|
||||||
*setup_frm++ = eaddrs[3];
|
*setup_frm++ = eaddrs[3];
|
||||||
setup_frm += 2;
|
|
||||||
*setup_frm++ = eaddrs[4];
|
*setup_frm++ = eaddrs[4];
|
||||||
*setup_frm++ = eaddrs[5];
|
*setup_frm++ = eaddrs[5];
|
||||||
setup_frm += 2;
|
*setup_frm++ = eaddrs[4];
|
||||||
|
*setup_frm++ = eaddrs[5];
|
||||||
}
|
}
|
||||||
/* Add the broadcast address when doing perfect filtering */
|
/* Add the broadcast address when doing perfect filtering */
|
||||||
memset(setup_frm, 0xff, 12);
|
memset((void*) setup_frm, 0xff, 12);
|
||||||
rmd->counts = 0x0a000000 | 192 ;
|
rmd->counts = 0x09000000 | 192 ;
|
||||||
rmd->status = 0x80000000;
|
rmd->status = 0x80000000;
|
||||||
*(tbase+memCSR1) = 1;
|
st_le32( (tbase+memCSR6), CSR6_INIT | CSR6_TX);
|
||||||
|
st_le32( (tbase+memCSR1), 1);
|
||||||
while (rmd->status != 0x7fffffff);
|
while (rmd->status != 0x7fffffff);
|
||||||
|
rmd->counts = 0x01000000;
|
||||||
|
sc->TxMD = rmd+1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enable RX and TX
|
* Enable RX and TX
|
||||||
*/
|
*/
|
||||||
*(tbase+memCSR6) = CSR6_INIT | CSR6_TXRX;
|
st_le32( (tbase+memCSR5), IT_SETUP);
|
||||||
|
st_le32( (tbase+memCSR7), IT_SETUP);
|
||||||
|
st_le32( (unsigned int*)(tbase+memCSR6), CSR6_INIT | CSR6_TXRX);
|
||||||
|
|
||||||
/*
|
|
||||||
* Set up PHY
|
|
||||||
*/
|
|
||||||
|
|
||||||
i = rombuf.c[27];
|
|
||||||
i+=2;
|
|
||||||
direction = rombuf.c[i];
|
|
||||||
i +=4;
|
|
||||||
*(tbase+memCSR12) = direction | 0x100;
|
|
||||||
for (i2 = 0; i2 < rombuf.c[(i+2) + rombuf.c[i+1]]; i2++){
|
|
||||||
*(tbase + memCSR12) = rombuf.c[(i+3) + rombuf.c[i+1] + i2];
|
|
||||||
}
|
|
||||||
for (i2 = 0; i2 < rombuf.c[i+1]; i2++){
|
|
||||||
*(tbase + memCSR12) = rombuf.c[(i+2) + i2];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dec21140_rxDaemon (void *arg)
|
dec21140_rxDaemon (void *arg)
|
||||||
{
|
{
|
||||||
unsigned int *tbase;
|
volatile unsigned int *tbase;
|
||||||
struct ether_header *eh;
|
struct ether_header *eh;
|
||||||
struct dec21140_softc *dp = (struct dec21140_softc *)&dec21140_softc[0];
|
struct dec21140_softc *dp = (struct dec21140_softc *)&dec21140_softc[0];
|
||||||
struct ifnet *ifp = &dp->arpcom.ac_if;
|
struct ifnet *ifp = &dp->arpcom.ac_if;
|
||||||
struct mbuf *m;
|
struct mbuf *m;
|
||||||
struct MD *rmd;
|
volatile struct MD *rmd;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
char *temp;
|
|
||||||
rtems_event_set events;
|
rtems_event_set events;
|
||||||
int nbMD;
|
|
||||||
|
|
||||||
tbase = dec21140_softc[0].base ;
|
tbase = dec21140_softc[0].base ;
|
||||||
|
rmd = dec21140_softc[0].MDbase;
|
||||||
|
|
||||||
for (;;){
|
for (;;){
|
||||||
|
|
||||||
@@ -528,27 +500,27 @@ dec21140_rxDaemon (void *arg)
|
|||||||
RTEMS_WAIT|RTEMS_EVENT_ANY,
|
RTEMS_WAIT|RTEMS_EVENT_ANY,
|
||||||
RTEMS_NO_TIMEOUT,
|
RTEMS_NO_TIMEOUT,
|
||||||
&events);
|
&events);
|
||||||
rmd = dec21140_softc[0].MDbase;
|
|
||||||
nbMD = 0;
|
|
||||||
|
|
||||||
while (nbMD < NRXBUFS){
|
while((rmd->status & 0x80000000) == 0){
|
||||||
if ( (rmd->status & 0x80000000) == 0){
|
/* pass on the packet in the mbuf */
|
||||||
len = (rmd->status >> 16) & 0x7ff;
|
len = (rmd->status >> 16) & 0x7ff;
|
||||||
MGETHDR (m, M_WAIT, MT_DATA);
|
m = (struct mbuf *)(rmd->m);
|
||||||
MCLGET (m, M_WAIT);
|
m->m_len = m->m_pkthdr.len = len - sizeof(struct ether_header);
|
||||||
m->m_pkthdr.rcvif = ifp;
|
eh = mtod (m, struct ether_header *);
|
||||||
temp = m->m_data;
|
m->m_data += sizeof(struct ether_header);
|
||||||
m->m_len = m->m_pkthdr.len = len - sizeof(struct ether_header);
|
ether_input (ifp, eh, m);
|
||||||
memcpy(temp, (char *)rmd->buf1, len);
|
|
||||||
rmd->status = 0x80000000;
|
/* get a new mbuf for the 21140 */
|
||||||
eh = mtod (m, struct ether_header *);
|
MGETHDR (m, M_WAIT, MT_DATA);
|
||||||
m->m_data += sizeof(struct ether_header);
|
MCLGET (m, M_WAIT);
|
||||||
ether_input (ifp, eh, m);
|
m->m_pkthdr.rcvif = ifp;
|
||||||
}
|
rmd->m = m;
|
||||||
rmd++;
|
rmd->buf1 = phys_to_bus(mtod(m, void *));
|
||||||
nbMD++;
|
|
||||||
|
rmd->status = 0x80000000;
|
||||||
|
|
||||||
|
rmd=rmd->next;
|
||||||
}
|
}
|
||||||
*(tbase+memCSR7) = IT_SETUP;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -557,37 +529,41 @@ sendpacket (struct ifnet *ifp, struct mbuf *m)
|
|||||||
{
|
{
|
||||||
struct dec21140_softc *dp = ifp->if_softc;
|
struct dec21140_softc *dp = ifp->if_softc;
|
||||||
volatile struct MD *tmd;
|
volatile struct MD *tmd;
|
||||||
unsigned char *temp;
|
volatile unsigned char *temp;
|
||||||
struct mbuf *n;
|
struct mbuf *n;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
unsigned int *tbase;
|
volatile unsigned int *tbase;
|
||||||
|
|
||||||
tbase = dp->base;
|
tbase = dp->base;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Waiting for Transmitter ready
|
* Waiting for Transmitter ready
|
||||||
*/
|
*/
|
||||||
tmd = dec21140_softc[0].MDbase + NRXBUFS;
|
tmd = dec21140_softc[0].TxMD;
|
||||||
while ( (tmd->status & 0x80000000) != 0 );
|
|
||||||
len = 0;
|
|
||||||
n = m;
|
n = m;
|
||||||
temp = (char *)(tmd->buf1);
|
|
||||||
|
while ((tmd->status & 0x80000000) != 0){
|
||||||
|
tmd=tmd->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = 0;
|
||||||
|
temp = (volatile unsigned char *)(bus_to_phys(tmd->buf1));
|
||||||
|
|
||||||
for (;;){
|
for (;;){
|
||||||
len += m->m_len;
|
len += m->m_len;
|
||||||
memcpy(temp, (char *)m->m_data, m->m_len);
|
memcpy((void*) temp, (char *)m->m_data, m->m_len);
|
||||||
temp += m->m_len ;
|
temp += m->m_len ;
|
||||||
if ((m = m->m_next) == NULL)
|
if ((m = m->m_next) == NULL)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len < ET_MINLEN) len = ET_MINLEN;
|
if (len < ET_MINLEN) len = ET_MINLEN;
|
||||||
tmd->counts = 0xe2000000 | len;
|
tmd->counts = 0xe1000000 | (len & 0x7ff);
|
||||||
tmd->status = 0x80000000;
|
tmd->status = 0x80000000;
|
||||||
|
|
||||||
*(tbase+memCSR1) = 0x1;
|
st_le32( (tbase+memCSR1), 0x1);
|
||||||
|
|
||||||
m_freem(n);
|
m_freem(n);
|
||||||
|
dec21140_softc[0].TxMD = tmd->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -672,7 +648,7 @@ dec21140_init (void *arg)
|
|||||||
static void
|
static void
|
||||||
dec21140_stop (struct dec21140_softc *sc)
|
dec21140_stop (struct dec21140_softc *sc)
|
||||||
{
|
{
|
||||||
unsigned int *tbase;
|
volatile unsigned int *tbase;
|
||||||
struct ifnet *ifp = &sc->arpcom.ac_if;
|
struct ifnet *ifp = &sc->arpcom.ac_if;
|
||||||
|
|
||||||
ifp->if_flags &= ~IFF_RUNNING;
|
ifp->if_flags &= ~IFF_RUNNING;
|
||||||
@@ -681,9 +657,9 @@ dec21140_stop (struct dec21140_softc *sc)
|
|||||||
* Stop the transmitter
|
* Stop the transmitter
|
||||||
*/
|
*/
|
||||||
tbase=dec21140_softc[0].base ;
|
tbase=dec21140_softc[0].base ;
|
||||||
*(tbase+memCSR7) = NO_IT;
|
st_le32( (tbase+memCSR7), NO_IT);
|
||||||
*(tbase+memCSR6) = CSR6_INIT;
|
st_le32( (tbase+memCSR6), CSR6_INIT);
|
||||||
free(sc->bufferBase);
|
free((void*)sc->bufferBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -759,6 +735,7 @@ dec21140_ioctl (struct ifnet *ifp, int command, caddr_t data)
|
|||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -772,14 +749,16 @@ rtems_dec21140_driver_attach (struct rtems_bsdnet_ifconfig *config)
|
|||||||
struct ifnet *ifp;
|
struct ifnet *ifp;
|
||||||
int mtu;
|
int mtu;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* First, find a DEC board
|
||||||
|
*/
|
||||||
|
#if defined(__i386)
|
||||||
int signature;
|
int signature;
|
||||||
int value;
|
int value;
|
||||||
char interrupt;
|
char interrupt;
|
||||||
int diag;
|
int diag;
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialise PCI module
|
|
||||||
*/
|
|
||||||
if (pcib_init() == PCIB_ERR_NOTPRESENT)
|
if (pcib_init() == PCIB_ERR_NOTPRESENT)
|
||||||
rtems_panic("PCI BIOS not found !!");
|
rtems_panic("PCI BIOS not found !!");
|
||||||
|
|
||||||
@@ -794,7 +773,37 @@ rtems_dec21140_driver_attach (struct rtems_bsdnet_ifconfig *config)
|
|||||||
else {
|
else {
|
||||||
printk("DEC PCI Device found\n");
|
printk("DEC PCI Device found\n");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(__PPC)
|
||||||
|
unsigned char ucSlotNumber, ucFnNumber;
|
||||||
|
unsigned int ulDeviceID, lvalue, tmp;
|
||||||
|
unsigned char cvalue;
|
||||||
|
|
||||||
|
for(ucSlotNumber=0;ucSlotNumber<PCI_MAX_DEVICES;ucSlotNumber++) {
|
||||||
|
for(ucFnNumber=0;ucFnNumber<PCI_MAX_FUNCTIONS;ucFnNumber++) {
|
||||||
|
(void)pci_read_config_dword(0,
|
||||||
|
ucSlotNumber,
|
||||||
|
ucFnNumber,
|
||||||
|
PCI_VENDOR_ID,
|
||||||
|
&ulDeviceID);
|
||||||
|
if(ulDeviceID==PCI_INVALID_VENDORDEVICEID) {
|
||||||
|
/*
|
||||||
|
* This slot is empty
|
||||||
|
*/
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ulDeviceID == ((PCI_DEVICE_ID_DEC_TULIP_FAST<<16) + PCI_VENDOR_ID_DEC))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ulDeviceID == ((PCI_DEVICE_ID_DEC_TULIP_FAST<<16) + PCI_VENDOR_ID_DEC)){
|
||||||
|
printk("DEC Adapter found !!\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ulDeviceID==PCI_INVALID_VENDORDEVICEID)
|
||||||
|
rtems_panic("DEC PCI board not found !!\n");
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
* Find a free driver
|
* Find a free driver
|
||||||
*/
|
*/
|
||||||
@@ -812,7 +821,7 @@ rtems_dec21140_driver_attach (struct rtems_bsdnet_ifconfig *config)
|
|||||||
/*
|
/*
|
||||||
* Process options
|
* Process options
|
||||||
*/
|
*/
|
||||||
|
#if defined(__i386)
|
||||||
pcib_conf_read32(signature, 16, &value);
|
pcib_conf_read32(signature, 16, &value);
|
||||||
sc->port = value & ~IO_MASK;
|
sc->port = value & ~IO_MASK;
|
||||||
|
|
||||||
@@ -827,7 +836,34 @@ rtems_dec21140_driver_attach (struct rtems_bsdnet_ifconfig *config)
|
|||||||
|
|
||||||
pcib_conf_read8(signature, 60, &interrupt);
|
pcib_conf_read8(signature, 60, &interrupt);
|
||||||
sc->irqInfo.name = (rtems_irq_symbolic_name)interrupt;
|
sc->irqInfo.name = (rtems_irq_symbolic_name)interrupt;
|
||||||
|
#endif
|
||||||
|
#if defined(__PPC)
|
||||||
|
(void)pci_read_config_dword(0,
|
||||||
|
ucSlotNumber,
|
||||||
|
ucFnNumber,
|
||||||
|
PCI_BASE_ADDRESS_0,
|
||||||
|
&lvalue);
|
||||||
|
|
||||||
|
sc->port = lvalue & (unsigned int)(~IO_MASK);
|
||||||
|
|
||||||
|
(void)pci_read_config_dword(0,
|
||||||
|
ucSlotNumber,
|
||||||
|
ucFnNumber,
|
||||||
|
PCI_BASE_ADDRESS_1 ,
|
||||||
|
&lvalue);
|
||||||
|
|
||||||
|
|
||||||
|
tmp = (unsigned int)(lvalue & (unsigned int)(~MEM_MASK))
|
||||||
|
+ (unsigned int)PREP_ISA_MEM_BASE;
|
||||||
|
sc->base = (unsigned int *)(tmp);
|
||||||
|
|
||||||
|
(void)pci_read_config_byte(0,
|
||||||
|
ucSlotNumber,
|
||||||
|
ucFnNumber,
|
||||||
|
PCI_INTERRUPT_LINE,
|
||||||
|
&cvalue);
|
||||||
|
sc->irqInfo.name = (rtems_irq_symbolic_name)cvalue;
|
||||||
|
#endif
|
||||||
if (config->hardware_address) {
|
if (config->hardware_address) {
|
||||||
memcpy (sc->arpcom.ac_enaddr, config->hardware_address,
|
memcpy (sc->arpcom.ac_enaddr, config->hardware_address,
|
||||||
ETHER_ADDR_LEN);
|
ETHER_ADDR_LEN);
|
||||||
@@ -866,13 +902,3 @@ rtems_dec21140_driver_attach (struct rtems_bsdnet_ifconfig *config)
|
|||||||
return 1;
|
return 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user