Merged in new ethernet code to potentially leverage AsynchIO
This commit is contained in:
parent
a1930c9b05
commit
eb514e2a8d
7 changed files with 3081 additions and 605 deletions
|
@ -2,45 +2,125 @@ This file contains information about the SIMH Ethernet package.
|
|||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
The XQ emulator is a host-independant software emulation of Digital's
|
||||
DELQA (M7516) and DEQNA (M7504) Q-bus ethernet cards for the SIMH emulator.
|
||||
The XQ emulator is a host-independent software emulation of Digital's
|
||||
DELQA-T (M7516-YM), DELQA (M7516) and DEQNA (M7504) Q-bus Ethernet cards
|
||||
for the SIMH emulator.
|
||||
|
||||
The XU emulator is a host-independant software emulation of Digital's DEUNA
|
||||
(M7792/M7793) and DELUA (M7521) Unibus ethernet cards for the SIMH emulator.
|
||||
The XU emulator is a host-independent software emulation of Digital's DEUNA
|
||||
(M7792/M7793) and DELUA (M7521) Unibus Ethernet cards for the SIMH emulator.
|
||||
|
||||
The XQ and XU simulators use the Sim_Ether module to execute host-specific
|
||||
packet reads and writes, since all operating systems talk to real ethernet
|
||||
packet reads and writes, since all operating systems talk to real Ethernet
|
||||
cards/controllers differently. See the comments at the top of sim_ether.c
|
||||
for the list of currently supported host platforms.
|
||||
|
||||
The Sim_Ether module sets the selected ethernet card into
|
||||
The Sim_Ether module sets the selected Ethernet card into
|
||||
promiscuous mode to gather all packets, then filters out the packets that it
|
||||
doesn't want. In Windows, packets having the same source MAC address as the
|
||||
controller are ignored for WinPCAP compatibility (see Windows notes below).
|
||||
|
||||
If your ethernet card is plugged into a switch, the promiscuous mode setting
|
||||
If your Ethernet card is plugged into a switch, the promiscuous mode setting
|
||||
should not cause much of a problem, since the switch will still filter out
|
||||
most of the undesirable traffic. You will only see "excessive" traffic if you
|
||||
are on a direct or hub(repeater) segment.
|
||||
|
||||
Using the libpcap/WinPcap interface, the simulated computer cannot "talk" to
|
||||
the host computer via the selected interface, since the packets are not
|
||||
reflected back to the host. The workaround for this is to use a second NIC in
|
||||
the host and connect them both into the same network; then the host and the
|
||||
simulator can communicate over the physical LAN.
|
||||
On Windows using the WinPcap interface, the simulated computer can "talk" to
|
||||
the host computer on the same interface. On other platforms with libpcap
|
||||
(*nix), the simulated computer can not "talk" to the host computer via the
|
||||
selected interface, since simulator transmitted packets are not received
|
||||
by the host's network stack. The workaround for this is to use a second NIC
|
||||
in the host and connect them both into the same network; then the host and
|
||||
the simulator can communicate over the physical LAN.
|
||||
|
||||
Universal TUN/TAP support provides another solution for the above dual-NIC
|
||||
problem for systems that support Universal TUN/TAP. Since the TUN/TAP interface
|
||||
is at a different network level, the host can create a TAP device for the
|
||||
simulator and then bridge or route packets between the TAP device and the real
|
||||
network interface. Note that the TAP device and any bridging or routing must be
|
||||
established before running the simulator; SIMH does not create, bridge, or
|
||||
route TAP devices for you.
|
||||
Integrated Universal TUN/TAP support provides another solution for the above
|
||||
dual-NIC problem for systems that support Universal TUN/TAP. Since the TUN/TAP
|
||||
interface is a pseudo network interface, the host can create a TAP device for
|
||||
the simulator and then bridge or route packets between the TAP device and the
|
||||
real network interface. Note that the TAP device and any bridging or routing
|
||||
must be established before running the simulator; SIMH does not create,
|
||||
bridge, or route TAP devices for you.
|
||||
|
||||
Integrated Universal TUN/TAP support can be used for host<->simulator network
|
||||
traffic (on the platforms where it is available) by using the SIMH command:
|
||||
"attach xq tap:tapN" (i.e. attach xq tap:tap0). Platforms that this has been
|
||||
tested on include: Linux, FreeBSD, OpenBSD, NetBSD. Each of these platforms
|
||||
has some way to create a tap pseudo device and then bridge it with a physical
|
||||
network interface.
|
||||
|
||||
The following steps were performed to get a working SIMH vax simulator
|
||||
sharing a physical NIC and allowing Host<->SIMH vax communications:
|
||||
|
||||
Linux (Ubuntu 10.04):
|
||||
apt-get install bridge-utils
|
||||
apt-get install uml-utilities
|
||||
|
||||
|
||||
#!/bin/sh
|
||||
HOSTIP=`/sbin/ifconfig eth0 | grep "inet addr" | gawk -- '{ print $2 }' | gawk -F : -- '{ print $2 }'`
|
||||
HOSTNETMASK=`/sbin/ifconfig eth0 | grep "inet addr" | gawk -- '{ print $4 }' | gawk -F : -- '{ print $2 }'`
|
||||
HOSTBCASTADDR=`/sbin/ifconfig eth0 | grep "inet addr" | gawk -- '{ print $3 }' | gawk -F : -- '{ print $2 }'`
|
||||
HOSTDEFAULTGATEWAY=`/sbin/route -n | grep ^0.0.0.0 | gawk -- '{ print $2 }'`
|
||||
#
|
||||
/usr/sbin/tunctl -t tap0 [-u someuser]
|
||||
/sbin/ifconfig tap0 up
|
||||
#
|
||||
# Now convert eth0 to a bridge and bridge it with the TAP interface
|
||||
/usr/sbin/brctl addbr br0
|
||||
/usr/sbin/brctl addif br0 eth0
|
||||
/usr/sbin/brctl setfd br0 0
|
||||
/sbin/ifconfig eth0 0.0.0.0
|
||||
/sbin/ifconfig br0 $HOSTIP netmask $HOSTNETMASK broadcast $HOSTBCASTADDR up
|
||||
# set the default route to the br0 interface
|
||||
/sbin/route add -net 0.0.0.0/0 gw $HOSTDEFAULTGATEWAY
|
||||
# bridge in the tap device
|
||||
/usr/sbin/brctl addif br0 tap0
|
||||
/sbin/ifconfig tap0 0.0.0.0
|
||||
|
||||
# Run simulator and "attach xq tap:tap0"
|
||||
|
||||
OpenBSD (OpenBSD 4.6)
|
||||
|
||||
/sbin/ifconfig tun0 create
|
||||
/sbin/ifconfig tun0 link0
|
||||
/sbin/ifconfig tun0 up
|
||||
|
||||
/sbin/ifconfig bridge0 create
|
||||
/sbin/brconfig bridge0 fwddelay 4
|
||||
/sbin/brconfig bridge0 add em0 add tun0 # Change em0 to reflect your physical NIC name
|
||||
/sbin/brconfig bridge0 up
|
||||
|
||||
# Run simulator and "attach xq tap:tun0"
|
||||
|
||||
FreeBSD (FreeBSD 8.0)
|
||||
|
||||
/sbin/ifconfig tap0 create
|
||||
/sbin/ifconfig tap0 up
|
||||
|
||||
/sbin/ifconfig bridge0 create
|
||||
/sbin/ifconfig bridge0 addm em0 addm tap0 # Change em0 to reflect your physical NIC name
|
||||
/sbin/ifconfig bridge0 up
|
||||
|
||||
# Run simulator and "attach xq tap:tap0"
|
||||
# Note: it seems that on FreeBSD you may have to
|
||||
# "/sbin/ifconfig tap0 up" and "/sbin/ifconfig bridge0 up" prior to each
|
||||
# time simh "attach"es the tap:tap0 device
|
||||
|
||||
NetBSD (NetBSD 5.0.2)
|
||||
|
||||
/sbin/ifconfig tap0 create
|
||||
/sbin/ifconfig tap0 up
|
||||
|
||||
/sbin/ifconfig bridge0 create
|
||||
/sbin/brconfig bridge0 fwddelay 1
|
||||
/sbin/brconfig bridge0 add wm0 add tap0 # Change wm0 to reflect your physical NIC name
|
||||
/sbin/brconfig bridge0 up
|
||||
|
||||
# Run simulator and "attach xq tap:tap0"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Windows notes:
|
||||
1. The Windows-specific code uses the WinPCAP 3.0 package from
|
||||
1. The Windows-specific code uses the WinPCAP 4.x package from
|
||||
http://www.winpcap.org. This package for windows simulates the libpcap
|
||||
package that is freely available for un*x systems.
|
||||
|
||||
|
@ -48,29 +128,27 @@ Windows notes:
|
|||
|
||||
3. The first time the WinPCAP driver is used, it will be dynamically loaded,
|
||||
and the user must be an Administrator on the machine to do so. If you need
|
||||
to run as an unprivileged user, you must set the service to autostart. See
|
||||
the WinPCAP documentation for details on the static loading workaround.
|
||||
|
||||
4. If you want to use TAP devices, they must be created before running SIMH.
|
||||
(TAP component from the OpenVPN project; http://openvpn.sourceforge.net)
|
||||
|
||||
5. Compaq PATHWORKS 32 v7.2 also enabled bridging for the ethernet adapters
|
||||
when the DECNET and LAT drivers were installed; TAP was not needed.
|
||||
to run as an unprivileged user, you must set the "npf" driver to autostart.
|
||||
Current WinPcap installers provide an option to configure this at
|
||||
installation time.
|
||||
|
||||
|
||||
Building on Windows:
|
||||
1. Install WinPCAP 3.0 runtime and the WinPCAP Developer's kit.
|
||||
1. Install WinPCAP 4.x runtime and the WinPCAP Developer's kit.
|
||||
|
||||
2. Put the required .h files (bittypes,devioctl,ip6_misc,packet32,pcap,
|
||||
pcap-stdinc).h from the WinPCAP 3.0 developer's kit in the compiler's path
|
||||
2. Put the required .h files (bittypes,devioctl,ip6_misc,pcap,pcap-stdinc
|
||||
packet32,ntddndis).h from the WinPCAP 4.x developer's kit in the
|
||||
compiler's include file path
|
||||
|
||||
3. Put the required .lib files (packet,wpcap).lib from the WinPCAP 3.0
|
||||
developer's kit in the linker's path
|
||||
3. Put the required .lib files (packet,wpcap).lib from the WinPCAP 4.x
|
||||
developer's kit in the linker's library path
|
||||
|
||||
4. If you're using Borland C++, use COFF2OMF to convert the .lib files into
|
||||
a format that can be used by the compiler.
|
||||
|
||||
5. Define USE_NETWORK.
|
||||
5. Define USE_NETWORK. The current windows network built binaries will
|
||||
run on any system. regardless of whether or not WinPcap is installed,
|
||||
and will provide Network functionality when WinPcap is available.
|
||||
|
||||
6. Build it!
|
||||
|
||||
|
@ -85,28 +163,31 @@ need to get a version of libpcap that is 0.9 or greater. This can be
|
|||
downloaded from www.tcpdump.org - see the comments at the top of Sim_ether.c
|
||||
for details.
|
||||
|
||||
At the time of this release, the "Current Version" available at:
|
||||
http://www.tcpdump.org/daily/libpcap-current.tar.gz is the
|
||||
latest checked-in source code that is actually higher than the released
|
||||
0.8.3 version number. Specifically, for all platforms, it contains code that
|
||||
opens the ethernet device in Read/Write mode instead of the Read-Only mode
|
||||
that previous libpcap versions for platforms which use one of pcap-bpf.c,
|
||||
pcap-pf.c, or pcap-snit.c. This capabiligy now exists to support a newly
|
||||
provided generic packet sending capability.
|
||||
|
||||
----- WARNING ----- WARNING ----- WARNING ----- WARNING ----- WARNING -----
|
||||
|
||||
1. For all platforms, you must run SIMH(scp) with sufficient privilege to
|
||||
allow the ethernet card can be set into promiscuous mode and to write
|
||||
packets through the driver. For most Unix/Unix-like platforms this will
|
||||
mean running as root. For systems which use bpf devices (NetBSD,
|
||||
OpenBSD, FreeBSD and OS/X) it is possible to set permissions on the bpf
|
||||
devices to allow read and write access to users other than root (For
|
||||
example: chmod 666 /dev/bpf*). Doing this, has its own security issues.
|
||||
allow the Ethernet card can be set into promiscuous mode and to write
|
||||
packets through the driver.
|
||||
a) For Windows systems this means having administrator privileges to
|
||||
start the "npf" driver. The current WinPcap installer offers an
|
||||
option to autostart the "npf" driver when the system boots.
|
||||
b) For more recent Linux systems, The concepts leveraging "Filesystem
|
||||
Capabilities" can be used to specifically grant the simh binary
|
||||
the needed privileges to access the network. The article at:
|
||||
http://packetlife.net/blog/2010/mar/19/sniffing-wireshark-non-root-user/
|
||||
describes how to do this for wireshark. The exact same capabilities
|
||||
are needed by SIMH for network support. Use that article as a guide.
|
||||
c) For Unix/Unix-like systems which use bpf devices (NetBSD,
|
||||
OpenBSD, FreeBSD and OS/X) it is possible to set permissions on
|
||||
the bpf devices to allow read and write access to users other
|
||||
than root (For example: chmod 666 /dev/bpf*). Doing this, has
|
||||
its own security issues.
|
||||
d) For other platforms this will likely mean running as root.
|
||||
Additional alternative methods for avoiding the 'run as root' requirement
|
||||
will be welcomed.
|
||||
|
||||
2. If you want to use TAP devices, they must be created before running SIMH.
|
||||
2. If you want to use TAP devices, and any surrounding system network/bridge
|
||||
setup must be done before running SIMH.
|
||||
|
||||
Building on Linux, {Free|Net|Open}BSD, OS/X, Un*x:
|
||||
|
||||
|
@ -116,12 +197,18 @@ Building on Linux, {Free|Net|Open}BSD, OS/X, Un*x:
|
|||
Linux : search for your variant on http://rpmfind.net
|
||||
OS/X : Apple Developer's site?
|
||||
|
||||
NOTE: These repositories will not likely contain a version
|
||||
of libpcap greater than 0.8.1 for several years since
|
||||
other packages in these repositories don't depend on a
|
||||
later version than they currently have.
|
||||
NOTE: These repositories for older versions of these platforms
|
||||
don't contain a version of libpcap greater than 0.8.1.
|
||||
However, most(all) recent releases of *nix environments ship
|
||||
with sufficiently recent versions of libpcap either automatically
|
||||
installed or available for installation as part of the
|
||||
distribution.
|
||||
|
||||
2. Use 'make USE_NETWORK=1'
|
||||
2. If you install the vendor supplied libpcap-dev package and it provides
|
||||
a /usr/lib/libpcap.a file, then the existing makefile will automatically
|
||||
use the vendor supplied library without any additional arguments.
|
||||
If you have downloaded and built the libpcap from tcpdump.org, then
|
||||
you can use it during a build by typing 'make USE_NETWORK=1'
|
||||
|
||||
3. Build it!
|
||||
|
||||
|
@ -132,27 +219,27 @@ OpenVMS Alpha notes:
|
|||
when required VCI promiscuous mode support was added. Hobbyists can
|
||||
get the required version of VMS from the OpenVMS Alpha Hobbyist Kit 3.0.
|
||||
|
||||
Running a simulator built with ethernet support on a version of VMS prior
|
||||
to 7.3-1 will behave as if there is no ethernet support built in due to
|
||||
Running a simulator built with Ethernet support on a version of VMS prior
|
||||
to 7.3-1 will behave as if there is no Ethernet support built in due to
|
||||
the inability of the software to set the PCAPVCM into promiscuous mode.
|
||||
|
||||
An example display of fully functional ethernet support:
|
||||
An example display of fully functional Ethernet support:
|
||||
sim> SHOW XQ ETH
|
||||
ETH devices:
|
||||
0 we0 (VMS Device: _EWA0:)
|
||||
1 we1 (VMS Device: _EWB0:)
|
||||
|
||||
An example display when the simulator was built without ethernet support
|
||||
An example display when the simulator was built without Ethernet support
|
||||
or is not running the required version of VMS:
|
||||
sim> SHOW XQ ETH
|
||||
ETH devices:
|
||||
no network devices are available
|
||||
|
||||
2. You must place the PCAPVCM.EXE execlet in SYS$LOADABLE_IMAGES before
|
||||
running a simulator with ethernet support. Note: This is done by the
|
||||
running a simulator with Ethernet support. Note: This is done by the
|
||||
build commands in descrip.mms.
|
||||
|
||||
3. You must have CMKRNL privilege to SHOW or ATTACH an ethernet device;
|
||||
3. You must have CMKRNL privilege to SHOW or ATTACH an Ethernet device;
|
||||
alternatively, you can INSTALL the simulator with CMKRNL privilege.
|
||||
|
||||
4. If you use a second adapter to communicate to the host, SOME protocol
|
||||
|
@ -162,13 +249,13 @@ OpenVMS Alpha notes:
|
|||
|
||||
Building on OpenVMS Alpha:
|
||||
The current descrip.mms file will build simulators capable of using
|
||||
ethernet support with them automatically. These currently are: VAX,
|
||||
Ethernet support with them automatically. These currently are: VAX,
|
||||
PDP11, and PDP10. The descrip.mms driven builds will also build the
|
||||
pcap library and build and install the VCI execlet.
|
||||
|
||||
1. Fetch the VMS-PCAP zip file from:
|
||||
http://simh.trailing-edge.com/sources/vms-pcap.zip
|
||||
2. Unzip it into the base of the simh distribution directory.
|
||||
2. Unzip it into the base of the SIMH distribution directory.
|
||||
3. Build the simulator(s) with MMS or MMK:
|
||||
$ MMx {VAX,PDP11,PDP10, etc...}
|
||||
|
||||
|
@ -195,15 +282,15 @@ RSX11M+ system image that also contains DECNET, LAT, and/or TCP/IP software.
|
|||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
How to debug problems with the ethernet subsystems:
|
||||
How to debug problems with the Ethernet subsystems:
|
||||
|
||||
PLEASE read the host-specific notes in sim_ether.c!
|
||||
|
||||
While running SCP, the following commands can be used to enable debug messages:
|
||||
|
||||
scp> SET DEBUG STDERR
|
||||
scp> SET XQ DEBUG={ETH|TRC|REG|WRN|CSR|VAR|SAN|SET|PCK}
|
||||
scp> SET XU DEBUG={ETH|TRC|REG|WRN}
|
||||
sim> SET DEBUG STDERR
|
||||
sim> SET XQ DEBUG=TRACE;CSR;VAR;WARN;SETUP;SANITY;REG;PACKET;DATA;ETH
|
||||
sim> SET XU DEBUG=ETH;TRACE;REG;WARN;PACKET;DATA
|
||||
|
||||
Documentation of the functionality of these debug modifiers can be found in
|
||||
pdp11_xq.h and pdp11_xu.h. Inline debugging has replaced the previous #ifdef
|
||||
|
@ -212,16 +299,13 @@ style of debugging, which required recompilation before debugging.
|
|||
-------------------------------------------------------------------------------
|
||||
|
||||
Things planned for future releases:
|
||||
1. PDP-11 bootstrap/bootrom
|
||||
2. Full MOP implementation
|
||||
3. DESQA support (if someone can get me the user manuals)
|
||||
4. DETQA support [DELQA-Turbo] (I have the manual)
|
||||
1. Full MOP implementation
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Things which I need help with:
|
||||
1. Information about Remote MOP processing
|
||||
2. VAX/PDP-11 hardware diagnotics image files and docs, to test XQ thoroughly.
|
||||
2. VAX/PDP-11 hardware diagnostics image files and docs, to test XQ thoroughly.
|
||||
3. Feedback on operation with other VAX/PDP-11 OS's.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
@ -237,11 +321,160 @@ Dave
|
|||
Change Log
|
||||
===============================================================================
|
||||
|
||||
12-Jan-11 DTH Added SHOW XU FILTERS modifier
|
||||
11-Jan-11 DTH Corrected DEUNA/DELUA SELFTEST command, enabling use by
|
||||
VMS 3.7, VMS 4.7, and Ultrix 1.1
|
||||
09-Jan-11 MP Fixed missing crc data when USE_READER_THREAD is defined and
|
||||
crc's are needed (only the pdp11_xu)
|
||||
16-Dec-10 MP added priority boost for read and write threads when
|
||||
USE_READER_THREAD does I/O in separate threads. This helps
|
||||
throughput since it allows these I/O bound threads to preempt
|
||||
the main thread (which is executing simulated instructions).
|
||||
09-Dec-10 MP allowed more flexible parsing of MAC address strings
|
||||
09-Dec-10 MP Added support to determine if network address conflicts exist
|
||||
07-Dec-10 MP Reworked DECnet self detection to the more general approach
|
||||
of loopback self when any Physical Address is being set.
|
||||
06-Dec-10 MP Added loopback processing support to pdp11_xu.c
|
||||
06-Dec-10 MP Fixed loopback processing to correctly handle forward packets.
|
||||
04-Dec-10 MP Changed eth_write to do nonblocking writes when
|
||||
USE_READER_THREAD is defined.
|
||||
30-Nov-10 MP Fixed the fact that no broadcast packets were received by the DEUNA
|
||||
29-Nov-10 MP Fixed interrupt dispatch issue which caused delivered packets
|
||||
(in and out) to sometimes not interrupt the CPU after processing.
|
||||
17-Jun-10 MP Fixed bug in the AUTODIN II hash filtering.
|
||||
14-Jun-10 MP Added support for integrated Tap networking interfaces on BSD
|
||||
platforms.
|
||||
13-Jun-10 MP Added support for integrated Tap networking interfaces on Linux
|
||||
platforms.
|
||||
31-May-10 MP Added support for more TOE (TCP Offload Engine) features for IPv4
|
||||
network traffic from the host and/or from hosts on the LAN. These
|
||||
new TOE features are: LSO (Large Send Offload) and Jumbo packet
|
||||
fragmentation support. These features allow a simulated network
|
||||
device to support traffic when a host leverages a NIC's Large
|
||||
Send Offload capabilities to fragment and/or segment outgoing
|
||||
network traffic. Additionally a simulated network device can
|
||||
reasonably exist on a LAN which is configured to use Jumbo frames.
|
||||
21-May-10 MP Added functionality to fix up IP header checksums to accommodate
|
||||
packets from a host with a NIC which has TOE (TCP Offload Engine)
|
||||
enabled which is expected to implement the checksum computations
|
||||
in hardware. Since we catch packets before they arrive at the
|
||||
NIC the expected checksum insertions haven't been performed yet.
|
||||
This processing is only done for packets sent from the host to
|
||||
the guest we're supporting. In general this will be a relatively
|
||||
small number of packets so it is done for all IP frame packets
|
||||
coming from the host to the guest. In order to make the
|
||||
determination of packets specifically arriving from the host we
|
||||
need to know the hardware MAC address of the host NIC. Currently
|
||||
determining a NIC's MAC address is relatively easy on Windows.
|
||||
The non-windows code works on linux and may work on other *nix
|
||||
platforms either as is or with slight modifications. The code,
|
||||
as implemented, only messes with this activity if the host
|
||||
interface MAC address can be determined.
|
||||
20-May-10 MP Added general support to deal with receiving packets smaller
|
||||
than ETH_MIN_PACKET in length. These come from packets
|
||||
looped back by some bridging mechanism and need to be padded
|
||||
to the minimum frame size. A real NIC won't pass us any
|
||||
packets like that. This fix belongs here since this layer
|
||||
is responsible for interfacing to the physical layer
|
||||
devices, AND it belongs here to get CRC processing right.
|
||||
15-Aug-08 MP Fixed transmitted packets to have the correct source MAC address.
|
||||
Fixed incorrect address filter setting calling eth_filter().
|
||||
07-Mar-08 MP Fixed the SCP visible SA registers to always display the
|
||||
ROM MAC address, even after it is changed by SET XQ MAC=.
|
||||
07-Mar-08 MP Added changes so that the Console DELQA diagnostic (>>>TEST 82)
|
||||
will succeed.
|
||||
03-Mar-08 MP Added DELQA-T (aka DELQA Plus) device emulation support.
|
||||
06-Feb-08 MP Added dropped frame statistics to record when the receiver discards
|
||||
received packets due to the receiver being disabled, or due to the
|
||||
XQ device's packet receive queue being full.
|
||||
Fixed bug in receive processing when we're not polling. This could
|
||||
cause receive processing to never be activated again if we don't
|
||||
read all available packets via eth_read each time we get the
|
||||
opportunity.
|
||||
31-Jan-08 MP Added the ability to Coalesce received packet interrupts. This
|
||||
is enabled by SET XQ POLL=DELAY=nnn where nnn is a number of
|
||||
microseconds to delay the triggering of an interrupt when a packet
|
||||
is received.
|
||||
29-Jan-08 MP Added SET XQ POLL=DISABLE (aka SET XQ POLL=0) to operate without
|
||||
polling for packet read completion.
|
||||
29-Jan-08 MP Changed the sanity and id timer mechanisms to use a separate timer
|
||||
unit so that transmit and receive activities can be dealt with
|
||||
by the normal xq_svc routine.
|
||||
Dynamically determine the timer polling rate based on the
|
||||
calibrated tmr_poll and clk_tps values of the simulator.
|
||||
25-Jan-08 MP Enabled the SET XQ POLL to be meaningful if the simulator currently
|
||||
doesn't support idling.
|
||||
25-Jan-08 MP Changed xq_debug_setup to use sim_debug instead of printf so that
|
||||
all debug output goes to the same place.
|
||||
25-Jan-08 MP Restored the call to xq_svc after all successful calls to eth_write
|
||||
to allow receive processing to happen before the next event
|
||||
service time. This must have been inadvertently commented out
|
||||
while other things were being tested.
|
||||
23-Jan-08 MP Added debugging support to display packet headers and packet data
|
||||
18-Jun-07 RMS Added UNIT_IDLE flag
|
||||
29-Oct-06 RMS Synced poll and clock
|
||||
27-Jan-06 RMS Fixed unaligned accesses in XQB (found by Doug Carman)
|
||||
07-Jan-06 RMS Fixed unaligned access bugs (found by Doug Carman)
|
||||
07-Sep-05 DTH Removed unused variable
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
|
||||
05-Mar-08 MP Added optional multicast filtering support for doing
|
||||
LANCE style AUTODIN II based hashed filtering.
|
||||
07-Feb-08 MP Added eth_show_dev to display Ethernet state
|
||||
Changed the return value from eth_read to return whether
|
||||
or not a packet was read. No existing callers used or
|
||||
checked constant return value that previously was being
|
||||
supplied.
|
||||
29-Jan-08 MP Added eth_set_async to provide a mechanism (when
|
||||
USE_READER_THREAD is enabled) to allow packet reception
|
||||
to dynamically update the simulator event queue and
|
||||
potentially avoid polling for I/O. This provides a minimal
|
||||
overhead (no polling) maximal responsiveness for network
|
||||
activities.
|
||||
29-Jan-08 MP Properly sequenced activities in eth_close to avoid a race
|
||||
condition when USE_READER_THREAD is enabled.
|
||||
25-Jan-08 MP Changed the following when USE_READER_THREAD is enabled:
|
||||
- Fixed bug when the simulated device doesn't need crc
|
||||
in packet data which is read.
|
||||
- Added call to pcap_setmintocopy to minimize packet
|
||||
delivery latencies.
|
||||
- Added ethq_destroy and used it to avoid a memory leak in
|
||||
eth_close.
|
||||
- Properly cleaned up pthread mutexes in eth_close.
|
||||
Migrated to using sim_os_ms_sleep for a delay instead of
|
||||
a call to select().
|
||||
Fixed the bpf filter used when no traffic is to be matched.
|
||||
Reworked eth_add_packet_crc32 implementation to avoid an
|
||||
extra buffer copy while reading packets.
|
||||
Fixed up #ifdef's relating to USE_SHARED so that setting
|
||||
USE_SHARED or USE_NETWORK will build a working network
|
||||
environment.
|
||||
23-Jan-08 MP Reworked eth_packet_trace and eth_packet_trace_ex to allow
|
||||
only output Ethernet header+crc and provide a mechanism for
|
||||
the simulated device to display full packet data debugging.
|
||||
17-May-07 DTH Fixed non-Ethernet device removal loop (from Naoki Hamada)
|
||||
15-May-07 DTH Added dynamic loading of wpcap.dll;
|
||||
Corrected exceed max index bug in ethX lookup
|
||||
04-May-07 DTH Corrected failure to look up Ethernet device names in
|
||||
the registry on Windows XP x64
|
||||
10-Jul-06 RMS Fixed linux conditionalization (from Chaskiel Grundman)
|
||||
02-Jun-06 JDB Fixed compiler warning for incompatible sscanf parameter
|
||||
15-Dec-05 DTH Patched eth_host_devices [remove non-Ethernet devices]
|
||||
(from Mark Pizzolato and Galen Tackett, 08-Jun-05)
|
||||
Patched eth_open [tun fix](from Antal Ritter, 06-Oct-05)
|
||||
30-Nov-05 DTH Added option to regenerate CRC on received packets; some
|
||||
Ethernet devices need to pass it on to the simulation, and by
|
||||
the time libpcap/winpcap gets the packet, the host OS network
|
||||
layer has already stripped CRC out of the packet
|
||||
01-Dec-04 DTH Added Windows user-defined adapter names (from Timothe Litt)
|
||||
|
||||
|
||||
|
||||
19-Mar-04 Release:
|
||||
1. Genericized Sim_Ether code, reduced #ifdefs (David Hittner)
|
||||
2. Further refinement of sim_ether, qualified more platforms (Mark Pizzolato)
|
||||
3. Added XU module (David Hittner)
|
||||
4. Corrected XQ interrupt signalling for PDP11s (David Hittner)
|
||||
4. Corrected XQ interrupt signaling for PDP11s (David Hittner)
|
||||
5. Added inline debugging support (David Hittner)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
@ -251,7 +484,7 @@ Dave
|
|||
2. Added DECNET duplicate detection for Windows (Mark Pizzolato)
|
||||
3. Added BPF filtering to increase efficiency (Mark Pizzolato)
|
||||
4. Corrected XQ Runt processing (Mark Pizzolato)
|
||||
5. Corrected XQ Sofware Reset (Mark Pizzolato)
|
||||
5. Corrected XQ Software Reset (Mark Pizzolato)
|
||||
6. Corrected XQ Multicast/Promiscuous mode setting/resetting (Mark Pizzolato)
|
||||
7. Added Universal TUN/TAP support (Mark Pizzolato)
|
||||
8. Added FreeBSD support (Edward Brocklesby)
|
||||
|
@ -271,7 +504,7 @@ Dave
|
|||
1. Corrected bug in xq_setmac introduced in v3.0 (multiple people)
|
||||
2. Made XQ rcv buffer allocation dynamic to reduce scp size (David Hittner)
|
||||
3. Optimized some structs, removed legacy variables (Mark Pizzolato)
|
||||
4. Changed #ifdef WIN32 to _WIN32 for consistancy (Mark Pizzolato)
|
||||
4. Changed #ifdef WIN32 to _WIN32 for consistency (Mark Pizzolato)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
@ -308,7 +541,7 @@ Dave
|
|||
|
||||
08-Nov-02 Release:
|
||||
1. Added USE_NETWORK conditional to Sim_Ether
|
||||
2. Fixed behaviour of SHOW XQ ETH if no devices exist
|
||||
2. Fixed behavior of SHOW XQ ETH if no devices exist
|
||||
3. Added OpenBSD support to Sim_Ether (courtesy of Federico Schwindt)
|
||||
4. Added ethX detection simplification (from Megan Gentry)
|
||||
|
||||
|
|
1032
PDP11/pdp11_xq.c
1032
PDP11/pdp11_xq.c
File diff suppressed because it is too large
Load diff
187
PDP11/pdp11_xq.h
187
PDP11/pdp11_xq.h
|
@ -28,6 +28,14 @@
|
|||
|
||||
Modification history:
|
||||
|
||||
03-Mar-08 MP Added DELQA-T (aka DELQA Plus) device emulation support.
|
||||
06-Feb-08 MP Added dropped frame statistics to record when the receiver discards
|
||||
received packets due to the receiver being disabled, or due to the
|
||||
XQ device's packet receive queue being full. Also removed the
|
||||
filter statistic counter since there was no code which ever set it.
|
||||
29-Jan-08 MP Dynamically determine the timer polling rate based on the
|
||||
calibrated tmr_poll and clk_tps values of the simulator.
|
||||
23-Jan-08 MP Added debugging support to display packet headers and packet data
|
||||
07-Jul-05 RMS Removed extraneous externs
|
||||
20-Jan-04 DTH Added new sanity timer and system id timer
|
||||
19-Jan-04 DTH Added XQ_SERVICE_INTERVAL, poll
|
||||
|
@ -84,12 +92,11 @@ extern int32 int_req[IPL_HLVL];
|
|||
#define XQ_HW_SANITY_SECS 240 /* seconds before HW sanity timer expires */
|
||||
#define XQ_MAX_CONTROLLERS 2 /* maximum controllers allowed */
|
||||
|
||||
enum xq_type {XQ_T_DEQNA, XQ_T_DELQA};
|
||||
enum xq_type {XQ_T_DEQNA, XQ_T_DELQA, XQ_T_DELQA_PLUS};
|
||||
|
||||
struct xq_sanity {
|
||||
int enabled; /* sanity timer enabled? 2=HW, 1=SW, 0=off */
|
||||
int quarter_secs; /* sanity timer value in 1/4 seconds */
|
||||
int max; /* maximum timeout (based on poll) */
|
||||
int timer; /* countdown timer */
|
||||
};
|
||||
|
||||
|
@ -104,17 +111,132 @@ struct xq_setup {
|
|||
ETH_MAC macs[XQ_FILTER_MAX]; /* MAC addresses to respond to */
|
||||
};
|
||||
|
||||
struct xq_turbo_init_block { /* DELQA-T Initialization Block */
|
||||
uint16 mode;
|
||||
#define XQ_IN_MO_PRO 0x8000 /* Promiscuous Mode */
|
||||
#define XQ_IN_MO_INT 0x0040 /* Internal Loopback Mode */
|
||||
#define XQ_IN_MO_DRT 0x0020 /* Disable Retry */
|
||||
#define XQ_IN_MO_DTC 0x0008 /* Disable Transmit CRC */
|
||||
#define XQ_IN_MO_LOP 0x0004 /* Loopback */
|
||||
ETH_MAC phys; /* Physical MAC Address */
|
||||
ETH_MULTIHASH hash_filter; /* 64bit LANCE Hash Filter for Multicast Address selection */
|
||||
uint16 rdra_l;
|
||||
uint16 rdra_h;
|
||||
uint16 tdra_l;
|
||||
uint16 tdra_h;
|
||||
uint16 options;
|
||||
#define XQ_IN_OP_HIT 0x0002 /* Host Inactivity Timer Enable Flag */
|
||||
#define XQ_IN_OP_INT 0x0001 /* Interrupt Enable Flag*/
|
||||
uint16 vector; /* Interrupt Vector */
|
||||
uint16 hit_timeout; /* Host Inactivity Timer Timeout Value */
|
||||
uint8 bootpassword[6]; /* MOP Console Boot Password */
|
||||
};
|
||||
|
||||
/* DELQA-T Mode - Transmit Buffer Descriptor */
|
||||
struct transmit_buffer_descriptor {
|
||||
uint16 tmd0;
|
||||
#define XQ_TMD0_ERR1 0x4000 /* Error Summary. The OR of TMD1 (LC0, LCA, and RTR) */
|
||||
#define XQ_TMD0_MOR 0x1000 /* More than one retry on transmit */
|
||||
#define XQ_TMD0_ONE 0x0800 /* One retry on transmit */
|
||||
#define XQ_TMD0_DEF 0x0400 /* Deferral during transmit */
|
||||
uint16 tmd1;
|
||||
#define XQ_TMD1_LCO 0x1000 /* Late collision on transmit - packet not transmitted */
|
||||
#define XQ_TMD1_LCA 0x0800 /* Loss of carrier on transmit - packet not transmitted */
|
||||
#define XQ_TMD1_RTR 0x0400 /* Retry error on transmit - packet not transmitted */
|
||||
#define XQ_TMD1_TDR 0x03FF /* Time Domain Reflectometry value */
|
||||
uint16 tmd2;
|
||||
#define XQ_TMD2_ERR2 0x8000 /* Error Summary. The OR of TMD2 (BBL, CER, and MIS) */
|
||||
#define XQ_TMD2_BBL 0x4000 /* Babble error on transmit */
|
||||
#define XQ_TMD2_CER 0x2000 /* Collision error on transmit */
|
||||
#define XQ_TMD2_MIS 0x1000 /* Packet lost on receive */
|
||||
#define XQ_TMD2_EOR 0x0800 /* End Of Receive Ring Reached */
|
||||
#define XQ_TMD2_RON 0x0020 /* Receiver On */
|
||||
#define XQ_TMD2_TON 0x0010 /* Transmitter On */
|
||||
uint16 tmd3;
|
||||
#define XQ_TMD3_OWN 0x8000 /* Ownership field. 0 = DELQA-T, 1 = Host Driver */
|
||||
#define XQ_TMD3_FOT 0x4000 /* First Of Two flag. 1 = first in chained, 0 = no chain or last in chain */
|
||||
#define XQ_TMD3_BCT 0x0FFF /* Byte Count */
|
||||
uint16 ladr; /* Low 16bits of Buffer Address */
|
||||
uint16 hadr; /* Most significant bits of the Buffer Address */
|
||||
uint16 hostuse1;
|
||||
uint16 hostuse2;
|
||||
};
|
||||
#define XQ_TURBO_XM_BCNT 12 /* Transmit Buffer Descriptor Count */
|
||||
|
||||
struct receive_buffer_descriptor {
|
||||
uint16 rmd0;
|
||||
#define XQ_RMD0_ERR3 0x4000 /* Error Summary. The OR of FRA, CRC, OFL and BUF */
|
||||
#define XQ_RMD0_FRA 0x2000 /* Framing error on receive */
|
||||
#define XQ_RMD0_OFL 0x1000 /* Overflow error on receive (Giant packet) */
|
||||
#define XQ_RMD0_CRC 0x0800 /* CRC error on receive */
|
||||
#define XQ_RMD0_BUF 0x0400 /* Internal device buffer error. Part of Giant packet lost */
|
||||
#define XQ_RMD0_STP 0x0200 /* Start of Packet Flag */
|
||||
#define XQ_RMD0_ENP 0x0100 /* End of Packet Flag */
|
||||
uint16 rmd1;
|
||||
#define XQ_RMD1_MCNT 0x0FFF /* Message byte count (including CRC) */
|
||||
uint16 rmd2;
|
||||
#define XQ_RMD2_ERR4 0x8000 /* Error Summary. The OR of RMD2 (RBL, CER, and MIS) */
|
||||
#define XQ_RMD2_BBL 0x4000 /* Babble error on transmit */
|
||||
#define XQ_RMD2_CER 0x2000 /* Collision error on transmit */
|
||||
#define XQ_RMD2_MIS 0x1000 /* Packet lost on receive */
|
||||
#define XQ_RMD2_EOR 0x0800 /* End Of Receive Ring Reached */
|
||||
#define XQ_RMD2_RON 0x0020 /* Receiver On */
|
||||
#define XQ_RMD2_TON 0x0010 /* Transmitter On */
|
||||
uint16 rmd3;
|
||||
#define XQ_RMD3_OWN 0x8000 /* Ownership field. 0 = DELQA-T, 1 = Host Driver */
|
||||
uint16 ladr; /* Low 16bits of Buffer Address */
|
||||
uint16 hadr; /* Most significant bits of the Buffer Address */
|
||||
uint16 hostuse1;
|
||||
uint16 hostuse2;
|
||||
};
|
||||
#define XQ_TURBO_RC_BCNT 32 /* Receive Buffer Descriptor Count */
|
||||
|
||||
struct xq_stats {
|
||||
int recv; /* received packets */
|
||||
int filter; /* filtered packets */
|
||||
int dropped; /* received packets dropped */
|
||||
int xmit; /* transmitted packets */
|
||||
int fail; /* transmit failed */
|
||||
int runt; /* runts */
|
||||
int reset; /* reset count */
|
||||
int giant; /* oversize packets */
|
||||
int setup; /* setup packets */
|
||||
int loop; /* loopback packets */
|
||||
};
|
||||
|
||||
#pragma pack(2)
|
||||
struct xq_mop_counters {
|
||||
uint16 seconds; /* Seconds since last zeroed */
|
||||
uint32 b_rcvd; /* Bytes Received */
|
||||
uint32 b_xmit; /* Bytes Transmitted */
|
||||
uint32 p_rcvd; /* Packets Received */
|
||||
uint32 p_xmit; /* Packets Transmitted */
|
||||
uint32 mb_rcvd; /* Multicast Bytes Received */
|
||||
uint32 mp_rcvd; /* Multicast Packets Received */
|
||||
uint32 p_x_col1; /* Packets Transmitted Initially Deferred */
|
||||
uint32 p_x_col2; /* Packets Transmitted after 2 attempts */
|
||||
uint32 p_x_col3; /* Packets Transmitted after 3+ attempts */
|
||||
uint16 p_x_fail; /* Transmit Packets Aborted (Send Failure) */
|
||||
uint16 p_x_f_bitmap; /* Transmit Packets Aborted (Send Failure) Bitmap */
|
||||
#define XQ_XF_RTRY 0x0001 /* Excessive Collisions */
|
||||
#define XQ_XF_LCAR 0x0002 /* Loss of Carrier */
|
||||
#define XQ_XF_MLEN 0x0010 /* Data Block Too Long */
|
||||
#define XQ_XF_LCOL 0x0020 /* Late Collision */
|
||||
uint16 p_r_fail; /* Packets received with Error (Receive Failure) */
|
||||
uint16 p_r_f_bitmap; /* Packets received with Error (Receive Failure) Bitmap */
|
||||
#define XQ_RF_CRC 0x0001 /* Block Check Error */
|
||||
#define XQ_RF_FRAM 0x0002 /* Framing Error */
|
||||
#define XQ_RF_MLEN 0x0004 /* Message Length Error */
|
||||
uint16 h_dest_err; /* Host Counter - Unrecognized Frame Destination Error */
|
||||
uint16 r_p_lost_i; /* Receive Packet Lost: Internal Buffer Error */
|
||||
uint16 r_p_lost_s; /* Receive Packet Lost: System Buffer Error (Unavailable or Truncated) */
|
||||
uint16 h_no_buf; /* Host Counter - User Buffer Unavailable */
|
||||
uint32 mb_xmit; /* Multicast Bytes Tramsmitted */
|
||||
uint16 reserved1; /* */
|
||||
uint16 reserved2; /* */
|
||||
uint16 babble; /* Babble Counter */
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
struct xq_meb { /* MEB block */
|
||||
uint8 type;
|
||||
uint8 add_lo;
|
||||
|
@ -128,18 +250,36 @@ struct xq_device {
|
|||
/*+ initialized values - DO NOT MOVE */
|
||||
ETH_PCALLBACK rcallback; /* read callback routine */
|
||||
ETH_PCALLBACK wcallback; /* write callback routine */
|
||||
ETH_MAC mac; /* MAC address */
|
||||
ETH_MAC mac; /* Hardware MAC address */
|
||||
enum xq_type type; /* controller type */
|
||||
int poll; /* poll ethernet times/sec */
|
||||
enum xq_type mode; /* controller operating mode */
|
||||
uint16 poll; /* configured poll ethernet times/sec for receive */
|
||||
uint16 coalesce_latency; /* microseconds to hold-off interrupts when not polling */
|
||||
uint16 coalesce_latency_ticks; /* instructions in coalesce_latency microseconds */
|
||||
struct xq_sanity sanity; /* sanity timer information */
|
||||
/*- initialized values - DO NOT MOVE */
|
||||
|
||||
/* I/O register storage */
|
||||
uint16 addr[6];
|
||||
|
||||
uint16 rbdl[2];
|
||||
uint16 xbdl[2];
|
||||
uint16 var;
|
||||
uint16 csr;
|
||||
|
||||
uint16 srr; /* Status and Response Register - DELQA-T only */
|
||||
uint16 srqr; /* Synchronous Request Register - DELQA-T only */
|
||||
uint32 iba; /* Init Block Address Register - DELQA-T only */
|
||||
uint16 icr; /* Interrupt Request Register - DELQA-T only */
|
||||
uint16 pending_interrupt; /* Pending Interrupt - DELQA-T only */
|
||||
struct xq_turbo_init_block
|
||||
init;
|
||||
struct transmit_buffer_descriptor
|
||||
xring[XQ_TURBO_XM_BCNT]; /* Transmit Buffer Ring */
|
||||
uint32 tbindx; /* Transmit Buffer Ring Index */
|
||||
struct receive_buffer_descriptor
|
||||
rring[XQ_TURBO_RC_BCNT]; /* Receive Buffer Ring */
|
||||
uint32 rbindx; /* Receive Buffer Ring Index */
|
||||
|
||||
uint32 irq; /* interrupt request flag */
|
||||
|
||||
/* buffers, etc. */
|
||||
|
@ -151,11 +291,11 @@ struct xq_device {
|
|||
uint32 rbdl_ba;
|
||||
uint32 xbdl_ba;
|
||||
ETH_DEV* etherface;
|
||||
int receiving;
|
||||
ETH_PACK read_buffer;
|
||||
ETH_PACK write_buffer;
|
||||
ETH_QUE ReadQ;
|
||||
int idtmr; /* countdown for ID Timer */
|
||||
int32 idtmr; /* countdown for ID Timer */
|
||||
uint32 must_poll; /* receiver must poll instead of counting on asynch polls */
|
||||
};
|
||||
|
||||
struct xq_controller {
|
||||
|
@ -207,6 +347,7 @@ typedef struct xq_controller CTLR;
|
|||
#define XQ_VEC_RO 0x5C02 /* Read-Only bits */
|
||||
#define XQ_VEC_RW 0xA3FD /* Read/Write bits */
|
||||
|
||||
/* DEQNA - DELQA Normal Mode Buffer Descriptors */
|
||||
#define XQ_DSC_V 0x8000 /* Valid bit */
|
||||
#define XQ_DSC_C 0x4000 /* Chain bit */
|
||||
#define XQ_DSC_E 0x2000 /* End of Message bit [Transmit only] */
|
||||
|
@ -214,11 +355,38 @@ typedef struct xq_controller CTLR;
|
|||
#define XQ_DSC_L 0x0080 /* Low Byte Termination bit [Transmit only] */
|
||||
#define XQ_DSC_H 0x0040 /* High Byte Start bit [Transmit only] */
|
||||
|
||||
/* DEQNA - DELQA Normal Mode Setup Packet Flags */
|
||||
#define XQ_SETUP_MC 0x0001 /* multicast bit */
|
||||
#define XQ_SETUP_PM 0x0002 /* promiscuous bit */
|
||||
#define XQ_SETUP_LD 0x000C /* led bits */
|
||||
#define XQ_SETUP_ST 0x0070 /* sanity timer bits */
|
||||
|
||||
/* DELQA-T Mode - Status and Response Register (SRR) */
|
||||
#define XQ_SRR_FES 0x8000 /* Fatal Error Summary [RO] */
|
||||
#define XQ_SRR_CHN 0x4000 /* Chaining Error [RO] */
|
||||
#define XQ_SRR_NXM 0x1000 /* Non-Existant Memory Error [RO] */
|
||||
#define XQ_SRR_PAR 0x0800 /* Parity Error (Qbus) [RO] */
|
||||
#define XQ_SRR_IME 0x0400 /* Internal Memory Error [RO] */
|
||||
#define XQ_SRR_TBL 0x0200 /* Transmit Buffer Too Long Error [RO] */
|
||||
#define XQ_SRR_RESP 0x0003 /* Synchronous Response Field [RO] */
|
||||
#define XQ_SRR_TRBO 0x0001 /* Select Turbo Response [RO] */
|
||||
#define XQ_SRR_STRT 0x0002 /* Start Device Response [RO] */
|
||||
#define XQ_SRR_STOP 0x0003 /* Stop Device Response [RO] */
|
||||
|
||||
/* DELQA-T Mode - Synchronous Request Register (SRQR) */
|
||||
#define XQ_SRQR_STRT 0x0002 /* Start Device Request [WO] */
|
||||
#define XQ_SRQR_STOP 0x0003 /* Stop Device Request [WO] */
|
||||
#define XQ_SRQR_RW 0x0003 /* Writable Bits in SRQR [WO] */
|
||||
|
||||
/* DELQA-T Mode - Asynchronous Request Register (ARQR) */
|
||||
#define XQ_ARQR_TRQ 0x8000 /* Transmit Request [WO] */
|
||||
#define XQ_ARQR_RRQ 0x0080 /* Receieve Request [WO] */
|
||||
#define XQ_ARQR_SR 0x0002 /* Software Reset Request [WO] */
|
||||
|
||||
/* DELQA-T Mode - Interrupt Control Register (ICR) */
|
||||
#define XQ_ICR_ENA 0x0001 /* Interrupt Enabled [WO] */
|
||||
|
||||
|
||||
/* debugging bitmaps */
|
||||
#define DBG_TRC 0x0001 /* trace routine calls */
|
||||
#define DBG_REG 0x0002 /* trace read/write registers */
|
||||
|
@ -227,7 +395,8 @@ typedef struct xq_controller CTLR;
|
|||
#define DBG_WRN 0x0010 /* display warnings */
|
||||
#define DBG_SAN 0x0020 /* display sanity timer info */
|
||||
#define DBG_SET 0x0040 /* display setup info */
|
||||
#define DBG_PCK 0x0080 /* display packets */
|
||||
#define DBG_PCK 0x0080 /* display packet headers */
|
||||
#define DBG_DAT 0x0100 /* display packet data */
|
||||
#define DBG_ETH 0x8000 /* debug ethernet device */
|
||||
|
||||
#endif /* _PDP11_XQ_H */
|
||||
|
|
180
PDP11/pdp11_xu.c
180
PDP11/pdp11_xu.c
|
@ -1,7 +1,7 @@
|
|||
/* pdp11_xu.c: DEUNA/DELUA ethernet controller simulator
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2003-2007, David T. Hittner
|
||||
Copyright (c) 2003-2011, David T. Hittner
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -30,7 +30,7 @@
|
|||
Digital DELUA Users Guide, Part# EK-DELUA-UG-002
|
||||
Digital DEUNA Users Guide, Part# EK-DEUNA-UG-001
|
||||
These manuals can be found online at:
|
||||
http://www.spies.com/~aek/pdf/dec/unibus
|
||||
http://www.bitsavers.org/pdf/dec/unibus
|
||||
|
||||
Testing performed:
|
||||
1) Receives/Transmits single packet under custom RSX driver
|
||||
|
@ -41,7 +41,13 @@
|
|||
DECNET - SET HOST in/out, COPY in/out
|
||||
TCP/IP - PING in/out; SET HOST/TELNET in/out, COPY/FTP in/out
|
||||
Clustering - Successfully clustered with AlphaVMS 8.2
|
||||
4) Runs VAX EVDWA diagnostic tests 1-10; tests 11-19 (M68000/ROM/RAM) fail
|
||||
4) VMS 4.7 on VAX780 summary:
|
||||
(Jan/2011: Win7 x64 host; MS VC++ 2008; SIMH v3.8-2 rc1 base; WinPcap 4.1)
|
||||
LAT - SET HOST/LAT in (no outbound exists)
|
||||
DECNET - SET HOST in/out, DIR in/out, COPY in/out
|
||||
TCP/IP - no kit available to test
|
||||
Clustering - not tested
|
||||
5) Runs VAX EVDWA diagnostic tests 1-10; tests 11-19 (M68000/ROM/RAM) fail
|
||||
|
||||
Known issues:
|
||||
1) Most auxiliary commands are not implemented yet.
|
||||
|
@ -56,6 +62,14 @@
|
|||
|
||||
Modification history:
|
||||
|
||||
12-Jan-11 DTH Added SHOW XU FILTERS modifier
|
||||
11-Jan-11 DTH Corrected SELFTEST command, enabling use by VMS 3.7, VMS 4.7, and Ultrix 1.1
|
||||
09-Dec-10 MP Added address conflict check during attach.
|
||||
06-Dec-10 MP Added loopback processing support
|
||||
30-Nov-10 MP Fixed the fact that no broadcast packets were received by the DEUNA
|
||||
15-Aug-08 MP Fixed transmitted packets to have the correct source MAC address.
|
||||
Fixed incorrect address filter setting calling eth_filter().
|
||||
23-Jan-08 MP Added debugging support to display packet headers and packet data
|
||||
18-Jun-07 RMS Added UNIT_IDLE flag
|
||||
03-May-07 DTH Added missing FC_RMAL command; cleared multicast on write
|
||||
29-Oct-06 RMS Synced poll and clock
|
||||
|
@ -112,6 +126,7 @@ void xu_clrint (CTLR* xu);
|
|||
void xu_process_receive(CTLR* xu);
|
||||
void xu_dump_rxring(CTLR* xu);
|
||||
void xu_dump_txring(CTLR* xu);
|
||||
t_stat xu_show_filters (FILE* st, UNIT* uptr, int32 val, void* desc);
|
||||
|
||||
DIB xua_dib = { IOBA_XU, IOLN_XU, &xu_rd, &xu_wr,
|
||||
1, IVCL (XU), VEC_XU, {&xu_int} };
|
||||
|
@ -143,6 +158,8 @@ MTAB xu_mod[] = {
|
|||
NULL, ð_show, NULL },
|
||||
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATS", "STATS",
|
||||
&xu_set_stats, &xu_show_stats, NULL },
|
||||
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "FILTERS", "FILTERS",
|
||||
NULL, &xu_show_filters, NULL },
|
||||
{ MTAB_XTD | MTAB_VDV, 0, "TYPE", "TYPE={DEUNA|DELUA}",
|
||||
&xu_set_type, &xu_show_type, NULL },
|
||||
{ 0 },
|
||||
|
@ -156,6 +173,7 @@ DEBTAB xu_debug[] = {
|
|||
{"WARN", DBG_WRN},
|
||||
{"REG", DBG_REG},
|
||||
{"PACKET", DBG_PCK},
|
||||
{"DATA", DBG_DAT},
|
||||
{"ETH", DBG_ETH},
|
||||
{0}
|
||||
};
|
||||
|
@ -294,20 +312,39 @@ t_stat xu_set_stats (UNIT* uptr, int32 val, char* cptr, void* desc)
|
|||
|
||||
t_stat xu_show_stats (FILE* st, UNIT* uptr, int32 val, void* desc)
|
||||
{
|
||||
char* fmt = " %-24s%d\n";
|
||||
char* fmt = " %-26s%d\n";
|
||||
CTLR* xu = xu_unit2ctlr(uptr);
|
||||
struct xu_stats* stats = &xu->var->stats;
|
||||
|
||||
fprintf(st, "Ethernet statistics:\n");
|
||||
fprintf(st, fmt, "Seconds since cleared:", stats->secs);
|
||||
fprintf(st, fmt, "Recv frames:", stats->frecv);
|
||||
fprintf(st, fmt, "Recv dbytes:", stats->rbytes);
|
||||
fprintf(st, fmt, "Xmit frames:", stats->ftrans);
|
||||
fprintf(st, fmt, "Xmit dbytes:", stats->tbytes);
|
||||
fprintf(st, fmt, "Recv frames(multicast):", stats->mfrecv);
|
||||
fprintf(st, fmt, "Recv dbytes(multicast):", stats->mrbytes);
|
||||
fprintf(st, fmt, "Xmit frames(multicast):", stats->mftrans);
|
||||
fprintf(st, fmt, "Xmit dbytes(multicast):", stats->mtbytes);
|
||||
fprintf(st, fmt, "Seconds since cleared:", stats->secs);
|
||||
fprintf(st, fmt, "Recv frames:", stats->frecv);
|
||||
fprintf(st, fmt, "Recv dbytes:", stats->rbytes);
|
||||
fprintf(st, fmt, "Xmit frames:", stats->ftrans);
|
||||
fprintf(st, fmt, "Xmit dbytes:", stats->tbytes);
|
||||
fprintf(st, fmt, "Recv frames(multicast):", stats->mfrecv);
|
||||
fprintf(st, fmt, "Recv dbytes(multicast):", stats->mrbytes);
|
||||
fprintf(st, fmt, "Xmit frames(multicast):", stats->mftrans);
|
||||
fprintf(st, fmt, "Xmit dbytes(multicast):", stats->mtbytes);
|
||||
fprintf(st, fmt, "Loopback forward Frames:", stats->loopf);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat xu_show_filters (FILE* st, UNIT* uptr, int32 val, void* desc)
|
||||
{
|
||||
CTLR* xu = xu_unit2ctlr(uptr);
|
||||
char buffer[20];
|
||||
int i;
|
||||
|
||||
fprintf(st, "Filters:\n");
|
||||
for (i=0; i<XU_FILTER_MAX; i++) {
|
||||
eth_mac_fmt((ETH_MAC*)xu->var->setup.macs[i], buffer);
|
||||
fprintf(st, " [%2d]: %s\n", i, buffer);
|
||||
}
|
||||
if (xu->var->setup.multicast)
|
||||
fprintf(st, "All Multicast Receive Mode\n");
|
||||
if (xu->var->setup.promiscuous)
|
||||
fprintf(st, "Promiscuous Receive Mode\n");
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
@ -359,13 +396,63 @@ void bit_stat16(uint16* stat, uint16 bits)
|
|||
*stat |= bits;
|
||||
}
|
||||
|
||||
t_stat xu_process_loopback(CTLR* xu, ETH_PACK* pack)
|
||||
{
|
||||
ETH_PACK response;
|
||||
ETH_MAC physical_address;
|
||||
t_stat status;
|
||||
int offset = 16 + (pack->msg[14] | (pack->msg[15] << 8));
|
||||
int function = pack->msg[offset] | (pack->msg[offset+1] << 8);
|
||||
|
||||
sim_debug(DBG_TRC, xu->dev, "xu_process_loopback()\n");
|
||||
|
||||
if (function != 2 /*forward*/)
|
||||
return SCPE_NOFNC;
|
||||
|
||||
/* create forward response packet */
|
||||
memcpy (&response, pack, sizeof(ETH_PACK));
|
||||
memcpy (physical_address, xu->var->setup.macs[0], sizeof(ETH_MAC));
|
||||
memcpy (&response.msg[0], &response.msg[offset+2], sizeof(ETH_MAC));
|
||||
memcpy (&response.msg[6], physical_address, sizeof(ETH_MAC));
|
||||
offset += 8;
|
||||
response.msg[14] = offset & 0xFF;
|
||||
response.msg[15] = (offset >> 8) & 0xFF;
|
||||
|
||||
/* send response packet */
|
||||
status = eth_write(xu->var->etherface, &response, NULL);
|
||||
++xu->var->stats.loopf;
|
||||
|
||||
if (DBG_PCK & xu->dev->dctrl)
|
||||
eth_packet_trace_ex(xu->var->etherface, response.msg, response.len, ((function == 1) ? "xu-loopbackreply" : "xu-loopbackforward"), DBG_DAT & xu->dev->dctrl, DBG_PCK);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
t_stat xu_process_local (CTLR* xu, ETH_PACK* pack)
|
||||
{
|
||||
return SCPE_NOFNC; /* not implemented yet */
|
||||
/* returns SCPE_OK if local processing occurred,
|
||||
otherwise returns SCPE_NOFNC or some other code */
|
||||
int protocol;
|
||||
|
||||
sim_debug(DBG_TRC, xu->dev, "xu_process_local()\n");
|
||||
|
||||
protocol = pack->msg[12] | (pack->msg[13] << 8);
|
||||
switch (protocol) {
|
||||
case 0x0090: /* ethernet loopback */
|
||||
return xu_process_loopback(xu, pack);
|
||||
break;
|
||||
case 0x0260: /* MOP remote console */
|
||||
return SCPE_NOFNC; /* not implemented yet */
|
||||
break;
|
||||
}
|
||||
return SCPE_NOFNC;
|
||||
}
|
||||
|
||||
void xu_read_callback(CTLR* xu, int status)
|
||||
{
|
||||
if (DBG_PCK & xu->dev->dctrl)
|
||||
eth_packet_trace_ex(xu->var->etherface, xu->var->read_buffer.msg, xu->var->read_buffer.len, "xu-recvd", DBG_DAT & xu->dev->dctrl, DBG_PCK);
|
||||
|
||||
/* process any packets locally that can be */
|
||||
status = xu_process_local (xu, &xu->var->read_buffer);
|
||||
|
||||
|
@ -442,6 +529,8 @@ t_stat xu_system_id (CTLR* xu, const ETH_MAC dest, uint16 receipt_id)
|
|||
/* write system id */
|
||||
system_id.len = 60;
|
||||
status = eth_write(xu->var->etherface, &system_id, NULL);
|
||||
if (DBG_PCK & xu->dev->dctrl)
|
||||
eth_packet_trace_ex(xu->var->etherface, system_id.msg, system_id.len, "xu-systemid", DBG_DAT & xu->dev->dctrl, DBG_PCK);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -524,6 +613,7 @@ void xu_setclrint(CTLR* xu, int32 bits)
|
|||
t_stat xu_sw_reset (CTLR* xu)
|
||||
{
|
||||
t_stat status;
|
||||
int i;
|
||||
|
||||
sim_debug(DBG_TRC, xu->dev, "xu_sw_reset()\n");
|
||||
|
||||
|
@ -559,10 +649,12 @@ t_stat xu_sw_reset (CTLR* xu)
|
|||
|
||||
/* reset ethernet interface */
|
||||
memcpy (xu->var->setup.macs[0], xu->var->mac, sizeof(ETH_MAC));
|
||||
xu->var->setup.mac_count = 1;
|
||||
for (i=0; i<6; i++)
|
||||
xu->var->setup.macs[1][i] = 0xff; /* Broadcast Address */
|
||||
xu->var->setup.mac_count = 2;
|
||||
if (xu->var->etherface)
|
||||
status = eth_filter (xu->var->etherface, xu->var->setup.mac_count,
|
||||
&xu->var->mac, xu->var->setup.multicast,
|
||||
xu->var->setup.macs, xu->var->setup.multicast,
|
||||
xu->var->setup.promiscuous);
|
||||
|
||||
/* activate device if not disabled */
|
||||
|
@ -670,24 +762,24 @@ int32 xu_command(CTLR* xu)
|
|||
case FC_RMAL: /* read multicast address list */
|
||||
mtlen = (xu->var->pcb[2] & 0xFF00) >> 8;
|
||||
udbb = xu->var->pcb[1] | ((xu->var->pcb[2] & 03) << 16);
|
||||
wstatus = Map_WriteB(udbb, mtlen * 3, (uint8*) &xu->var->setup.macs[1]);
|
||||
break;
|
||||
wstatus = Map_WriteB(udbb, mtlen * 3, (uint8*) &xu->var->setup.macs[2]);
|
||||
break;
|
||||
|
||||
case FC_WMAL: /* write multicast address list */
|
||||
mtlen = (xu->var->pcb[2] & 0xFF00) >> 8;
|
||||
sim_debug(DBG_TRC, xu->dev, "FC_WAL: mtlen=%d\n", mtlen);
|
||||
sim_debug(DBG_TRC, xu->dev, "FC_WAL: mtlen=%d\n", mtlen);
|
||||
if (mtlen > 10)
|
||||
return PCSR0_PCEI;
|
||||
udbb = xu->var->pcb[1] | ((xu->var->pcb[2] & 03) << 16);
|
||||
/* clear existing multicast list */
|
||||
for (i=1; i<XU_FILTER_MAX; i++) {
|
||||
for (j=0; j<6; j++)
|
||||
xu->var->setup.macs[i][j] = 0;
|
||||
}
|
||||
/* get multicast list from host */
|
||||
rstatus = Map_ReadB(udbb, mtlen * 6, (uint8*) &xu->var->setup.macs[1]);
|
||||
/* clear existing multicast list */
|
||||
for (i=2; i<XU_FILTER_MAX; i++) {
|
||||
for (j=0; j<6; j++)
|
||||
xu->var->setup.macs[i][j] = 0;
|
||||
}
|
||||
/* get multicast list from host */
|
||||
rstatus = Map_ReadB(udbb, mtlen * 6, (uint8*) &xu->var->setup.macs[2]);
|
||||
if (rstatus == 0) {
|
||||
xu->var->setup.mac_count = mtlen + 1;
|
||||
xu->var->setup.mac_count = mtlen + 2;
|
||||
status = eth_filter (xu->var->etherface, xu->var->setup.mac_count,
|
||||
xu->var->setup.macs, xu->var->setup.multicast,
|
||||
xu->var->setup.promiscuous);
|
||||
|
@ -807,7 +899,7 @@ sim_debug(DBG_TRC, xu->dev, "FC_WAL: mtlen=%d\n", mtlen);
|
|||
case FC_WMODE: /* write mode register */
|
||||
value = xu->var->mode;
|
||||
xu->var->mode = xu->var->pcb[1];
|
||||
sim_debug(DBG_TRC, xu->dev, "FC_WMODE: mode=%04x\n", xu->var->mode);
|
||||
sim_debug(DBG_TRC, xu->dev, "FC_WMODE: mode=%04x\n", xu->var->mode);
|
||||
|
||||
/* set promiscuous and multicast flags */
|
||||
xu->var->setup.promiscuous = (xu->var->mode & MODE_PROM) ? 1 : 0;
|
||||
|
@ -816,7 +908,7 @@ sim_debug(DBG_TRC, xu->dev, "FC_WMODE: mode=%04x\n", xu->var->mode);
|
|||
/* if promiscuous or multicast flags changed, change filter */
|
||||
if ((value ^ xu->var->mode) & (MODE_PROM | MODE_ENAL))
|
||||
status = eth_filter (xu->var->etherface, xu->var->setup.mac_count,
|
||||
&xu->var->mac, xu->var->setup.multicast,
|
||||
xu->var->setup.macs, xu->var->setup.multicast,
|
||||
xu->var->setup.promiscuous);
|
||||
break;
|
||||
|
||||
|
@ -1151,6 +1243,11 @@ void xu_process_transmit(CTLR* xu)
|
|||
runt = 1;
|
||||
}
|
||||
|
||||
/* As described in the DEUNA User Guide (Section 4.7), the DEUNA is responsible
|
||||
for inserting the appropriate source MAC address in the outgoing packet header,
|
||||
so we do that now. */
|
||||
memcpy(xu->var->write_buffer.msg+6, (uint8*)&xu->var->setup.macs[0], sizeof(ETH_MAC));
|
||||
|
||||
/* are we in internal loopback mode ? */
|
||||
if ((xu->var->mode & MODE_LOOP) && (xu->var->mode & MODE_INTL)) {
|
||||
/* just put packet in receive buffer */
|
||||
|
@ -1160,6 +1257,9 @@ void xu_process_transmit(CTLR* xu)
|
|||
wstatus = eth_write(xu->var->etherface, &xu->var->write_buffer, xu->var->wcallback);
|
||||
if (wstatus)
|
||||
xu->var->pcsr0 |= PCSR0_PCEI;
|
||||
else
|
||||
if (DBG_PCK & xu->dev->dctrl)
|
||||
eth_packet_trace_ex(xu->var->etherface, xu->var->write_buffer.msg, xu->var->write_buffer.len, "xu-write", DBG_DAT & xu->dev->dctrl, DBG_PCK);
|
||||
}
|
||||
|
||||
/* update transmit status in transmit buffer */
|
||||
|
@ -1263,7 +1363,14 @@ void xu_port_command (CTLR* xu)
|
|||
break;
|
||||
|
||||
case CMD_SELFTEST: /* SELFTEST */
|
||||
xu_sw_reset(xu);
|
||||
/*
|
||||
SELFTEST is a <=15-second self diagnostic test, setting various
|
||||
error flags and the DONE (DNI) flag when complete. For simulation
|
||||
purposes, signal completion immediately with no errors. This
|
||||
inexact behavior could be incompatible with any guest machine
|
||||
diagnostics that are expecting to be able to monitor the
|
||||
controller's progress through the diagnostic testing.
|
||||
*/
|
||||
xu->var->pcsr0 |= PCSR0_DNI;
|
||||
break;
|
||||
|
||||
|
@ -1348,7 +1455,7 @@ t_stat xu_rd(int32 *data, int32 PA, int32 access)
|
|||
*data = xu->var->pcsr3;
|
||||
break;
|
||||
}
|
||||
sim_debug(DBG_TRC, xu->dev, "xu_rd(), PCSR%d, data=%04x\n", reg, *data);
|
||||
sim_debug(DBG_REG, xu->dev, "xu_rd(), PCSR%d, data=%04x\n", reg, *data);
|
||||
if (PA & 1)
|
||||
sim_debug(DBG_WRN, xu->dev, "xu_rd(), Unexpected Odd address access of PCSR%d\n", reg);
|
||||
return SCPE_OK;
|
||||
|
@ -1375,7 +1482,7 @@ t_stat xu_wr(int32 data, int32 PA, int32 access)
|
|||
strcpy(desc, "Unknown");
|
||||
break;
|
||||
}
|
||||
sim_debug(DBG_TRC, xu->dev, "xu_wr(), PCSR%d, data=%08x, PA=%08x, access=%d[%s]\n", reg, data, PA, access, desc);
|
||||
sim_debug(DBG_REG, xu->dev, "xu_wr(), PCSR%d, data=%08x, PA=%08x, access=%d[%s]\n", reg, data, PA, access, desc);
|
||||
switch (reg) {
|
||||
case 00:
|
||||
/* Clear write-one-to-clear interrupt bits */
|
||||
|
@ -1458,6 +1565,15 @@ t_stat xu_attach(UNIT* uptr, char* cptr)
|
|||
xu->var->etherface = 0;
|
||||
return status;
|
||||
}
|
||||
if (SCPE_OK != eth_check_address_conflict (xu->var->etherface, &xu->var->mac)) {
|
||||
char buf[32];
|
||||
|
||||
eth_mac_fmt(&xu->var->mac, buf); /* format ethernet mac address */
|
||||
printf("%s: MAC Address Conflict on LAN for address %s\n", xu->dev->name, buf);
|
||||
if (sim_log) fprintf (sim_log, "%s: MAC Address Conflict on LAN for address %s\n", xu->dev->name, buf);
|
||||
eth_close(xu->var->etherface);
|
||||
return SCPE_NOATT;
|
||||
}
|
||||
uptr->filename = tptr;
|
||||
uptr->flags |= UNIT_ATT;
|
||||
eth_setcrc(xu->var->etherface, 1); /* enable CRC */
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* pdp11_xu.h: DEUNA/DELUA ethernet controller information
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2003-2008, David T. Hittner
|
||||
Copyright (c) 2003-2005, David T. Hittner
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -28,6 +28,7 @@
|
|||
|
||||
Modification history:
|
||||
|
||||
23-Jan-08 MP Added debugging support to display packet headers and packet data
|
||||
08-Dec-05 DTH Added load_server, increased UDBSIZE for system ID parameters
|
||||
07-Jul-05 RMS Removed extraneous externs
|
||||
05-Jan-04 DTH Added network statistics
|
||||
|
@ -66,7 +67,7 @@ extern int32 int_req[IPL_HLVL];
|
|||
#include "sim_ether.h"
|
||||
|
||||
#define XU_QUE_MAX 500 /* message queue array */
|
||||
#define XU_FILTER_MAX 11 /* mac + 10 multicast addrs */
|
||||
#define XU_FILTER_MAX 12 /* mac + broadcast + 10 multicast addrs */
|
||||
#define XU_SERVICE_INTERVAL 100 /* times per second */
|
||||
#define XU_ID_TIMER_VAL 540 /* 9 min * 60 sec */
|
||||
#define UDBSIZE 200 /* max size of UDB (in words) */
|
||||
|
@ -107,6 +108,7 @@ struct xu_stats {
|
|||
uint16 txccf; /* transmit collision test failure */
|
||||
uint16 porterr; /* port driver errors */
|
||||
uint16 bablcnt; /* babble counter */
|
||||
uint32 loopf; /* loopback frames processed */
|
||||
};
|
||||
|
||||
struct xu_device {
|
||||
|
@ -300,7 +302,8 @@ typedef struct xu_controller CTLR;
|
|||
#define DBG_TRC 0x0001 /* trace routine calls */
|
||||
#define DBG_REG 0x0002 /* trace read/write registers */
|
||||
#define DBG_WRN 0x0004 /* display warnings */
|
||||
#define DBG_PCK 0x0080 /* display packets */
|
||||
#define DBG_PCK 0x0080 /* display packet headers */
|
||||
#define DBG_DAT 0x0100 /* display packet data */
|
||||
#define DBG_ETH 0x8000 /* debug ethernet device */
|
||||
|
||||
#endif /* _PDP11_XU_H */
|
||||
|
|
1812
sim_ether.c
1812
sim_ether.c
File diff suppressed because it is too large
Load diff
77
sim_ether.h
77
sim_ether.h
|
@ -28,6 +28,14 @@
|
|||
|
||||
Modification history:
|
||||
|
||||
09-Dec-10 MP Added support to determine if network address conflicts exist
|
||||
07-Dec-10 MP Reworked DECnet self detection to the more general approach
|
||||
of loopback self when any Physical Address is being set.
|
||||
04-Dec-10 MP Changed eth_write to do nonblocking writes when
|
||||
USE_READER_THREAD is defined.
|
||||
07-Feb-08 MP Added eth_show_dev to display ethernet state
|
||||
28-Jan-08 MP Added eth_set_async
|
||||
23-Jan-08 MP Added eth_packet_trace_ex and ethq_destroy
|
||||
30-Nov-05 DTH Added CRC length to packet and more field comments
|
||||
04-Feb-04 DTH Added debugging information
|
||||
14-Jan-04 MP Generalized BSD support issues
|
||||
|
@ -64,7 +72,7 @@
|
|||
#define USE_SETNONBLOCK 1
|
||||
#endif
|
||||
|
||||
#if defined(__sun__) && defined(__i386__)
|
||||
#if (((defined(__sun__) && defined(__i386__)) || defined(__linux)) && !defined(DONT_USE_READER_THREAD))
|
||||
#define USE_READER_THREAD 1
|
||||
#endif
|
||||
|
||||
|
@ -108,13 +116,20 @@
|
|||
#define ETH_DEV_DESC_MAX 256 /* maximum device description size */
|
||||
#define ETH_MIN_PACKET 60 /* minimum ethernet packet size */
|
||||
#define ETH_MAX_PACKET 1514 /* maximum ethernet packet size */
|
||||
#define ETH_MAX_JUMBO_FRAME 16384 /* maximum ethernet jumbo frame size */
|
||||
#define ETH_MAX_DEVICE 10 /* maximum ethernet devices */
|
||||
#define ETH_CRC_SIZE 4 /* ethernet CRC size */
|
||||
#define ETH_FRAME_SIZE 1518 /* ethernet maximum frame size */
|
||||
#define ETH_FRAME_SIZE (ETH_MAX_PACKET+ETH_CRC_SIZE) /* ethernet maximum frame size */
|
||||
#define ETH_MIN_JUMBO_FRAME ETH_MAX_PACKET /* Threshold size for Jumbo Frame Processing */
|
||||
|
||||
#define DECNET_SELF_FRAME(dnet_mac, msg) \
|
||||
((memcmp(dnet_mac, msg , 6) == 0) && \
|
||||
(memcmp(dnet_mac, msg+6, 6) == 0))
|
||||
#define LOOPBACK_SELF_FRAME(phy_mac, msg) \
|
||||
((memcmp(phy_mac, msg , 6) == 0) && \
|
||||
(memcmp(phy_mac, msg+6, 6) == 0) && \
|
||||
((msg)[12] == 0x90) && ((msg)[13] == 0x00) && \
|
||||
((msg)[14] == 0x00) && ((msg)[15] == 0x00) && \
|
||||
((msg)[16] == 0x02) && ((msg)[17] == 0x00) && \
|
||||
(memcmp(phy_mac, msg+18, 6) == 0) && \
|
||||
((msg)[24] == 0x01) && ((msg)[25] == 0x00))
|
||||
|
||||
struct eth_packet {
|
||||
uint8 msg[ETH_FRAME_SIZE]; /* ethernet frame (message) */
|
||||
|
@ -147,6 +162,7 @@ struct eth_list {
|
|||
|
||||
typedef int ETH_BOOL;
|
||||
typedef unsigned char ETH_MAC[6];
|
||||
typedef unsigned char ETH_MULTIHASH[8];
|
||||
typedef struct eth_packet ETH_PACK;
|
||||
typedef void (*ETH_PCALLBACK)(int status);
|
||||
typedef struct eth_list ETH_LIST;
|
||||
|
@ -156,24 +172,45 @@ typedef struct eth_item ETH_ITEM;
|
|||
struct eth_device {
|
||||
char* name; /* name of ethernet device */
|
||||
void* handle; /* handle of implementation-specific device */
|
||||
int fd_handle; /* fd to kernel device (where needed) */
|
||||
int pcap_mode; /* Flag indicating if pcap API are being used to move packets */
|
||||
ETH_PCALLBACK read_callback; /* read callback function */
|
||||
ETH_PCALLBACK write_callback; /* write callback function */
|
||||
ETH_PACK* read_packet; /* read packet */
|
||||
ETH_PACK* write_packet; /* write packet */
|
||||
ETH_MAC filter_address[ETH_FILTER_MAX]; /* filtering addresses */
|
||||
int addr_count; /* count of filtering addresses */
|
||||
ETH_BOOL promiscuous; /* promiscuous mode flag */
|
||||
ETH_BOOL all_multicast; /* receive all multicast messages */
|
||||
int32 decnet_self_sent; /* loopback packets sent but not seen */
|
||||
ETH_MAC decnet_addr; /* decnet address of interface */
|
||||
ETH_BOOL hash_filter; /* filter using AUTODIN II multicast hash */
|
||||
ETH_MULTIHASH hash; /* AUTODIN II multicast hash */
|
||||
int32 loopback_self_sent; /* loopback packets sent but not seen */
|
||||
int32 loopback_self_sent_total; /* total loopback packets sent */
|
||||
int32 loopback_self_rcvd_total; /* total loopback packets seen */
|
||||
ETH_MAC physical_addr; /* physical address of interface */
|
||||
int32 have_host_nic_phy_addr; /* flag indicating that the host_nic_phy_hw_addr is valid */
|
||||
ETH_MAC host_nic_phy_hw_addr; /* MAC address of the attached NIC */
|
||||
uint32 jumbo_fragmented; /* Giant IPv4 Frames Fragmented */
|
||||
uint32 jumbo_dropped; /* Giant Frames Dropped */
|
||||
DEVICE* dptr; /* device ethernet is attached to */
|
||||
uint32 dbit; /* debugging bit */
|
||||
int reflections; /* packet reflections on interface */
|
||||
int need_crc; /* device needs CRC (Cyclic Redundancy Check) */
|
||||
int need_crc; /* device needs CRC (Cyclic Redundancy Check) */
|
||||
#if defined (USE_READER_THREAD)
|
||||
int asynch_io; /* Asynchronous Interrupt scheduling enabled */
|
||||
int asynch_io_latency; /* instructions to delay pending interrupt */
|
||||
ETH_QUE read_queue;
|
||||
pthread_mutex_t lock;
|
||||
pthread_t reader_thread; /* Reader Thread Id */
|
||||
pthread_t writer_thread; /* Writer Thread Id */
|
||||
pthread_mutex_t writer_lock;
|
||||
pthread_cond_t writer_cond;
|
||||
struct write_request {
|
||||
struct write_request *next;
|
||||
ETH_PACK packet;
|
||||
} *write_requests;
|
||||
int write_queue_peak;
|
||||
struct write_request *write_buffers;
|
||||
t_stat write_status;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -186,18 +223,30 @@ t_stat eth_open (ETH_DEV* dev, char* name, /* open ethernet interfa
|
|||
t_stat eth_close (ETH_DEV* dev); /* close ethernet interface */
|
||||
t_stat eth_write (ETH_DEV* dev, ETH_PACK* packet, /* write sychronous packet; */
|
||||
ETH_PCALLBACK routine); /* callback when done */
|
||||
t_stat eth_read (ETH_DEV* dev, ETH_PACK* packet, /* read single packet; */
|
||||
int eth_read (ETH_DEV* dev, ETH_PACK* packet, /* read single packet; */
|
||||
ETH_PCALLBACK routine); /* callback when done*/
|
||||
t_stat eth_filter (ETH_DEV* dev, int addr_count, /* set filter on incoming packets */
|
||||
ETH_MAC* addresses,
|
||||
ETH_MAC* const addresses,
|
||||
ETH_BOOL all_multicast,
|
||||
ETH_BOOL promiscuous);
|
||||
t_stat eth_filter_hash (ETH_DEV* dev, int addr_count, /* set filter on incoming packets with AUTODIN II based hash */
|
||||
ETH_MAC* const addresses,
|
||||
ETH_BOOL all_multicast,
|
||||
ETH_BOOL promiscuous,
|
||||
ETH_MULTIHASH* const hash);
|
||||
t_stat eth_check_address_conflict (ETH_DEV* dev,
|
||||
ETH_MAC* const address);
|
||||
int eth_devices (int max, ETH_LIST* dev); /* get ethernet devices on host */
|
||||
void eth_setcrc (ETH_DEV* dev, int need_crc); /* enable/disable CRC mode */
|
||||
t_stat eth_set_async (ETH_DEV* dev, int latency); /* set read behavior to be async */
|
||||
t_stat eth_clr_async (ETH_DEV* dev); /* set read behavior to be not async */
|
||||
uint32 eth_crc32(uint32 crc, const void* vbuf, size_t len); /* Compute Ethernet Autodin II CRC for buffer */
|
||||
|
||||
void eth_packet_trace (ETH_DEV* dev, const uint8 *msg, int len, char* txt); /* trace ethernet packet */
|
||||
void eth_packet_trace (ETH_DEV* dev, const uint8 *msg, int len, char* txt); /* trace ethernet packet header+crc */
|
||||
void eth_packet_trace_ex (ETH_DEV* dev, const uint8 *msg, int len, char* txt, int detail, uint32 reason); /* trace ethernet packet */
|
||||
t_stat eth_show (FILE* st, UNIT* uptr, /* show ethernet devices */
|
||||
int32 val, void* desc);
|
||||
void eth_show_dev (FILE*st, ETH_DEV* dev); /* show ethernet device state */
|
||||
|
||||
void eth_mac_fmt (ETH_MAC* add, char* buffer); /* format ethernet mac address */
|
||||
t_stat eth_mac_scan (ETH_MAC* mac, char* strmac); /* scan string for mac, put in mac */
|
||||
|
@ -207,6 +256,10 @@ void ethq_clear (ETH_QUE* que); /* clear FIFO queue */
|
|||
void ethq_remove (ETH_QUE* que); /* remove item from FIFO queue */
|
||||
void ethq_insert (ETH_QUE* que, int32 type, /* insert item into FIFO queue */
|
||||
ETH_PACK* packet, int32 status);
|
||||
void ethq_insert_data(ETH_QUE* que, int32 type, /* insert item into FIFO queue */
|
||||
const uint8 *data, int used, int len,
|
||||
int crc_len, const uint8 *crc_data, int32 status);
|
||||
t_stat ethq_destroy(ETH_QUE* que); /* release FIFO queue */
|
||||
|
||||
|
||||
#endif /* _SIM_ETHER_H */
|
||||
|
|
Loading…
Add table
Reference in a new issue