aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2018-05-01 16:30:48 +0000
committerEd Maste <emaste@FreeBSD.org>2018-05-01 16:30:48 +0000
commite6a376d196feea7a598005ad0ff2d7f04aa0889d (patch)
treedc3eda9efd21ba0e3f3ac402f1d525f94ea6447f
parente4eef18848a141a0ad4312bd120effc1472e0811 (diff)
Notes
-rw-r--r--ObsoleteFiles.inc7
-rw-r--r--UPDATING6
-rw-r--r--include/Makefile2
-rw-r--r--lib/libsysdecode/Makefile3
-rw-r--r--share/man/man4/Makefile2
-rw-r--r--share/man/man4/lmc.4771
-rw-r--r--sys/conf/NOTES4
-rw-r--r--sys/conf/files1
-rw-r--r--sys/dev/lmc/if_lmc.c4592
-rw-r--r--sys/dev/lmc/if_lmc.h1325
-rw-r--r--sys/modules/Makefile1
-rw-r--r--sys/modules/lmc/Makefile15
-rw-r--r--tools/kerneldoc/subsys/Doxyfile-dev_lmc21
-rw-r--r--usr.sbin/Makefile1
-rw-r--r--usr.sbin/lmcconfig/Makefile10
-rw-r--r--usr.sbin/lmcconfig/Makefile.depend18
-rw-r--r--usr.sbin/lmcconfig/lmcconfig.8723
-rw-r--r--usr.sbin/lmcconfig/lmcconfig.c2553
18 files changed, 14 insertions, 10041 deletions
diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
index a34d49ff4b82e..3bac420fbbc94 100644
--- a/ObsoleteFiles.inc
+++ b/ObsoleteFiles.inc
@@ -38,6 +38,13 @@
# xargs -n1 | sort | uniq -d;
# done
+# 20180501: retire lmc
+OLD_FILES+=usr/include/dev/lmc/if_lmc.h
+OLD_DIRS+=usr/include/dev/lmc
+OLD_FILES+=usr/sbin/lmcconfig
+OLD_FILES+=usr/share/man/man4/lmc.4.gz
+OLD_FILES+=usr/share/man/man4/if_lmc.4.gz
+OLD_FILES+=usr/share/man/man8/lmcconfig.8.gz
# 20180417: remove fuswintr and suswintr
OLD_FILES+=usr/share/man/man9/fuswintr.9.gz
OLD_FILES+=usr/share/man/man9/suswintr.9.gz
diff --git a/UPDATING b/UPDATING
index e3c1ab6d311ae..d0114df3a6296 100644
--- a/UPDATING
+++ b/UPDATING
@@ -51,6 +51,12 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW:
****************************** SPECIAL WARNING: ******************************
+20180501:
+ The lmc(4) driver has been removed. This was a WAN interface
+ card that was already reportedly rare in 2003, and had an ambiguous
+ license. If you have device lmc in your kernel config file it must
+ be removed.
+
20180413:
Support for Arcnet networks has been removed. If you have device
arcnet or device cm in your kernel config file they must be
diff --git a/include/Makefile b/include/Makefile
index 97124d65370e3..21930868a27c8 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -45,7 +45,7 @@ LDIRS= bsm cam geom net net80211 netgraph netinet netinet6 \
LSUBDIRS= cam/ata cam/mmc cam/nvme cam/scsi \
dev/acpica dev/agp dev/an dev/bktr dev/ciss dev/filemon dev/firewire \
dev/hwpmc dev/hyperv \
- dev/ic dev/iicbus dev/io dev/lmc dev/mfi dev/mmc dev/nvme \
+ dev/ic dev/iicbus dev/io dev/mfi dev/mmc dev/nvme \
dev/ofw dev/pbio dev/pci ${_dev_powermac_nvram} dev/ppbus dev/smbus \
dev/speaker dev/tcp_log dev/vkbd dev/wi \
fs/devfs fs/fdescfs fs/msdosfs fs/nandfs fs/nfs fs/nullfs \
diff --git a/lib/libsysdecode/Makefile b/lib/libsysdecode/Makefile
index 6233149c43fb8..a37d05de20c4c 100644
--- a/lib/libsysdecode/Makefile
+++ b/lib/libsysdecode/Makefile
@@ -120,9 +120,6 @@ CFLAGS+=-DPF
# Workaround duplicate declarations in <netinet/ip_compat.h>
CFLAGS.gcc.ioctl.c+= -Wno-redundant-decls
-# Workaround warning for unused ssi_cables[] in <dev/lmc/if_lmc.h>
-CFLAGS.gcc.ioctl.c+= -Wno-unused
-
CFLAGS.gcc+= ${CFLAGS.gcc.${.IMPSRC}}
DEPENDOBJS+= tables.h
diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index 6626679f98d82..f3b1dc383725c 100644
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -266,7 +266,6 @@ MAN= aac.4 \
${_linux.4} \
liquidio.4 \
lm75.4 \
- lmc.4 \
lo.4 \
lp.4 \
lpbb.4 \
@@ -688,7 +687,6 @@ MLINKS+=lagg.4 trunk.4
MLINKS+=lagg.4 if_lagg.4
MLINKS+=le.4 if_le.4
MLINKS+=lge.4 if_lge.4
-MLINKS+=lmc.4 if_lmc.4
MLINKS+=lo.4 loop.4
MLINKS+=lp.4 plip.4
MLINKS+=malo.4 if_malo.4
diff --git a/share/man/man4/lmc.4 b/share/man/man4/lmc.4
deleted file mode 100644
index 0e0c3979a042a..0000000000000
--- a/share/man/man4/lmc.4
+++ /dev/null
@@ -1,771 +0,0 @@
-.\"
-.\" $FreeBSD$
-.\"
-.\" Copyright (c) 2002-2005 David Boggs. (boggs@boggs.palo-alto.ca.us)
-.\" All rights reserved.
-.\"
-.\" BSD License:
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" GNU General Public License:
-.\"
-.\" This program is free software; you can redistribute it and/or modify it
-.\" under the terms of the GNU General Public License as published by the Free
-.\" Software Foundation; either version 2 of the License, or (at your option)
-.\" any later version.
-.\"
-.\" This program is distributed in the hope that it will be useful, but WITHOUT
-.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-.\" more details.
-.\"
-.\" You should have received a copy of the GNU General Public License along with
-.\" this program; if not, write to the Free Software Foundation, Inc., 59
-.\" Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-.\"
-.Dd April 24, 2018
-.Dt LMC 4
-.Os
-.\"
-.Sh NAME
-.\"
-.Nm lmc
-.Nd device driver for
-.Tn LMC
-(now
-.Tn SBE )
-wide-area network interface cards
-.\"
-.Sh SYNOPSIS
-.\"
-To wire this driver into your kernel,
-add the following line to your kernel configuration file:
-.Bd -ragged -offset indent
-.Cd "device lmc"
-.Ed
-.Pp
-Alternatively, to load this module at boot time, add
-.Bd -literal -offset indent
-if_lmc_load="YES"
-.Ed
-.Pp
-to
-.Pa /boot/loader.conf ;
-see
-.Xr loader.conf 5 .
-.Pp
-To wire a line protocol into your kernel, add:
-.Bd -ragged -offset indent
-.Cd "options NETGRAPH"
-.Cd "device sppp"
-.Ed
-.Pp
-It is not necessary to wire line protocols into your kernel,
-they can be loaded later with
-.Xr kldload 8 .
-The driver can send and receive raw IP packets even if neither
-SPPP nor Netgraph are configured into the kernel.
-Netgraph and SPPP can both be enabled; Netgraph will be used if the
-.Va rawdata
-hook is connected.
-.\"
-.Sh DEPRECATION NOTICE
-The
-.Nm
-driver is not present in
-.Fx 12.0
-and later.
-.\"
-.Sh DESCRIPTION
-.\"
-This is an open-source
-.Ux
-device driver for PCI-bus WAN interface cards.
-It sends and receives packets in HDLC frames over synchronous circuits.
-A generic PC plus
-.Ux
-plus some
-.Tn LMC / SBE
-cards makes an
-.Em open
-router.
-This driver works with
-.Fx ,
-.Nx ,
-.Ox ,
-.Bsx
-and
-.Tn Linux
-OSs.
-It has been tested on i386 (SMP 32-bit little-endian) and Sparc (64-bit big-endian)
-architectures.
-.Pp
-The
-.Nm
-driver works with the following cards:
-.Bl -bullet
-.It
-SBE wanADAPT-HSSI (LMC5200)
-.Pp
-High Speed Serial Interface,
-EIA612/613, 50-pin connector,
-0 to 52 Mb/s, DTE only.
-.It
-SBE wanADAPT-T3 (LMC5245)
-.Pp
-T3: two 75-ohm BNC connectors,
-C-Parity or M13 Framing,
-44.736 Mb/s, up to 950 ft.
-.It
-SBE wanADAPT-SSI (LMC1000)
-.Pp
-Synchronous Serial Interface,
-V.35, X.21, EIA449, EIA530(A), EIA232,
-0 to 10 Mb/s, DTE or DCE.
-.It
-SBE wanADAPT-T1E1 (LMC1200)
-.Pp
-T1 or E1: RJ45 conn, 100 or 120 ohms,
-T1-ESF-B8ZS, T1-SF-AMI, E1-(many)-HDB3,
-1.544 Mb/s or 2.048 Mb/s, up to 6 Kft.
-.El
-.Pp
-Cards contain a high-performance
-.Sy "PCI"
-interface, an
-.Sy "HDLC"
-function and
-either integrated
-.Sy "modems"
-(T1, T3) or
-.Sy "modem"
-interfaces (HSSI and SSI).
-.Bl -tag -width "Modem"
-.It Sy "PCI"
-The PCI interface is a DEC 21140A "Tulip" Fast Ethernet chip.
-This chip has an efficient PCI implementation with scatter/gather DMA,
-and can run at 100 Mb/s full duplex (twice as fast as needed here).
-.It Sy "HDLC"
-The HDLC functions (ISO-3309: flags, bit-stuffing, CRC) are implemented
-in a Field Programmable Gate Array (FPGA) which talks to the Ethernet
-chip through a Media Independent Interface (MII).
-The hardware in the FPGA translates between Ethernet packets and
-HDLC frames on-the-fly; think it as a WAN PHY chip for Ethernet.
-.It Sy "Modem"
-The modem chips are the main differences between cards.
-HSSI cards use ECL10K chips to implement the EIA-612/613 interface.
-T3 cards use a TranSwitch TXC-03401 framer chip.
-SSI cards use Linear Technology LTC1343 modem interface chips.
-T1 cards use a BrookTree/Conexant/Mindspeed Bt8370 framer
-and line interface chip.
-.El
-.Pp
-Line protocols exist above device drivers and below internet protocols.
-They typically encapsulate packets in HDLC frames and deal with
-higher-level issues like protocol multiplexing and security.
-This driver is compatible with several line protocol packages:
-.Bl -tag -width "Generic HDLC"
-.It Sy "Netgraph"
-.Xr netgraph 4
-implements many basic packet-handling functions as kernel loadable modules.
-They can be interconnected in a graph to implement many protocols.
-Configuration is done from userland without rebuilding the kernel.
-Packets are sent and received through this interface if the driver's
-.Em rawdata
-hook is connected, otherwise the ifnet interface (SPPP and RawIP) is used.
-ASCII configuration control messages are
-.Em not
-currently supported.
-.It Sy "SPPP"
-.Xr sppp 4
-implements Synchronous-PPP, Frame-Relay and Cisco-HDLC in the kernel.
-.It Sy "RawIP"
-This null line protocol, built into the driver, sends and receives
-raw IPv4 and IPv6 packets in HDLC frames (aka IP-in-HDLC) with
-no extra bytes of overhead and no state at the end points.
-.El
-.\"
-.Sh EXAMPLES
-.\"
-.Ss "ifconfig and lmcconfig"
-.\"
-The program
-.Xr lmcconfig 8
-manipulates interface parameters beyond the scope of
-.Xr ifconfig 8 .
-In normal operation only a few arguments are needed:
-.Pp
-.Bl -tag -width ".Fl X" -offset indent -compact
-.It Fl X
-selects the external
-SPPP
-line protocol package.
-.It Fl x
-selects the built-in RawIP line protocol package.
-.It Fl Z
-selects PPP line protocol.
-.It Fl z
-selects Cisco-HDLC line protocol.
-.It Fl F
-selects Frame-Relay line protocol.
-.El
-.Bl -tag -width indent
-.It Li "lmcconfig lmc0"
-displays interface configuration and status.
-.It Li "lmcconfig lmc0 -D"
-enables debugging output from the device driver only.
-.It Li "ifconfig lmc0 debug"
-enables debugging output from the device driver and from
-the line protocol module above it.
-Debugging messages that appear on the console are also
-written to file
-.Pa "/var/log/messages" .
-.Em Caution :
-when things go very wrong, a torrent of debugging messages
-can swamp the console and bring a machine to its knees.
-.El
-.\"
-.Ss Operation
-.\"
-Activate a PPP link using SPPP and Netgraph with:
-.Bd -literal -offset indent
-ngctl mkpeer lmc0: sppp rawdata downstream
-ifconfig sppp0 10.0.0.1 10.0.0.2
-.Ed
-.Pp
-Activate a PPP link using only SPPP with:
-.Bd -literal -offset indent
-lmcconfig lmc0 -XYZ
-ifconfig lmc0 10.0.0.1 10.0.0.2
-.Ed
-.Pp
-Activate a Cisco-HDLC link using SPPP and Netgraph with:
-.Bd -literal -offset indent
-ngctl mkpeer lmc0: sppp rawdata downstream
-ifconfig sppp0 10.0.0.1 10.0.0.2 link2
-.Ed
-.Pp
-Activate a Cisco-HDLC link using only SPPP with:
-.Bd -literal -offset indent
-lmcconfig lmc0 -XYz
-ifconfig lmc0 10.0.0.1 10.0.0.2
-.Ed
-.Pp
-Activate a Cisco-HDLC link using only Netgraph with:
-.Bd -literal -offset indent
-ngctl mkpeer lmc0: cisco rawdata downstream
-ngctl mkpeer lmc0:rawdata iface inet inet
-ifconfig ng0 10.0.0.1 10.0.0.2
-.Ed
-.Pp
-Activate a Frame-Relay DTE link using SPPP with:
-.Bd -literal -offset indent
-lmcconfig lmc0 -XYF
-ifconfig lmc0 10.0.0.1 10.0.0.2
-.Ed
-.Pp
-(SPPP implements the ANSI T1.617 annex D LMI.)
-.Pp
-Activate a Frame-Relay DTE link using Netgraph with:
-.Bd -literal -offset indent
-ngctl mkpeer lmc0: frame_relay rawdata downstream
-ngctl mkpeer lmc0:rawdata lmi dlci0 auto0
-ngctl connect lmc0:rawdata dlci0 dlci1023 auto1023
-ngctl mkpeer lmc0:rawdata rfc1490 dlci500 downstream
-ngctl mkpeer lmc0:rawdata.dlci500 iface inet inet
-ifconfig ng0 10.0.0.1 10.0.0.2
-.Ed
-This is
-.Em ONE
-possible Frame Relay configuration; there are many.
-.Pp
-Activate a RAWIP link using only the driver with:
-.Bd -literal -offset indent
-lmcconfig lmc0 -x
-ifconfig lmc0 10.0.0.1 10.0.0.2
-.Ed
-.Pp
-Activate a RAWIP link using Netgraph with:
-.Bd -literal -offset indent
-ngctl mkpeer lmc0: iface rawdata inet
-ifconfig ng0 10.0.0.1 10.0.0.2
-.Ed
-.Pp
-If the driver is unloaded and then loaded, reconnect hooks by:
-.Pp
-.Dl "ngctl connect lmc0: ng0: rawdata inet"
-.\"
-.Sh TESTING
-.\"
-.Ss Testing with Loopbacks
-.\"
-Testing with loopbacks requires only one card.
-Packets can be looped back at many points: in the PCI chip,
-in the modem chips, through a loopback plug, in the
-local external equipment, or at the far end of a circuit.
-.Pp
-Activate the card with
-.Xr ifconfig 8 :
-.Pp
-.Dl "ifconfig lmc0 10.0.0.1 10.0.0.1"
-.Pp
-All cards can be looped through the PCI chip.
-Cards with internal modems can be looped through
-the modem framer and the modem line interface.
-Cards for external modems can be looped through
-the driver/receiver chips.
-See
-.Xr lmcconfig 8
-for details.
-.Pp
-Loopback plugs test everything on the card.
-.Bl -tag -width ".Sy T1/E1"
-.It Sy HSSI
-Loopback plugs can be ordered from SBE (and others).
-Transmit clock is normally supplied by the external modem.
-When an HSSI card is operated with a loopback plug, the PCI bus
-clock must be used as the transmit clock, typically 33 MHz.
-When testing an HSSI card with a loopback plug,
-configure it with
-.Xr lmcconfig 8 :
-.Pp
-.Dl "lmcconfig lmc0 -a 2"
-.Pp
-.Dq Fl a Li 2
-selects the PCI bus clock as the transmit clock.
-.It Sy T3
-Connect the two BNC jacks with a short coax cable.
-.It Sy SSI
-Loopback plugs can be ordered from SBE (only).
-Transmit clock is normally supplied by the external modem.
-When an SSI card is operated with a loopback plug,
-the on-board clock synthesizer must be used.
-When testing an SSI card with a loopback plug,
-configure it with
-.Xr lmcconfig 8 :
-.Pp
-.Dl "lmcconfig lmc0 -E -f 10000000"
-.Pp
-.Fl E
-puts the card in DCE mode to source a transmit clock.
-.Dq Fl f Li 10000000
-sets the internal clock source to 10 Mb/s.
-.It Sy T1/E1
-A loopback plug is a modular plug with two wires
-connecting pin 1 to pin 4 and pin 2 to pin 5.
-.El
-.Pp
-One can also test by connecting to a local modem (HSSI and SSI)
-or NI (T1 and T3) configured to loop back.
-Cards can generate signals to loopback remote equipment
-so that complete circuits can be tested; see
-.Xr lmcconfig 8
-for details.
-.\"
-.Ss Testing with a Modem
-.\"
-Testing with a modem requires two cards of different types.
-.Bl -tag -width ".Sy T3/HSSI"
-.It Sy T3/HSSI
-If you have a T3 modem with an HSSI interface
-(made by Digital Link, Larscom, Kentrox etc.\&)
-then use an HSSI card in one machine and a T3 card in the other machine.
-The T3 coax cables must use the null modem configuration (see below).
-.It Sy T1/V.35
-If you have a T1 (or E1) modem with a V.35, X.21 or EIA530 interface,
-then use an SSI card in one machine and a T1 card in the other machine.
-Use a T1 null modem cable (see below).
-.El
-.\"
-.Ss Testing with a Null Modem Cable
-.\"
-Testing with a null modem cable requires two cards of the same type.
-.Bl -tag -width ".Sy T1/E1"
-.It Sy HSSI
-Three-meter HSSI null-modem cables can be ordered from SBE.
-In a pinch, a 50-pin SCSI-II cable up to a few meters will
-work as a straight HSSI cable (not a null modem cable).
-Longer cables should be purpose-built HSSI cables because
-the cable impedance is different.
-Transmit clock is normally supplied by the external modem.
-When an HSSI card is connected by a null modem cable, the PCI bus
-clock can be used as the transmit clock, typically 33 MHz.
-When testing an HSSI card with a null modem cable, configure it
-with
-.Xr lmcconfig 8 :
-.Pp
-.Dl "lmcconfig lmc0 -a 2"
-.Pp
-.Dq Fl a Li 2
-selects the PCI bus clock as the transmit clock.
-.It Sy T3
-T3 null modem cables are just 75-ohm coax cables with BNC connectors.
-TX OUT on one card should be connected to RX IN on the other card.
-In a pinch, 50-ohm thin Ethernet cables
-.Em usually
-work up to a few meters, but they will
-.Em not
-work for longer runs \[em] 75-ohm coax is
-.Em required .
-.It Sy SSI
-Three-meter SSI null modem cables can be ordered from SBE.
-An SSI null modem cable reports a cable type of V.36/EIA449.
-Transmit clock is normally supplied by the external modem.
-When an SSI card is connected by a null modem cable,
-an on-board clock synthesizer is used.
-When testing an SSI card with a null modem cable, configure it
-with
-.Xr lmcconfig 8 :
-.Pp
-.Dl "lmcconfig lmc0 -E -f 10000000"
-.Pp
-.Fl E
-puts the card in DCE mode to source a transmit clock.
-.Dq Fl f Li 10000000
-sets the internal clock source to 10 Mb/s.
-.It Sy T1/E1
-A T1 null modem cable has two twisted pairs that connect
-pins 1 and 2 on one plug to pins 4 and 5 on the other plug.
-Looking into the cable entry hole of a plug,
-with the locking tab oriented down,
-pin 1 is on the left.
-A twisted pair Ethernet cable makes an excellent straight T1 cable.
-Alas, Ethernet cross-over cables do not work as T1 null modem cables.
-.El
-.\"
-.Sh OPERATION NOTES
-.\"
-.Ss Packet Lengths
-Maximum transmit and receive packet length is unlimited.
-Minimum transmit and receive packet length is one byte.
-.Pp
-Cleaning up after one packet and setting up for the next
-packet involves making several DMA references.
-This can take longer than the duration of a short packet,
-causing the adapter to fall behind.
-For typical PCI bus traffic levels and memory system latencies,
-back-to-back packets longer than about 20 bytes will always
-work (53 byte cells work), but a burst of several hundred
-back-to-back packets shorter than 20 bytes will cause packets
-to be dropped.
-This usually is not a problem since an IPv4 packet header is
-at least 20 bytes long.
-.Pp
-This device driver imposes no constraints on packet size.
-Most operating systems set the default Maximum Transmission
-Unit (MTU) to 1500 bytes; the legal range is usually (72..65535).
-This can be changed with
-.Pp
-.Dl "ifconfig lmc0 mtu 2000"
-.Pp
-SPPP enforces an MTU of (128..far-end-MRU) for PPP
-and 1500 bytes for Cisco-HDLC.
-RAWIP sets the default MTU to 4032 bytes,
-but it can be changed to anything.
-.\"
-.Ss BPF - Berkeley Packet Filter
-.\"
-This driver has hooks for
-.Xr bpf 4 ,
-the Berkeley Packet Filter.
-The line protocol header length reported to BPF is four bytes
-for SPPP and P2P line protocols and zero bytes for RawIP.
-.Pp
-To include BPF support into your kernel,
-add the following line to
-.Pa conf/YOURKERNEL :
-.Pp
-.Dl "device bpf"
-.Pp
-To test the BPF kernel interface,
-bring up a link between two machines, then run
-.Xr ping 8
-and
-.Xr tcpdump 1 :
-.Pp
-.Dl "ping 10.0.0.1"
-.Pp
-and in a different window:
-.Pp
-.Dl "tcpdump -i lmc0"
-.Pp
-The output from
-.Xr tcpdump 1
-should look like this:
-.Bd -literal -offset indent
-03:54:35.979965 10.0.0.2 > 10.0.0.1: icmp: echo request
-03:54:35.981423 10.0.0.1 > 10.0.0.2: icmp: echo reply
-.Ed
-.Pp
-Line protocol control packets will appear among the
-.Xr ping 8
-packets occasionally.
-.\"
-.Ss Device Polling
-.\"
-A T3 receiver can generate over 100K interrupts per second,
-this can cause a system to
-.Dq live-lock :
-spend all of its
-time servicing interrupts.
-.Fx
-has a polling mechanism to prevent live-lock.
-.Pp
-.Fx Ns 's
-mechanism permanently disables interrupts from the card
-and instead the card's interrupt service routine is called each
-time the kernel is entered (syscall, timer interrupt, etc.\&) and
-from the kernel idle loop; this adds some latency.
-The driver is permitted to process a limited number of packets.
-The percentage of the CPU that can be consumed this way is settable.
-.Pp
-See the
-.Xr polling 4
-manpage for details on how to enable the polling mode.
-.\"
-.Ss SNMP: Simple Network Management Protocol
-.\"
-This driver is aware of what is required to be a Network Interface
-Object managed by an Agent of the Simple Network Management Protocol.
-The driver exports SNMP-formatted configuration and status
-information sufficient for an SNMP Agent to create MIBs for:
-.Pp
-.Bl -item -offset indent -compact
-.It
-.%T "RFC-2233: Interfaces group" ,
-.It
-.%T "RFC-2496: DS3 interfaces" ,
-.It
-.%T "RFC-2495: DS1/E1 interfaces" ,
-.It
-.%T "RFC-1659: RS232-like interfaces" .
-.El
-.Pp
-An SNMP Agent is a user program, not a kernel function.
-Agents can retrieve configuration and status information
-by using
-Netgraph control messages or
-.Xr ioctl 2
-system calls.
-User programs should poll
-.Va sc->cfg.ticks
-which increments once per second after the SNMP state has been updated.
-.\"
-.Ss HSSI and SSI LEDs
-.\"
-The card should be operational if all three green LEDs are on
-(the upper-left one should be blinking) and the red LED is off.
-All four LEDs turn on at power-on and module unload.
-.Pp
-.Bl -column -compact -offset indent "YELLOW" "upper-right" "Software"
-.It "RED" Ta "upper-right" Ta "No Transmit clock"
-.It "GREEN" Ta "upper-left" Ta "Device driver is alive if blinking"
-.It "GREEN" Ta "lower-right" Ta "Modem signals are good"
-.It "GREEN" Ta "lower-left" Ta "Cable is plugged in (SSI only)"
-.El
-.\"
-.Ss T1E1 and T3 LEDs
-.\"
-The card should be operational if the upper-left green LED is blinking
-and all other LEDs are off.
-For the T3 card, if other LEDs are on or
-blinking, try swapping the coax cables!
-All four LEDs turn on at power-on and module unload.
-.Pp
-.Bl -column -compact -offset indent "YELLOW" "upper-right" "Received"
-.It "RED" Ta "upper-right" Ta "Received signal is wrong"
-.It "GREEN" Ta "upper-left" Ta "Device driver is alive if blinking"
-.It "BLUE" Ta "lower-right" Ta "Alarm Information Signal (AIS)"
-.It "YELLOW" Ta "lower-left" Ta "Remote Alarm Indication (RAI)"
-.El \" YELLOW
-.Pp
-.Bl -column -compact "The yellow" "LED"
-.It "The green" Ta "LED blinks if the device driver is alive."
-.It "The red" Ta "LED blinks if an outward loopback is active."
-.It "The blue" Ta "LED blinks if sending AIS, on solid if receiving AIS."
-.It "The yellow" Ta "LED blinks if sending RAI, on solid if receiving RAI."
-.El \" LED
-.\"
-.Ss E1 Framing
-.\"
-Phone companies usually insist that customers put a
-.Em Frame Alignment Signal
-(FAS) in time slot 0.
-A Cyclic Redundancy Checksum (CRC) can also ride in time slot 0.
-.Em Channel Associated Signalling
-(CAS) uses Time Slot 16.
-In telco-speak
-.Em signalling
-is on/off hook, ringing, busy, etc.
-Signalling is not needed here and consumes 64 Kb/s.
-Only use E1-CAS formats if the other end insists on it!
-Use E1-FAS+CRC framing format on a public circuit.
-Depending on the equipment installed in a private circuit,
-it may be possible to use all 32 time slots for data (E1-NONE).
-.\"
-.Ss T3 Framing
-.\"
-M13 is a technique for multiplexing 28 T1s into a T3.
-Muxes use the C-bits for speed-matching the tributaries.
-Muxing is not needed here and usurps the FEBE and FEAC bits.
-Only use T3-M13 format if the other end insists on it!
-Use T3-CParity framing format if possible.
-Loop Timing, Fractional T3, and HDLC packets in
-the Facility Data Link are
-.Em not
-supported.
-.\"
-.Ss T1 & T3 Frame Overhead Functions
-.\"
-.Bl -item -compact
-.It
-Performance Report Messages (PRMs) are enabled in T1-ESF.
-.It
-Bit Oriented Protocol (BOP) messages are enabled in T1-ESF.
-.It
-In-band loopback control (framed or not) is enabled in T1-SF.
-.It
-Far End Alarm and Control (FEAC) msgs are enabled in T3-CPar.
-.It
-Far End Block Error (FEBE) reports are enabled in T3-CPar.
-.It
-Remote Alarm Indication (RAI) is enabled in T3-Any.
-.It
-Loopbacks initiated remotely time out after 300 seconds.
-.El
-.\"
-.Ss T1/E1 'Fractional' 64 kb/s Time Slots
-.\"
-T1 uses time slots 24..1; E1 uses time slots 31..0.
-E1 uses TS0 for FAS overhead and TS16 for CAS overhead.
-E1-NONE has
-.Em no
-overhead, so all 32 TSs are available for data.
-Enable/disable time slots by setting 32 1s/0s in a config param.
-Enabling an E1 overhead time slot,
-or enabling TS0 or TS25-TS31 for T1,
-is ignored by the driver, which knows better.
-The default TS param, 0xFFFFFFFF, enables the maximum number
-of time slots for whatever frame format is selected.
-56 Kb/s time slots are
-.Em not
-supported.
-.\"
-.Ss T1 Raw Mode
-.\"
-Special gate array microcode exists for the T1/E1 card.
-Each T1 frame of 24 bytes is treated as a packet.
-A raw T1 byte stream can be delivered to main memory
-and transmitted from main memory.
-The T1 card adds or deletes framing bits but does not
-touch the data.
-ATM cells can be transmitted and received this way, with
-the software doing all the work.
-But that is not hard; after all it is only 1.5 Mb/s second!
-.\"
-.Ss T3 Circuit Emulation Mode
-.\"
-Special gate array microcode exists for the T3 card.
-Each T3 frame of 595 bytes is treated as a packet.
-A raw T3 signal can be
-.Em packetized ,
-transported through a
-packet network (using some protocol) and then
-.Em reconstituted
-as a T3 signal at the far end.
-The output transmitter's
-bit rate can be controlled from software so that it can be
-.Em frequency locked
-to the distant input signal.
-.\"
-.Ss HSSI and SSI Transmit Clocks
-.\"
-Synchronous interfaces use two transmit clocks to eliminate
-.Em skew
-caused by speed-of-light delays in the modem cable.
-DCEs (modems) drive ST, Send Timing, the first transmit clock.
-DTEs (hosts) receive ST and use it to clock transmit data, TD,
-onto the modem cable.
-DTEs also drive a copy of ST back towards the DCE and call it TT,
-Transmit Timing, the second transmit clock.
-DCEs receive TT and TD and use TT to clock TD into a flip flop.
-TT experiences the same delay as (and has no
-.Em skew
-relative to) TD.
-Thus, cable length does not affect data/clock timing.
-.\"
-.Sh SEE ALSO
-.\"
-.Xr tcpdump 1 ,
-.Xr ioctl 2 ,
-.Xr bpf 4 ,
-.Xr kld 4 ,
-.Xr netgraph 4 ,
-.Xr polling 4 ,
-.Xr sppp 4 ,
-.Xr loader.conf 5 ,
-.Xr ifconfig 8 ,
-.Xr lmcconfig 8 ,
-.Xr mpd 8 Pq Pa ports/net/mpd ,
-.Xr ngctl 8 ,
-.Xr ping 8 ,
-.Xr ifnet 9
-.\"
-.Sh HISTORY
-.\"
-.An Ron Crane
-had the idea to use a Fast Ethernet chip as a PCI interface
-and add an Ethernet-to-HDLC gate array to make a WAN card.
-.An David Boggs
-designed the Ethernet-to-HDLC gate array and PC cards.
-We did this at our company, LAN Media Corporation
-.Tn (LMC) .
-.Tn SBE
-Corp.\& acquired
-.Tn LMC
-and continues to make the cards.
-.Pp
-Since the cards use Tulip Ethernet chips, we started with
-.An Matt Thomas Ns '
-ubiquitous
-.Xr de 4
-driver.
-.An Michael Graff
-stripped out the Ethernet stuff and added HSSI stuff.
-.An Basil Gunn
-ported it to
-.Tn Solaris
-(lost) and
-.Tn Rob Braun
-ported it to
-.Tn Linux .
-.An Andrew Stanley-Jones
-added support
-for three more cards and wrote the first version of
-.Xr lmcconfig 8 .
-.An David Boggs
-rewrote everything and now feels responsible for it.
-.\"
-.Sh AUTHORS
-.\"
-.An David Boggs Aq Mt boggs@boggs.palo-alto.ca.us
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index 5ffdf8401a346..e3bfd1788adc6 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -1982,7 +1982,6 @@ device xmphy # XaQti XMAC II
# Yukon II Gigabit controllers, including 88E8021, 88E8022, 88E8061,
# 88E8062, 88E8035, 88E8036, 88E8038, 88E8050, 88E8052, 88E8053,
# 88E8055, 88E8056 and D-Link 560T/550SX.
-# lmc: Support for the LMC/SBE wide-area network interface cards.
# mlx5: Mellanox ConnectX-4 and ConnectX-4 LX IB and Eth shared code module.
# mlx5en:Mellanox ConnectX-4 and ConnectX-4 LX PCIe Ethernet adapters.
# my: Myson Fast Ethernet (MTD80X, MTD89X)
@@ -2136,9 +2135,6 @@ device txp # 3Com 3cR990 (``Typhoon'')
device vx # 3Com 3c590, 3c595 (``Vortex'')
device vxge # Exar/Neterion XFrame 3100 10GbE
-# PCI WAN adapters.
-device lmc
-
# PCI IEEE 802.11 Wireless NICs
device ath # Atheros pci/cardbus NIC's
device ath_hal # pci/cardbus chip support
diff --git a/sys/conf/files b/sys/conf/files
index 8be95fc6ebb67..7548dc0967f15 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -2373,7 +2373,6 @@ lio_23xx_nic.bin.fw optional lio \
compile-with "${NORMAL_FW}" \
no-obj no-implicit-rule \
clean "lio_23xx_nic.bin.fw"
-dev/lmc/if_lmc.c optional lmc
dev/malo/if_malo.c optional malo
dev/malo/if_malohal.c optional malo
dev/malo/if_malo_pci.c optional malo pci
diff --git a/sys/dev/lmc/if_lmc.c b/sys/dev/lmc/if_lmc.c
deleted file mode 100644
index 8f85dd023791d..0000000000000
--- a/sys/dev/lmc/if_lmc.c
+++ /dev/null
@@ -1,4592 +0,0 @@
-/*-
- * $FreeBSD$
- *
- * Copyright (c) 2002-2004 David Boggs. <boggs@boggs.palo-alto.ca.us>
- * All rights reserved.
- *
- * BSD License:
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * GNU General Public License:
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Description:
- *
- * This is an open-source Unix device driver for PCI-bus WAN interface cards.
- * It sends and receives packets in HDLC frames over synchronous links.
- * A generic PC plus Unix plus some SBE/LMC cards makes an OPEN router.
- * This driver works with FreeBSD, NetBSD, OpenBSD, BSD/OS and Linux.
- * It has been tested on i386 (32-bit little-end), Sparc (64-bit big-end),
- * and Alpha (64-bit little-end) architectures.
- *
- * History and Authors:
- *
- * Ron Crane had the neat idea to use a Fast Ethernet chip as a PCI
- * interface and add an Ethernet-to-HDLC gate array to make a WAN card.
- * David Boggs designed the Ethernet-to-HDLC gate arrays and PC cards.
- * We did this at our company, LAN Media Corporation (LMC).
- * SBE Corp acquired LMC and continues to make the cards.
- *
- * Since the cards use Tulip Ethernet chips, we started with Matt Thomas'
- * ubiquitous "de" driver. Michael Graff stripped out the Ethernet stuff
- * and added HSSI stuff. Basil Gunn ported it to Solaris (lost) and
- * Rob Braun ported it to Linux. Andrew Stanley-Jones added support
- * for three more cards and wrote the first version of lmcconfig.
- * During 2002-5 David Boggs rewrote it and now feels responsible for it.
- *
- * Responsible Individual:
- *
- * Send bug reports and improvements to <boggs@boggs.palo-alto.ca.us>.
- */
-# include <sys/param.h> /* OS version */
-# define IFNET 1
-# include "opt_inet.h" /* INET */
-# include "opt_inet6.h" /* INET6 */
-# include "opt_netgraph.h" /* NETGRAPH */
-# ifdef HAVE_KERNEL_OPTION_HEADERS
-# include "opt_device_polling.h" /* DEVICE_POLLING */
-# endif
-# ifndef INET
-# define INET 0
-# endif
-# ifndef INET6
-# define INET6 0
-# endif
-# ifndef NETGRAPH
-# define NETGRAPH 0
-# endif
-# define P2P 0 /* not in FreeBSD */
-# define NSPPP 1 /* No count devices in FreeBSD 5 */
-# include "opt_bpf.h" /* DEV_BPF */
-# ifdef DEV_BPF
-# define NBPFILTER 1
-# else
-# define NBPFILTER 0
-# endif
-# define GEN_HDLC 0 /* not in FreeBSD */
-#
-# include <sys/systm.h>
-# include <sys/kernel.h>
-# include <sys/malloc.h>
-# include <sys/mbuf.h>
-# include <sys/socket.h>
-# include <sys/sockio.h>
-# include <sys/module.h>
-# include <sys/bus.h>
-# include <sys/lock.h>
-# include <net/if.h>
-# include <net/if_var.h>
-# include <net/if_types.h>
-# include <net/if_media.h>
-# include <net/netisr.h>
-# include <net/route.h>
-# include <machine/bus.h>
-# include <machine/resource.h>
-# include <sys/rman.h>
-# include <vm/vm.h>
-# include <vm/pmap.h>
-# include <sys/priv.h>
-# include <sys/mutex.h>
-# include <dev/pci/pcivar.h>
-# if NETGRAPH
-# include <netgraph/ng_message.h>
-# include <netgraph/netgraph.h>
-# endif
-# if (INET || INET6)
-# include <netinet/in.h>
-# include <netinet/in_var.h>
-# endif
-# if NSPPP
-# include <net/if_sppp.h>
-# endif
-# if NBPFILTER
-# include <net/bpf.h>
-# endif
-/* and finally... */
-# include <dev/lmc/if_lmc.h>
-
-
-
-
-
-/* The SROM is a generic 93C46 serial EEPROM (64 words by 16 bits). */
-/* Data is set up before the RISING edge of CLK; CLK is parked low. */
-static void
-shift_srom_bits(softc_t *sc, u_int32_t data, u_int32_t len)
- {
- u_int32_t csr = READ_CSR(TLP_SROM_MII);
- for (; len>0; len--)
- { /* MSB first */
- if (data & (1<<(len-1)))
- csr |= TLP_SROM_DIN; /* DIN setup */
- else
- csr &= ~TLP_SROM_DIN; /* DIN setup */
- WRITE_CSR(TLP_SROM_MII, csr);
- csr |= TLP_SROM_CLK; /* CLK rising edge */
- WRITE_CSR(TLP_SROM_MII, csr);
- csr &= ~TLP_SROM_CLK; /* CLK falling edge */
- WRITE_CSR(TLP_SROM_MII, csr);
- }
- }
-
-/* Data is sampled on the RISING edge of CLK; CLK is parked low. */
-static u_int16_t
-read_srom(softc_t *sc, u_int8_t addr)
- {
- int i;
- u_int32_t csr;
- u_int16_t data;
-
- /* Enable SROM access. */
- csr = (TLP_SROM_SEL | TLP_SROM_RD | TLP_MII_MDOE);
- WRITE_CSR(TLP_SROM_MII, csr);
- /* CS rising edge prepares SROM for a new cycle. */
- csr |= TLP_SROM_CS;
- WRITE_CSR(TLP_SROM_MII, csr); /* assert CS */
- shift_srom_bits(sc, 6, 4); /* issue read cmd */
- shift_srom_bits(sc, addr, 6); /* issue address */
- for (data=0, i=16; i>=0; i--) /* read ->17<- bits of data */
- { /* MSB first */
- csr = READ_CSR(TLP_SROM_MII); /* DOUT sampled */
- data = (data<<1) | ((csr & TLP_SROM_DOUT) ? 1:0);
- csr |= TLP_SROM_CLK; /* CLK rising edge */
- WRITE_CSR(TLP_SROM_MII, csr);
- csr &= ~TLP_SROM_CLK; /* CLK falling edge */
- WRITE_CSR(TLP_SROM_MII, csr);
- }
- /* Disable SROM access. */
- WRITE_CSR(TLP_SROM_MII, TLP_MII_MDOE);
-
- return data;
- }
-
-/* The SROM is formatted by the mfgr and should NOT be written! */
-/* But lmcconfig can rewrite it in case it gets overwritten somehow. */
-/* IOCTL SYSCALL: can sleep. */
-static void
-write_srom(softc_t *sc, u_int8_t addr, u_int16_t data)
- {
- u_int32_t csr;
- int i;
-
- /* Enable SROM access. */
- csr = (TLP_SROM_SEL | TLP_SROM_RD | TLP_MII_MDOE);
- WRITE_CSR(TLP_SROM_MII, csr);
-
- /* Issue write-enable command. */
- csr |= TLP_SROM_CS;
- WRITE_CSR(TLP_SROM_MII, csr); /* assert CS */
- shift_srom_bits(sc, 4, 4); /* issue write enable cmd */
- shift_srom_bits(sc, 63, 6); /* issue address */
- csr &= ~TLP_SROM_CS;
- WRITE_CSR(TLP_SROM_MII, csr); /* deassert CS */
-
- /* Issue erase command. */
- csr |= TLP_SROM_CS;
- WRITE_CSR(TLP_SROM_MII, csr); /* assert CS */
- shift_srom_bits(sc, 7, 4); /* issue erase cmd */
- shift_srom_bits(sc, addr, 6); /* issue address */
- csr &= ~TLP_SROM_CS;
- WRITE_CSR(TLP_SROM_MII, csr); /* deassert CS */
-
- /* Issue write command. */
- csr |= TLP_SROM_CS;
- WRITE_CSR(TLP_SROM_MII, csr); /* assert CS */
- for (i=0; i<10; i++) /* 100 ms max wait */
- if ((READ_CSR(TLP_SROM_MII) & TLP_SROM_DOUT)==0) SLEEP(10000);
- shift_srom_bits(sc, 5, 4); /* issue write cmd */
- shift_srom_bits(sc, addr, 6); /* issue address */
- shift_srom_bits(sc, data, 16); /* issue data */
- csr &= ~TLP_SROM_CS;
- WRITE_CSR(TLP_SROM_MII, csr); /* deassert CS */
-
- /* Issue write-disable command. */
- csr |= TLP_SROM_CS;
- WRITE_CSR(TLP_SROM_MII, csr); /* assert CS */
- for (i=0; i<10; i++) /* 100 ms max wait */
- if ((READ_CSR(TLP_SROM_MII) & TLP_SROM_DOUT)==0) SLEEP(10000);
- shift_srom_bits(sc, 4, 4); /* issue write disable cmd */
- shift_srom_bits(sc, 0, 6); /* issue address */
- csr &= ~TLP_SROM_CS;
- WRITE_CSR(TLP_SROM_MII, csr); /* deassert CS */
-
- /* Disable SROM access. */
- WRITE_CSR(TLP_SROM_MII, TLP_MII_MDOE);
- }
-
-/* Not all boards have BIOS roms. */
-/* The BIOS ROM is an AMD 29F010 1Mbit (128K by 8) EEPROM. */
-static u_int8_t
-read_bios(softc_t *sc, u_int32_t addr)
- {
- u_int32_t srom_mii;
-
- /* Load the BIOS rom address register. */
- WRITE_CSR(TLP_BIOS_ROM, addr);
-
- /* Enable the BIOS rom. */
- srom_mii = TLP_BIOS_SEL | TLP_BIOS_RD | TLP_MII_MDOE;
- WRITE_CSR(TLP_SROM_MII, srom_mii);
-
- /* Wait at least 20 PCI cycles. */
- DELAY(20);
-
- /* Read the BIOS rom data. */
- srom_mii = READ_CSR(TLP_SROM_MII);
-
- /* Disable the BIOS rom. */
- WRITE_CSR(TLP_SROM_MII, TLP_MII_MDOE);
-
- return (u_int8_t)srom_mii & 0xFF;
- }
-
-static void
-write_bios_phys(softc_t *sc, u_int32_t addr, u_int8_t data)
- {
- u_int32_t srom_mii;
-
- /* Load the BIOS rom address register. */
- WRITE_CSR(TLP_BIOS_ROM, addr);
-
- /* Enable the BIOS rom. */
- srom_mii = TLP_BIOS_SEL | TLP_BIOS_WR | TLP_MII_MDOE;
-
- /* Load the data into the data register. */
- srom_mii = (srom_mii & 0xFFFFFF00) | (data & 0xFF);
- WRITE_CSR(TLP_SROM_MII, srom_mii);
-
- /* Wait at least 20 PCI cycles. */
- DELAY(20);
-
- /* Disable the BIOS rom. */
- WRITE_CSR(TLP_SROM_MII, TLP_MII_MDOE);
- }
-
-/* IOCTL SYSCALL: can sleep. */
-static void
-write_bios(softc_t *sc, u_int32_t addr, u_int8_t data)
- {
- u_int8_t read_data;
-
- /* this sequence enables writing */
- write_bios_phys(sc, 0x5555, 0xAA);
- write_bios_phys(sc, 0x2AAA, 0x55);
- write_bios_phys(sc, 0x5555, 0xA0);
- write_bios_phys(sc, addr, data);
-
- /* Wait for the write operation to complete. */
- for (;;) /* interruptable syscall */
- {
- for (;;)
- {
- read_data = read_bios(sc, addr);
- if ((read_data & 0x80) == (data & 0x80)) break;
- if (read_data & 0x20)
- { /* Data sheet says read it again. */
- read_data = read_bios(sc, addr);
- if ((read_data & 0x80) == (data & 0x80)) break;
- if (DRIVER_DEBUG)
- printf("%s: write_bios() failed; rom addr=0x%x\n",
- NAME_UNIT, addr);
- return;
- }
- }
- read_data = read_bios(sc, addr);
- if (read_data == data) break;
- }
- }
-
-/* IOCTL SYSCALL: can sleep. */
-static void
-erase_bios(softc_t *sc)
- {
- unsigned char read_data;
-
- /* This sequence enables erasing: */
- write_bios_phys(sc, 0x5555, 0xAA);
- write_bios_phys(sc, 0x2AAA, 0x55);
- write_bios_phys(sc, 0x5555, 0x80);
- write_bios_phys(sc, 0x5555, 0xAA);
- write_bios_phys(sc, 0x2AAA, 0x55);
- write_bios_phys(sc, 0x5555, 0x10);
-
- /* Wait for the erase operation to complete. */
- for (;;) /* interruptable syscall */
- {
- for (;;)
- {
- read_data = read_bios(sc, 0);
- if (read_data & 0x80) break;
- if (read_data & 0x20)
- { /* Data sheet says read it again. */
- read_data = read_bios(sc, 0);
- if (read_data & 0x80) break;
- if (DRIVER_DEBUG)
- printf("%s: erase_bios() failed\n", NAME_UNIT);
- return;
- }
- }
- read_data = read_bios(sc, 0);
- if (read_data == 0xFF) break;
- }
- }
-
-/* MDIO is 3-stated between tranactions. */
-/* MDIO is set up before the RISING edge of MDC; MDC is parked low. */
-static void
-shift_mii_bits(softc_t *sc, u_int32_t data, u_int32_t len)
- {
- u_int32_t csr = READ_CSR(TLP_SROM_MII);
- for (; len>0; len--)
- { /* MSB first */
- if (data & (1<<(len-1)))
- csr |= TLP_MII_MDOUT; /* MDOUT setup */
- else
- csr &= ~TLP_MII_MDOUT; /* MDOUT setup */
- WRITE_CSR(TLP_SROM_MII, csr);
- csr |= TLP_MII_MDC; /* MDC rising edge */
- WRITE_CSR(TLP_SROM_MII, csr);
- csr &= ~TLP_MII_MDC; /* MDC falling edge */
- WRITE_CSR(TLP_SROM_MII, csr);
- }
- }
-
-/* The specification for the MII is IEEE Std 802.3 clause 22. */
-/* MDIO is sampled on the RISING edge of MDC; MDC is parked low. */
-static u_int16_t
-read_mii(softc_t *sc, u_int8_t regad)
- {
- int i;
- u_int32_t csr;
- u_int16_t data = 0;
-
- WRITE_CSR(TLP_SROM_MII, TLP_MII_MDOUT);
-
- shift_mii_bits(sc, 0xFFFFF, 20); /* preamble */
- shift_mii_bits(sc, 0xFFFFF, 20); /* preamble */
- shift_mii_bits(sc, 1, 2); /* start symbol */
- shift_mii_bits(sc, 2, 2); /* read op */
- shift_mii_bits(sc, 0, 5); /* phyad=0 */
- shift_mii_bits(sc, regad, 5); /* regad */
- csr = READ_CSR(TLP_SROM_MII);
- csr |= TLP_MII_MDOE;
- WRITE_CSR(TLP_SROM_MII, csr);
- shift_mii_bits(sc, 0, 2); /* turn-around */
- for (i=15; i>=0; i--) /* data */
- { /* MSB first */
- csr = READ_CSR(TLP_SROM_MII); /* MDIN sampled */
- data = (data<<1) | ((csr & TLP_MII_MDIN) ? 1:0);
- csr |= TLP_MII_MDC; /* MDC rising edge */
- WRITE_CSR(TLP_SROM_MII, csr);
- csr &= ~TLP_MII_MDC; /* MDC falling edge */
- WRITE_CSR(TLP_SROM_MII, csr);
- }
- return data;
- }
-
-static void
-write_mii(softc_t *sc, u_int8_t regad, u_int16_t data)
- {
- WRITE_CSR(TLP_SROM_MII, TLP_MII_MDOUT);
- shift_mii_bits(sc, 0xFFFFF, 20); /* preamble */
- shift_mii_bits(sc, 0xFFFFF, 20); /* preamble */
- shift_mii_bits(sc, 1, 2); /* start symbol */
- shift_mii_bits(sc, 1, 2); /* write op */
- shift_mii_bits(sc, 0, 5); /* phyad=0 */
- shift_mii_bits(sc, regad, 5); /* regad */
- shift_mii_bits(sc, 2, 2); /* turn-around */
- shift_mii_bits(sc, data, 16); /* data */
- WRITE_CSR(TLP_SROM_MII, TLP_MII_MDOE);
- if (regad == 16) sc->led_state = data; /* a small optimization */
- }
-
-static void
-set_mii16_bits(softc_t *sc, u_int16_t bits)
- {
- u_int16_t mii16 = read_mii(sc, 16);
- mii16 |= bits;
- write_mii(sc, 16, mii16);
- }
-
-static void
-clr_mii16_bits(softc_t *sc, u_int16_t bits)
- {
- u_int16_t mii16 = read_mii(sc, 16);
- mii16 &= ~bits;
- write_mii(sc, 16, mii16);
- }
-
-static void
-set_mii17_bits(softc_t *sc, u_int16_t bits)
- {
- u_int16_t mii17 = read_mii(sc, 17);
- mii17 |= bits;
- write_mii(sc, 17, mii17);
- }
-
-static void
-clr_mii17_bits(softc_t *sc, u_int16_t bits)
- {
- u_int16_t mii17 = read_mii(sc, 17);
- mii17 &= ~bits;
- write_mii(sc, 17, mii17);
- }
-
-/*
- * Watchdog code is more readable if it refreshes LEDs
- * once a second whether they need it or not.
- * But MII refs take 150 uSecs each, so remember the last value
- * written to MII16 and avoid LED writes that do nothing.
- */
-
-static void
-led_off(softc_t *sc, u_int16_t led)
- {
- if ((led & sc->led_state) == led) return;
- set_mii16_bits(sc, led);
- }
-
-static void
-led_on(softc_t *sc, u_int16_t led)
- {
- if ((led & sc->led_state) == 0) return;
- clr_mii16_bits(sc, led);
- }
-
-static void
-led_inv(softc_t *sc, u_int16_t led)
- {
- u_int16_t mii16 = read_mii(sc, 16);
- mii16 ^= led;
- write_mii(sc, 16, mii16);
- }
-
-/*
- * T1 & T3 framer registers are accessed through MII regs 17 & 18.
- * Write the address to MII reg 17 then R/W data through MII reg 18.
- * The hardware interface is an Intel-style 8-bit muxed A/D bus.
- */
-static void
-write_framer(softc_t *sc, u_int16_t addr, u_int8_t data)
- {
- write_mii(sc, 17, addr);
- write_mii(sc, 18, data);
- }
-
-static u_int8_t
-read_framer(softc_t *sc, u_int16_t addr)
- {
- write_mii(sc, 17, addr);
- return (u_int8_t)read_mii(sc, 18);
- }
-
-/* Tulip's hardware implementation of General Purpose IO
- * (GPIO) pins makes life difficult for software.
- * Bits 7-0 in the Tulip GPIO CSR are used for two purposes
- * depending on the state of bit 8.
- * If bit 8 is 0 then bits 7-0 are "data" bits.
- * If bit 8 is 1 then bits 7-0 are "direction" bits.
- * If a direction bit is one, the data bit is an output.
- * The problem is that the direction bits are WRITE-ONLY.
- * Software must remember the direction bits in a shadow copy.
- * (sc->gpio_dir) in order to change some but not all of the bits.
- * All accesses to the Tulip GPIO register use these five procedures.
- */
-
-static void
-make_gpio_input(softc_t *sc, u_int32_t bits)
- {
- sc->gpio_dir &= ~bits;
- WRITE_CSR(TLP_GPIO, TLP_GPIO_DIR | (sc->gpio_dir));
- }
-
-static void
-make_gpio_output(softc_t *sc, u_int32_t bits)
- {
- sc->gpio_dir |= bits;
- WRITE_CSR(TLP_GPIO, TLP_GPIO_DIR | (sc->gpio_dir));
- }
-
-static u_int32_t
-read_gpio(softc_t *sc)
- {
- return READ_CSR(TLP_GPIO);
- }
-
-static void
-set_gpio_bits(softc_t *sc, u_int32_t bits)
- {
- WRITE_CSR(TLP_GPIO, (read_gpio(sc) | bits) & 0xFF);
- }
-
-static void
-clr_gpio_bits(softc_t *sc, u_int32_t bits)
- {
- WRITE_CSR(TLP_GPIO, (read_gpio(sc) & ~bits) & 0xFF);
- }
-
-/* Reset ALL of the flip-flops in the gate array to zero. */
-/* This does NOT change the gate array programming. */
-/* Called during initialization so it must not sleep. */
-static void
-reset_xilinx(softc_t *sc)
- {
- /* Drive RESET low to force initialization. */
- clr_gpio_bits(sc, GPIO_RESET);
- make_gpio_output(sc, GPIO_RESET);
-
- /* Hold RESET low for more than 10 uSec. */
- DELAY(50);
-
- /* Done with RESET; make it an input. */
- make_gpio_input(sc, GPIO_RESET);
- }
-
-/* Load Xilinx gate array program from on-board rom. */
-/* This changes the gate array programming. */
-/* IOCTL SYSCALL: can sleep. */
-static void
-load_xilinx_from_rom(softc_t *sc)
- {
- int i;
-
- /* Drive MODE low to load from ROM rather than GPIO. */
- clr_gpio_bits(sc, GPIO_MODE);
- make_gpio_output(sc, GPIO_MODE);
-
- /* Drive DP & RESET low to force configuration. */
- clr_gpio_bits(sc, GPIO_RESET | GPIO_DP);
- make_gpio_output(sc, GPIO_RESET | GPIO_DP);
-
- /* Hold RESET & DP low for more than 10 uSec. */
- DELAY(50);
-
- /* Done with RESET & DP; make them inputs. */
- make_gpio_input(sc, GPIO_DP | GPIO_RESET);
-
- /* BUSY-WAIT for Xilinx chip to configure itself from ROM bits. */
- for (i=0; i<100; i++) /* 1 sec max delay */
- if ((read_gpio(sc) & GPIO_DP) == 0) SLEEP(10000);
-
- /* Done with MODE; make it an input. */
- make_gpio_input(sc, GPIO_MODE);
- }
-
-/* Load the Xilinx gate array program from userland bits. */
-/* This changes the gate array programming. */
-/* IOCTL SYSCALL: can sleep. */
-static int
-load_xilinx_from_file(softc_t *sc, char *addr, u_int32_t len)
- {
- char *data;
- int i, j, error;
-
- /* Get some pages to hold the Xilinx bits; biggest file is < 6 KB. */
- if (len > 8192) return EFBIG; /* too big */
- data = malloc(len, M_DEVBUF, M_WAITOK);
- if (data == NULL) return ENOMEM;
-
- /* Copy the Xilinx bits from userland. */
- if ((error = copyin(addr, data, len)))
- {
- free(data, M_DEVBUF);
- return error;
- }
-
- /* Drive MODE high to load from GPIO rather than ROM. */
- set_gpio_bits(sc, GPIO_MODE);
- make_gpio_output(sc, GPIO_MODE);
-
- /* Drive DP & RESET low to force configuration. */
- clr_gpio_bits(sc, GPIO_RESET | GPIO_DP);
- make_gpio_output(sc, GPIO_RESET | GPIO_DP);
-
- /* Hold RESET & DP low for more than 10 uSec. */
- DELAY(50);
-
- /* Done with RESET & DP; make them inputs. */
- make_gpio_input(sc, GPIO_RESET | GPIO_DP);
-
- /* BUSY-WAIT for Xilinx chip to clear its config memory. */
- make_gpio_input(sc, GPIO_INIT);
- for (i=0; i<10000; i++) /* 1 sec max delay */
- if ((read_gpio(sc) & GPIO_INIT)==0) SLEEP(10000);
-
- /* Configure CLK and DATA as outputs. */
- set_gpio_bits(sc, GPIO_CLK); /* park CLK high */
- make_gpio_output(sc, GPIO_CLK | GPIO_DATA);
-
- /* Write bits to Xilinx; CLK is parked HIGH. */
- /* DATA is set up before the RISING edge of CLK. */
- for (i=0; i<len; i++)
- for (j=0; j<8; j++)
- { /* LSB first */
- if ((data[i] & (1<<j)) != 0)
- set_gpio_bits(sc, GPIO_DATA); /* DATA setup */
- else
- clr_gpio_bits(sc, GPIO_DATA); /* DATA setup */
- clr_gpio_bits(sc, GPIO_CLK); /* CLK falling edge */
- set_gpio_bits(sc, GPIO_CLK); /* CLK rising edge */
- }
-
- /* Stop driving all Xilinx-related signals. */
- /* Pullup and pulldown resistors take over. */
- make_gpio_input(sc, GPIO_CLK | GPIO_DATA | GPIO_MODE);
-
- free(data, M_DEVBUF);
- return 0;
- }
-
-/* Write fragments of a command into the synthesized oscillator. */
-/* DATA is set up before the RISING edge of CLK. CLK is parked low. */
-static void
-shift_synth_bits(softc_t *sc, u_int32_t data, u_int32_t len)
- {
- int i;
-
- for (i=0; i<len; i++)
- { /* LSB first */
- if ((data & (1<<i)) != 0)
- set_gpio_bits(sc, GPIO_DATA); /* DATA setup */
- else
- clr_gpio_bits(sc, GPIO_DATA); /* DATA setup */
- set_gpio_bits(sc, GPIO_CLK); /* CLK rising edge */
- clr_gpio_bits(sc, GPIO_CLK); /* CLK falling edge */
- }
- }
-
-/* Write a command to the synthesized oscillator on SSI and HSSIc. */
-static void
-write_synth(softc_t *sc, struct synth *synth)
- {
- /* SSI cards have a programmable prescaler */
- if (sc->status.card_type == TLP_CSID_SSI)
- {
- if (synth->prescale == 9) /* divide by 512 */
- set_mii17_bits(sc, MII17_SSI_PRESCALE);
- else /* divide by 32 */
- clr_mii17_bits(sc, MII17_SSI_PRESCALE);
- }
-
- clr_gpio_bits(sc, GPIO_DATA | GPIO_CLK);
- make_gpio_output(sc, GPIO_DATA | GPIO_CLK);
-
- /* SYNTH is a low-true chip enable for the AV9110 chip. */
- set_gpio_bits(sc, GPIO_SSI_SYNTH);
- make_gpio_output(sc, GPIO_SSI_SYNTH);
- clr_gpio_bits(sc, GPIO_SSI_SYNTH);
-
- /* Serially shift the command into the AV9110 chip. */
- shift_synth_bits(sc, synth->n, 7);
- shift_synth_bits(sc, synth->m, 7);
- shift_synth_bits(sc, synth->v, 1);
- shift_synth_bits(sc, synth->x, 2);
- shift_synth_bits(sc, synth->r, 2);
- shift_synth_bits(sc, 0x16, 5); /* enable clk/x output */
-
- /* SYNTH (chip enable) going high ends the command. */
- set_gpio_bits(sc, GPIO_SSI_SYNTH);
- make_gpio_input(sc, GPIO_SSI_SYNTH);
-
- /* Stop driving serial-related signals; pullups/pulldowns take over. */
- make_gpio_input(sc, GPIO_DATA | GPIO_CLK);
-
- /* remember the new synthesizer parameters */
- if (&sc->config.synth != synth) sc->config.synth = *synth;
- }
-
-/* Write a command to the DAC controlling the VCXO on some T3 adapters. */
-/* The DAC is a TI-TLV5636: 12-bit resolution and a serial interface. */
-/* DATA is set up before the FALLING edge of CLK. CLK is parked HIGH. */
-static void
-write_dac(softc_t *sc, u_int16_t data)
- {
- int i;
-
- /* Prepare to use DATA and CLK. */
- set_gpio_bits(sc, GPIO_DATA | GPIO_CLK);
- make_gpio_output(sc, GPIO_DATA | GPIO_CLK);
-
- /* High-to-low transition prepares DAC for new value. */
- set_gpio_bits(sc, GPIO_T3_DAC);
- make_gpio_output(sc, GPIO_T3_DAC);
- clr_gpio_bits(sc, GPIO_T3_DAC);
-
- /* Serially shift command bits into DAC. */
- for (i=0; i<16; i++)
- { /* MSB first */
- if ((data & (1<<(15-i))) != 0)
- set_gpio_bits(sc, GPIO_DATA); /* DATA setup */
- else
- clr_gpio_bits(sc, GPIO_DATA); /* DATA setup */
- clr_gpio_bits(sc, GPIO_CLK); /* CLK falling edge */
- set_gpio_bits(sc, GPIO_CLK); /* CLK rising edge */
- }
-
- /* Done with DAC; make it an input; loads new value into DAC. */
- set_gpio_bits(sc, GPIO_T3_DAC);
- make_gpio_input(sc, GPIO_T3_DAC);
-
- /* Stop driving serial-related signals; pullups/pulldowns take over. */
- make_gpio_input(sc, GPIO_DATA | GPIO_CLK);
- }
-
-/* begin HSSI card code */
-
-/* Must not sleep. */
-static void
-hssi_config(softc_t *sc)
- {
- if (sc->status.card_type == 0)
- { /* defaults */
- sc->status.card_type = READ_PCI_CFG(sc, TLP_CSID);
- sc->config.crc_len = CFG_CRC_16;
- sc->config.loop_back = CFG_LOOP_NONE;
- sc->config.tx_clk_src = CFG_CLKMUX_ST;
- sc->config.dte_dce = CFG_DTE;
- sc->config.synth.n = 52; /* 52.000 Mbs */
- sc->config.synth.m = 5;
- sc->config.synth.v = 0;
- sc->config.synth.x = 0;
- sc->config.synth.r = 0;
- sc->config.synth.prescale = 2;
- }
-
- /* set CRC length */
- if (sc->config.crc_len == CFG_CRC_32)
- set_mii16_bits(sc, MII16_HSSI_CRC32);
- else
- clr_mii16_bits(sc, MII16_HSSI_CRC32);
-
- /* Assert pin LA in HSSI conn: ask modem for local loop. */
- if (sc->config.loop_back == CFG_LOOP_LL)
- set_mii16_bits(sc, MII16_HSSI_LA);
- else
- clr_mii16_bits(sc, MII16_HSSI_LA);
-
- /* Assert pin LB in HSSI conn: ask modem for remote loop. */
- if (sc->config.loop_back == CFG_LOOP_RL)
- set_mii16_bits(sc, MII16_HSSI_LB);
- else
- clr_mii16_bits(sc, MII16_HSSI_LB);
-
- if (sc->status.card_type == TLP_CSID_HSSI)
- {
- /* set TXCLK src */
- if (sc->config.tx_clk_src == CFG_CLKMUX_ST)
- set_gpio_bits(sc, GPIO_HSSI_TXCLK);
- else
- clr_gpio_bits(sc, GPIO_HSSI_TXCLK);
- make_gpio_output(sc, GPIO_HSSI_TXCLK);
- }
- else if (sc->status.card_type == TLP_CSID_HSSIc)
- { /* cPCI HSSI rev C has extra features */
- /* Set TXCLK source. */
- u_int16_t mii16 = read_mii(sc, 16);
- mii16 &= ~MII16_HSSI_CLKMUX;
- mii16 |= (sc->config.tx_clk_src&3)<<13;
- write_mii(sc, 16, mii16);
-
- /* cPCI HSSI implements loopback towards the net. */
- if (sc->config.loop_back == CFG_LOOP_LINE)
- set_mii16_bits(sc, MII16_HSSI_LOOP);
- else
- clr_mii16_bits(sc, MII16_HSSI_LOOP);
-
- /* Set DTE/DCE mode. */
- if (sc->config.dte_dce == CFG_DCE)
- set_gpio_bits(sc, GPIO_HSSI_DCE);
- else
- clr_gpio_bits(sc, GPIO_HSSI_DCE);
- make_gpio_output(sc, GPIO_HSSI_DCE);
-
- /* Program the synthesized oscillator. */
- write_synth(sc, &sc->config.synth);
- }
- }
-
-static void
-hssi_ident(softc_t *sc)
- {
- }
-
-/* Called once a second; must not sleep. */
-static int
-hssi_watchdog(softc_t *sc)
- {
- u_int16_t mii16 = read_mii(sc, 16) & MII16_HSSI_MODEM;
- int link_status = STATUS_UP;
-
- led_inv(sc, MII16_HSSI_LED_UL); /* Software is alive. */
- led_on(sc, MII16_HSSI_LED_LL); /* always on (SSI cable) */
-
- /* Check the transmit clock. */
- if (sc->status.tx_speed == 0)
- {
- led_on(sc, MII16_HSSI_LED_UR);
- link_status = STATUS_DOWN;
- }
- else
- led_off(sc, MII16_HSSI_LED_UR);
-
- /* Is the modem ready? */
- if ((mii16 & MII16_HSSI_CA) == 0)
- {
- led_off(sc, MII16_HSSI_LED_LR);
- link_status = STATUS_DOWN;
- }
- else
- led_on(sc, MII16_HSSI_LED_LR);
-
- /* Print the modem control signals if they changed. */
- if ((DRIVER_DEBUG) && (mii16 != sc->last_mii16))
- {
- char *on = "ON ", *off = "OFF";
- printf("%s: TA=%s CA=%s LA=%s LB=%s LC=%s TM=%s\n", NAME_UNIT,
- (mii16 & MII16_HSSI_TA) ? on : off,
- (mii16 & MII16_HSSI_CA) ? on : off,
- (mii16 & MII16_HSSI_LA) ? on : off,
- (mii16 & MII16_HSSI_LB) ? on : off,
- (mii16 & MII16_HSSI_LC) ? on : off,
- (mii16 & MII16_HSSI_TM) ? on : off);
- }
-
- /* SNMP one-second-report */
- sc->status.snmp.hssi.sigs = mii16 & MII16_HSSI_MODEM;
-
- /* Remember this state until next time. */
- sc->last_mii16 = mii16;
-
- /* If a loop back is in effect, link status is UP */
- if (sc->config.loop_back != CFG_LOOP_NONE)
- link_status = STATUS_UP;
-
- return link_status;
- }
-
-/* IOCTL SYSCALL: can sleep (but doesn't). */
-static int
-hssi_ioctl(softc_t *sc, struct ioctl *ioctl)
- {
- int error = 0;
-
- if (ioctl->cmd == IOCTL_SNMP_SIGS)
- {
- u_int16_t mii16 = read_mii(sc, 16);
- mii16 &= ~MII16_HSSI_MODEM;
- mii16 |= (MII16_HSSI_MODEM & ioctl->data);
- write_mii(sc, 16, mii16);
- }
- else if (ioctl->cmd == IOCTL_SET_STATUS)
- {
- if (ioctl->data != 0)
- set_mii16_bits(sc, MII16_HSSI_TA);
- else
- clr_mii16_bits(sc, MII16_HSSI_TA);
- }
- else
- error = EINVAL;
-
- return error;
- }
-
-/* begin DS3 card code */
-
-/* Must not sleep. */
-static void
-t3_config(softc_t *sc)
- {
- int i;
- u_int8_t ctl1;
-
- if (sc->status.card_type == 0)
- { /* defaults */
- sc->status.card_type = TLP_CSID_T3;
- sc->config.crc_len = CFG_CRC_16;
- sc->config.loop_back = CFG_LOOP_NONE;
- sc->config.format = CFG_FORMAT_T3CPAR;
- sc->config.cable_len = 10; /* meters */
- sc->config.scrambler = CFG_SCRAM_DL_KEN;
- sc->config.tx_clk_src = CFG_CLKMUX_INT;
-
- /* Center the VCXO -- get within 20 PPM of 44736000. */
- write_dac(sc, 0x9002); /* set Vref = 2.048 volts */
- write_dac(sc, 2048); /* range is 0..4095 */
- }
-
- /* Set cable length. */
- if (sc->config.cable_len > 30)
- clr_mii16_bits(sc, MII16_DS3_ZERO);
- else
- set_mii16_bits(sc, MII16_DS3_ZERO);
-
- /* Set payload scrambler polynomial. */
- if (sc->config.scrambler == CFG_SCRAM_LARS)
- set_mii16_bits(sc, MII16_DS3_POLY);
- else
- clr_mii16_bits(sc, MII16_DS3_POLY);
-
- /* Set payload scrambler on/off. */
- if (sc->config.scrambler == CFG_SCRAM_OFF)
- clr_mii16_bits(sc, MII16_DS3_SCRAM);
- else
- set_mii16_bits(sc, MII16_DS3_SCRAM);
-
- /* Set CRC length. */
- if (sc->config.crc_len == CFG_CRC_32)
- set_mii16_bits(sc, MII16_DS3_CRC32);
- else
- clr_mii16_bits(sc, MII16_DS3_CRC32);
-
- /* Loopback towards host thru the line interface. */
- if (sc->config.loop_back == CFG_LOOP_OTHER)
- set_mii16_bits(sc, MII16_DS3_TRLBK);
- else
- clr_mii16_bits(sc, MII16_DS3_TRLBK);
-
- /* Loopback towards network thru the line interface. */
- if (sc->config.loop_back == CFG_LOOP_LINE)
- set_mii16_bits(sc, MII16_DS3_LNLBK);
- else if (sc->config.loop_back == CFG_LOOP_DUAL)
- set_mii16_bits(sc, MII16_DS3_LNLBK);
- else
- clr_mii16_bits(sc, MII16_DS3_LNLBK);
-
- /* Configure T3 framer chip; write EVERY writeable register. */
- ctl1 = CTL1_SER | CTL1_XTX;
- if (sc->config.loop_back == CFG_LOOP_INWARD) ctl1 |= CTL1_3LOOP;
- if (sc->config.loop_back == CFG_LOOP_DUAL) ctl1 |= CTL1_3LOOP;
- if (sc->config.format == CFG_FORMAT_T3M13) ctl1 |= CTL1_M13MODE;
- write_framer(sc, T3CSR_CTL1, ctl1);
- write_framer(sc, T3CSR_TX_FEAC, CTL5_EMODE);
- write_framer(sc, T3CSR_CTL8, CTL8_FBEC);
- write_framer(sc, T3CSR_CTL12, CTL12_DLCB1 | CTL12_C21 | CTL12_MCB1);
- write_framer(sc, T3CSR_DBL_FEAC, 0);
- write_framer(sc, T3CSR_CTL14, CTL14_RGCEN | CTL14_TGCEN);
- write_framer(sc, T3CSR_INTEN, 0);
- write_framer(sc, T3CSR_CTL20, CTL20_CVEN);
-
- /* Clear error counters and latched error bits */
- /* that may have happened while initializing. */
- for (i=0; i<21; i++) read_framer(sc, i);
- }
-
-static void
-t3_ident(softc_t *sc)
- {
- printf(", TXC03401 rev B");
- }
-
-/* Called once a second; must not sleep. */
-static int
-t3_watchdog(softc_t *sc)
- {
- u_int16_t CV;
- u_int8_t CERR, PERR, MERR, FERR, FEBE;
- u_int8_t ctl1, stat16, feac;
- int link_status = STATUS_UP;
- u_int16_t mii16;
-
- /* Read the alarm registers. */
- ctl1 = read_framer(sc, T3CSR_CTL1);
- stat16 = read_framer(sc, T3CSR_STAT16);
- mii16 = read_mii(sc, 16);
-
- /* Always ignore the RTLOC alarm bit. */
- stat16 &= ~STAT16_RTLOC;
-
- /* Software is alive. */
- led_inv(sc, MII16_DS3_LED_GRN);
-
- /* Receiving Alarm Indication Signal (AIS). */
- if ((stat16 & STAT16_RAIS) != 0) /* receiving ais */
- led_on(sc, MII16_DS3_LED_BLU);
- else if (ctl1 & CTL1_TXAIS) /* sending ais */
- led_inv(sc, MII16_DS3_LED_BLU);
- else
- led_off(sc, MII16_DS3_LED_BLU);
-
- /* Receiving Remote Alarm Indication (RAI). */
- if ((stat16 & STAT16_XERR) != 0) /* receiving rai */
- led_on(sc, MII16_DS3_LED_YEL);
- else if ((ctl1 & CTL1_XTX) == 0) /* sending rai */
- led_inv(sc, MII16_DS3_LED_YEL);
- else
- led_off(sc, MII16_DS3_LED_YEL);
-
- /* If certain status bits are set then the link is 'down'. */
- /* The bad bits are: rxlos rxoof rxais rxidl xerr. */
- if ((stat16 & ~(STAT16_FEAC | STAT16_SEF)) != 0)
- link_status = STATUS_DOWN;
-
- /* Declare local Red Alarm if the link is down. */
- if (link_status == STATUS_DOWN)
- led_on(sc, MII16_DS3_LED_RED);
- else if (sc->loop_timer != 0) /* loopback is active */
- led_inv(sc, MII16_DS3_LED_RED);
- else
- led_off(sc, MII16_DS3_LED_RED);
-
- /* Print latched error bits if they changed. */
- if ((DRIVER_DEBUG) && ((stat16 & ~STAT16_FEAC) != sc->last_stat16))
- {
- char *on = "ON ", *off = "OFF";
- printf("%s: RLOS=%s ROOF=%s RAIS=%s RIDL=%s SEF=%s XERR=%s\n",
- NAME_UNIT,
- (stat16 & STAT16_RLOS) ? on : off,
- (stat16 & STAT16_ROOF) ? on : off,
- (stat16 & STAT16_RAIS) ? on : off,
- (stat16 & STAT16_RIDL) ? on : off,
- (stat16 & STAT16_SEF) ? on : off,
- (stat16 & STAT16_XERR) ? on : off);
- }
-
- /* Check and print error counters if non-zero. */
- CV = read_framer(sc, T3CSR_CVHI)<<8;
- CV += read_framer(sc, T3CSR_CVLO);
- PERR = read_framer(sc, T3CSR_PERR);
- CERR = read_framer(sc, T3CSR_CERR);
- FERR = read_framer(sc, T3CSR_FERR);
- MERR = read_framer(sc, T3CSR_MERR);
- FEBE = read_framer(sc, T3CSR_FEBE);
-
- /* CV is invalid during LOS. */
- if ((stat16 & STAT16_RLOS)!=0) CV = 0;
- /* CERR & FEBE are invalid in M13 mode */
- if (sc->config.format == CFG_FORMAT_T3M13) CERR = FEBE = 0;
- /* FEBE is invalid during AIS. */
- if ((stat16 & STAT16_RAIS)!=0) FEBE = 0;
- if (DRIVER_DEBUG && (CV || PERR || CERR || FERR || MERR || FEBE))
- printf("%s: CV=%u PERR=%u CERR=%u FERR=%u MERR=%u FEBE=%u\n",
- NAME_UNIT, CV, PERR, CERR, FERR, MERR, FEBE);
-
- /* Driver keeps crude link-level error counters (SNMP is better). */
- sc->status.cntrs.lcv_errs += CV;
- sc->status.cntrs.par_errs += PERR;
- sc->status.cntrs.cpar_errs += CERR;
- sc->status.cntrs.frm_errs += FERR;
- sc->status.cntrs.mfrm_errs += MERR;
- sc->status.cntrs.febe_errs += FEBE;
-
- /* Check for FEAC messages (FEAC not defined in M13 mode). */
- if (FORMAT_T3CPAR && (stat16 & STAT16_FEAC)) do
- {
- feac = read_framer(sc, T3CSR_FEAC_STK);
- if ((feac & FEAC_STK_VALID)==0) break;
- /* Ignore RxFEACs while a far end loopback has been requested. */
- if ((sc->status.snmp.t3.line & TLOOP_FAR_LINE)!=0) continue;
- switch (feac & FEAC_STK_FEAC)
- {
- case T3BOP_LINE_UP: break;
- case T3BOP_LINE_DOWN: break;
- case T3BOP_LOOP_DS3:
- {
- if (sc->last_FEAC == T3BOP_LINE_DOWN)
- {
- if (DRIVER_DEBUG)
- printf("%s: Received a 'line loopback deactivate' FEAC msg\n", NAME_UNIT);
- clr_mii16_bits(sc, MII16_DS3_LNLBK);
- sc->loop_timer = 0;
- }
- if (sc->last_FEAC == T3BOP_LINE_UP)
- {
- if (DRIVER_DEBUG)
- printf("%s: Received a 'line loopback activate' FEAC msg\n", NAME_UNIT);
- set_mii16_bits(sc, MII16_DS3_LNLBK);
- sc->loop_timer = 300;
- }
- break;
- }
- case T3BOP_OOF:
- {
- if (DRIVER_DEBUG)
- printf("%s: Received a 'far end LOF' FEAC msg\n", NAME_UNIT);
- break;
- }
- case T3BOP_IDLE:
- {
- if (DRIVER_DEBUG)
- printf("%s: Received a 'far end IDL' FEAC msg\n", NAME_UNIT);
- break;
- }
- case T3BOP_AIS:
- {
- if (DRIVER_DEBUG)
- printf("%s: Received a 'far end AIS' FEAC msg\n", NAME_UNIT);
- break;
- }
- case T3BOP_LOS:
- {
- if (DRIVER_DEBUG)
- printf("%s: Received a 'far end LOS' FEAC msg\n", NAME_UNIT);
- break;
- }
- default:
- {
- if (DRIVER_DEBUG)
- printf("%s: Received a 'type 0x%02X' FEAC msg\n", NAME_UNIT, feac & FEAC_STK_FEAC);
- break;
- }
- }
- sc->last_FEAC = feac & FEAC_STK_FEAC;
- } while ((feac & FEAC_STK_MORE) != 0);
- stat16 &= ~STAT16_FEAC;
-
- /* Send Service-Affecting priority FEAC messages */
- if (((sc->last_stat16 ^ stat16) & 0xF0) && (FORMAT_T3CPAR))
- {
- /* Transmit continuous FEACs */
- write_framer(sc, T3CSR_CTL14,
- read_framer(sc, T3CSR_CTL14) & ~CTL14_FEAC10);
- if ((stat16 & STAT16_RLOS)!=0)
- write_framer(sc, T3CSR_TX_FEAC, 0xC0 + T3BOP_LOS);
- else if ((stat16 & STAT16_ROOF)!=0)
- write_framer(sc, T3CSR_TX_FEAC, 0xC0 + T3BOP_OOF);
- else if ((stat16 & STAT16_RAIS)!=0)
- write_framer(sc, T3CSR_TX_FEAC, 0xC0 + T3BOP_AIS);
- else if ((stat16 & STAT16_RIDL)!=0)
- write_framer(sc, T3CSR_TX_FEAC, 0xC0 + T3BOP_IDLE);
- else
- write_framer(sc, T3CSR_TX_FEAC, CTL5_EMODE);
- }
-
- /* Start sending RAI, Remote Alarm Indication. */
- if (((stat16 & STAT16_ROOF)!=0) && ((stat16 & STAT16_RLOS)==0) &&
- ((sc->last_stat16 & STAT16_ROOF)==0))
- write_framer(sc, T3CSR_CTL1, ctl1 &= ~CTL1_XTX);
- /* Stop sending RAI, Remote Alarm Indication. */
- else if (((stat16 & STAT16_ROOF)==0) && ((sc->last_stat16 & STAT16_ROOF)!=0))
- write_framer(sc, T3CSR_CTL1, ctl1 |= CTL1_XTX);
-
- /* Start sending AIS, Alarm Indication Signal */
- if (((stat16 & STAT16_RLOS)!=0) && ((sc->last_stat16 & STAT16_RLOS)==0))
- {
- set_mii16_bits(sc, MII16_DS3_FRAME);
- write_framer(sc, T3CSR_CTL1, ctl1 | CTL1_TXAIS);
- }
- /* Stop sending AIS, Alarm Indication Signal */
- else if (((stat16 & STAT16_RLOS)==0) && ((sc->last_stat16 & STAT16_RLOS)!=0))
- {
- clr_mii16_bits(sc, MII16_DS3_FRAME);
- write_framer(sc, T3CSR_CTL1, ctl1 & ~CTL1_TXAIS);
- }
-
- /* Time out loopback requests. */
- if (sc->loop_timer != 0)
- if (--sc->loop_timer == 0)
- if ((mii16 & MII16_DS3_LNLBK)!=0)
- {
- if (DRIVER_DEBUG)
- printf("%s: Timeout: Loop Down after 300 seconds\n", NAME_UNIT);
- clr_mii16_bits(sc, MII16_DS3_LNLBK); /* line loopback off */
- }
-
- /* SNMP error counters */
- sc->status.snmp.t3.lcv = CV;
- sc->status.snmp.t3.pcv = PERR;
- sc->status.snmp.t3.ccv = CERR;
- sc->status.snmp.t3.febe = FEBE;
-
- /* SNMP Line Status */
- sc->status.snmp.t3.line = 0;
- if ((ctl1 & CTL1_XTX)==0) sc->status.snmp.t3.line |= TLINE_TX_RAI;
- if (stat16 & STAT16_XERR) sc->status.snmp.t3.line |= TLINE_RX_RAI;
- if (ctl1 & CTL1_TXAIS) sc->status.snmp.t3.line |= TLINE_TX_AIS;
- if (stat16 & STAT16_RAIS) sc->status.snmp.t3.line |= TLINE_RX_AIS;
- if (stat16 & STAT16_ROOF) sc->status.snmp.t3.line |= TLINE_LOF;
- if (stat16 & STAT16_RLOS) sc->status.snmp.t3.line |= TLINE_LOS;
- if (stat16 & STAT16_SEF) sc->status.snmp.t3.line |= T3LINE_SEF;
-
- /* SNMP Loopback Status */
- sc->status.snmp.t3.loop &= ~TLOOP_FAR_LINE;
- if (sc->config.loop_back == CFG_LOOP_TULIP)
- sc->status.snmp.t3.loop |= TLOOP_NEAR_OTHER;
- if (ctl1 & CTL1_3LOOP) sc->status.snmp.t3.loop |= TLOOP_NEAR_INWARD;
- if (mii16 & MII16_DS3_TRLBK) sc->status.snmp.t3.loop |= TLOOP_NEAR_OTHER;
- if (mii16 & MII16_DS3_LNLBK) sc->status.snmp.t3.loop |= TLOOP_NEAR_LINE;
-/*if (ctl12 & CTL12_RTPLOOP) sc->status.snmp.t3.loop |= TLOOP_NEAR_PAYLOAD; */
-
- /* Remember this state until next time. */
- sc->last_stat16 = stat16;
-
- /* If an INWARD loopback is in effect, link status is UP */
- if (sc->config.loop_back != CFG_LOOP_NONE) /* XXX INWARD ONLY */
- link_status = STATUS_UP;
-
- return link_status;
- }
-
-/* IOCTL SYSCALL: can sleep. */
-static void
-t3_send_dbl_feac(softc_t *sc, int feac1, int feac2)
- {
- u_int8_t tx_feac;
- int i;
-
- /* The FEAC transmitter could be sending a continuous */
- /* FEAC msg when told to send a double FEAC message. */
- /* So save the current state of the FEAC transmitter. */
- tx_feac = read_framer(sc, T3CSR_TX_FEAC);
- /* Load second FEAC code and stop FEAC transmitter. */
- write_framer(sc, T3CSR_TX_FEAC, CTL5_EMODE + feac2);
- /* FEAC transmitter sends 10 more FEACs and then stops. */
- SLEEP(20000); /* sending one FEAC takes 1700 uSecs */
- /* Load first FEAC code and start FEAC transmitter. */
- write_framer(sc, T3CSR_DBL_FEAC, CTL13_DFEXEC + feac1);
- /* Wait for double FEAC sequence to complete -- about 70 ms. */
- for (i=0; i<10; i++) /* max delay 100 ms */
- if (read_framer(sc, T3CSR_DBL_FEAC) & CTL13_DFEXEC) SLEEP(10000);
- /* Flush received FEACS; don't respond to our own loop cmd! */
- while (read_framer(sc, T3CSR_FEAC_STK) & FEAC_STK_VALID) DELAY(1); /* XXX HANG */
- /* Restore previous state of the FEAC transmitter. */
- /* If it was sending a continuous FEAC, it will resume. */
- write_framer(sc, T3CSR_TX_FEAC, tx_feac);
- }
-
-/* IOCTL SYSCALL: can sleep. */
-static int
-t3_ioctl(softc_t *sc, struct ioctl *ioctl)
- {
- int error = 0;
-
- switch (ioctl->cmd)
- {
- case IOCTL_SNMP_SEND: /* set opstatus? */
- {
- if (sc->config.format != CFG_FORMAT_T3CPAR)
- error = EINVAL;
- else if (ioctl->data == TSEND_LINE)
- {
- sc->status.snmp.t3.loop |= TLOOP_FAR_LINE;
- t3_send_dbl_feac(sc, T3BOP_LINE_UP, T3BOP_LOOP_DS3);
- }
- else if (ioctl->data == TSEND_RESET)
- {
- t3_send_dbl_feac(sc, T3BOP_LINE_DOWN, T3BOP_LOOP_DS3);
- sc->status.snmp.t3.loop &= ~TLOOP_FAR_LINE;
- }
- else
- error = EINVAL;
- break;
- }
- case IOCTL_SNMP_LOOP: /* set opstatus = test? */
- {
- if (ioctl->data == CFG_LOOP_NONE)
- {
- clr_mii16_bits(sc, MII16_DS3_FRAME);
- clr_mii16_bits(sc, MII16_DS3_TRLBK);
- clr_mii16_bits(sc, MII16_DS3_LNLBK);
- write_framer(sc, T3CSR_CTL1,
- read_framer(sc, T3CSR_CTL1) & ~CTL1_3LOOP);
- write_framer(sc, T3CSR_CTL12,
- read_framer(sc, T3CSR_CTL12) & ~(CTL12_RTPLOOP | CTL12_RTPLLEN));
- }
- else if (ioctl->data == CFG_LOOP_LINE)
- set_mii16_bits(sc, MII16_DS3_LNLBK);
- else if (ioctl->data == CFG_LOOP_OTHER)
- set_mii16_bits(sc, MII16_DS3_TRLBK);
- else if (ioctl->data == CFG_LOOP_INWARD)
- write_framer(sc, T3CSR_CTL1,
- read_framer(sc, T3CSR_CTL1) | CTL1_3LOOP);
- else if (ioctl->data == CFG_LOOP_DUAL)
- {
- set_mii16_bits(sc, MII16_DS3_LNLBK);
- write_framer(sc, T3CSR_CTL1,
- read_framer(sc, T3CSR_CTL1) | CTL1_3LOOP);
- }
- else if (ioctl->data == CFG_LOOP_PAYLOAD)
- {
- set_mii16_bits(sc, MII16_DS3_FRAME);
- write_framer(sc, T3CSR_CTL12,
- read_framer(sc, T3CSR_CTL12) | CTL12_RTPLOOP);
- write_framer(sc, T3CSR_CTL12,
- read_framer(sc, T3CSR_CTL12) | CTL12_RTPLLEN);
- DELAY(25); /* at least two frames (22 uS) */
- write_framer(sc, T3CSR_CTL12,
- read_framer(sc, T3CSR_CTL12) & ~CTL12_RTPLLEN);
- }
- else
- error = EINVAL;
- break;
- }
- default:
- error = EINVAL;
- break;
- }
-
- return error;
- }
-
-/* begin SSI card code */
-
-/* Must not sleep. */
-static void
-ssi_config(softc_t *sc)
- {
- if (sc->status.card_type == 0)
- { /* defaults */
- sc->status.card_type = TLP_CSID_SSI;
- sc->config.crc_len = CFG_CRC_16;
- sc->config.loop_back = CFG_LOOP_NONE;
- sc->config.tx_clk_src = CFG_CLKMUX_ST;
- sc->config.dte_dce = CFG_DTE;
- sc->config.synth.n = 51; /* 1.536 MHz */
- sc->config.synth.m = 83;
- sc->config.synth.v = 1;
- sc->config.synth.x = 1;
- sc->config.synth.r = 1;
- sc->config.synth.prescale = 4;
- }
-
- /* Disable the TX clock driver while programming the oscillator. */
- clr_gpio_bits(sc, GPIO_SSI_DCE);
- make_gpio_output(sc, GPIO_SSI_DCE);
-
- /* Program the synthesized oscillator. */
- write_synth(sc, &sc->config.synth);
-
- /* Set DTE/DCE mode. */
- /* If DTE mode then DCD & TXC are received. */
- /* If DCE mode then DCD & TXC are driven. */
- /* Boards with MII rev=4.0 don't drive DCD. */
- if (sc->config.dte_dce == CFG_DCE)
- set_gpio_bits(sc, GPIO_SSI_DCE);
- else
- clr_gpio_bits(sc, GPIO_SSI_DCE);
- make_gpio_output(sc, GPIO_SSI_DCE);
-
- /* Set CRC length. */
- if (sc->config.crc_len == CFG_CRC_32)
- set_mii16_bits(sc, MII16_SSI_CRC32);
- else
- clr_mii16_bits(sc, MII16_SSI_CRC32);
-
- /* Loop towards host thru cable drivers and receivers. */
- /* Asserts DCD at the far end of a null modem cable. */
- if (sc->config.loop_back == CFG_LOOP_PINS)
- set_mii16_bits(sc, MII16_SSI_LOOP);
- else
- clr_mii16_bits(sc, MII16_SSI_LOOP);
-
- /* Assert pin LL in modem conn: ask modem for local loop. */
- /* Asserts TM at the far end of a null modem cable. */
- if (sc->config.loop_back == CFG_LOOP_LL)
- set_mii16_bits(sc, MII16_SSI_LL);
- else
- clr_mii16_bits(sc, MII16_SSI_LL);
-
- /* Assert pin RL in modem conn: ask modem for remote loop. */
- if (sc->config.loop_back == CFG_LOOP_RL)
- set_mii16_bits(sc, MII16_SSI_RL);
- else
- clr_mii16_bits(sc, MII16_SSI_RL);
- }
-
-static void
-ssi_ident(softc_t *sc)
- {
- printf(", LTC1343/44");
- }
-
-/* Called once a second; must not sleep. */
-static int
-ssi_watchdog(softc_t *sc)
- {
- u_int16_t cable;
- u_int16_t mii16 = read_mii(sc, 16) & MII16_SSI_MODEM;
- int link_status = STATUS_UP;
-
- /* Software is alive. */
- led_inv(sc, MII16_SSI_LED_UL);
-
- /* Check the transmit clock. */
- if (sc->status.tx_speed == 0)
- {
- led_on(sc, MII16_SSI_LED_UR);
- link_status = STATUS_DOWN;
- }
- else
- led_off(sc, MII16_SSI_LED_UR);
-
- /* Check the external cable. */
- cable = read_mii(sc, 17);
- cable = cable & MII17_SSI_CABLE_MASK;
- cable = cable >> MII17_SSI_CABLE_SHIFT;
- if (cable == 7)
- {
- led_off(sc, MII16_SSI_LED_LL); /* no cable */
- link_status = STATUS_DOWN;
- }
- else
- led_on(sc, MII16_SSI_LED_LL);
-
- /* The unit at the other end of the cable is ready if: */
- /* DTE mode and DCD pin is asserted */
- /* DCE mode and DSR pin is asserted */
- if (((sc->config.dte_dce == CFG_DTE) && ((mii16 & MII16_SSI_DCD)==0)) ||
- ((sc->config.dte_dce == CFG_DCE) && ((mii16 & MII16_SSI_DSR)==0)))
- {
- led_off(sc, MII16_SSI_LED_LR);
- link_status = STATUS_DOWN;
- }
- else
- led_on(sc, MII16_SSI_LED_LR);
-
- if (DRIVER_DEBUG && (cable != sc->status.cable_type))
- printf("%s: SSI cable type changed to '%s'\n",
- NAME_UNIT, ssi_cables[cable]);
- sc->status.cable_type = cable;
-
- /* Print the modem control signals if they changed. */
- if ((DRIVER_DEBUG) && (mii16 != sc->last_mii16))
- {
- char *on = "ON ", *off = "OFF";
- printf("%s: DTR=%s DSR=%s RTS=%s CTS=%s DCD=%s RI=%s LL=%s RL=%s TM=%s\n",
- NAME_UNIT,
- (mii16 & MII16_SSI_DTR) ? on : off,
- (mii16 & MII16_SSI_DSR) ? on : off,
- (mii16 & MII16_SSI_RTS) ? on : off,
- (mii16 & MII16_SSI_CTS) ? on : off,
- (mii16 & MII16_SSI_DCD) ? on : off,
- (mii16 & MII16_SSI_RI) ? on : off,
- (mii16 & MII16_SSI_LL) ? on : off,
- (mii16 & MII16_SSI_RL) ? on : off,
- (mii16 & MII16_SSI_TM) ? on : off);
- }
-
- /* SNMP one-second report */
- sc->status.snmp.ssi.sigs = mii16 & MII16_SSI_MODEM;
-
- /* Remember this state until next time. */
- sc->last_mii16 = mii16;
-
- /* If a loop back is in effect, link status is UP */
- if (sc->config.loop_back != CFG_LOOP_NONE)
- link_status = STATUS_UP;
-
- return link_status;
- }
-
-/* IOCTL SYSCALL: can sleep (but doesn't). */
-static int
-ssi_ioctl(softc_t *sc, struct ioctl *ioctl)
- {
- int error = 0;
-
- if (ioctl->cmd == IOCTL_SNMP_SIGS)
- {
- u_int16_t mii16 = read_mii(sc, 16);
- mii16 &= ~MII16_SSI_MODEM;
- mii16 |= (MII16_SSI_MODEM & ioctl->data);
- write_mii(sc, 16, mii16);
- }
- else if (ioctl->cmd == IOCTL_SET_STATUS)
- {
- if (ioctl->data != 0)
- set_mii16_bits(sc, (MII16_SSI_DTR | MII16_SSI_RTS | MII16_SSI_DCD));
- else
- clr_mii16_bits(sc, (MII16_SSI_DTR | MII16_SSI_RTS | MII16_SSI_DCD));
- }
- else
- error = EINVAL;
-
- return error;
- }
-
-/* begin T1E1 card code */
-
-/* Must not sleep. */
-static void
-t1_config(softc_t *sc)
- {
- int i;
- u_int8_t pulse, lbo, gain;
-
- if (sc->status.card_type == 0)
- { /* defaults */
- sc->status.card_type = TLP_CSID_T1E1;
- sc->config.crc_len = CFG_CRC_16;
- sc->config.loop_back = CFG_LOOP_NONE;
- sc->config.tx_clk_src = CFG_CLKMUX_INT;
- sc->config.format = CFG_FORMAT_T1ESF;
- sc->config.cable_len = 10;
- sc->config.time_slots = 0x01FFFFFE;
- sc->config.tx_pulse = CFG_PULSE_AUTO;
- sc->config.rx_gain = CFG_GAIN_AUTO;
- sc->config.tx_lbo = CFG_LBO_AUTO;
-
- /* Bt8370 occasionally powers up in a loopback mode. */
- /* Data sheet says zero LOOP reg and do a s/w reset. */
- write_framer(sc, Bt8370_LOOP, 0x00); /* no loopback */
- write_framer(sc, Bt8370_CR0, 0x80); /* s/w reset */
- for (i=0; i<10; i++) /* max delay 10 ms */
- if (read_framer(sc, Bt8370_CR0) & 0x80) DELAY(1000);
- }
-
- /* Set CRC length. */
- if (sc->config.crc_len == CFG_CRC_32)
- set_mii16_bits(sc, MII16_T1_CRC32);
- else
- clr_mii16_bits(sc, MII16_T1_CRC32);
-
- /* Invert HDLC payload data in SF/AMI mode. */
- /* HDLC stuff bits satisfy T1 pulse density. */
- if (FORMAT_T1SF)
- set_mii16_bits(sc, MII16_T1_INVERT);
- else
- clr_mii16_bits(sc, MII16_T1_INVERT);
-
- /* Set the transmitter output impedance. */
- if (FORMAT_E1ANY) set_mii16_bits(sc, MII16_T1_Z);
-
- /* 001:CR0 -- Control Register 0 - T1/E1 and frame format */
- write_framer(sc, Bt8370_CR0, sc->config.format);
-
- /* 002:JAT_CR -- Jitter Attenuator Control Register */
- if (sc->config.tx_clk_src == CFG_CLKMUX_RT) /* loop timing */
- write_framer(sc, Bt8370_JAT_CR, 0xA3); /* JAT in RX path */
- else
- { /* 64-bit elastic store; free-running JCLK and CLADO */
- write_framer(sc, Bt8370_JAT_CR, 0x4B); /* assert jcenter */
- write_framer(sc, Bt8370_JAT_CR, 0x43); /* release jcenter */
- }
-
- /* 00C-013:IERn -- Interrupt Enable Registers */
- for (i=Bt8370_IER7; i<=Bt8370_IER0; i++)
- write_framer(sc, i, 0); /* no interrupts; polled */
-
- /* 014:LOOP -- loopbacks */
- if (sc->config.loop_back == CFG_LOOP_PAYLOAD)
- write_framer(sc, Bt8370_LOOP, LOOP_PAYLOAD);
- else if (sc->config.loop_back == CFG_LOOP_LINE)
- write_framer(sc, Bt8370_LOOP, LOOP_LINE);
- else if (sc->config.loop_back == CFG_LOOP_OTHER)
- write_framer(sc, Bt8370_LOOP, LOOP_ANALOG);
- else if (sc->config.loop_back == CFG_LOOP_INWARD)
- write_framer(sc, Bt8370_LOOP, LOOP_FRAMER);
- else if (sc->config.loop_back == CFG_LOOP_DUAL)
- write_framer(sc, Bt8370_LOOP, LOOP_DUAL);
- else
- write_framer(sc, Bt8370_LOOP, 0x00); /* no loopback */
-
- /* 015:DL3_TS -- Data Link 3 */
- write_framer(sc, Bt8370_DL3_TS, 0x00); /* disabled */
-
- /* 018:PIO -- Programmable I/O */
- write_framer(sc, Bt8370_PIO, 0xFF); /* all pins are outputs */
-
- /* 019:POE -- Programmable Output Enable */
- write_framer(sc, Bt8370_POE, 0x00); /* all outputs are enabled */
-
- /* 01A;CMUX -- Clock Input Mux */
- if (sc->config.tx_clk_src == CFG_CLKMUX_EXT)
- write_framer(sc, Bt8370_CMUX, 0x0C); /* external timing */
- else
- write_framer(sc, Bt8370_CMUX, 0x0F); /* internal timing */
-
- /* 020:LIU_CR -- Line Interface Unit Config Register */
- write_framer(sc, Bt8370_LIU_CR, 0xC1); /* reset LIU, squelch */
-
- /* 022:RLIU_CR -- RX Line Interface Unit Config Reg */
- /* Errata sheet says don't use freeze-short, but we do anyway! */
- write_framer(sc, Bt8370_RLIU_CR, 0xB1); /* AGC=2048, Long Eye */
-
- /* Select Rx sensitivity based on cable length. */
- if ((gain = sc->config.rx_gain) == CFG_GAIN_AUTO)
- {
- if (sc->config.cable_len > 2000)
- gain = CFG_GAIN_EXTEND;
- else if (sc->config.cable_len > 1000)
- gain = CFG_GAIN_LONG;
- else if (sc->config.cable_len > 100)
- gain = CFG_GAIN_MEDIUM;
- else
- gain = CFG_GAIN_SHORT;
- }
-
- /* 024:VGA_MAX -- Variable Gain Amplifier Max gain */
- write_framer(sc, Bt8370_VGA_MAX, gain);
-
- /* 028:PRE_EQ -- Pre Equalizer */
- if (gain == CFG_GAIN_EXTEND)
- write_framer(sc, Bt8370_PRE_EQ, 0xE6); /* ON; thresh 6 */
- else
- write_framer(sc, Bt8370_PRE_EQ, 0xA6); /* OFF; thresh 6 */
-
- /* 038-03C:GAINn -- RX Equalizer gain thresholds */
- write_framer(sc, Bt8370_GAIN0, 0x24);
- write_framer(sc, Bt8370_GAIN1, 0x28);
- write_framer(sc, Bt8370_GAIN2, 0x2C);
- write_framer(sc, Bt8370_GAIN3, 0x30);
- write_framer(sc, Bt8370_GAIN4, 0x34);
-
- /* 040:RCR0 -- Receiver Control Register 0 */
- if (FORMAT_T1ESF)
- write_framer(sc, Bt8370_RCR0, 0x05); /* B8ZS, 2/5 FErrs */
- else if (FORMAT_T1SF)
- write_framer(sc, Bt8370_RCR0, 0x84); /* AMI, 2/5 FErrs */
- else if (FORMAT_E1NONE)
- write_framer(sc, Bt8370_RCR0, 0x41); /* HDB3, rabort */
- else if (FORMAT_E1CRC)
- write_framer(sc, Bt8370_RCR0, 0x09); /* HDB3, 3 FErrs or 915 CErrs */
- else /* E1 no CRC */
- write_framer(sc, Bt8370_RCR0, 0x19); /* HDB3, 3 FErrs */
-
- /* 041:RPATT -- Receive Test Pattern configuration */
- write_framer(sc, Bt8370_RPATT, 0x3E); /* looking for framed QRSS */
-
- /* 042:RLB -- Receive Loop Back code detector config */
- write_framer(sc, Bt8370_RLB, 0x09); /* 6 bits down; 5 bits up */
-
- /* 043:LBA -- Loop Back Activate code */
- write_framer(sc, Bt8370_LBA, 0x08); /* 10000 10000 10000 ... */
-
- /* 044:LBD -- Loop Back Deactivate code */
- write_framer(sc, Bt8370_LBD, 0x24); /* 100100 100100 100100 ... */
-
- /* 045:RALM -- Receive Alarm signal configuration */
- write_framer(sc, Bt8370_RALM, 0x0C); /* yel_intg rlof_intg */
-
- /* 046:LATCH -- Alarm/Error/Counter Latch register */
- write_framer(sc, Bt8370_LATCH, 0x1F); /* stop_cnt latch_{cnt,err,alm} */
-
- /* Select Pulse Shape based on cable length (T1 only). */
- if ((pulse = sc->config.tx_pulse) == CFG_PULSE_AUTO)
- {
- if (FORMAT_T1ANY)
- {
- if (sc->config.cable_len > 200)
- pulse = CFG_PULSE_T1CSU;
- else if (sc->config.cable_len > 160)
- pulse = CFG_PULSE_T1DSX4;
- else if (sc->config.cable_len > 120)
- pulse = CFG_PULSE_T1DSX3;
- else if (sc->config.cable_len > 80)
- pulse = CFG_PULSE_T1DSX2;
- else if (sc->config.cable_len > 40)
- pulse = CFG_PULSE_T1DSX1;
- else
- pulse = CFG_PULSE_T1DSX0;
- }
- else
- pulse = CFG_PULSE_E1TWIST;
- }
-
- /* Select Line Build Out based on cable length (T1CSU only). */
- if ((lbo = sc->config.tx_lbo) == CFG_LBO_AUTO)
- {
- if (pulse == CFG_PULSE_T1CSU)
- {
- if (sc->config.cable_len > 1500)
- lbo = CFG_LBO_0DB;
- else if (sc->config.cable_len > 1000)
- lbo = CFG_LBO_7DB;
- else if (sc->config.cable_len > 500)
- lbo = CFG_LBO_15DB;
- else
- lbo = CFG_LBO_22DB;
- }
- else
- lbo = 0;
- }
-
- /* 068:TLIU_CR -- Transmit LIU Control Register */
- write_framer(sc, Bt8370_TLIU_CR, (0x40 | (lbo & 0x30) | (pulse & 0x0E)));
-
- /* 070:TCR0 -- Transmit Framer Configuration */
- write_framer(sc, Bt8370_TCR0, sc->config.format>>1);
-
- /* 071:TCR1 -- Transmitter Configuration */
- if (FORMAT_T1SF)
- write_framer(sc, Bt8370_TCR1, 0x43); /* tabort, AMI PDV enforced */
- else
- write_framer(sc, Bt8370_TCR1, 0x41); /* tabort, B8ZS or HDB3 */
-
- /* 072:TFRM -- Transmit Frame format MYEL YEL MF FE CRC FBIT */
- if (sc->config.format == CFG_FORMAT_T1ESF)
- write_framer(sc, Bt8370_TFRM, 0x0B); /* - YEL MF - CRC FBIT */
- else if (sc->config.format == CFG_FORMAT_T1SF)
- write_framer(sc, Bt8370_TFRM, 0x19); /* - YEL MF - - FBIT */
- else if (sc->config.format == CFG_FORMAT_E1FAS)
- write_framer(sc, Bt8370_TFRM, 0x11); /* - YEL - - - FBIT */
- else if (sc->config.format == CFG_FORMAT_E1FASCRC)
- write_framer(sc, Bt8370_TFRM, 0x1F); /* - YEL MF FE CRC FBIT */
- else if (sc->config.format == CFG_FORMAT_E1FASCAS)
- write_framer(sc, Bt8370_TFRM, 0x31); /* MYEL YEL - - - FBIT */
- else if (sc->config.format == CFG_FORMAT_E1FASCRCCAS)
- write_framer(sc, Bt8370_TFRM, 0x3F); /* MYEL YEL MF FE CRC FBIT */
- else if (sc->config.format == CFG_FORMAT_E1NONE)
- write_framer(sc, Bt8370_TFRM, 0x00); /* NO FRAMING BITS AT ALL! */
-
- /* 073:TERROR -- Transmit Error Insert */
- write_framer(sc, Bt8370_TERROR, 0x00); /* no errors, please! */
-
- /* 074:TMAN -- Transmit Manual Sa-byte/FEBE configuration */
- write_framer(sc, Bt8370_TMAN, 0x00); /* none */
-
- /* 075:TALM -- Transmit Alarm Signal Configuration */
- if (FORMAT_E1ANY)
- write_framer(sc, Bt8370_TALM, 0x38); /* auto_myel auto_yel auto_ais */
- else if (FORMAT_T1ANY)
- write_framer(sc, Bt8370_TALM, 0x18); /* auto_yel auto_ais */
-
- /* 076:TPATT -- Transmit Test Pattern Configuration */
- write_framer(sc, Bt8370_TPATT, 0x00); /* disabled */
-
- /* 077:TLB -- Transmit Inband Loopback Code Configuration */
- write_framer(sc, Bt8370_TLB, 0x00); /* disabled */
-
- /* 090:CLAD_CR -- Clack Rate Adapter Configuration */
- if (FORMAT_T1ANY)
- write_framer(sc, Bt8370_CLAD_CR, 0x06); /* loop filter gain 1/2^6 */
- else
- write_framer(sc, Bt8370_CLAD_CR, 0x08); /* loop filter gain 1/2^8 */
-
- /* 091:CSEL -- CLAD frequency Select */
- if (FORMAT_T1ANY)
- write_framer(sc, Bt8370_CSEL, 0x55); /* 1544 kHz */
- else
- write_framer(sc, Bt8370_CSEL, 0x11); /* 2048 kHz */
-
- /* 092:CPHASE -- CLAD Phase detector */
- if (FORMAT_T1ANY)
- write_framer(sc, Bt8370_CPHASE, 0x22); /* phase compare @ 386 kHz */
- else
- write_framer(sc, Bt8370_CPHASE, 0x00); /* phase compare @ 2048 kHz */
-
- if (FORMAT_T1ESF) /* BOP & PRM are enabled in T1ESF mode only. */
- {
- /* 0A0:BOP -- Bit Oriented Protocol messages */
- write_framer(sc, Bt8370_BOP, RBOP_25 | TBOP_OFF);
- /* 0A4:DL1_TS -- Data Link 1 Time Slot Enable */
- write_framer(sc, Bt8370_DL1_TS, 0x40); /* FDL bits in odd frames */
- /* 0A6:DL1_CTL -- Data Link 1 Control */
- write_framer(sc, Bt8370_DL1_CTL, 0x03); /* FCS mode, TX on, RX on */
- /* 0A7:RDL1_FFC -- Rx Data Link 1 Fifo Fill Control */
- write_framer(sc, Bt8370_RDL1_FFC, 0x30); /* assert "near full" at 48 */
- /* 0AA:PRM -- Performance Report Messages */
- write_framer(sc, Bt8370_PRM, 0x80);
- }
-
- /* 0D0:SBI_CR -- System Bus Interface Configuration Register */
- if (FORMAT_T1ANY)
- write_framer(sc, Bt8370_SBI_CR, 0x47); /* 1.544 with 24 TS +Fbits */
- else
- write_framer(sc, Bt8370_SBI_CR, 0x46); /* 2.048 with 32 TS */
-
- /* 0D1:RSB_CR -- Receive System Bus Configuration Register */
- /* Change RINDO & RFSYNC on falling edge of RSBCLKI. */
- write_framer(sc, Bt8370_RSB_CR, 0x70);
-
- /* 0D2,0D3:RSYNC_{TS,BIT} -- Receive frame Sync offset */
- write_framer(sc, Bt8370_RSYNC_BIT, 0x00);
- write_framer(sc, Bt8370_RSYNC_TS, 0x00);
-
- /* 0D4:TSB_CR -- Transmit System Bus Configuration Register */
- /* Change TINDO & TFSYNC on falling edge of TSBCLKI. */
- write_framer(sc, Bt8370_TSB_CR, 0x30);
-
- /* 0D5,0D6:TSYNC_{TS,BIT} -- Transmit frame Sync offset */
- write_framer(sc, Bt8370_TSYNC_BIT, 0x00);
- write_framer(sc, Bt8370_TSYNC_TS, 0x00);
-
- /* 0D7:RSIG_CR -- Receive SIGnalling Configuratin Register */
- write_framer(sc, Bt8370_RSIG_CR, 0x00);
-
- /* Assign and configure 64Kb TIME SLOTS. */
- /* TS24..TS1 must be assigned for T1, TS31..TS0 for E1. */
- /* Timeslots with no user data have RINDO and TINDO off. */
- for (i=0; i<32; i++)
- {
- /* 0E0-0FF:SBCn -- System Bus Per-Channel Control */
- if (FORMAT_T1ANY && (i==0 || i>24))
- write_framer(sc, Bt8370_SBCn +i, 0x00); /* not assigned in T1 mode */
- else if (FORMAT_E1ANY && (i==0) && !FORMAT_E1NONE)
- write_framer(sc, Bt8370_SBCn +i, 0x01); /* assigned, TS0 o/h bits */
- else if (FORMAT_E1CAS && (i==16) && !FORMAT_E1NONE)
- write_framer(sc, Bt8370_SBCn +i, 0x01); /* assigned, TS16 o/h bits */
- else if ((sc->config.time_slots & (1<<i)) != 0)
- write_framer(sc, Bt8370_SBCn +i, 0x0D); /* assigned, RINDO, TINDO */
- else
- write_framer(sc, Bt8370_SBCn +i, 0x01); /* assigned, idle */
-
- /* 100-11F:TPCn -- Transmit Per-Channel Control */
- if (FORMAT_E1CAS && (i==0))
- write_framer(sc, Bt8370_TPCn +i, 0x30); /* tidle, sig=0000 (MAS) */
- else if (FORMAT_E1CAS && (i==16))
- write_framer(sc, Bt8370_TPCn +i, 0x3B); /* tidle, sig=1011 (XYXX) */
- else if ((sc->config.time_slots & (1<<i)) == 0)
- write_framer(sc, Bt8370_TPCn +i, 0x20); /* tidle: use TSLIP_LOn */
- else
- write_framer(sc, Bt8370_TPCn +i, 0x00); /* nothing special */
-
- /* 140-15F:TSLIP_LOn -- Transmit PCM Slip Buffer */
- write_framer(sc, Bt8370_TSLIP_LOn +i, 0x7F); /* idle chan data */
- /* 180-19F:RPCn -- Receive Per-Channel Control */
- write_framer(sc, Bt8370_RPCn +i, 0x00); /* nothing special */
- }
-
- /* Enable transmitter output drivers. */
- set_mii16_bits(sc, MII16_T1_XOE);
- }
-
-static void
-t1_ident(softc_t *sc)
- {
- printf(", Bt837%x rev %x",
- read_framer(sc, Bt8370_DID)>>4,
- read_framer(sc, Bt8370_DID)&0x0F);
- }
-
-/* Called once a second; must not sleep. */
-static int
-t1_watchdog(softc_t *sc)
- {
- u_int16_t LCV = 0, FERR = 0, CRC = 0, FEBE = 0;
- u_int8_t alm1, alm3, loop, isr0;
- int link_status = STATUS_UP;
- int i;
-
- /* Read the alarm registers */
- alm1 = read_framer(sc, Bt8370_ALM1);
- alm3 = read_framer(sc, Bt8370_ALM3);
- loop = read_framer(sc, Bt8370_LOOP);
- isr0 = read_framer(sc, Bt8370_ISR0);
-
- /* Always ignore the SIGFRZ alarm bit, */
- alm1 &= ~ALM1_SIGFRZ;
- if (FORMAT_T1ANY) /* ignore RYEL in T1 modes */
- alm1 &= ~ALM1_RYEL;
- else if (FORMAT_E1NONE) /* ignore all alarms except LOS */
- alm1 &= ALM1_RLOS;
-
- /* Software is alive. */
- led_inv(sc, MII16_T1_LED_GRN);
-
- /* Receiving Alarm Indication Signal (AIS). */
- if ((alm1 & ALM1_RAIS)!=0) /* receiving ais */
- led_on(sc, MII16_T1_LED_BLU);
- else if ((alm1 & ALM1_RLOS)!=0) /* sending ais */
- led_inv(sc, MII16_T1_LED_BLU);
- else
- led_off(sc, MII16_T1_LED_BLU);
-
- /* Receiving Remote Alarm Indication (RAI). */
- if ((alm1 & (ALM1_RMYEL | ALM1_RYEL))!=0) /* receiving rai */
- led_on(sc, MII16_T1_LED_YEL);
- else if ((alm1 & ALM1_RLOF)!=0) /* sending rai */
- led_inv(sc, MII16_T1_LED_YEL);
- else
- led_off(sc, MII16_T1_LED_YEL);
-
- /* If any alarm bits are set then the link is 'down'. */
- /* The bad bits are: rmyel ryel rais ralos rlos rlof. */
- /* Some alarm bits have been masked by this point. */
- if (alm1 != 0) link_status = STATUS_DOWN;
-
- /* Declare local Red Alarm if the link is down. */
- if (link_status == STATUS_DOWN)
- led_on(sc, MII16_T1_LED_RED);
- else if (sc->loop_timer != 0) /* loopback is active */
- led_inv(sc, MII16_T1_LED_RED);
- else
- led_off(sc, MII16_T1_LED_RED);
-
- /* Print latched error bits if they changed. */
- if ((DRIVER_DEBUG) && (alm1 != sc->last_alm1))
- {
- char *on = "ON ", *off = "OFF";
- printf("%s: RLOF=%s RLOS=%s RALOS=%s RAIS=%s RYEL=%s RMYEL=%s\n",
- NAME_UNIT,
- (alm1 & ALM1_RLOF) ? on : off,
- (alm1 & ALM1_RLOS) ? on : off,
- (alm1 & ALM1_RALOS) ? on : off,
- (alm1 & ALM1_RAIS) ? on : off,
- (alm1 & ALM1_RYEL) ? on : off,
- (alm1 & ALM1_RMYEL) ? on : off);
- }
-
- /* Check and print error counters if non-zero. */
- LCV = read_framer(sc, Bt8370_LCV_LO) +
- (read_framer(sc, Bt8370_LCV_HI)<<8);
- if (!FORMAT_E1NONE)
- FERR = read_framer(sc, Bt8370_FERR_LO) +
- (read_framer(sc, Bt8370_FERR_HI)<<8);
- if (FORMAT_E1CRC || FORMAT_T1ESF)
- CRC = read_framer(sc, Bt8370_CRC_LO) +
- (read_framer(sc, Bt8370_CRC_HI)<<8);
- if (FORMAT_E1CRC)
- FEBE = read_framer(sc, Bt8370_FEBE_LO) +
- (read_framer(sc, Bt8370_FEBE_HI)<<8);
- /* Only LCV is valid if Out-Of-Frame */
- if (FORMAT_E1NONE) FERR = CRC = FEBE = 0;
- if ((DRIVER_DEBUG) && (LCV || FERR || CRC || FEBE))
- printf("%s: LCV=%u FERR=%u CRC=%u FEBE=%u\n",
- NAME_UNIT, LCV, FERR, CRC, FEBE);
-
- /* Driver keeps crude link-level error counters (SNMP is better). */
- sc->status.cntrs.lcv_errs += LCV;
- sc->status.cntrs.frm_errs += FERR;
- sc->status.cntrs.crc_errs += CRC;
- sc->status.cntrs.febe_errs += FEBE;
-
- /* Check for BOP messages in the ESF Facility Data Link. */
- if ((FORMAT_T1ESF) && (read_framer(sc, Bt8370_ISR1) & 0x80))
- {
- u_int8_t bop_code = read_framer(sc, Bt8370_RBOP) & 0x3F;
-
- switch (bop_code)
- {
- case T1BOP_OOF:
- {
- if ((DRIVER_DEBUG) && ((sc->last_alm1 & ALM1_RMYEL)==0))
- printf("%s: Receiving a 'yellow alarm' BOP msg\n", NAME_UNIT);
- break;
- }
- case T1BOP_LINE_UP:
- {
- if (DRIVER_DEBUG)
- printf("%s: Received a 'line loopback activate' BOP msg\n", NAME_UNIT);
- write_framer(sc, Bt8370_LOOP, LOOP_LINE);
- sc->loop_timer = 305;
- break;
- }
- case T1BOP_LINE_DOWN:
- {
- if (DRIVER_DEBUG)
- printf("%s: Received a 'line loopback deactivate' BOP msg\n", NAME_UNIT);
- write_framer(sc, Bt8370_LOOP,
- read_framer(sc, Bt8370_LOOP) & ~LOOP_LINE);
- sc->loop_timer = 0;
- break;
- }
- case T1BOP_PAY_UP:
- {
- if (DRIVER_DEBUG)
- printf("%s: Received a 'payload loopback activate' BOP msg\n", NAME_UNIT);
- write_framer(sc, Bt8370_LOOP, LOOP_PAYLOAD);
- sc->loop_timer = 305;
- break;
- }
- case T1BOP_PAY_DOWN:
- {
- if (DRIVER_DEBUG)
- printf("%s: Received a 'payload loopback deactivate' BOP msg\n", NAME_UNIT);
- write_framer(sc, Bt8370_LOOP,
- read_framer(sc, Bt8370_LOOP) & ~LOOP_PAYLOAD);
- sc->loop_timer = 0;
- break;
- }
- default:
- {
- if (DRIVER_DEBUG)
- printf("%s: Received a type 0x%02X BOP msg\n", NAME_UNIT, bop_code);
- break;
- }
- }
- }
-
- /* Check for HDLC pkts in the ESF Facility Data Link. */
- if ((FORMAT_T1ESF) && (read_framer(sc, Bt8370_ISR2) & 0x70))
- {
- /* while (not fifo-empty && not start-of-msg) flush fifo */
- while ((read_framer(sc, Bt8370_RDL1_STAT) & 0x0C) == 0)
- read_framer(sc, Bt8370_RDL1);
- /* If (not fifo-empty), then begin processing fifo contents. */
- if ((read_framer(sc, Bt8370_RDL1_STAT) & 0x0C) == 0x08)
- {
- u_int8_t msg[64];
- u_int8_t stat = read_framer(sc, Bt8370_RDL1);
- sc->status.cntrs.fdl_pkts++;
- for (i=0; i<(stat & 0x3F); i++)
- msg[i] = read_framer(sc, Bt8370_RDL1);
- /* Is this FDL message a T1.403 performance report? */
- if (((stat & 0x3F)==11) &&
- ((msg[0]==0x38) || (msg[0]==0x3A)) &&
- (msg[1]==1) && (msg[2]==3))
- /* Copy 4 PRs from FDL pkt to SNMP struct. */
- memcpy(sc->status.snmp.t1.prm, msg+3, 8);
- }
- }
-
- /* Check for inband loop up/down commands. */
- if (FORMAT_T1ANY)
- {
- u_int8_t isr6 = read_framer(sc, Bt8370_ISR6);
- u_int8_t alarm2 = read_framer(sc, Bt8370_ALM2);
- u_int8_t tlb = read_framer(sc, Bt8370_TLB);
-
- /* Inband Code == Loop Up && On Transition && Inband Tx Inactive */
- if ((isr6 & 0x40) && (alarm2 & 0x40) && ((tlb & 1)==0))
- { /* CSU loop up is 10000 10000 ... */
- if (DRIVER_DEBUG)
- printf("%s: Received a 'CSU Loop Up' inband msg\n", NAME_UNIT);
- write_framer(sc, Bt8370_LOOP, LOOP_LINE); /* Loop up */
- sc->loop_timer = 305;
- }
- /* Inband Code == Loop Down && On Transition && Inband Tx Inactive */
- if ((isr6 & 0x80) && (alarm2 & 0x80) && ((tlb & 1)==0))
- { /* CSU loop down is 100 100 100 ... */
- if (DRIVER_DEBUG)
- printf("%s: Received a 'CSU Loop Down' inband msg\n", NAME_UNIT);
- write_framer(sc, Bt8370_LOOP,
- read_framer(sc, Bt8370_LOOP) & ~LOOP_LINE); /* loop down */
- sc->loop_timer = 0;
- }
- }
-
- /* Manually send Yellow Alarm BOP msgs. */
- if (FORMAT_T1ESF)
- {
- u_int8_t isr7 = read_framer(sc, Bt8370_ISR7);
-
- if ((isr7 & 0x02) && (alm1 & 0x02)) /* RLOF on-transition */
- { /* Start sending continuous Yellow Alarm BOP messages. */
- write_framer(sc, Bt8370_BOP, RBOP_25 | TBOP_CONT);
- write_framer(sc, Bt8370_TBOP, 0x00); /* send BOP; order matters */
- }
- else if ((isr7 & 0x02) && ((alm1 & 0x02)==0)) /* RLOF off-transition */
- { /* Stop sending continuous Yellow Alarm BOP messages. */
- write_framer(sc, Bt8370_BOP, RBOP_25 | TBOP_OFF);
- }
- }
-
- /* Time out loopback requests. */
- if (sc->loop_timer != 0)
- if (--sc->loop_timer == 0)
- if (loop != 0)
- {
- if (DRIVER_DEBUG)
- printf("%s: Timeout: Loop Down after 300 seconds\n", NAME_UNIT);
- write_framer(sc, Bt8370_LOOP, loop & ~(LOOP_PAYLOAD | LOOP_LINE));
- }
-
- /* RX Test Pattern status */
- if ((DRIVER_DEBUG) && (isr0 & 0x10))
- printf("%s: RX Test Pattern Sync\n", NAME_UNIT);
-
- /* SNMP Error Counters */
- sc->status.snmp.t1.lcv = LCV;
- sc->status.snmp.t1.fe = FERR;
- sc->status.snmp.t1.crc = CRC;
- sc->status.snmp.t1.febe = FEBE;
-
- /* SNMP Line Status */
- sc->status.snmp.t1.line = 0;
- if (alm1 & ALM1_RMYEL) sc->status.snmp.t1.line |= TLINE_RX_RAI;
- if (alm1 & ALM1_RYEL) sc->status.snmp.t1.line |= TLINE_RX_RAI;
- if (alm1 & ALM1_RLOF) sc->status.snmp.t1.line |= TLINE_TX_RAI;
- if (alm1 & ALM1_RAIS) sc->status.snmp.t1.line |= TLINE_RX_AIS;
- if (alm1 & ALM1_RLOS) sc->status.snmp.t1.line |= TLINE_TX_AIS;
- if (alm1 & ALM1_RLOF) sc->status.snmp.t1.line |= TLINE_LOF;
- if (alm1 & ALM1_RLOS) sc->status.snmp.t1.line |= TLINE_LOS;
- if (alm3 & ALM3_RMAIS) sc->status.snmp.t1.line |= T1LINE_RX_TS16_AIS;
- if (alm3 & ALM3_SRED) sc->status.snmp.t1.line |= T1LINE_TX_TS16_LOMF;
- if (alm3 & ALM3_SEF) sc->status.snmp.t1.line |= T1LINE_SEF;
- if (isr0 & 0x10) sc->status.snmp.t1.line |= T1LINE_RX_TEST;
- if ((alm1 & ALM1_RMYEL) && (FORMAT_E1CAS))
- sc->status.snmp.t1.line |= T1LINE_RX_TS16_LOMF;
-
- /* SNMP Loopback Status */
- sc->status.snmp.t1.loop &= ~(TLOOP_FAR_LINE | TLOOP_FAR_PAYLOAD);
- if (sc->config.loop_back == CFG_LOOP_TULIP)
- sc->status.snmp.t1.loop |= TLOOP_NEAR_OTHER;
- if (loop & LOOP_PAYLOAD) sc->status.snmp.t1.loop |= TLOOP_NEAR_PAYLOAD;
- if (loop & LOOP_LINE) sc->status.snmp.t1.loop |= TLOOP_NEAR_LINE;
- if (loop & LOOP_ANALOG) sc->status.snmp.t1.loop |= TLOOP_NEAR_OTHER;
- if (loop & LOOP_FRAMER) sc->status.snmp.t1.loop |= TLOOP_NEAR_INWARD;
-
- /* Remember this state until next time. */
- sc->last_alm1 = alm1;
-
- /* If an INWARD loopback is in effect, link status is UP */
- if (sc->config.loop_back != CFG_LOOP_NONE) /* XXX INWARD ONLY */
- link_status = STATUS_UP;
-
- return link_status;
- }
-
-/* IOCTL SYSCALL: can sleep. */
-static void
-t1_send_bop(softc_t *sc, int bop_code)
- {
- u_int8_t bop;
- int i;
-
- /* The BOP transmitter could be sending a continuous */
- /* BOP msg when told to send this BOP_25 message. */
- /* So save and restore the state of the BOP machine. */
- bop = read_framer(sc, Bt8370_BOP);
- write_framer(sc, Bt8370_BOP, RBOP_OFF | TBOP_OFF);
- for (i=0; i<40; i++) /* max delay 400 ms. */
- if (read_framer(sc, Bt8370_BOP_STAT) & 0x80) SLEEP(10000);
- /* send 25 repetitions of bop_code */
- write_framer(sc, Bt8370_BOP, RBOP_OFF | TBOP_25);
- write_framer(sc, Bt8370_TBOP, bop_code); /* order matters */
- /* wait for tx to stop */
- for (i=0; i<40; i++) /* max delay 400 ms. */
- if (read_framer(sc, Bt8370_BOP_STAT) & 0x80) SLEEP(10000);
- /* Restore previous state of the BOP machine. */
- write_framer(sc, Bt8370_BOP, bop);
- }
-
-/* IOCTL SYSCALL: can sleep. */
-static int
-t1_ioctl(softc_t *sc, struct ioctl *ioctl)
- {
- int error = 0;
-
- switch (ioctl->cmd)
- {
- case IOCTL_SNMP_SEND: /* set opstatus? */
- {
- switch (ioctl->data)
- {
- case TSEND_NORMAL:
- {
- write_framer(sc, Bt8370_TPATT, 0x00); /* tx pattern generator off */
- write_framer(sc, Bt8370_RPATT, 0x00); /* rx pattern detector off */
- write_framer(sc, Bt8370_TLB, 0x00); /* tx inband generator off */
- break;
- }
- case TSEND_LINE:
- {
- if (FORMAT_T1ESF)
- t1_send_bop(sc, T1BOP_LINE_UP);
- else if (FORMAT_T1SF)
- {
- write_framer(sc, Bt8370_LBP, 0x08); /* 10000 10000 ... */
- write_framer(sc, Bt8370_TLB, 0x05); /* 5 bits, framed, start */
- }
- sc->status.snmp.t1.loop |= TLOOP_FAR_LINE;
- break;
- }
- case TSEND_PAYLOAD:
- {
- t1_send_bop(sc, T1BOP_PAY_UP);
- sc->status.snmp.t1.loop |= TLOOP_FAR_PAYLOAD;
- break;
- }
- case TSEND_RESET:
- {
- if (sc->status.snmp.t1.loop == TLOOP_FAR_LINE)
- {
- if (FORMAT_T1ESF)
- t1_send_bop(sc, T1BOP_LINE_DOWN);
- else if (FORMAT_T1SF)
- {
- write_framer(sc, Bt8370_LBP, 0x24); /* 100100 100100 ... */
- write_framer(sc, Bt8370_TLB, 0x09); /* 6 bits, framed, start */
- }
- sc->status.snmp.t1.loop &= ~TLOOP_FAR_LINE;
- }
- if (sc->status.snmp.t1.loop == TLOOP_FAR_PAYLOAD)
- {
- t1_send_bop(sc, T1BOP_PAY_DOWN);
- sc->status.snmp.t1.loop &= ~TLOOP_FAR_PAYLOAD;
- }
- break;
- }
- case TSEND_QRS:
- {
- write_framer(sc, Bt8370_TPATT, 0x1E); /* framed QRSS */
- break;
- }
- default:
- {
- error = EINVAL;
- break;
- }
- }
- break;
- }
- case IOCTL_SNMP_LOOP: /* set opstatus = test? */
- {
- u_int8_t new_loop = 0;
-
- if (ioctl->data == CFG_LOOP_NONE)
- new_loop = 0;
- else if (ioctl->data == CFG_LOOP_PAYLOAD)
- new_loop = LOOP_PAYLOAD;
- else if (ioctl->data == CFG_LOOP_LINE)
- new_loop = LOOP_LINE;
- else if (ioctl->data == CFG_LOOP_OTHER)
- new_loop = LOOP_ANALOG;
- else if (ioctl->data == CFG_LOOP_INWARD)
- new_loop = LOOP_FRAMER;
- else if (ioctl->data == CFG_LOOP_DUAL)
- new_loop = LOOP_DUAL;
- else
- error = EINVAL;
- if (error == 0)
- {
- write_framer(sc, Bt8370_LOOP, new_loop);
- sc->config.loop_back = ioctl->data;
- }
- break;
- }
- default:
- error = EINVAL;
- break;
- }
-
- return error;
- }
-
-static
-struct card hssi_card =
- {
- .config = hssi_config,
- .ident = hssi_ident,
- .watchdog = hssi_watchdog,
- .ioctl = hssi_ioctl,
- };
-
-static
-struct card t3_card =
- {
- .config = t3_config,
- .ident = t3_ident,
- .watchdog = t3_watchdog,
- .ioctl = t3_ioctl,
- };
-
-static
-struct card ssi_card =
- {
- .config = ssi_config,
- .ident = ssi_ident,
- .watchdog = ssi_watchdog,
- .ioctl = ssi_ioctl,
- };
-
-static
-struct card t1_card =
- {
- .config = t1_config,
- .ident = t1_ident,
- .watchdog = t1_watchdog,
- .ioctl = t1_ioctl,
- };
-
-/* RAWIP is raw IP packets (v4 or v6) in HDLC frames with NO HEADERS. */
-/* No HDLC Address/Control fields! No line control protocol at all! */
-
-/* rxintr_cleanup calls this to give a newly arrived pkt to higher levels. */
-static void
-lmc_raw_input(struct ifnet *ifp, struct mbuf *mbuf)
- {
- softc_t *sc = IFP2SC(ifp);
-
- M_SETFIB(mbuf, ifp->if_fib);
-# if INET
- if (mbuf->m_data[0]>>4 == 4)
- netisr_dispatch(NETISR_IP, mbuf);
- else
-# endif
-# if INET6
- if (mbuf->m_data[0]>>4 == 6)
- netisr_dispatch(NETISR_IPV6, mbuf);
- else
-# endif
- {
- m_freem(mbuf);
- sc->status.cntrs.idiscards++;
- if (DRIVER_DEBUG)
- printf("%s: lmc_raw_input: rx pkt discarded: not IPv4 or IPv6\n",
- NAME_UNIT);
- }
- }
-
-/*
- * We are "standing on the head of a pin" in these routines.
- * Tulip CSRs can be accessed, but nothing else is interrupt-safe!
- * Do NOT access: MII, GPIO, SROM, BIOSROM, XILINX, SYNTH, or DAC.
- */
-
-
-/* Singly-linked tail-queues hold mbufs with active DMA.
- * For RX, single mbuf clusters; for TX, mbuf chains are queued.
- * NB: mbufs are linked through their m_nextpkt field.
- * Callers must hold sc->bottom_lock; not otherwise locked.
- */
-
-/* Put an mbuf (chain) on the tail of the descriptor ring queue. */
-static void /* BSD version */
-mbuf_enqueue(struct desc_ring *ring, struct mbuf *m)
- {
- m->m_nextpkt = NULL;
- if (ring->tail == NULL)
- ring->head = m;
- else
- ring->tail->m_nextpkt = m;
- ring->tail = m;
- }
-
-/* Get an mbuf (chain) from the head of the descriptor ring queue. */
-static struct mbuf* /* BSD version */
-mbuf_dequeue(struct desc_ring *ring)
- {
- struct mbuf *m = ring->head;
- if (m != NULL)
- if ((ring->head = m->m_nextpkt) == NULL)
- ring->tail = NULL;
- return m;
- }
-
-static void /* *** FreeBSD ONLY *** Callout from bus_dmamap_load() */
-fbsd_dmamap_load(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
- {
- struct desc_ring *ring = arg;
- ring->nsegs = error ? 0 : nsegs;
- ring->segs[0] = segs[0];
- ring->segs[1] = segs[1];
- }
-
-/* Initialize a DMA descriptor ring. */
-static int /* BSD version */
-create_ring(softc_t *sc, struct desc_ring *ring, int num_descs)
- {
- struct dma_desc *descs;
- int size_descs = sizeof(struct dma_desc)*num_descs;
- int i, error = 0;
-
- /* The DMA descriptor array must not cross a page boundary. */
- if (size_descs > PAGE_SIZE)
- {
- printf("%s: DMA descriptor array > PAGE_SIZE (%d)\n", NAME_UNIT,
- (u_int)PAGE_SIZE);
- return EINVAL;
- }
-
-
- /* Create a DMA tag for descriptors and buffers. */
- if ((error = bus_dma_tag_create(bus_get_dma_tag(sc->dev),
- 4, 0, BUS_SPACE_MAXADDR_32BIT,
- BUS_SPACE_MAXADDR, NULL, NULL, PAGE_SIZE, 2, PAGE_SIZE, BUS_DMA_ALLOCNOW,
- NULL, NULL,
- &ring->tag)))
- {
- printf("%s: bus_dma_tag_create() failed: error %d\n", NAME_UNIT, error);
- return error;
- }
-
- /* Allocate wired physical memory for DMA descriptor array */
- /* and map physical address to kernel virtual address. */
- if ((error = bus_dmamem_alloc(ring->tag, (void**)&ring->first,
- BUS_DMA_NOWAIT | BUS_DMA_COHERENT | BUS_DMA_ZERO, &ring->map)))
- {
- printf("%s: bus_dmamem_alloc() failed; error %d\n", NAME_UNIT, error);
- return error;
- }
- descs = ring->first;
-
- /* Map kernel virtual address to PCI address for DMA descriptor array. */
- if ((error = bus_dmamap_load(ring->tag, ring->map, descs, size_descs,
- fbsd_dmamap_load, ring, 0)))
- {
- printf("%s: bus_dmamap_load() failed; error %d\n", NAME_UNIT, error);
- return error;
- }
- ring->dma_addr = ring->segs[0].ds_addr;
-
- /* Allocate dmamaps for each DMA descriptor. */
- for (i=0; i<num_descs; i++)
- if ((error = bus_dmamap_create(ring->tag, 0, &descs[i].map)))
- {
- printf("%s: bus_dmamap_create() failed; error %d\n", NAME_UNIT, error);
- return error;
- }
-
-
- ring->read = descs;
- ring->write = descs;
- ring->first = descs;
- ring->last = descs + num_descs -1;
- ring->last->control = TLP_DCTL_END_RING;
- ring->num_descs = num_descs;
- ring->size_descs = size_descs;
- ring->head = NULL;
- ring->tail = NULL;
-
- return 0;
- }
-
-/* Destroy a DMA descriptor ring */
-static void /* BSD version */
-destroy_ring(softc_t *sc, struct desc_ring *ring)
- {
- struct dma_desc *desc;
- struct mbuf *m;
-
- /* Free queued mbufs. */
- while ((m = mbuf_dequeue(ring)) != NULL)
- m_freem(m);
-
- /* TX may have one pkt that is not on any queue. */
- if (sc->tx_mbuf != NULL)
- {
- m_freem(sc->tx_mbuf);
- sc->tx_mbuf = NULL;
- }
-
- /* Unmap active DMA descriptors. */
- while (ring->read != ring->write)
- {
- bus_dmamap_unload(ring->tag, ring->read->map);
- if (ring->read++ == ring->last) ring->read = ring->first;
- }
-
-
- /* Free the dmamaps of all DMA descriptors. */
- for (desc=ring->first; desc!=ring->last+1; desc++)
- if (desc->map != NULL)
- bus_dmamap_destroy(ring->tag, desc->map);
-
- /* Unmap PCI address for DMA descriptor array. */
- if (ring->dma_addr != 0)
- bus_dmamap_unload(ring->tag, ring->map);
- /* Free kernel memory for DMA descriptor array. */
- if (ring->first != NULL)
- bus_dmamem_free(ring->tag, ring->first, ring->map);
- /* Free the DMA tag created for this ring. */
- if (ring->tag != NULL)
- bus_dma_tag_destroy(ring->tag);
-
- }
-
-/* Clean up after a packet has been received. */
-static int /* BSD version */
-rxintr_cleanup(softc_t *sc)
- {
- struct desc_ring *ring = &sc->rxring;
- struct dma_desc *first_desc, *last_desc;
- struct mbuf *first_mbuf=NULL, *last_mbuf=NULL;
- struct mbuf *new_mbuf;
- int pkt_len, desc_len;
-
-#if defined(DEVICE_POLLING)
- /* Input packet flow control (livelock prevention): */
- /* Give pkts to higher levels only if quota is > 0. */
- if (sc->quota <= 0) return 0;
-#endif
-
- /* This looks complicated, but remember: typically packets up */
- /* to 2048 bytes long fit in one mbuf and use one descriptor. */
-
- first_desc = last_desc = ring->read;
-
- /* ASSERTION: If there is a descriptor in the ring and the hardware has */
- /* finished with it, then that descriptor will have RX_FIRST_DESC set. */
- if ((ring->read != ring->write) && /* descriptor ring not empty */
- ((ring->read->status & TLP_DSTS_OWNER) == 0) && /* hardware done */
- ((ring->read->status & TLP_DSTS_RX_FIRST_DESC) == 0)) /* should be set */
- panic("%s: rxintr_cleanup: rx-first-descriptor not set.\n", NAME_UNIT);
-
- /* First decide if a complete packet has arrived. */
- /* Run down DMA descriptors looking for one marked "last". */
- /* Bail out if an active descriptor is encountered. */
- /* Accumulate most significant bits of packet length. */
- pkt_len = 0;
- for (;;)
- {
- if (last_desc == ring->write) return 0; /* no more descs */
- if (last_desc->status & TLP_DSTS_OWNER) return 0; /* still active */
- if (last_desc->status & TLP_DSTS_RX_LAST_DESC) break; /* end of packet */
- pkt_len += last_desc->length1 + last_desc->length2; /* entire desc filled */
- if (last_desc++->control & TLP_DCTL_END_RING) last_desc = ring->first; /* ring wrap */
- }
-
- /* A complete packet has arrived; how long is it? */
- /* H/w ref man shows RX pkt length as a 14-bit field. */
- /* An experiment found that only the 12 LSBs work. */
- if (((last_desc->status>>16)&0xFFF) == 0) pkt_len += 4096; /* carry-bit */
- pkt_len = (pkt_len & 0xF000) + ((last_desc->status>>16) & 0x0FFF);
- /* Subtract the CRC length unless doing so would underflow. */
- if (pkt_len >= sc->config.crc_len) pkt_len -= sc->config.crc_len;
-
- /* Run down DMA descriptors again doing the following:
- * 1) put pkt info in pkthdr of first mbuf,
- * 2) link mbufs,
- * 3) set mbuf lengths.
- */
- first_desc = ring->read;
- do
- {
- /* Read a DMA descriptor from the ring. */
- last_desc = ring->read;
- /* Advance the ring read pointer. */
- if (ring->read++ == ring->last) ring->read = ring->first;
-
- /* Dequeue the corresponding cluster mbuf. */
- new_mbuf = mbuf_dequeue(ring);
- if (new_mbuf == NULL)
- panic("%s: rxintr_cleanup: expected an mbuf\n", NAME_UNIT);
-
- desc_len = last_desc->length1 + last_desc->length2;
- /* If bouncing, copy bounce buf to mbuf. */
- DMA_SYNC(last_desc->map, desc_len, BUS_DMASYNC_POSTREAD);
- /* Unmap kernel virtual address to PCI address. */
- bus_dmamap_unload(ring->tag, last_desc->map);
-
- /* 1) Put pkt info in pkthdr of first mbuf. */
- if (last_desc == first_desc)
- {
- first_mbuf = new_mbuf;
- first_mbuf->m_pkthdr.len = pkt_len; /* total pkt length */
- first_mbuf->m_pkthdr.rcvif = sc->ifp; /* how it got here */
- }
- else /* 2) link mbufs. */
- {
- last_mbuf->m_next = new_mbuf;
- /* M_PKTHDR should be set in the first mbuf only. */
- new_mbuf->m_flags &= ~M_PKTHDR;
- }
- last_mbuf = new_mbuf;
-
- /* 3) Set mbuf lengths. */
- new_mbuf->m_len = (pkt_len >= desc_len) ? desc_len : pkt_len;
- pkt_len -= new_mbuf->m_len;
- } while ((last_desc->status & TLP_DSTS_RX_LAST_DESC) == 0);
-
- /* Decide whether to accept or to discard this packet. */
- /* RxHDLC sets MIIERR for bad CRC, abort and partial byte at pkt end. */
- if (((last_desc->status & TLP_DSTS_RX_BAD) == 0) &&
- (sc->status.oper_status == STATUS_UP) &&
- (first_mbuf->m_pkthdr.len > 0))
- {
- /* Optimization: copy a small pkt into a small mbuf. */
- if (first_mbuf->m_pkthdr.len <= COPY_BREAK)
- {
- MGETHDR(new_mbuf, M_NOWAIT, MT_DATA);
- if (new_mbuf != NULL)
- {
- new_mbuf->m_pkthdr.rcvif = first_mbuf->m_pkthdr.rcvif;
- new_mbuf->m_pkthdr.len = first_mbuf->m_pkthdr.len;
- new_mbuf->m_len = first_mbuf->m_len;
- memcpy(new_mbuf->m_data, first_mbuf->m_data,
- first_mbuf->m_pkthdr.len);
- m_freem(first_mbuf);
- first_mbuf = new_mbuf;
- }
- }
- /* Include CRC and one flag byte in input byte count. */
- sc->status.cntrs.ibytes += first_mbuf->m_pkthdr.len + sc->config.crc_len +1;
- sc->status.cntrs.ipackets++;
- if_inc_counter(sc->ifp, IFCOUNTER_IPACKETS, 1);
- LMC_BPF_MTAP(first_mbuf);
-#if defined(DEVICE_POLLING)
- sc->quota--;
-#endif
-
- /* Give this good packet to the network stacks. */
-#if NETGRAPH
- if (sc->ng_hook != NULL) /* is hook connected? */
- {
- int error; /* ignore error */
- NG_SEND_DATA_ONLY(error, sc->ng_hook, first_mbuf);
- return 1; /* did something */
- }
-#endif /* NETGRAPH */
- if (sc->config.line_pkg == PKG_RAWIP)
- lmc_raw_input(sc->ifp, first_mbuf);
- else
- {
-#if NSPPP
- sppp_input(sc->ifp, first_mbuf);
-#elif P2P
- new_mbuf = first_mbuf;
- while (new_mbuf != NULL)
- {
- sc->p2p->p2p_hdrinput(sc->p2p, new_mbuf->m_data, new_mbuf->m_len);
- new_mbuf = new_mbuf->m_next;
- }
- sc->p2p->p2p_input(sc->p2p, NULL);
- m_freem(first_mbuf);
-#else
- m_freem(first_mbuf);
- sc->status.cntrs.idiscards++;
-#endif
- }
- }
- else if (sc->status.oper_status != STATUS_UP)
- {
- /* If the link is down, this packet is probably noise. */
- m_freem(first_mbuf);
- sc->status.cntrs.idiscards++;
- if (DRIVER_DEBUG)
- printf("%s: rxintr_cleanup: rx pkt discarded: link down\n", NAME_UNIT);
- }
- else /* Log and discard this bad packet. */
- {
- if (DRIVER_DEBUG)
- printf("%s: RX bad pkt; len=%d %s%s%s%s\n",
- NAME_UNIT, first_mbuf->m_pkthdr.len,
- (last_desc->status & TLP_DSTS_RX_MII_ERR) ? " miierr" : "",
- (last_desc->status & TLP_DSTS_RX_DRIBBLE) ? " dribble" : "",
- (last_desc->status & TLP_DSTS_RX_DESC_ERR) ? " descerr" : "",
- (last_desc->status & TLP_DSTS_RX_OVERRUN) ? " overrun" : "");
- if (last_desc->status & TLP_DSTS_RX_OVERRUN)
- sc->status.cntrs.fifo_over++;
- else
- sc->status.cntrs.ierrors++;
- m_freem(first_mbuf);
- }
-
- return 1; /* did something */
- }
-
-/* Setup (prepare) to receive a packet. */
-/* Try to keep the RX descriptor ring full of empty buffers. */
-static int /* BSD version */
-rxintr_setup(softc_t *sc)
- {
- struct desc_ring *ring = &sc->rxring;
- struct dma_desc *desc;
- struct mbuf *m;
- int desc_len;
- int error;
-
- /* Ring is full if (wrap(write+1)==read) */
- if (((ring->write == ring->last) ? ring->first : ring->write+1) == ring->read)
- return 0; /* ring is full; nothing to do */
-
- /* Allocate a small mbuf and attach an mbuf cluster. */
- MGETHDR(m, M_NOWAIT, MT_DATA);
- if (m == NULL)
- {
- sc->status.cntrs.rxdma++;
- if (DRIVER_DEBUG)
- printf("%s: rxintr_setup: MGETHDR() failed\n", NAME_UNIT);
- return 0;
- }
- if (!(MCLGET(m, M_NOWAIT)))
- {
- m_freem(m);
- sc->status.cntrs.rxdma++;
- if (DRIVER_DEBUG)
- printf("%s: rxintr_setup: MCLGET() failed\n", NAME_UNIT);
- return 0;
- }
-
- /* Queue the mbuf for later processing by rxintr_cleanup. */
- mbuf_enqueue(ring, m);
-
- /* Write a DMA descriptor into the ring. */
- /* Hardware won't see it until the OWNER bit is set. */
- desc = ring->write;
- /* Advance the ring write pointer. */
- if (ring->write++ == ring->last) ring->write = ring->first;
-
- desc_len = (MCLBYTES < MAX_DESC_LEN) ? MCLBYTES : MAX_DESC_LEN;
- /* Map kernel virtual address to PCI address. */
- if ((error = DMA_LOAD(desc->map, m->m_data, desc_len)))
- printf("%s: bus_dmamap_load(rx) failed; error %d\n", NAME_UNIT, error);
- /* Invalidate the cache for this mbuf. */
- DMA_SYNC(desc->map, desc_len, BUS_DMASYNC_PREREAD);
-
- /* Set up the DMA descriptor. */
- desc->address1 = ring->segs[0].ds_addr;
- desc->length1 = desc_len>>1;
- desc->address2 = desc->address1 + desc->length1;
- desc->length2 = desc_len>>1;
-
- /* Before setting the OWNER bit, flush the cache (memory barrier). */
- DMA_SYNC(ring->map, ring->size_descs, BUS_DMASYNC_PREWRITE);
-
- /* Commit the DMA descriptor to the hardware. */
- desc->status = TLP_DSTS_OWNER;
-
- /* Notify the receiver that there is another buffer available. */
- WRITE_CSR(TLP_RX_POLL, 1);
-
- return 1; /* did something */
- }
-
-/* Clean up after a packet has been transmitted. */
-/* Free the mbuf chain and update the DMA descriptor ring. */
-static int /* BSD version */
-txintr_cleanup(softc_t *sc)
- {
- struct desc_ring *ring = &sc->txring;
- struct dma_desc *desc;
-
- while ((ring->read != ring->write) && /* while ring is not empty */
- ((ring->read->status & TLP_DSTS_OWNER) == 0))
- {
- /* Read a DMA descriptor from the ring. */
- desc = ring->read;
- /* Advance the ring read pointer. */
- if (ring->read++ == ring->last) ring->read = ring->first;
-
- /* This is a no-op on most architectures. */
- DMA_SYNC(desc->map, desc->length1 + desc->length2, BUS_DMASYNC_POSTWRITE);
- /* Unmap kernel virtual address to PCI address. */
- bus_dmamap_unload(ring->tag, desc->map);
-
- /* If this descriptor is the last segment of a packet, */
- /* then dequeue and free the corresponding mbuf chain. */
- if ((desc->control & TLP_DCTL_TX_LAST_SEG) != 0)
- {
- struct mbuf *m;
- if ((m = mbuf_dequeue(ring)) == NULL)
- panic("%s: txintr_cleanup: expected an mbuf\n", NAME_UNIT);
-
- /* Include CRC and one flag byte in output byte count. */
- sc->status.cntrs.obytes += m->m_pkthdr.len + sc->config.crc_len +1;
- sc->status.cntrs.opackets++;
- if_inc_counter(sc->ifp, IFCOUNTER_OPACKETS, 1);
- LMC_BPF_MTAP(m);
- /* The only bad TX status is fifo underrun. */
- if ((desc->status & TLP_DSTS_TX_UNDERRUN) != 0)
- sc->status.cntrs.fifo_under++;
-
- m_freem(m);
- return 1; /* did something */
- }
- }
-
- return 0;
- }
-
-/* Build DMA descriptors for a transmit packet mbuf chain. */
-static int /* 0=success; 1=error */ /* BSD version */
-txintr_setup_mbuf(softc_t *sc, struct mbuf *m)
- {
- struct desc_ring *ring = &sc->txring;
- struct dma_desc *desc;
- unsigned int desc_len;
-
- /* build DMA descriptors for a chain of mbufs. */
- while (m != NULL)
- {
- char *data = m->m_data;
- int length = m->m_len; /* zero length mbufs happen! */
-
- /* Build DMA descriptors for one mbuf. */
- while (length > 0)
- {
- int error;
-
- /* Ring is full if (wrap(write+1)==read) */
- if (((ring->temp==ring->last) ? ring->first : ring->temp+1) == ring->read)
- { /* Not enough DMA descriptors; try later. */
- for (; ring->temp!=ring->write;
- ring->temp = (ring->temp==ring->first)? ring->last : ring->temp-1)
- bus_dmamap_unload(ring->tag, ring->temp->map);
- sc->status.cntrs.txdma++;
- return 1;
- }
-
- /* Provisionally, write a descriptor into the ring. */
- /* But don't change the REAL ring write pointer. */
- /* Hardware won't see it until the OWNER bit is set. */
- desc = ring->temp;
- /* Advance the temporary ring write pointer. */
- if (ring->temp++ == ring->last) ring->temp = ring->first;
-
- /* Clear all control bits except the END_RING bit. */
- desc->control &= TLP_DCTL_END_RING;
- /* Don't pad short packets up to 64 bytes. */
- desc->control |= TLP_DCTL_TX_NO_PAD;
- /* Use Tulip's CRC-32 generator, if appropriate. */
- if (sc->config.crc_len != CFG_CRC_32)
- desc->control |= TLP_DCTL_TX_NO_CRC;
- /* Set the OWNER bit, except in the first descriptor. */
- if (desc != ring->write)
- desc->status = TLP_DSTS_OWNER;
-
- desc_len = (length > MAX_CHUNK_LEN) ? MAX_CHUNK_LEN : length;
- /* Map kernel virtual address to PCI address. */
- if ((error = DMA_LOAD(desc->map, data, desc_len)))
- printf("%s: bus_dmamap_load(tx) failed; error %d\n", NAME_UNIT, error);
- /* Flush the cache and if bouncing, copy mbuf to bounce buf. */
- DMA_SYNC(desc->map, desc_len, BUS_DMASYNC_PREWRITE);
-
- /* Prevent wild fetches if mapping fails (nsegs==0). */
- desc->length1 = desc->length2 = 0;
- desc->address1 = desc->address2 = 0;
- {
- bus_dma_segment_t *segs = ring->segs;
- int nsegs = ring->nsegs;
- if (nsegs >= 1)
- {
- desc->address1 = segs[0].ds_addr;
- desc->length1 = segs[0].ds_len;
- }
- if (nsegs == 2)
- {
- desc->address2 = segs[1].ds_addr;
- desc->length2 = segs[1].ds_len;
- }
- }
-
- data += desc_len;
- length -= desc_len;
- } /* while (length > 0) */
-
- m = m->m_next;
- } /* while (m != NULL) */
-
- return 0; /* success */
- }
-
-/* Setup (prepare) to transmit a packet. */
-/* Select a packet, build DMA descriptors and give packet to hardware. */
-/* If DMA descriptors run out, abandon the attempt and return 0. */
-static int /* BSD version */
-txintr_setup(softc_t *sc)
- {
- struct desc_ring *ring = &sc->txring;
- struct dma_desc *first_desc, *last_desc;
-
- /* Protect against half-up links: Don't transmit */
- /* if the receiver can't hear the far end. */
- if (sc->status.oper_status != STATUS_UP) return 0;
-
- /* Pick a packet to transmit. */
-#if NETGRAPH
- if ((sc->ng_hook != NULL) && (sc->tx_mbuf == NULL))
- {
- if (!IFQ_IS_EMPTY(&sc->ng_fastq))
- IFQ_DEQUEUE(&sc->ng_fastq, sc->tx_mbuf);
- else
- IFQ_DEQUEUE(&sc->ng_sndq, sc->tx_mbuf);
- }
- else
-#endif
- if (sc->tx_mbuf == NULL)
- {
- if (sc->config.line_pkg == PKG_RAWIP)
- IFQ_DEQUEUE(&sc->ifp->if_snd, sc->tx_mbuf);
- else
- {
-#if NSPPP
- sc->tx_mbuf = sppp_dequeue(sc->ifp);
-#elif P2P
- if (!IFQ_IS_EMPTY(&sc->p2p->p2p_isnd))
- IFQ_DEQUEUE(&sc->p2p->p2p_isnd, sc->tx_mbuf);
- else
- IFQ_DEQUEUE(&sc->ifp->if_snd, sc->tx_mbuf);
-#endif
- }
- }
- if (sc->tx_mbuf == NULL) return 0; /* no pkt to transmit */
-
- /* Build DMA descriptors for an outgoing mbuf chain. */
- ring->temp = ring->write; /* temporary ring write pointer */
- if (txintr_setup_mbuf(sc, sc->tx_mbuf) != 0) return 0;
-
- /* Enqueue the mbuf; txintr_cleanup will free it. */
- mbuf_enqueue(ring, sc->tx_mbuf);
-
- /* The transmitter has room for another packet. */
- sc->tx_mbuf = NULL;
-
- /* Set first & last segment bits. */
- /* last_desc is the desc BEFORE the one pointed to by ring->temp. */
- first_desc = ring->write;
- first_desc->control |= TLP_DCTL_TX_FIRST_SEG;
- last_desc = (ring->temp==ring->first)? ring->last : ring->temp-1;
- last_desc->control |= TLP_DCTL_TX_LAST_SEG;
- /* Interrupt at end-of-transmission? Why bother the poor computer! */
-/* last_desc->control |= TLP_DCTL_TX_INTERRUPT; */
-
- /* Make sure the OWNER bit is not set in the next descriptor. */
- /* The OWNER bit may have been set if a previous call aborted. */
- ring->temp->status = 0;
-
- /* Commit the DMA descriptors to the software. */
- ring->write = ring->temp;
-
- /* Before setting the OWNER bit, flush the cache (memory barrier). */
- DMA_SYNC(ring->map, ring->size_descs, BUS_DMASYNC_PREWRITE);
-
- /* Commit the DMA descriptors to the hardware. */
- first_desc->status = TLP_DSTS_OWNER;
-
- /* Notify the transmitter that there is another packet to send. */
- WRITE_CSR(TLP_TX_POLL, 1);
-
- return 1; /* did something */
- }
-
-
-
-static void
-check_intr_status(softc_t *sc)
- {
- u_int32_t status, cfcs, op_mode;
- u_int32_t missed, overruns;
-
- /* Check for four unusual events:
- * 1) fatal PCI bus errors - some are recoverable
- * 2) transmitter FIFO underruns - increase fifo threshold
- * 3) receiver FIFO overruns - clear potential hangup
- * 4) no receive descs or bufs - count missed packets
- */
-
- /* 1) A fatal bus error causes a Tulip to stop initiating bus cycles. */
- /* Module unload/load or boot are the only fixes for Parity Errors. */
- /* Master and Target Aborts can be cleared and life may continue. */
- status = READ_CSR(TLP_STATUS);
- if ((status & TLP_STAT_FATAL_ERROR) != 0)
- {
- u_int32_t fatal = (status & TLP_STAT_FATAL_BITS)>>TLP_STAT_FATAL_SHIFT;
- printf("%s: FATAL PCI BUS ERROR: %s%s%s%s\n", NAME_UNIT,
- (fatal == 0) ? "PARITY ERROR" : "",
- (fatal == 1) ? "MASTER ABORT" : "",
- (fatal == 2) ? "TARGET ABORT" : "",
- (fatal >= 3) ? "RESERVED (?)" : "");
- cfcs = READ_PCI_CFG(sc, TLP_CFCS); /* try to clear it */
- cfcs &= ~(TLP_CFCS_MSTR_ABORT | TLP_CFCS_TARG_ABORT);
- WRITE_PCI_CFG(sc, TLP_CFCS, cfcs);
- }
-
- /* 2) If the transmitter fifo underruns, increase the transmit fifo */
- /* threshold: the number of bytes required to be in the fifo */
- /* before starting the transmitter (cost: increased tx delay). */
- /* The TX_FSM must be stopped to change this parameter. */
- if ((status & TLP_STAT_TX_UNDERRUN) != 0)
- {
- op_mode = READ_CSR(TLP_OP_MODE);
- /* enable store-and-forward mode if tx_threshold tops out? */
- if ((op_mode & TLP_OP_TX_THRESH) < TLP_OP_TX_THRESH)
- {
- op_mode += 0x4000; /* increment TX_THRESH field; can't overflow */
- WRITE_CSR(TLP_OP_MODE, op_mode & ~TLP_OP_TX_RUN);
- /* Wait for the TX FSM to stop; it might be processing a pkt. */
- while (READ_CSR(TLP_STATUS) & TLP_STAT_TX_FSM); /* XXX HANG */
- WRITE_CSR(TLP_OP_MODE, op_mode); /* restart tx */
- if (DRIVER_DEBUG)
- printf("%s: tx underrun; tx fifo threshold now %d bytes\n",
- NAME_UNIT, 128<<((op_mode>>TLP_OP_TR_SHIFT)&3));
- }
- }
-
- /* 3) Errata memo from Digital Equipment Corp warns that 21140A */
- /* receivers through rev 2.2 can hang if the fifo overruns. */
- /* Recommended fix: stop and start the RX FSM after an overrun. */
- missed = READ_CSR(TLP_MISSED);
- if ((overruns = ((missed & TLP_MISS_OVERRUN)>>TLP_OVERRUN_SHIFT)) != 0)
- {
- if (DRIVER_DEBUG)
- printf("%s: rx overrun cntr=%d\n", NAME_UNIT, overruns);
- sc->status.cntrs.overruns += overruns;
- if ((READ_PCI_CFG(sc, TLP_CFRV) & 0xFF) <= 0x22)
- {
- op_mode = READ_CSR(TLP_OP_MODE);
- WRITE_CSR(TLP_OP_MODE, op_mode & ~TLP_OP_RX_RUN);
- /* Wait for the RX FSM to stop; it might be processing a pkt. */
- while (READ_CSR(TLP_STATUS) & TLP_STAT_RX_FSM); /* XXX HANG */
- WRITE_CSR(TLP_OP_MODE, op_mode); /* restart rx */
- }
- }
-
- /* 4) When the receiver is enabled and a packet arrives, but no DMA */
- /* descriptor is available, the packet is counted as 'missed'. */
- /* The receiver should never miss packets; warn if it happens. */
- if ((missed = (missed & TLP_MISS_MISSED)) != 0)
- {
- if (DRIVER_DEBUG)
- printf("%s: rx missed %d pkts\n", NAME_UNIT, missed);
- sc->status.cntrs.missed += missed;
- }
- }
-
-static void /* This is where the work gets done. */
-core_interrupt(void *arg, int check_status)
- {
- softc_t *sc = arg;
- int activity;
-
- /* If any CPU is inside this critical section, then */
- /* other CPUs should go away without doing anything. */
- if (BOTTOM_TRYLOCK == 0)
- {
- sc->status.cntrs.lck_intr++;
- return;
- }
-
- /* Clear pending card interrupts. */
- WRITE_CSR(TLP_STATUS, READ_CSR(TLP_STATUS));
-
- /* In Linux, pci_alloc_consistent() means DMA descriptors */
- /* don't need explicit syncing. */
- {
- struct desc_ring *ring = &sc->txring;
- DMA_SYNC(sc->txring.map, sc->txring.size_descs,
- BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
- ring = &sc->rxring;
- DMA_SYNC(sc->rxring.map, sc->rxring.size_descs,
- BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
- }
-
- do /* This is the main loop for interrupt processing. */
- {
- activity = txintr_cleanup(sc);
- activity += txintr_setup(sc);
- activity += rxintr_cleanup(sc);
- activity += rxintr_setup(sc);
- } while (activity);
-
- {
- struct desc_ring *ring = &sc->txring;
- DMA_SYNC(sc->txring.map, sc->txring.size_descs,
- BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- ring = &sc->rxring;
- DMA_SYNC(sc->rxring.map, sc->rxring.size_descs,
- BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- }
-
- /* As the interrupt is dismissed, check for four unusual events. */
- if (check_status) check_intr_status(sc);
-
- BOTTOM_UNLOCK;
- }
-
-/* user_interrupt() may be called from a syscall or a softirq */
-static void
-user_interrupt(softc_t *sc, int check_status)
- {
- DISABLE_INTR; /* noop on FreeBSD-5 and Linux */
- core_interrupt(sc, check_status);
- ENABLE_INTR; /* noop on FreeBSD-5 and Linux */
- }
-
-
-# if defined(DEVICE_POLLING)
-
-/* Service the card from the kernel idle loop without interrupts. */
-static int
-fbsd_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
- {
- softc_t *sc = IFP2SC(ifp);
-
-
- sc->quota = count;
- core_interrupt(sc, (cmd==POLL_AND_CHECK_STATUS));
- return 0;
- }
-
-# endif /* DEVICE_POLLING */
-
-/* BSD kernels call this procedure when an interrupt happens. */
-static intr_return_t
-bsd_interrupt(void *arg)
- {
- softc_t *sc = arg;
-
- /* Cut losses early if this is not our interrupt. */
- if ((READ_CSR(TLP_STATUS) & TLP_INT_TXRX) == 0)
- return IRQ_NONE;
-
-# if defined(DEVICE_POLLING)
- if (sc->ifp->if_capenable & IFCAP_POLLING)
- return IRQ_NONE;
-
- if ((sc->ifp->if_capabilities & IFCAP_POLLING) &&
- (ether_poll_register(fbsd_poll, sc->ifp)))
- {
- WRITE_CSR(TLP_INT_ENBL, TLP_INT_DISABLE);
- return IRQ_NONE;
- }
- else
- sc->quota = sc->rxring.num_descs; /* input flow control */
-# endif /* DEVICE_POLLING */
-
- /* Disable card interrupts. */
- WRITE_CSR(TLP_INT_ENBL, TLP_INT_DISABLE);
-
- core_interrupt(sc, 0);
-
- /* Enable card interrupts. */
- WRITE_CSR(TLP_INT_ENBL, TLP_INT_TXRX);
-
- return IRQ_HANDLED;
- }
-
-
-/* Administrative status of the driver (UP or DOWN) has changed. */
-/* A card-specific action may be required: T1 and T3 cards: no-op. */
-/* HSSI and SSI cards change the state of modem ready signals. */
-static void
-set_status(softc_t *sc, int status)
- {
- struct ioctl ioctl;
-
- ioctl.cmd = IOCTL_SET_STATUS;
- ioctl.data = status;
-
- sc->card->ioctl(sc, &ioctl);
- }
-
-#if P2P
-
-/* Callout from P2P: */
-/* Get the state of DCD (Data Carrier Detect). */
-static int
-p2p_getmdm(struct p2pcom *p2p, caddr_t result)
- {
- softc_t *sc = IFP2SC(&p2p->p2p_if);
-
- /* Non-zero isn't good enough; TIOCM_CAR is 0x40. */
- *(int *)result = (sc->status.oper_status==STATUS_UP) ? TIOCM_CAR : 0;
-
- return 0;
- }
-
-/* Callout from P2P: */
-/* Set the state of DTR (Data Terminal Ready). */
-static int
-p2p_mdmctl(struct p2pcom *p2p, int flag)
- {
- softc_t *sc = IFP2SC(&p2p->p2p_if);
-
- set_status(sc, flag);
-
- return 0;
- }
-
-#endif /* P2P */
-
-#if NSPPP
-
-# ifndef PP_FR
-# define PP_FR 0
-# endif
-
-/* Callout from SPPP: */
-static void
-sppp_tls(struct sppp *sppp)
- {
- if (!(sppp->pp_mode & IFF_LINK2) &&
- !(sppp->pp_flags & PP_FR))
- sppp->pp_up(sppp);
- }
-
-/* Callout from SPPP: */
-static void
-sppp_tlf(struct sppp *sppp)
- {
- if (!(sppp->pp_mode & IFF_LINK2) &&
- !(sppp->pp_flags & PP_FR))
- sppp->pp_down(sppp);
- }
-
-#endif /* NSPPP */
-
-/* Configure line protocol stuff.
- * Called by attach_card() during module init.
- * Called by core_ioctl() when lmcconfig writes sc->config.
- * Called by detach_card() during module shutdown.
- */
-static void
-config_proto(softc_t *sc, struct config *config)
- {
- /* Use line protocol stack instead of RAWIP mode. */
- if ((sc->config.line_pkg == PKG_RAWIP) &&
- (config->line_pkg != PKG_RAWIP))
- {
-#if NSPPP
- LMC_BPF_DETACH;
- sppp_attach(sc->ifp);
- LMC_BPF_ATTACH(DLT_PPP, 4);
- sc->sppp->pp_tls = sppp_tls;
- sc->sppp->pp_tlf = sppp_tlf;
- /* Force reconfiguration of SPPP params. */
- sc->config.line_prot = 0;
- sc->config.keep_alive = config->keep_alive ? 0:1;
-#elif P2P
- int error = 0;
- sc->p2p->p2p_proto = 0; /* force p2p_attach */
- if ((error = p2p_attach(sc->p2p))) /* calls bpfattach() */
- {
- printf("%s: p2p_attach() failed; error %d\n", NAME_UNIT, error);
- config->line_pkg = PKG_RAWIP; /* still in RAWIP mode */
- }
- else
- {
- sc->p2p->p2p_mdmctl = p2p_mdmctl; /* set DTR */
- sc->p2p->p2p_getmdm = p2p_getmdm; /* get DCD */
- }
-#elif GEN_HDLC
- int error = 0;
- sc->net_dev->mtu = HDLC_MAX_MTU;
- if ((error = hdlc_open(sc->net_dev)))
- {
- printf("%s: hdlc_open() failed; error %d\n", NAME_UNIT, error);
- printf("%s: Try 'sethdlc %s ppp'\n", NAME_UNIT, NAME_UNIT);
- config->line_pkg = PKG_RAWIP; /* still in RAWIP mode */
- }
-#else /* no line protocol stack was configured */
- config->line_pkg = PKG_RAWIP; /* still in RAWIP mode */
-#endif
- }
-
- /* Bypass line protocol stack and return to RAWIP mode. */
- if ((sc->config.line_pkg != PKG_RAWIP) &&
- (config->line_pkg == PKG_RAWIP))
- {
-#if NSPPP
- LMC_BPF_DETACH;
- sppp_flush(sc->ifp);
- sppp_detach(sc->ifp);
- setup_ifnet(sc->ifp);
- LMC_BPF_ATTACH(DLT_RAW, 0);
-#elif P2P
- int error = 0;
- if_qflush(&sc->p2p->p2p_isnd);
- if ((error = p2p_detach(sc->p2p)))
- {
- printf("%s: p2p_detach() failed; error %d\n", NAME_UNIT, error);
- printf("%s: Try 'ifconfig %s down -remove'\n", NAME_UNIT, NAME_UNIT);
- config->line_pkg = PKG_P2P; /* not in RAWIP mode; still attached to P2P */
- }
- else
- {
- setup_ifnet(sc->ifp);
- LMC_BPF_ATTACH(DLT_RAW, 0);
- }
-#elif GEN_HDLC
- hdlc_proto_detach(sc->hdlc_dev);
- hdlc_close(sc->net_dev);
- setup_netdev(sc->net_dev);
-#endif
- }
-
-#if NSPPP
-
- if (config->line_pkg != PKG_RAWIP)
- {
- /* Check for change to PPP protocol. */
- if ((sc->config.line_prot != PROT_PPP) &&
- (config->line_prot == PROT_PPP))
- {
- LMC_BPF_DETACH;
- sc->ifp->if_flags &= ~IFF_LINK2;
- sc->sppp->pp_flags &= ~PP_FR;
- LMC_BPF_ATTACH(DLT_PPP, 4);
- sppp_ioctl(sc->ifp, SIOCSIFFLAGS, NULL);
- }
-
-# ifndef DLT_C_HDLC
-# define DLT_C_HDLC DLT_PPP
-# endif
-
- /* Check for change to C_HDLC protocol. */
- if ((sc->config.line_prot != PROT_C_HDLC) &&
- (config->line_prot == PROT_C_HDLC))
- {
- LMC_BPF_DETACH;
- sc->ifp->if_flags |= IFF_LINK2;
- sc->sppp->pp_flags &= ~PP_FR;
- LMC_BPF_ATTACH(DLT_C_HDLC, 4);
- sppp_ioctl(sc->ifp, SIOCSIFFLAGS, NULL);
- }
-
- /* Check for change to Frame Relay protocol. */
- if ((sc->config.line_prot != PROT_FRM_RLY) &&
- (config->line_prot == PROT_FRM_RLY))
- {
- LMC_BPF_DETACH;
- sc->ifp->if_flags &= ~IFF_LINK2;
- sc->sppp->pp_flags |= PP_FR;
- LMC_BPF_ATTACH(DLT_FRELAY, 4);
- sppp_ioctl(sc->ifp, SIOCSIFFLAGS, NULL);
- }
-
- /* Check for disabling keep-alives. */
- if ((sc->config.keep_alive != 0) &&
- (config->keep_alive == 0))
- sc->sppp->pp_flags &= ~PP_KEEPALIVE;
-
- /* Check for enabling keep-alives. */
- if ((sc->config.keep_alive == 0) &&
- (config->keep_alive != 0))
- sc->sppp->pp_flags |= PP_KEEPALIVE;
- }
-
-#endif /* NSPPP */
-
- /* Loop back through the TULIP Ethernet chip; (no CRC). */
- /* Data sheet says stop DMA before changing OPMODE register. */
- /* But that's not as simple as it sounds; works anyway. */
- /* Check for enabling loopback thru Tulip chip. */
- if ((sc->config.loop_back != CFG_LOOP_TULIP) &&
- (config->loop_back == CFG_LOOP_TULIP))
- {
- u_int32_t op_mode = READ_CSR(TLP_OP_MODE);
- op_mode |= TLP_OP_INT_LOOP;
- WRITE_CSR(TLP_OP_MODE, op_mode);
- config->crc_len = CFG_CRC_0;
- }
-
- /* Check for disabling loopback thru Tulip chip. */
- if ((sc->config.loop_back == CFG_LOOP_TULIP) &&
- (config->loop_back != CFG_LOOP_TULIP))
- {
- u_int32_t op_mode = READ_CSR(TLP_OP_MODE);
- op_mode &= ~TLP_OP_LOOP_MODE;
- WRITE_CSR(TLP_OP_MODE, op_mode);
- config->crc_len = CFG_CRC_16;
- }
- }
-
-/* This is the core ioctl procedure. */
-/* It handles IOCTLs from lmcconfig(8). */
-/* It must not run when card watchdogs run. */
-/* Called from a syscall (user context; no spinlocks). */
-/* This procedure can SLEEP. */
-static int
-core_ioctl(softc_t *sc, u_long cmd, caddr_t data)
- {
- struct iohdr *iohdr = (struct iohdr *) data;
- struct ioctl *ioctl = (struct ioctl *) data;
- struct status *status = (struct status *) data;
- struct config *config = (struct config *) data;
- int error = 0;
-
- /* All structs start with a string and a cookie. */
- if (((struct iohdr *)data)->cookie != NGM_LMC_COOKIE)
- return EINVAL;
-
- while (TOP_TRYLOCK == 0)
- {
- sc->status.cntrs.lck_ioctl++;
- SLEEP(10000); /* yield? */
- }
- switch (cmd)
- {
- case LMCIOCGSTAT:
- {
- *status = sc->status;
- iohdr->cookie = NGM_LMC_COOKIE;
- break;
- }
- case LMCIOCGCFG:
- {
- *config = sc->config;
- iohdr->cookie = NGM_LMC_COOKIE;
- break;
- }
- case LMCIOCSCFG:
- {
- if ((error = CHECK_CAP)) break;
- config_proto(sc, config);
- sc->config = *config;
- sc->card->config(sc);
- break;
- }
- case LMCIOCREAD:
- {
- if (ioctl->cmd == IOCTL_RW_PCI)
- {
- if (ioctl->address > 252) { error = EFAULT; break; }
- ioctl->data = READ_PCI_CFG(sc, ioctl->address);
- }
- else if (ioctl->cmd == IOCTL_RW_CSR)
- {
- if (ioctl->address > 15) { error = EFAULT; break; }
- ioctl->data = READ_CSR(ioctl->address*TLP_CSR_STRIDE);
- }
- else if (ioctl->cmd == IOCTL_RW_SROM)
- {
- if (ioctl->address > 63) { error = EFAULT; break; }
- ioctl->data = read_srom(sc, ioctl->address);
- }
- else if (ioctl->cmd == IOCTL_RW_BIOS)
- ioctl->data = read_bios(sc, ioctl->address);
- else if (ioctl->cmd == IOCTL_RW_MII)
- ioctl->data = read_mii(sc, ioctl->address);
- else if (ioctl->cmd == IOCTL_RW_FRAME)
- ioctl->data = read_framer(sc, ioctl->address);
- else
- error = EINVAL;
- break;
- }
- case LMCIOCWRITE:
- {
- if ((error = CHECK_CAP)) break;
- if (ioctl->cmd == IOCTL_RW_PCI)
- {
- if (ioctl->address > 252) { error = EFAULT; break; }
- WRITE_PCI_CFG(sc, ioctl->address, ioctl->data);
- }
- else if (ioctl->cmd == IOCTL_RW_CSR)
- {
- if (ioctl->address > 15) { error = EFAULT; break; }
- WRITE_CSR(ioctl->address*TLP_CSR_STRIDE, ioctl->data);
- }
- else if (ioctl->cmd == IOCTL_RW_SROM)
- {
- if (ioctl->address > 63) { error = EFAULT; break; }
- write_srom(sc, ioctl->address, ioctl->data); /* can sleep */
- }
- else if (ioctl->cmd == IOCTL_RW_BIOS)
- {
- if (ioctl->address == 0) erase_bios(sc);
- write_bios(sc, ioctl->address, ioctl->data); /* can sleep */
- }
- else if (ioctl->cmd == IOCTL_RW_MII)
- write_mii(sc, ioctl->address, ioctl->data);
- else if (ioctl->cmd == IOCTL_RW_FRAME)
- write_framer(sc, ioctl->address, ioctl->data);
- else if (ioctl->cmd == IOCTL_WO_SYNTH)
- write_synth(sc, (struct synth *)&ioctl->data);
- else if (ioctl->cmd == IOCTL_WO_DAC)
- {
- write_dac(sc, 0x9002); /* set Vref = 2.048 volts */
- write_dac(sc, ioctl->data & 0xFFF);
- }
- else
- error = EINVAL;
- break;
- }
- case LMCIOCTL:
- {
- if ((error = CHECK_CAP)) break;
- if (ioctl->cmd == IOCTL_XILINX_RESET)
- {
- reset_xilinx(sc);
- sc->card->config(sc);
- }
- else if (ioctl->cmd == IOCTL_XILINX_ROM)
- {
- load_xilinx_from_rom(sc); /* can sleep */
- sc->card->config(sc);
- }
- else if (ioctl->cmd == IOCTL_XILINX_FILE)
- {
- /* load_xilinx_from_file() can sleep. */
- error = load_xilinx_from_file(sc, ioctl->ucode, ioctl->data);
- if (error != 0) load_xilinx_from_rom(sc); /* try the rom */
- sc->card->config(sc);
- set_status(sc, (error==0)); /* XXX */
- }
- else if (ioctl->cmd == IOCTL_RESET_CNTRS)
- {
- memset(&sc->status.cntrs, 0, sizeof(struct event_cntrs));
- microtime(&sc->status.cntrs.reset_time);
- }
- else
- error = sc->card->ioctl(sc, ioctl); /* can sleep */
- break;
- }
- default:
- error = EINVAL;
- break;
- }
- TOP_UNLOCK;
-
- return error;
- }
-
-/* This is the core watchdog procedure. */
-/* It calculates link speed, and calls the card-specific watchdog code. */
-/* Calls interrupt() in case one got lost; also kick-starts the device. */
-/* ioctl syscalls and card watchdog routines must be interlocked. */
-/* This procedure must not sleep. */
-static void
-core_watchdog(softc_t *sc)
- {
- /* Read and restart the Tulip timer. */
- u_int32_t tx_speed = READ_CSR(TLP_TIMER);
- WRITE_CSR(TLP_TIMER, 0xFFFF);
-
- /* Measure MII clock using a timer in the Tulip chip.
- * This timer counts transmitter bits divided by 4096.
- * Since this is called once a second the math is easy.
- * This is only correct when the link is NOT sending pkts.
- * On a fully-loaded link, answer will be HALF actual rate.
- * Clock rate during pkt is HALF clk rate between pkts.
- * Measuring clock rate really measures link utilization!
- */
- sc->status.tx_speed = (0xFFFF - (tx_speed & 0xFFFF)) << 12;
-
- /* The first status reset time is when the calendar clock is set. */
- if (sc->status.cntrs.reset_time.tv_sec < 1000)
- microtime(&sc->status.cntrs.reset_time);
-
- /* Update hardware (operational) status. */
- /* Call the card-specific watchdog routines. */
- if (TOP_TRYLOCK != 0)
- {
- sc->status.oper_status = sc->card->watchdog(sc);
-
- /* Increment a counter which tells user-land */
- /* observers that SNMP state has been updated. */
- sc->status.ticks++;
-
- TOP_UNLOCK;
- }
- else
- sc->status.cntrs.lck_watch++;
-
- /* In case an interrupt gets lost... */
- user_interrupt(sc, 1);
- }
-
-
-/* Called from a syscall (user context; no spinlocks). */
-static int
-lmc_raw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
- {
- struct ifreq *ifr = (struct ifreq *) data;
- int error = 0;
-
- switch (cmd)
- {
- case SIOCAIFADDR:
- case SIOCSIFFLAGS:
- case SIOCSIFADDR:
- ifp->if_flags |= IFF_UP; /* a Unix tradition */
- break;
- case SIOCSIFMTU:
- ifp->if_mtu = ifr->ifr_mtu;
- break;
- default:
- error = EINVAL;
- break;
- }
- return error;
- }
-
-/* Called from a syscall (user context; no spinlocks). */
-static int
-lmc_ifnet_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
- {
- softc_t *sc = IFP2SC(ifp);
- int error = 0;
-
- switch (cmd)
- {
- /* Catch the IOCTLs used by lmcconfig. */
- case LMCIOCGSTAT:
- case LMCIOCGCFG:
- case LMCIOCSCFG:
- case LMCIOCREAD:
- case LMCIOCWRITE:
- case LMCIOCTL:
- error = core_ioctl(sc, cmd, data);
- break;
- /* Pass the rest to the line protocol. */
- default:
- if (sc->config.line_pkg == PKG_RAWIP)
- error = lmc_raw_ioctl(ifp, cmd, data);
- else
-# if NSPPP
- error = sppp_ioctl(ifp, cmd, data);
-# elif P2P
- error = p2p_ioctl(ifp, cmd, data);
-# else
- error = EINVAL;
-# endif
- break;
- }
-
- if (DRIVER_DEBUG && (error!=0))
- printf("%s: lmc_ifnet_ioctl; cmd=0x%08lx error=%d\n",
- NAME_UNIT, cmd, error);
-
- return error;
- }
-
-/* Called from a syscall (user context; no spinlocks). */
-static void
-lmc_ifnet_start(struct ifnet *ifp)
- {
- softc_t *sc = IFP2SC(ifp);
-
- /* Start the transmitter; incoming pkts are NOT processed. */
- user_interrupt(sc, 0);
- }
-
-/* sppp and p2p replace this with their own proc. */
-/* RAWIP mode is the only time this is used. */
-/* Called from a syscall (user context; no spinlocks). */
-static int
-lmc_raw_output(struct ifnet *ifp, struct mbuf *m,
- const struct sockaddr *dst, struct route *ro)
- {
- softc_t *sc = IFP2SC(ifp);
- int error = 0;
-
- /* Fail if the link is down. */
- if (sc->status.oper_status != STATUS_UP)
- {
- m_freem(m);
- sc->status.cntrs.odiscards++;
- if (DRIVER_DEBUG)
- printf("%s: lmc_raw_output: tx pkt discarded: link down\n", NAME_UNIT);
- return ENETDOWN;
- }
-
-# if NETGRAPH
- /* Netgraph has priority over the ifnet kernel interface. */
- if (sc->ng_hook != NULL)
- {
- m_freem(m);
- sc->status.cntrs.odiscards++;
- if (DRIVER_DEBUG)
- printf("%s: lmc_raw_output: tx pkt discarded: netgraph active\n",
- NAME_UNIT);
- return EBUSY;
- }
-# endif
-
- /* lmc_raw_output() ENQUEUEs in a syscall or softirq. */
- /* txintr_setup() DEQUEUEs in a hard interrupt. */
- /* Some BSD QUEUE routines are not interrupt-safe. */
- {
- DISABLE_INTR;
- IFQ_ENQUEUE(&ifp->if_snd, m, error);
- ENABLE_INTR;
- }
-
- if (error==0)
- user_interrupt(sc, 0); /* start the transmitter */
- else
- {
- m_freem(m);
- sc->status.cntrs.odiscards++;
- if_inc_counter(ifp, IFCOUNTER_OQDROPS, 1);
- if (DRIVER_DEBUG)
- printf("%s: lmc_raw_output: IFQ_ENQUEUE() failed; error %d\n",
- NAME_UNIT, error);
- }
-
- return error;
- }
-
-/* Called from a softirq once a second. */
-static void
-lmc_watchdog(void *arg)
-{
- struct ifnet *ifp = arg;
- softc_t *sc = IFP2SC(ifp);
- u_int8_t old_oper_status = sc->status.oper_status;
-
- core_watchdog(sc); /* updates oper_status */
-
-#if NETGRAPH
- if (sc->ng_hook != NULL)
- {
- sc->status.line_pkg = PKG_NG;
- sc->status.line_prot = 0;
- }
- else
-#endif
- if (sc->config.line_pkg == PKG_RAWIP)
- {
- sc->status.line_pkg = PKG_RAWIP;
- sc->status.line_prot = PROT_IP_HDLC;
- }
- else
- {
-# if P2P
- /* Notice change in link status. */
- if ((old_oper_status != sc->status.oper_status) && (sc->p2p->p2p_modem))
- (*sc->p2p->p2p_modem)(sc->p2p, sc->status.oper_status==STATUS_UP);
-
- /* Notice change in line protocol. */
- sc->status.line_pkg = PKG_P2P;
- switch (sc->ifp->if_type)
- {
- case IFT_PPP:
- sc->status.line_prot = PROT_PPP;
- break;
- case IFT_PTPSERIAL:
- sc->status.line_prot = PROT_C_HDLC;
- break;
- case IFT_FRELAY:
- sc->status.line_prot = PROT_FRM_RLY;
- break;
- default:
- sc->status.line_prot = 0;
- break;
- }
-
-# elif NSPPP
- /* Notice change in link status. */
- if ((old_oper_status != STATUS_UP) &&
- (sc->status.oper_status == STATUS_UP)) /* link came up */
- sppp_tls(sc->sppp);
- if ((old_oper_status == STATUS_UP) &&
- (sc->status.oper_status != STATUS_UP)) /* link went down */
- sppp_tlf(sc->sppp);
-
- /* Notice change in line protocol. */
- sc->status.line_pkg = PKG_SPPP;
- if (sc->sppp->pp_flags & PP_FR)
- sc->status.line_prot = PROT_FRM_RLY;
- else if (sc->ifp->if_flags & IFF_LINK2)
- sc->status.line_prot = PROT_C_HDLC;
- else
- sc->status.line_prot = PROT_PPP;
-
-# else
- /* Suppress compiler warning. */
- if (old_oper_status == STATUS_UP);
-# endif
- }
-
- ifp->if_baudrate = sc->status.tx_speed;
- if (sc->status.oper_status == STATUS_UP)
- ifp->if_link_state = LINK_STATE_UP;
- else
- ifp->if_link_state = LINK_STATE_DOWN;
-
- /* Call this procedure again after one second. */
- callout_reset(&sc->callout, hz, lmc_watchdog, ifp);
-}
-
-static uint64_t
-lmc_get_counter(struct ifnet *ifp, ift_counter cnt)
-{
- softc_t *sc;
- struct event_cntrs *cntrs;
-
- sc = if_getsoftc(ifp);
- cntrs = &sc->status.cntrs;
-
- switch (cnt) {
- case IFCOUNTER_IPACKETS:
- return (cntrs->ipackets);
- case IFCOUNTER_OPACKETS:
- return (cntrs->opackets);
- case IFCOUNTER_IBYTES:
- return (cntrs->ibytes);
- case IFCOUNTER_OBYTES:
- return (cntrs->obytes);
- case IFCOUNTER_IERRORS:
- return (cntrs->ierrors);
- case IFCOUNTER_OERRORS:
- return (cntrs->oerrors);
- case IFCOUNTER_IQDROPS:
- return (cntrs->idiscards);
- default:
- return (if_get_counter_default(ifp, cnt));
- }
-}
-
-static void
-setup_ifnet(struct ifnet *ifp)
- {
- softc_t *sc = ifp->if_softc;
-
- /* Initialize the generic network interface. */
- ifp->if_flags = IFF_POINTOPOINT;
- ifp->if_flags |= IFF_RUNNING;
- ifp->if_ioctl = lmc_ifnet_ioctl;
- ifp->if_start = lmc_ifnet_start; /* sppp changes this */
- ifp->if_output = lmc_raw_output; /* sppp & p2p change this */
- ifp->if_input = lmc_raw_input;
- ifp->if_get_counter = lmc_get_counter;
- ifp->if_mtu = MAX_DESC_LEN; /* sppp & p2p change this */
- ifp->if_type = IFT_PTPSERIAL; /* p2p changes this */
-
-# if defined(DEVICE_POLLING)
- ifp->if_capabilities |= IFCAP_POLLING;
-# endif
-
- if_initname(ifp, device_get_name(sc->dev), device_get_unit(sc->dev));
- }
-
-static int
-lmc_ifnet_attach(softc_t *sc)
- {
- sc->ifp = if_alloc(NSPPP ? IFT_PPP : IFT_OTHER);
- if (sc->ifp == NULL) return ENOMEM;
-# if NSPPP
- sc->sppp = sc->ifp->if_l2com;
-# elif P2P
- sc->ifp = &sc->p2pcom.p2p_if;
- sc->p2p = &sc->p2pcom;
-# endif
-
- /* Initialize the network interface struct. */
- sc->ifp->if_softc = sc;
- setup_ifnet(sc->ifp);
-
- /* ALTQ output queue initialization. */
- IFQ_SET_MAXLEN(&sc->ifp->if_snd, SNDQ_MAXLEN);
- IFQ_SET_READY(&sc->ifp->if_snd);
-
- /* Attach to the ifnet kernel interface. */
- if_attach(sc->ifp);
-
- /* Attach Berkeley Packet Filter. */
- LMC_BPF_ATTACH(DLT_RAW, 0);
-
- callout_reset(&sc->callout, hz, lmc_watchdog, sc);
-
- return 0;
- }
-
-static void
-lmc_ifnet_detach(softc_t *sc)
- {
-
-# if defined(DEVICE_POLLING)
- if (sc->ifp->if_capenable & IFCAP_POLLING)
- ether_poll_deregister(sc->ifp);
-# endif
-
- /* Detach Berkeley Packet Filter. */
- LMC_BPF_DETACH;
-
- /* Detach from the ifnet kernel interface. */
- if_detach(sc->ifp);
-
- if_free(sc->ifp);
- }
-
-
-#if NETGRAPH
-
-/* These next two macros should be added to netgraph */
-# define NG_TYPE_REF(type) atomic_add_int(&(type)->refs, 1)
-# define NG_TYPE_UNREF(type) \
-do { \
- if ((type)->refs == 1) \
- ng_rmtype(type); \
- else \
- atomic_subtract_int(&(type)->refs, 1); \
- } while (0)
-
-/* It is an error to construct new copies of this Netgraph node. */
-/* All instances are constructed by ng_attach and are persistent. */
-static int ng_constructor(node_p node) { return EINVAL; }
-
-/* Incoming Netgraph control message. */
-static int
-ng_rcvmsg(node_p node, item_p item, hook_p lasthook)
- {
- struct ng_mesg *msg;
- struct ng_mesg *resp = NULL;
- softc_t *sc = NG_NODE_PRIVATE(node);
- int error = 0;
-
- NGI_GET_MSG(item, msg);
- if (msg->header.typecookie == NGM_LMC_COOKIE)
- {
- switch (msg->header.cmd)
- {
- case LMCIOCGSTAT:
- case LMCIOCGCFG:
- case LMCIOCSCFG:
- case LMCIOCREAD:
- case LMCIOCWRITE:
- case LMCIOCTL:
- {
- /* Call the core ioctl procedure. */
- error = core_ioctl(sc, msg->header.cmd, msg->data);
- if ((msg->header.cmd & IOC_OUT) != 0)
- { /* synchronous response */
- NG_MKRESPONSE(resp, msg, sizeof(struct ng_mesg) +
- IOCPARM_LEN(msg->header.cmd), M_NOWAIT);
- if (resp == NULL)
- error = ENOMEM;
- else
- memcpy(resp->data, msg->data, IOCPARM_LEN(msg->header.cmd));
- }
- break;
- }
- default:
- error = EINVAL;
- break;
- }
- }
- else if ((msg->header.typecookie == NGM_GENERIC_COOKIE) &&
- (msg->header.cmd == NGM_TEXT_STATUS))
- { /* synchronous response */
- NG_MKRESPONSE(resp, msg, sizeof(struct ng_mesg) +
- NG_TEXTRESPONSE, M_NOWAIT);
- if (resp == NULL)
- error = ENOMEM;
- else
- {
- char *s = resp->data;
- sprintf(s, "Card type = <%s>\n"
- "This driver considers the link to be %s.\n"
- "Use lmcconfig to configure this interface.\n",
- sc->dev_desc, (sc->status.oper_status==STATUS_UP) ? "UP" : "DOWN");
- resp->header.arglen = strlen(s) +1;
- }
- }
- else
-/* Netgraph should be able to read and write these
- * parameters with text-format control messages:
- * SSI HSSI T1E1 T3
- * crc crc crc crc
- * loop loop loop loop
- * clksrc clksrc
- * dte dte format format
- * synth synth cablen cablen
- * cable timeslot scram
- * gain
- * pulse
- * lbo
- * Someday I'll implement this...
- */
- error = EINVAL;
-
- /* Handle synchronous response. */
- NG_RESPOND_MSG(error, node, item, resp);
- NG_FREE_MSG(msg);
-
- return error;
- }
-
-/* This is a persistent netgraph node. */
-static int
-ng_shutdown(node_p node)
- {
- /* unless told to really die, bounce back to life */
- if ((node->nd_flags & NG_REALLY_DIE)==0)
- node->nd_flags &= ~NG_INVALID; /* bounce back to life */
-
- return 0;
- }
-
-/* ng_disconnect is the opposite of this procedure. */
-static int
-ng_newhook(node_p node, hook_p hook, const char *name)
- {
- softc_t *sc = NG_NODE_PRIVATE(node);
-
- /* Hook name must be 'rawdata'. */
- if (strncmp(name, "rawdata", 7) != 0) return EINVAL;
-
- /* Is our hook connected? */
- if (sc->ng_hook != NULL) return EBUSY;
-
- /* Accept the hook. */
- sc->ng_hook = hook;
-
- return 0;
- }
-
-/* Both ends have accepted their hooks and the links have been made. */
-/* This is the last chance to reject the connection request. */
-static int
-ng_connect(hook_p hook)
- {
- /* Probably not at splnet, force outward queueing. (huh?) */
- NG_HOOK_FORCE_QUEUE(NG_HOOK_PEER(hook));
- return 0; /* always accept */
- }
-
-/* Receive data in mbufs from another Netgraph node. */
-/* Transmit an mbuf-chain on the communication link. */
-/* This procedure is very similar to lmc_raw_output(). */
-/* Called from a syscall (user context; no spinlocks). */
-static int
-ng_rcvdata(hook_p hook, item_p item)
- {
- softc_t *sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
- int error = 0;
- struct mbuf *m;
- meta_p meta = NULL;
-
- NGI_GET_M(item, m);
- NGI_GET_META(item, meta);
- NG_FREE_ITEM(item);
-
- /* This macro must not store into meta! */
- NG_FREE_META(meta);
-
- /* Fail if the link is down. */
- if (sc->status.oper_status != STATUS_UP)
- {
- m_freem(m);
- sc->status.cntrs.odiscards++;
- if (DRIVER_DEBUG)
- printf("%s: ng_rcvdata: tx pkt discarded: link down\n", NAME_UNIT);
- return ENETDOWN;
- }
-
- /* ng_rcvdata() ENQUEUEs in a syscall or softirq. */
- /* txintr_setup() DEQUEUEs in a hard interrupt. */
- /* Some BSD QUEUE routines are not interrupt-safe. */
- {
- DISABLE_INTR;
- if (meta==NULL)
- IFQ_ENQUEUE(&sc->ng_sndq, m, error);
- else
- IFQ_ENQUEUE(&sc->ng_fastq, m, error);
- ENABLE_INTR;
- }
-
- if (error==0)
- user_interrupt(sc, 0); /* start the transmitter */
- else
- {
- m_freem(m);
- sc->status.cntrs.odiscards++;
- if (DRIVER_DEBUG)
- printf("%s: ng_rcvdata: IFQ_ENQUEUE() failed; error %d\n",
- NAME_UNIT, error);
- }
-
- return error;
- }
-
-/* ng_newhook is the opposite of this procedure, not */
-/* ng_connect, as you might expect from the names. */
-static int
-ng_disconnect(hook_p hook)
- {
- softc_t *sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
-
- /* Disconnect the hook. */
- sc->ng_hook = NULL;
-
- return 0;
- }
-
-static
-struct ng_type ng_type =
- {
- .version = NG_ABI_VERSION,
- .name = NG_LMC_NODE_TYPE,
- .mod_event = NULL,
- .constructor = ng_constructor,
- .rcvmsg = ng_rcvmsg,
- .close = NULL,
- .shutdown = ng_shutdown,
- .newhook = ng_newhook,
- .findhook = NULL,
- .connect = ng_connect,
- .rcvdata = ng_rcvdata,
- .disconnect = ng_disconnect,
- };
-
-
-/* Attach to the Netgraph kernel interface (/sys/netgraph).
- * It is called once for each physical card during device attach.
- * This is effectively ng_constructor.
- */
-static int
-ng_attach(softc_t *sc)
- {
- int error;
-
- /* If this node type is not known to Netgraph then register it. */
- if (ng_type.refs == 0) /* or: if (ng_findtype(&ng_type) == NULL) */
- {
- if ((error = ng_newtype(&ng_type)))
- {
- printf("%s: ng_newtype() failed; error %d\n", NAME_UNIT, error);
- return error;
- }
- }
- else
- NG_TYPE_REF(&ng_type);
-
- /* Call the superclass node constructor. */
- if ((error = ng_make_node_common(&ng_type, &sc->ng_node)))
- {
- NG_TYPE_UNREF(&ng_type);
- printf("%s: ng_make_node_common() failed; error %d\n", NAME_UNIT, error);
- return error;
- }
-
- /* Associate a name with this netgraph node. */
- if ((error = ng_name_node(sc->ng_node, NAME_UNIT)))
- {
- NG_NODE_UNREF(sc->ng_node);
- NG_TYPE_UNREF(&ng_type);
- printf("%s: ng_name_node() failed; error %d\n", NAME_UNIT, error);
- return error;
- }
-
- /* Initialize the send queue mutexes. */
- mtx_init(&sc->ng_sndq.ifq_mtx, NAME_UNIT, "sndq", MTX_DEF);
- mtx_init(&sc->ng_fastq.ifq_mtx, NAME_UNIT, "fastq", MTX_DEF);
-
- /* Put a backpointer to the softc in the netgraph node. */
- NG_NODE_SET_PRIVATE(sc->ng_node, sc);
-
- /* ALTQ output queue initialization. */
- IFQ_SET_MAXLEN(&sc->ng_fastq, SNDQ_MAXLEN);
- IFQ_SET_READY(&sc->ng_fastq);
- IFQ_SET_MAXLEN(&sc->ng_sndq, SNDQ_MAXLEN);
- IFQ_SET_READY(&sc->ng_sndq);
-
-
- return 0;
- }
-
-static void
-ng_detach(softc_t *sc)
- {
- callout_drain(&sc->callout);
- mtx_destroy(&sc->ng_sndq.ifq_mtx);
- mtx_destroy(&sc->ng_fastq.ifq_mtx);
- ng_rmnode_self(sc->ng_node); /* free hook */
- NG_NODE_UNREF(sc->ng_node); /* free node */
- NG_TYPE_UNREF(&ng_type);
- }
-
-#endif /* NETGRAPH */
-
-/* The next few procedures initialize the card. */
-
-/* Returns 0 on success; error code on failure. */
-static int
-startup_card(softc_t *sc)
- {
- int num_rx_descs, error = 0;
- u_int32_t tlp_bus_pbl, tlp_bus_cal, tlp_op_tr;
- u_int32_t tlp_cfdd, tlp_cfcs;
- u_int32_t tlp_cflt, tlp_csid, tlp_cfit;
-
- /* Make sure the COMMAND bits are reasonable. */
- tlp_cfcs = READ_PCI_CFG(sc, TLP_CFCS);
- tlp_cfcs &= ~TLP_CFCS_MWI_ENABLE;
- tlp_cfcs |= TLP_CFCS_BUS_MASTER;
- tlp_cfcs |= TLP_CFCS_MEM_ENABLE;
- tlp_cfcs |= TLP_CFCS_IO_ENABLE;
- tlp_cfcs |= TLP_CFCS_PAR_ERROR;
- tlp_cfcs |= TLP_CFCS_SYS_ERROR;
- WRITE_PCI_CFG(sc, TLP_CFCS, tlp_cfcs);
-
- /* Set the LATENCY TIMER to the recommended value, */
- /* and make sure the CACHE LINE SIZE is reasonable. */
- tlp_cfit = READ_PCI_CFG(sc, TLP_CFIT);
- tlp_cflt = READ_PCI_CFG(sc, TLP_CFLT);
- tlp_cflt &= ~TLP_CFLT_LATENCY;
- tlp_cflt |= (tlp_cfit & TLP_CFIT_MAX_LAT)>>16;
- /* "prgmbl burst length" and "cache alignment" used below. */
- switch(tlp_cflt & TLP_CFLT_CACHE)
- {
- case 8: /* 8 bytes per cache line */
- { tlp_bus_pbl = 32; tlp_bus_cal = 1; break; }
- case 16:
- { tlp_bus_pbl = 32; tlp_bus_cal = 2; break; }
- case 32:
- { tlp_bus_pbl = 32; tlp_bus_cal = 3; break; }
- default:
- {
- tlp_bus_pbl = 32; tlp_bus_cal = 1;
- tlp_cflt &= ~TLP_CFLT_CACHE;
- tlp_cflt |= 8;
- break;
- }
- }
- WRITE_PCI_CFG(sc, TLP_CFLT, tlp_cflt);
-
- /* Make sure SNOOZE and SLEEP modes are disabled. */
- tlp_cfdd = READ_PCI_CFG(sc, TLP_CFDD);
- tlp_cfdd &= ~TLP_CFDD_SLEEP;
- tlp_cfdd &= ~TLP_CFDD_SNOOZE;
- WRITE_PCI_CFG(sc, TLP_CFDD, tlp_cfdd);
- DELAY(11*1000); /* Tulip wakes up in 10 ms max */
-
- /* Software Reset the Tulip chip; stops DMA and Interrupts. */
- /* This does not change the PCI config regs just set above. */
- WRITE_CSR(TLP_BUS_MODE, TLP_BUS_RESET); /* self-clearing */
- DELAY(5); /* Tulip is dead for 50 PCI cycles after reset. */
-
- /* Reset the Xilinx Field Programmable Gate Array. */
- reset_xilinx(sc); /* side effect: turns on all four LEDs */
-
- /* Configure card-specific stuff (framers, line interfaces, etc.). */
- sc->card->config(sc);
-
- /* Initializing cards can glitch clocks and upset fifos. */
- /* Reset the FIFOs between the Tulip and Xilinx chips. */
- set_mii16_bits(sc, MII16_FIFO);
- clr_mii16_bits(sc, MII16_FIFO);
-
- /* Initialize the PCI busmode register. */
- /* The PCI bus cycle type "Memory Write and Invalidate" does NOT */
- /* work cleanly in any version of the 21140A, so don't enable it! */
- WRITE_CSR(TLP_BUS_MODE,
- (tlp_bus_cal ? TLP_BUS_READ_LINE : 0) |
- (tlp_bus_cal ? TLP_BUS_READ_MULT : 0) |
- (tlp_bus_pbl<<TLP_BUS_PBL_SHIFT) |
- (tlp_bus_cal<<TLP_BUS_CAL_SHIFT) |
- ((BYTE_ORDER == BIG_ENDIAN) ? TLP_BUS_DESC_BIGEND : 0) |
- ((BYTE_ORDER == BIG_ENDIAN) ? TLP_BUS_DATA_BIGEND : 0) |
- TLP_BUS_DSL_VAL |
- TLP_BUS_ARB);
-
- /* Pick number of RX descriptors and TX fifo threshold. */
- /* tx_threshold in bytes: 0=128, 1=256, 2=512, 3=1024 */
- tlp_csid = READ_PCI_CFG(sc, TLP_CSID);
- switch(tlp_csid)
- {
- case TLP_CSID_HSSI: /* 52 Mb/s */
- case TLP_CSID_HSSIc: /* 52 Mb/s */
- case TLP_CSID_T3: /* 45 Mb/s */
- { num_rx_descs = 48; tlp_op_tr = 2; break; }
- case TLP_CSID_SSI: /* 10 Mb/s */
- { num_rx_descs = 32; tlp_op_tr = 1; break; }
- case TLP_CSID_T1E1: /* 2 Mb/s */
- { num_rx_descs = 16; tlp_op_tr = 0; break; }
- default:
- { num_rx_descs = 16; tlp_op_tr = 0; break; }
- }
-
- /* Create DMA descriptors and initialize list head registers. */
- if ((error = create_ring(sc, &sc->txring, NUM_TX_DESCS))) return error;
- WRITE_CSR(TLP_TX_LIST, sc->txring.dma_addr);
- if ((error = create_ring(sc, &sc->rxring, num_rx_descs))) return error;
- WRITE_CSR(TLP_RX_LIST, sc->rxring.dma_addr);
-
- /* Initialize the operating mode register. */
- WRITE_CSR(TLP_OP_MODE, TLP_OP_INIT | (tlp_op_tr<<TLP_OP_TR_SHIFT));
-
- /* Read the missed frame register (result ignored) to zero it. */
- error = READ_CSR( TLP_MISSED); /* error is used as a bit-dump */
-
- /* Disable rx watchdog and tx jabber features. */
- WRITE_CSR(TLP_WDOG, TLP_WDOG_INIT);
-
- /* Enable card interrupts. */
- WRITE_CSR(TLP_INT_ENBL, TLP_INT_TXRX);
-
- return 0;
- }
-
-/* Stop DMA and Interrupts; free descriptors and buffers. */
-static void
-shutdown_card(void *arg)
- {
- softc_t *sc = arg;
-
- /* Leave the LEDs in the state they were in after power-on. */
- led_on(sc, MII16_LED_ALL);
-
- /* Software reset the Tulip chip; stops DMA and Interrupts */
- WRITE_CSR(TLP_BUS_MODE, TLP_BUS_RESET); /* self-clearing */
- DELAY(5); /* Tulip is dead for 50 PCI cycles after reset. */
-
- /* Disconnect from the PCI bus except for config cycles. */
- /* Hmmm; Linux syslogs a warning that IO and MEM are disabled. */
- WRITE_PCI_CFG(sc, TLP_CFCS, TLP_CFCS_MEM_ENABLE | TLP_CFCS_IO_ENABLE);
-
- /* Free the DMA descriptor rings. */
- destroy_ring(sc, &sc->txring);
- destroy_ring(sc, &sc->rxring);
- }
-
-/* Start the card and attach a kernel interface and line protocol. */
-static int
-attach_card(softc_t *sc, const char *intrstr)
- {
- struct config config;
- u_int32_t tlp_cfrv;
- u_int16_t mii3;
- u_int8_t *ieee;
- int i, error = 0;
-
- /* Start the card. */
- if ((error = startup_card(sc))) return error;
-
- callout_init(&sc->callout, 0);
-
- /* Attach a kernel interface. */
-#if NETGRAPH
- if ((error = ng_attach(sc))) return error;
- sc->flags |= FLAG_NETGRAPH;
-#endif
- if ((error = lmc_ifnet_attach(sc))) return error;
- sc->flags |= FLAG_IFNET;
-
- /* Attach a line protocol stack. */
- sc->config.line_pkg = PKG_RAWIP;
- config = sc->config; /* get current config */
- config.line_pkg = 0; /* select external stack */
- config.line_prot = PROT_C_HDLC;
- config.keep_alive = 1;
- config_proto(sc, &config); /* reconfigure */
- sc->config = config; /* save new configuration */
-
- /* Print interesting hardware-related things. */
- mii3 = read_mii(sc, 3);
- tlp_cfrv = READ_PCI_CFG(sc, TLP_CFRV);
- printf("%s: PCI rev %d.%d, MII rev %d.%d", NAME_UNIT,
- (tlp_cfrv>>4) & 0xF, tlp_cfrv & 0xF, (mii3>>4) & 0xF, mii3 & 0xF);
- ieee = (u_int8_t *)sc->status.ieee;
- for (i=0; i<3; i++) sc->status.ieee[i] = read_srom(sc, 10+i);
- printf(", IEEE addr %02x:%02x:%02x:%02x:%02x:%02x",
- ieee[0], ieee[1], ieee[2], ieee[3], ieee[4], ieee[5]);
- sc->card->ident(sc);
- printf(" %s\n", intrstr);
-
- /* Print interesting software-related things. */
- printf("%s: Driver rev %d.%d.%d", NAME_UNIT,
- DRIVER_MAJOR_VERSION, DRIVER_MINOR_VERSION, DRIVER_SUB_VERSION);
- printf(", Options %s%s%s%s%s%s%s%s%s\n",
- NETGRAPH ? "NETGRAPH " : "", GEN_HDLC ? "GEN_HDLC " : "",
- NSPPP ? "SPPP " : "", P2P ? "P2P " : "",
- ALTQ_PRESENT ? "ALTQ " : "", NBPFILTER ? "BPF " : "",
- DEV_POLL ? "POLL " : "", IOREF_CSR ? "IO_CSR " : "MEM_CSR ",
- (BYTE_ORDER == BIG_ENDIAN) ? "BIG_END " : "LITTLE_END ");
-
- /* Make the local hardware ready. */
- set_status(sc, 1);
-
- return 0;
- }
-
-/* Detach from the kernel in all ways. */
-static void
-detach_card(softc_t *sc)
- {
- struct config config;
-
- /* Make the local hardware NOT ready. */
- set_status(sc, 0);
-
- /* Detach external line protocol stack. */
- if (sc->config.line_pkg != PKG_RAWIP)
- {
- config = sc->config;
- config.line_pkg = PKG_RAWIP;
- config_proto(sc, &config);
- sc->config = config;
- }
-
- /* Detach kernel interfaces. */
-#if NETGRAPH
- if (sc->flags & FLAG_NETGRAPH)
- {
- IFQ_PURGE(&sc->ng_fastq);
- IFQ_PURGE(&sc->ng_sndq);
- ng_detach(sc);
- sc->flags &= ~FLAG_NETGRAPH;
- }
-#endif
- if (sc->flags & FLAG_IFNET)
- {
- IFQ_PURGE(&sc->ifp->if_snd);
- lmc_ifnet_detach(sc);
- sc->flags &= ~FLAG_IFNET;
- }
-
- /* Reset the Tulip chip; stops DMA and Interrupts. */
- shutdown_card(sc);
- }
-
-/* This is the I/O configuration interface for FreeBSD */
-
-
-static int
-fbsd_probe(device_t dev)
- {
- u_int32_t cfid = pci_read_config(dev, TLP_CFID, 4);
- u_int32_t csid = pci_read_config(dev, TLP_CSID, 4);
-
- /* Looking for a DEC 21140A chip on any Lan Media Corp card. */
- if (cfid != TLP_CFID_TULIP) return ENXIO;
- switch (csid)
- {
- case TLP_CSID_HSSI:
- case TLP_CSID_HSSIc:
- device_set_desc(dev, HSSI_DESC);
- break;
- case TLP_CSID_T3:
- device_set_desc(dev, T3_DESC);
- break;
- case TLP_CSID_SSI:
- device_set_desc(dev, SSI_DESC);
- break;
- case TLP_CSID_T1E1:
- device_set_desc(dev, T1E1_DESC);
- break;
- default:
- return ENXIO;
- }
- return 0;
- }
-
-static int
-fbsd_detach(device_t dev)
- {
- softc_t *sc = device_get_softc(dev);
-
- /* Stop the card and detach from the kernel. */
- detach_card(sc);
-
- /* Release resources. */
- if (sc->irq_cookie != NULL)
- {
- bus_teardown_intr(dev, sc->irq_res, sc->irq_cookie);
- sc->irq_cookie = NULL;
- }
- if (sc->irq_res != NULL)
- {
- bus_release_resource(dev, SYS_RES_IRQ, sc->irq_res_id, sc->irq_res);
- sc->irq_res = NULL;
- }
- if (sc->csr_res != NULL)
- {
- bus_release_resource(dev, sc->csr_res_type, sc->csr_res_id, sc->csr_res);
- sc->csr_res = NULL;
- }
-
- mtx_destroy(&sc->top_mtx);
- mtx_destroy(&sc->bottom_mtx);
- return 0; /* no error */
- }
-
-static int
-fbsd_shutdown(device_t dev)
- {
- shutdown_card(device_get_softc(dev));
- return 0;
- }
-
-static int
-fbsd_attach(device_t dev)
- {
- softc_t *sc = device_get_softc(dev);
- int error;
-
- /* READ/WRITE_PCI_CFG need this. */
- sc->dev = dev;
-
- /* What kind of card are we driving? */
- switch (READ_PCI_CFG(sc, TLP_CSID))
- {
- case TLP_CSID_HSSI:
- case TLP_CSID_HSSIc:
- sc->card = &hssi_card;
- break;
- case TLP_CSID_T3:
- sc->card = &t3_card;
- break;
- case TLP_CSID_SSI:
- sc->card = &ssi_card;
- break;
- case TLP_CSID_T1E1:
- sc->card = &t1_card;
- break;
- default:
- return ENXIO;
- }
- sc->dev_desc = device_get_desc(dev);
-
- /* Allocate PCI memory or IO resources to access the Tulip chip CSRs. */
-# if IOREF_CSR
- sc->csr_res_id = TLP_CBIO;
- sc->csr_res_type = SYS_RES_IOPORT;
-# else
- sc->csr_res_id = TLP_CBMA;
- sc->csr_res_type = SYS_RES_MEMORY;
-# endif
- sc->csr_res = bus_alloc_resource_any(dev, sc->csr_res_type, &sc->csr_res_id,
- RF_ACTIVE);
- if (sc->csr_res == NULL)
- {
- printf("%s: bus_alloc_resource(csr) failed.\n", NAME_UNIT);
- return ENXIO;
- }
- sc->csr_tag = rman_get_bustag(sc->csr_res);
- sc->csr_handle = rman_get_bushandle(sc->csr_res);
-
- /* Allocate PCI interrupt resources for the card. */
- sc->irq_res_id = 0;
- sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_res_id,
- RF_ACTIVE | RF_SHAREABLE);
- if (sc->irq_res == NULL)
- {
- printf("%s: bus_alloc_resource(irq) failed.\n", NAME_UNIT);
- fbsd_detach(dev);
- return ENXIO;
- }
- if ((error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE,
- NULL, bsd_interrupt, sc, &sc->irq_cookie)))
- {
- printf("%s: bus_setup_intr() failed; error %d\n", NAME_UNIT, error);
- fbsd_detach(dev);
- return error;
- }
-
- /* Initialize the top-half and bottom-half locks. */
- mtx_init(&sc->top_mtx, NAME_UNIT, "top half lock", MTX_DEF);
- mtx_init(&sc->bottom_mtx, NAME_UNIT, "bottom half lock", MTX_DEF);
-
- /* Start the card and attach a kernel interface and line protocol. */
- if ((error = attach_card(sc, ""))) detach_card(sc);
- gone_in_dev(dev, 12, "lmc(4) driver");
- return error;
- }
-
-static device_method_t methods[] =
- {
- DEVMETHOD(device_probe, fbsd_probe),
- DEVMETHOD(device_attach, fbsd_attach),
- DEVMETHOD(device_detach, fbsd_detach),
- DEVMETHOD(device_shutdown, fbsd_shutdown),
- /* This driver does not suspend and resume. */
- { 0, 0 }
- };
-
-static driver_t driver =
- {
- .name = DEVICE_NAME,
- .methods = methods,
- .size = sizeof(softc_t),
- };
-
-static devclass_t devclass;
-
-DRIVER_MODULE(lmc, pci, driver, devclass, 0, 0);
-MODULE_VERSION(lmc, 2);
-MODULE_DEPEND(lmc, pci, 1, 1, 1);
-# if NETGRAPH
-MODULE_DEPEND(lmc, netgraph, NG_ABI_VERSION, NG_ABI_VERSION, NG_ABI_VERSION);
-# endif
-# if NSPPP
-MODULE_DEPEND(lmc, sppp, 1, 1, 1);
-# endif
-
-
-/* This is the I/O configuration interface for NetBSD. */
-
-
-/* This is the I/O configuration interface for OpenBSD. */
-
-
-/* This is the I/O configuration interface for BSD/OS. */
-
-
diff --git a/sys/dev/lmc/if_lmc.h b/sys/dev/lmc/if_lmc.h
deleted file mode 100644
index 23765008b64b7..0000000000000
--- a/sys/dev/lmc/if_lmc.h
+++ /dev/null
@@ -1,1325 +0,0 @@
-/*-
- * $FreeBSD$
- *
- * Copyright (c) 2002-2004 David Boggs. (boggs@boggs.palo-alto.ca.us)
- * All rights reserved.
- *
- * BSD License:
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * GNU General Public License:
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef IF_LMC_H
-#define IF_LMC_H
-
-#define DEVICE_NAME "lmc"
-
-/* Linux RPM-style version information */
-#define DRIVER_MAJOR_VERSION 2005 /* year */
-#define DRIVER_MINOR_VERSION 9 /* month */
-#define DRIVER_SUB_VERSION 29 /* day */
-
-/* netgraph stuff */
-#define NG_LMC_NODE_TYPE DEVICE_NAME
-#define NGM_LMC_COOKIE 1128054761 /* date -u +'%s' */
-
-/* Tulip PCI configuration registers */
-#define TLP_CFID 0x00 /* 0: CFg ID register */
-#define TLP_CFCS 0x04 /* 1: CFg Command/Status */
-#define TLP_CFRV 0x08 /* 2: CFg ReVision */
-#define TLP_CFLT 0x0C /* 3: CFg Latency Timer */
-#define TLP_CBIO 0x10 /* 4: Cfg Base IO address */
-#define TLP_CBMA 0x14 /* 5: Cfg Base Mem Addr */
-#define TLP_CSID 0x2C /* 11: Cfg Subsys ID reg */
-#define TLP_CFIT 0x3C /* 15: CFg InTerrupt */
-#define TLP_CFDD 0x40 /* 16: CFg Driver Data */
-
-#define TLP_CFID_TULIP 0x00091011 /* DEC 21140A Ethernet chip */
-
-#define TLP_CFCS_MSTR_ABORT 0x20000000
-#define TLP_CFCS_TARG_ABORT 0x10000000
-#define TLP_CFCS_SYS_ERROR 0x00000100
-#define TLP_CFCS_PAR_ERROR 0x00000040
-#define TLP_CFCS_MWI_ENABLE 0x00000010
-#define TLP_CFCS_BUS_MASTER 0x00000004
-#define TLP_CFCS_MEM_ENABLE 0x00000002
-#define TLP_CFCS_IO_ENABLE 0x00000001
-
-#define TLP_CFLT_LATENCY 0x0000FF00
-#define TLP_CFLT_CACHE 0x000000FF
-
-#define TLP_CSID_HSSI 0x00031376 /* LMC 5200 HSSI card */
-#define TLP_CSID_T3 0x00041376 /* LMC 5245 T3 card */
-#define TLP_CSID_SSI 0x00051376 /* LMC 1000 SSI card */
-#define TLP_CSID_T1E1 0x00061376 /* LMC 1200 T1E1 card */
-#define TLP_CSID_HSSIc 0x00071376 /* LMC 5200 HSSI cPCI */
-#define TLP_CSID_SDSL 0x00081376 /* LMC 1168 SDSL card */
-
-#define TLP_CFIT_MAX_LAT 0xFF000000
-
-#define TLP_CFDD_SLEEP 0x80000000
-#define TLP_CFDD_SNOOZE 0x40000000
-
-/* Tulip Control and Status Registers */
-#define TLP_CSR_STRIDE 8 /* 64 bits */
-#define TLP_BUS_MODE 0 * TLP_CSR_STRIDE
-#define TLP_TX_POLL 1 * TLP_CSR_STRIDE
-#define TLP_RX_POLL 2 * TLP_CSR_STRIDE
-#define TLP_RX_LIST 3 * TLP_CSR_STRIDE
-#define TLP_TX_LIST 4 * TLP_CSR_STRIDE
-#define TLP_STATUS 5 * TLP_CSR_STRIDE
-#define TLP_OP_MODE 6 * TLP_CSR_STRIDE
-#define TLP_INT_ENBL 7 * TLP_CSR_STRIDE
-#define TLP_MISSED 8 * TLP_CSR_STRIDE
-#define TLP_SROM_MII 9 * TLP_CSR_STRIDE
-#define TLP_BIOS_ROM 10 * TLP_CSR_STRIDE
-#define TLP_TIMER 11 * TLP_CSR_STRIDE
-#define TLP_GPIO 12 * TLP_CSR_STRIDE
-#define TLP_CSR13 13 * TLP_CSR_STRIDE
-#define TLP_CSR14 14 * TLP_CSR_STRIDE
-#define TLP_WDOG 15 * TLP_CSR_STRIDE
-#define TLP_CSR_SIZE 128 /* IO bus space size */
-
-/* CSR 0 - PCI Bus Mode Register */
-#define TLP_BUS_WRITE_INVAL 0x01000000 /* DONT USE! */
-#define TLP_BUS_READ_LINE 0x00800000
-#define TLP_BUS_READ_MULT 0x00200000
-#define TLP_BUS_DESC_BIGEND 0x00100000
-#define TLP_BUS_TAP 0x000E0000
-#define TLP_BUS_CAL 0x0000C000
-#define TLP_BUS_PBL 0x00003F00
-#define TLP_BUS_DATA_BIGEND 0x00000080
-#define TLP_BUS_DSL 0x0000007C
-#define TLP_BUS_ARB 0x00000002
-#define TLP_BUS_RESET 0x00000001
-#define TLP_BUS_CAL_SHIFT 14
-#define TLP_BUS_PBL_SHIFT 8
-
-/* CSR 5 - Status Register */
-#define TLP_STAT_FATAL_BITS 0x03800000
-#define TLP_STAT_TX_FSM 0x00700000
-#define TLP_STAT_RX_FSM 0x000E0000
-#define TLP_STAT_FATAL_ERROR 0x00002000
-#define TLP_STAT_TX_UNDERRUN 0x00000020
-#define TLP_STAT_FATAL_SHIFT 23
-
-/* CSR 6 - Operating Mode Register */
-#define TLP_OP_RECEIVE_ALL 0x40000000
-#define TLP_OP_MUST_BE_ONE 0x02000000
-#define TLP_OP_NO_HEART_BEAT 0x00080000
-#define TLP_OP_PORT_SELECT 0x00040000
-#define TLP_OP_TX_THRESH 0x0000C000
-#define TLP_OP_TX_RUN 0x00002000
-#define TLP_OP_LOOP_MODE 0x00000C00
-#define TLP_OP_EXT_LOOP 0x00000800
-#define TLP_OP_INT_LOOP 0x00000400
-#define TLP_OP_FULL_DUPLEX 0x00000200
-#define TLP_OP_PROMISCUOUS 0x00000040
-#define TLP_OP_PASS_BAD_PKT 0x00000008
-#define TLP_OP_RX_RUN 0x00000002
-#define TLP_OP_TR_SHIFT 14
-#define TLP_OP_INIT (TLP_OP_PORT_SELECT | \
- TLP_OP_FULL_DUPLEX | \
- TLP_OP_MUST_BE_ONE | \
- TLP_OP_NO_HEART_BEAT | \
- TLP_OP_RECEIVE_ALL | \
- TLP_OP_PROMISCUOUS | \
- TLP_OP_PASS_BAD_PKT | \
- TLP_OP_RX_RUN | \
- TLP_OP_TX_RUN)
-
-/* CSR 7 - Interrupt Enable Register */
-#define TLP_INT_NORMAL_INTR 0x00010000
-#define TLP_INT_ABNRML_INTR 0x00008000
-#define TLP_INT_FATAL_ERROR 0x00002000
-#define TLP_INT_RX_NO_BUFS 0x00000080
-#define TLP_INT_RX_INTR 0x00000040
-#define TLP_INT_TX_UNDERRUN 0x00000020
-#define TLP_INT_TX_INTR 0x00000001
-#define TLP_INT_DISABLE 0
-#define TLP_INT_TX (TLP_INT_NORMAL_INTR | \
- TLP_INT_ABNRML_INTR | \
- TLP_INT_FATAL_ERROR | \
- TLP_INT_TX_UNDERRUN | \
- TLP_INT_TX_INTR)
-#define TLP_INT_RX (TLP_INT_NORMAL_INTR | \
- TLP_INT_ABNRML_INTR | \
- TLP_INT_FATAL_ERROR | \
- TLP_INT_RX_NO_BUFS | \
- TLP_INT_RX_INTR)
-#define TLP_INT_TXRX (TLP_INT_TX | TLP_INT_RX)
-
-/* CSR 8 - RX Missed Frames & Overrun Register */
-#define TLP_MISS_OCO 0x10000000
-#define TLP_MISS_OVERRUN 0x0FFE0000
-#define TLP_MISS_MFO 0x00010000
-#define TLP_MISS_MISSED 0x0000FFFF
-#define TLP_OVERRUN_SHIFT 17
-
-/* CSR 9 - SROM & MII & Boot ROM Register */
-#define TLP_MII_MDIN 0x00080000
-#define TLP_MII_MDOE 0x00040000
-#define TLP_MII_MDOUT 0x00020000
-#define TLP_MII_MDC 0x00010000
-
-#define TLP_BIOS_RD 0x00004000
-#define TLP_BIOS_WR 0x00002000
-#define TLP_BIOS_SEL 0x00001000
-
-#define TLP_SROM_RD 0x00004000
-#define TLP_SROM_SEL 0x00000800
-#define TLP_SROM_DOUT 0x00000008
-#define TLP_SROM_DIN 0x00000004
-#define TLP_SROM_CLK 0x00000002
-#define TLP_SROM_CS 0x00000001
-
-/* CSR 12 - General Purpose IO register */
-#define TLP_GPIO_DIR 0x00000100
-
-/* CSR 15 - Watchdog Timer Register */
-#define TLP_WDOG_RX_OFF 0x00000010
-#define TLP_WDOG_TX_OFF 0x00000001
-#define TLP_WDOG_INIT (TLP_WDOG_TX_OFF | \
- TLP_WDOG_RX_OFF)
-
-/* GPIO bits common to all cards */
-#define GPIO_INIT 0x01 /* from Xilinx */
-#define GPIO_RESET 0x02 /* to Xilinx */
-/* bits 2 and 3 vary with board type -- see below */
-#define GPIO_MODE 0x10 /* to Xilinx */
-#define GPIO_DP 0x20 /* to/from Xilinx */
-#define GPIO_DATA 0x40 /* serial data */
-#define GPIO_CLK 0x80 /* serial clock */
-
-/* HSSI GPIO bits */
-#define GPIO_HSSI_ST 0x04 /* send timing sense (deprecated) */
-#define GPIO_HSSI_TXCLK 0x08 /* clock source */
-
-/* HSSIc GPIO bits */
-#define GPIO_HSSI_SYNTH 0x04 /* Synth osc chip select */
-#define GPIO_HSSI_DCE 0x08 /* provide clock on TXCLOCK output */
-
-/* T3 GPIO bits */
-#define GPIO_T3_DAC 0x04 /* DAC chip select */
-#define GPIO_T3_INTEN 0x08 /* Framer Interrupt enable */
-
-/* SSI GPIO bits */
-#define GPIO_SSI_SYNTH 0x04 /* Synth osc chip select */
-#define GPIO_SSI_DCE 0x08 /* provide clock on TXCLOCK output */
-
-/* T1E1 GPIO bits */
-#define GPIO_T1_INTEN 0x08 /* Framer Interrupt enable */
-
-/* MII register 16 bits common to all cards */
-/* NB: LEDs for HSSI & SSI are in DIFFERENT bits than for T1E1 & T3; oops */
-/* NB: CRC32 for HSSI & SSI is in DIFFERENT bit than for T1E1 & T3; oops */
-#define MII16_LED_ALL 0x0780 /* RW: LED bit mask */
-#define MII16_FIFO 0x0800 /* RW: 1=reset, 0=not reset */
-
-/* MII register 16 bits for HSSI */
-#define MII16_HSSI_TA 0x0001 /* RW: host ready; host->modem */
-#define MII16_HSSI_CA 0x0002 /* RO: modem ready; modem->host */
-#define MII16_HSSI_LA 0x0004 /* RW: loopback A; host->modem */
-#define MII16_HSSI_LB 0x0008 /* RW: loopback B; host->modem */
-#define MII16_HSSI_LC 0x0010 /* RO: loopback C; modem->host */
-#define MII16_HSSI_TM 0x0020 /* RO: test mode; modem->host */
-#define MII16_HSSI_CRC32 0x0040 /* RW: CRC length 16/32 */
-#define MII16_HSSI_LED_LL 0x0080 /* RW: lower left - green */
-#define MII16_HSSI_LED_LR 0x0100 /* RW: lower right - green */
-#define MII16_HSSI_LED_UL 0x0200 /* RW: upper left - green */
-#define MII16_HSSI_LED_UR 0x0400 /* RW: upper right - red */
-#define MII16_HSSI_FIFO 0x0800 /* RW: reset fifos */
-#define MII16_HSSI_FORCECA 0x1000 /* RW: [cPCI] force CA on */
-#define MII16_HSSI_CLKMUX 0x6000 /* RW: [cPCI] TX clock selection */
-#define MII16_HSSI_LOOP 0x8000 /* RW: [cPCI] LOOP TX into RX */
-#define MII16_HSSI_MODEM 0x003F /* TA+CA+LA+LB+LC+TM */
-
-/* MII register 16 bits for DS3 */
-#define MII16_DS3_ZERO 0x0001 /* RW: short/long cables */
-#define MII16_DS3_TRLBK 0x0002 /* RW: loop towards host */
-#define MII16_DS3_LNLBK 0x0004 /* RW: loop towards net */
-#define MII16_DS3_RAIS 0x0008 /* RO: LIU receive AIS (depr) */
-#define MII16_DS3_TAIS 0x0010 /* RW: LIU transmit AIS (depr) */
-#define MII16_DS3_BIST 0x0020 /* RO: LIU QRSS patt match (depr) */
-#define MII16_DS3_DLOS 0x0040 /* RO: LIU Digital LOS (depr) */
-#define MII16_DS3_LED_BLU 0x0080 /* RW: lower right - blue */
-#define MII16_DS3_LED_YEL 0x0100 /* RW: lower left - yellow */
-#define MII16_DS3_LED_RED 0x0200 /* RW: upper right - red */
-#define MII16_DS3_LED_GRN 0x0400 /* RW: upper left - green */
-#define MII16_DS3_FIFO 0x0800 /* RW: reset fifos */
-#define MII16_DS3_CRC32 0x1000 /* RW: CRC length 16/32 */
-#define MII16_DS3_SCRAM 0x2000 /* RW: payload scrambler */
-#define MII16_DS3_POLY 0x4000 /* RW: 1=Larse, 0=DigLink|Kentrox */
-#define MII16_DS3_FRAME 0x8000 /* RW: 1=stop txframe pulses */
-
-/* MII register 16 bits for SSI */
-#define MII16_SSI_DTR 0x0001 /* RW: DTR host->modem */
-#define MII16_SSI_DSR 0x0002 /* RO: DSR modem->host */
-#define MII16_SSI_RTS 0x0004 /* RW: RTS host->modem */
-#define MII16_SSI_CTS 0x0008 /* RO: CTS modem->host */
-#define MII16_SSI_DCD 0x0010 /* RW: DCD modem<->host */
-#define MII16_SSI_RI 0x0020 /* RO: RI modem->host */
-#define MII16_SSI_CRC32 0x0040 /* RW: CRC length 16/32 */
-#define MII16_SSI_LED_LL 0x0080 /* RW: lower left - green */
-#define MII16_SSI_LED_LR 0x0100 /* RW: lower right - green */
-#define MII16_SSI_LED_UL 0x0200 /* RW: upper left - green */
-#define MII16_SSI_LED_UR 0x0400 /* RW: upper right - red */
-#define MII16_SSI_FIFO 0x0800 /* RW: reset fifos */
-#define MII16_SSI_LL 0x1000 /* RW: LL: host->modem */
-#define MII16_SSI_RL 0x2000 /* RW: RL: host->modem */
-#define MII16_SSI_TM 0x4000 /* RO: TM: modem->host */
-#define MII16_SSI_LOOP 0x8000 /* RW: Loop at ext conn */
-#define MII16_SSI_MODEM 0x703F /* DTR+DSR+RTS+CTS+DCD+RI+LL+RL+TM */
-
-/* Mii register 17 has the SSI cable bits */
-#define MII17_SSI_CABLE_SHIFT 3 /* shift to get cable type */
-#define MII17_SSI_CABLE_MASK 0x0038 /* RO: mask to get cable type */
-#define MII17_SSI_PRESCALE 0x0040 /* RW: divide by: 0=16; 1=512 */
-#define MII17_SSI_ITF 0x0100 /* RW: fill with: 0=flags; 1=ones */
-#define MII17_SSI_NRZI 0x0400 /* RW: coding: NRZ= 0; NRZI=1 */
-
-/* MII register 16 bits for T1/E1 */
-#define MII16_T1_UNUSED1 0x0001
-#define MII16_T1_INVERT 0x0002 /* RW: invert data (for SF/AMI) */
-#define MII16_T1_XOE 0x0004 /* RW: TX Output Enable; 0=disable */
-#define MII16_T1_RST 0x0008 /* RW: Bt8370 chip reset */
-#define MII16_T1_Z 0x0010 /* RW: output impedance T1=1 E1=0 */
-#define MII16_T1_INTR 0x0020 /* RO: interrupt from Bt8370 */
-#define MII16_T1_ONESEC 0x0040 /* RO: one second square wave */
-#define MII16_T1_LED_BLU 0x0080 /* RW: lower right - blue */
-#define MII16_T1_LED_YEL 0x0100 /* RW: lower left - yellow */
-#define MII16_T1_LED_RED 0x0200 /* RW: upper right - red */
-#define MII16_T1_LED_GRN 0x0400 /* RW: upper left - green */
-#define MII16_T1_FIFO 0x0800 /* RW: reset fifos */
-#define MII16_T1_CRC32 0x1000 /* RW: CRC length 16/32 */
-#define MII16_T1_UNUSED2 0xE000
-
-/* T3 framer: RW=Read/Write; RO=Read-Only; RC=Read/Clr; WO=Write-Only */
-#define T3CSR_STAT0 0x00 /* RO: real-time status */
-#define T3CSR_CTL1 0x01 /* RW: global control bits */
-#define T3CSR_FEBE 0x02 /* RC: Far End Block Error Counter */
-#define T3CSR_CERR 0x03 /* RC: C-bit Parity Error Counter */
-#define T3CSR_PERR 0x04 /* RC: P-bit Parity Error Counter */
-#define T3CSR_TX_FEAC 0x05 /* RW: Far End Alarm & Control */
-#define T3CSR_RX_FEAC 0x06 /* RO: Far End Alarm & Control */
-#define T3CSR_STAT7 0x07 /* RL: latched real-time status */
-#define T3CSR_CTL8 0x08 /* RW: extended global ctl bits */
-#define T3CSR_STAT9 0x09 /* RL: extended status bits */
-#define T3CSR_FERR 0x0A /* RC: F-bit Error Counter */
-#define T3CSR_MERR 0x0B /* RC: M-bit Error Counter */
-#define T3CSR_CTL12 0x0C /* RW: more extended ctl bits */
-#define T3CSR_DBL_FEAC 0x0D /* RW: TX double FEAC */
-#define T3CSR_CTL14 0x0E /* RW: even more extended ctl bits */
-#define T3CSR_FEAC_STK 0x0F /* RO: RX FEAC stack */
-#define T3CSR_STAT16 0x10 /* RL: extended latched status */
-#define T3CSR_INTEN 0x11 /* RW: interrupt enable */
-#define T3CSR_CVLO 0x12 /* RC: coding violation cntr LSB */
-#define T3CSR_CVHI 0x13 /* RC: coding violation cntr MSB */
-#define T3CSR_CTL20 0x14 /* RW: yet more extended ctl bits */
-
-#define CTL1_XTX 0x01 /* Transmit X-bit value */
-#define CTL1_3LOOP 0x02 /* framer loop back */
-#define CTL1_SER 0x04 /* SERial interface selected */
-#define CTL1_M13MODE 0x08 /* M13 frame format */
-#define CTL1_TXIDL 0x10 /* Transmit Idle signal */
-#define CTL1_ENAIS 0x20 /* Enable AIS upon LOS */
-#define CTL1_TXAIS 0x40 /* Transmit Alarm Indication Sig */
-#define CTL1_NOFEBE 0x80 /* No Far End Block Errors */
-
-#define CTL5_EMODE 0x80 /* rev B Extended features enabled */
-#define CTL5_START 0x40 /* transmit the FEAC msg now */
-
-#define CTL8_FBEC 0x80 /* F-Bit Error Count control */
-#define CTL8_TBLU 0x20 /* Transmit Blue signal */
-
-#define STAT9_SEF 0x80 /* Severely Errored Frame */
-#define STAT9_RBLU 0x20 /* Receive Blue signal */
-
-#define CTL12_RTPLLEN 0x80 /* Rx-to-Tx Payload Lpbk Lock ENbl */
-#define CTL12_RTPLOOP 0x40 /* Rx-to-Tx Payload Loopback */
-#define CTL12_DLCB1 0x08 /* Data Link C-Bits forced to 1 */
-#define CTL12_C21 0x04 /* C2 forced to 1 */
-#define CTL12_MCB1 0x02 /* Most C-Bits forced to 1 */
-
-#define CTL13_DFEXEC 0x40 /* Execute Double FEAC */
-
-#define CTL14_FEAC10 0x80 /* Transmit FEAC word 10 times */
-#define CTL14_RGCEN 0x20 /* Receive Gapped Clock Out Enbl */
-#define CTL14_TGCEN 0x10 /* Timing Gen Gapped Clk Out Enbl */
-
-#define FEAC_STK_MORE 0x80 /* FEAC stack has more FEACs */
-#define FEAC_STK_VALID 0x40 /* FEAC stack is valid */
-#define FEAC_STK_FEAC 0x3F /* FEAC stack FEAC data */
-
-#define STAT16_XERR 0x01 /* X-bit Error */
-#define STAT16_SEF 0x02 /* Severely Errored Frame */
-#define STAT16_RTLOC 0x04 /* Rx/Tx Loss Of Clock */
-#define STAT16_FEAC 0x08 /* new FEAC msg */
-#define STAT16_RIDL 0x10 /* channel IDLe signal */
-#define STAT16_RAIS 0x20 /* Alarm Indication Signal */
-#define STAT16_ROOF 0x40 /* Out Of Frame sync */
-#define STAT16_RLOS 0x80 /* Loss Of Signal */
-
-#define CTL20_CVEN 0x01 /* Coding Violation Counter Enbl */
-
-/* T1.107 Bit Oriented C-Bit Parity Far End Alarm Control and Status codes */
-#define T3BOP_OOF 0x00 /* Yellow alarm status */
-#define T3BOP_LINE_UP 0x07 /* line loopback activate */
-#define T3BOP_LINE_DOWN 0x1C /* line loopback deactivate */
-#define T3BOP_LOOP_DS3 0x1B /* loopback full DS3 */
-#define T3BOP_IDLE 0x1A /* IDLE alarm status */
-#define T3BOP_AIS 0x16 /* AIS alarm status */
-#define T3BOP_LOS 0x0E /* LOS alarm status */
-
-/* T1E1 regs; RW=Read/Write; RO=Read-Only; RC=Read/Clr; WO=Write-Only */
-#define Bt8370_DID 0x000 /* RO: Device ID */
-#define Bt8370_CR0 0x001 /* RW; Primary Control Register */
-#define Bt8370_JAT_CR 0x002 /* RW: Jitter Attenuator CR */
-#define Bt8370_IRR 0x003 /* RO: Interrupt Request Reg */
-#define Bt8370_ISR7 0x004 /* RC: Alarm 1 Interrupt Status */
-#define Bt8370_ISR6 0x005 /* RC: Alarm 2 Interrupt Status */
-#define Bt8370_ISR5 0x006 /* RC: Error Interrupt Status */
-#define Bt8370_ISR4 0x007 /* RC; Cntr Ovfl Interrupt Status */
-#define Bt8370_ISR3 0x008 /* RC: Timer Interrupt Status */
-#define Bt8370_ISR2 0x009 /* RC: Data Link 1 Int Status */
-#define Bt8370_ISR1 0x00A /* RC: Data Link 2 Int Status */
-#define Bt8370_ISR0 0x00B /* RC: Pattrn Interrupt Status */
-#define Bt8370_IER7 0x00C /* RW: Alarm 1 Interrupt Enable */
-#define Bt8370_IER6 0x00D /* RW: Alarm 2 Interrupt Enable */
-#define Bt8370_IER5 0x00E /* RW: Error Interrupt Enable */
-#define Bt8370_IER4 0x00F /* RW: Cntr Ovfl Interrupt Enable */
-
-#define Bt8370_IER3 0x010 /* RW: Timer Interrupt Enable */
-#define Bt8370_IER2 0x011 /* RW: Data Link 1 Int Enable */
-#define Bt8370_IER1 0x012 /* RW: Data Link 2 Int Enable */
-#define Bt8370_IER0 0x013 /* RW: Pattern Interrupt Enable */
-#define Bt8370_LOOP 0x014 /* RW: Loopback Config Reg */
-#define Bt8370_DL3_TS 0x015 /* RW: External Data Link Channel */
-#define Bt8370_DL3_BIT 0x016 /* RW: External Data Link Bit */
-#define Bt8370_FSTAT 0x017 /* RO: Offline Framer Status */
-#define Bt8370_PIO 0x018 /* RW: Programmable Input/Output */
-#define Bt8370_POE 0x019 /* RW: Programmable Output Enable */
-#define Bt8370_CMUX 0x01A /* RW: Clock Input Mux */
-#define Bt8370_TMUX 0x01B /* RW: Test Mux Config */
-#define Bt8370_TEST 0x01C /* RW: Test Config */
-
-#define Bt8370_LIU_CR 0x020 /* RW: Line Intf Unit Config Reg */
-#define Bt8370_RSTAT 0x021 /* RO; Receive LIU Status */
-#define Bt8370_RLIU_CR 0x022 /* RW: Receive LIU Config */
-#define Bt8370_LPF 0x023 /* RW: RPLL Low Pass Filter */
-#define Bt8370_VGA_MAX 0x024 /* RW: Variable Gain Amplifier Max */
-#define Bt8370_EQ_DAT 0x025 /* RW: Equalizer Coeff Data Reg */
-#define Bt8370_EQ_PTR 0x026 /* RW: Equzlizer Coeff Table Ptr */
-#define Bt8370_DSLICE 0x027 /* RW: Data Slicer Threshold */
-#define Bt8370_EQ_OUT 0x028 /* RW: Equalizer Output Levels */
-#define Bt8370_VGA 0x029 /* RO: Variable Gain Ampl Status */
-#define Bt8370_PRE_EQ 0x02A /* RW: Pre-Equalizer */
-
-#define Bt8370_COEFF0 0x030 /* RO: LMS Adj Eq Coeff Status */
-#define Bt8370_GAIN0 0x038 /* RW: Equalizer Gain Thresh */
-#define Bt8370_GAIN1 0x039 /* RW: Equalizer Gain Thresh */
-#define Bt8370_GAIN2 0x03A /* RW: Equalizer Gain Thresh */
-#define Bt8370_GAIN3 0x03B /* RW: Equalizer Gain Thresh */
-#define Bt8370_GAIN4 0x03C /* RW: Equalizer Gain Thresh */
-
-#define Bt8370_RCR0 0x040 /* RW: Rx Configuration */
-#define Bt8370_RPATT 0x041 /* RW: Rx Test Pattern Config */
-#define Bt8370_RLB 0x042 /* RW: Rx Loopback Code Detr Conf */
-#define Bt8370_LBA 0x043 /* RW: Loopback Activate Code Patt */
-#define Bt8370_LBD 0x044 /* RW: Loopback Deact Code Patt */
-#define Bt8370_RALM 0x045 /* RW: Rx Alarm Signal Config */
-#define Bt8370_LATCH 0x046 /* RW: Alarm/Err/Cntr Latch Config */
-#define Bt8370_ALM1 0x047 /* RO: Alarm 1 Status */
-#define Bt8370_ALM2 0x048 /* RO: Alarm 2 Status */
-#define Bt8370_ALM3 0x049 /* RO: Alarm 3 Status */
-
-#define Bt8370_FERR_LO 0x050 /* RC: Framing Bit Error Cntr LSB */
-#define Bt8370_FERR_HI 0x051 /* RC: Framing Bit Error Cntr MSB */
-#define Bt8370_CRC_LO 0x052 /* RC: CRC Error Counter LSB */
-#define Bt8370_CRC_HI 0x053 /* RC: CRC Error Counter MSB */
-#define Bt8370_LCV_LO 0x054 /* RC: Line Code Viol Counter LSB */
-#define Bt8370_LCV_HI 0x055 /* RC: Line Code Viol Counter MSB */
-#define Bt8370_FEBE_LO 0x056 /* RC: Far End Block Err Cntr LSB */
-#define Bt8370_FEBE_HI 0x057 /* RC: Far End Block Err Cntr MSB */
-#define Bt8370_BERR_LO 0x058 /* RC: PRBS Bit Error Counter LSB */
-#define Bt8370_BERR_HI 0x059 /* RC: PRBS Bit Error Counter MSB */
-#define Bt8370_AERR 0x05A /* RC: SEF/LOF/COFA counter */
-#define Bt8370_RSA4 0x05B /* RO: Rx Sa4 Byte Buffer */
-#define Bt8370_RSA5 0x05C /* RO: Rx Sa5 Byte Buffer */
-#define Bt8370_RSA6 0x05D /* RO: Rx Sa6 Byte Buffer */
-#define Bt8370_RSA7 0x05E /* RO: Rx Sa7 Byte Buffer */
-#define Bt8370_RSA8 0x05F /* RO: Rx Sa8 Byte Buffer */
-
-#define Bt8370_SHAPE0 0x060 /* RW: Tx Pulse Shape Config */
-#define Bt8370_TLIU_CR 0x068 /* RW: Tx LIU Config Reg */
-
-#define Bt8370_TCR0 0x070 /* RW: Tx Framer Config */
-#define Bt8370_TCR1 0x071 /* RW: Txter Configuration */
-#define Bt8370_TFRM 0x072 /* RW: Tx Frame Format */
-#define Bt8370_TERROR 0x073 /* RW: Tx Error Insert */
-#define Bt8370_TMAN 0x074 /* RW: Tx Manual Sa/FEBE Config */
-#define Bt8370_TALM 0x075 /* RW: Tx Alarm Signal Config */
-#define Bt8370_TPATT 0x076 /* RW: Tx Test Pattern Config */
-#define Bt8370_TLB 0x077 /* RW: Tx Inband Loopback Config */
-#define Bt8370_LBP 0x078 /* RW: Tx Inband Loopback Patt */
-#define Bt8370_TSA4 0x07B /* RW: Tx Sa4 Byte Buffer */
-#define Bt8370_TSA5 0x07C /* RW: Tx Sa5 Byte Buffer */
-#define Bt8370_TSA6 0x07D /* RW: Tx Sa6 Byte Buffer */
-#define Bt8370_TSA7 0x07E /* RW: Tx Sa7 Byte Buffer */
-#define Bt8370_TSA8 0x07F /* RW: Tx Sa8 Byte Buffer */
-
-#define Bt8370_CLAD_CR 0x090 /* RW: Clock Rate Adapter Config */
-#define Bt8370_CSEL 0x091 /* RW: CLAD Frequency Select */
-#define Bt8370_CPHASE 0x092 /* RW: CLAD Phase Det Scale Factor */
-#define Bt8370_CTEST 0x093 /* RW: CLAD Test */
-
-#define Bt8370_BOP 0x0A0 /* RW: Bit Oriented Protocol Xcvr */
-#define Bt8370_TBOP 0x0A1 /* RW: Tx BOP Codeword */
-#define Bt8370_RBOP 0x0A2 /* RO; Rx BOP Codeword */
-#define Bt8370_BOP_STAT 0x0A3 /* RO: BOP Status */
-#define Bt8370_DL1_TS 0x0A4 /* RW: DL1 Time Slot Enable */
-#define Bt8370_DL1_BIT 0x0A5 /* RW: DL1 Bit Enable */
-#define Bt8370_DL1_CTL 0x0A6 /* RW: DL1 Control */
-#define Bt8370_RDL1_FFC 0x0A7 /* RW: RDL1 FIFO Fill Control */
-#define Bt8370_RDL1 0x0A8 /* RO: RDL1 FIFO */
-#define Bt8370_RDL1_STAT 0x0A9 /* RO: RDL1 Status */
-#define Bt8370_PRM 0x0AA /* RW: Performance Report Message */
-#define Bt8370_TDL1_FEC 0x0AB /* RW: TDL1 FIFO Empty Control */
-#define Bt8370_TDL1_EOM 0x0AC /* WO: TDL1 End Of Message Control */
-#define Bt8370_TDL1 0x0AD /* RW: TDL1 FIFO */
-#define Bt8370_TDL1_STAT 0x0AE /* RO: TDL1 Status */
-#define Bt8370_DL2_TS 0x0AF /* RW: DL2 Time Slot Enable */
-
-#define Bt8370_DL2_BIT 0x0B0 /* RW: DL2 Bit Enable */
-#define Bt8370_DL2_CTL 0x0B1 /* RW: DL2 Control */
-#define Bt8370_RDL2_FFC 0x0B2 /* RW: RDL2 FIFO Fill Control */
-#define Bt8370_RDL2 0x0B3 /* RO: RDL2 FIFO */
-#define Bt8370_RDL2_STAT 0x0B4 /* RO: RDL2 Status */
-#define Bt8370_TDL2_FEC 0x0B6 /* RW: TDL2 FIFO Empty Control */
-#define Bt8370_TDL2_EOM 0x0B7 /* WO; TDL2 End Of Message Control */
-#define Bt8370_TDL2 0x0B8 /* RW: TDL2 FIFO */
-#define Bt8370_TDL2_STAT 0x0B9 /* RO: TDL2 Status */
-#define Bt8370_DL_TEST1 0x0BA /* RW: DLINK Test Config */
-#define Bt8370_DL_TEST2 0x0BB /* RW: DLINK Test Status */
-#define Bt8370_DL_TEST3 0x0BC /* RW: DLINK Test Status */
-#define Bt8370_DL_TEST4 0x0BD /* RW: DLINK Test Control */
-#define Bt8370_DL_TEST5 0x0BE /* RW: DLINK Test Control */
-
-#define Bt8370_SBI_CR 0x0D0 /* RW: System Bus Interface Config */
-#define Bt8370_RSB_CR 0x0D1 /* RW: Rx System Bus Config */
-#define Bt8370_RSYNC_BIT 0x0D2 /* RW: Rx System Bus Sync Bit Offs */
-#define Bt8370_RSYNC_TS 0x0D3 /* RW: Rx System Bus Sync TS Offs */
-#define Bt8370_TSB_CR 0x0D4 /* RW: Tx System Bus Config */
-#define Bt8370_TSYNC_BIT 0x0D5 /* RW: Tx System Bus Sync Bit OFfs */
-#define Bt8370_TSYNC_TS 0x0D6 /* RW: Tx System Bus Sync TS Offs */
-#define Bt8370_RSIG_CR 0x0D7 /* RW: Rx Siganalling Config */
-#define Bt8370_RSYNC_FRM 0x0D8 /* RW: Sig Reinsertion Frame Offs */
-#define Bt8370_SSTAT 0x0D9 /* RO: Slip Buffer Status */
-#define Bt8370_STACK 0x0DA /* RO: Rx Signalling Stack */
-#define Bt8370_RPHASE 0x0DB /* RO: RSLIP Phase Status */
-#define Bt8370_TPHASE 0x0DC /* RO: TSLIP Phase Status */
-#define Bt8370_PERR 0x0DD /* RO: RAM Parity Status */
-
-#define Bt8370_SBCn 0x0E0 /* RW: System Bus Per-Channel Ctl */
-#define Bt8370_TPCn 0x100 /* RW: Tx Per-Channel Control */
-#define Bt8370_TSIGn 0x120 /* RW: Tx Signalling Buffer */
-#define Bt8370_TSLIP_LOn 0x140 /* RW: Tx PCM Slip Buffer Lo */
-#define Bt8370_TSLIP_HIn 0x160 /* RW: Tx PCM Slip Buffer Hi */
-#define Bt8370_RPCn 0x180 /* RW: Rx Per-Channel Control */
-#define Bt8370_RSIGn 0x1A0 /* RW: Rx Signalling Buffer */
-#define Bt8370_RSLIP_LOn 0x1C0 /* RW: Rx PCM Slip Buffer Lo */
-#define Bt8370_RSLIP_HIn 0x1E0 /* RW: Rx PCM Slip Buffer Hi */
-
-/* Bt8370_LOOP (0x14) framer loopback control register bits */
-#define LOOP_ANALOG 0x01 /* inward loop thru LIU */
-#define LOOP_FRAMER 0x02 /* inward loop thru framer */
-#define LOOP_LINE 0x04 /* outward loop thru LIU */
-#define LOOP_PAYLOAD 0x08 /* outward loop of payload */
-#define LOOP_DUAL 0x06 /* inward framer + outward line */
-
-/* Bt8370_ALM1 (0x47) receiver alarm status register bits */
-#define ALM1_SIGFRZ 0x01 /* Rx Signalling Freeze */
-#define ALM1_RLOF 0x02 /* Rx loss of frame alignment */
-#define ALM1_RLOS 0x04 /* Rx digital loss of signal */
-#define ALM1_RALOS 0x08 /* Rx analog loss of signal */
-#define ALM1_RAIS 0x10 /* Rx Alarm Indication Signal */
-#define ALM1_RYEL 0x40 /* Rx Yellow alarm indication */
-#define ALM1_RMYEL 0x80 /* Rx multiframe YELLOW alarm */
-
-/* Bt8370_ALM3 (0x49) receive framer status register bits */
-#define ALM3_FRED 0x04 /* Rx Out Of T1/FAS alignment */
-#define ALM3_MRED 0x08 /* Rx Out Of MFAS alignment */
-#define ALM3_SRED 0x10 /* Rx Out Of CAS alignment */
-#define ALM3_SEF 0x20 /* Rx Severely Errored Frame */
-#define ALM3_RMAIS 0x40 /* Rx TS16 AIS (CAS) */
-
-/* Bt8370_TALM (0x75) transmit alarm control register bits */
-#define TALM_TAIS 0x01 /* Tx Alarm Indication Signal */
-#define TALM_TYEL 0x02 /* Tx Yellow alarm */
-#define TALM_TMYEL 0x04 /* Tx Multiframe Yellow alarm */
-#define TALM_AUTO_AIS 0x08 /* auto send AIS on LOS */
-#define TALM_AUTO_YEL 0x10 /* auto send YEL on LOF */
-#define TALM_AUTO_MYEL 0x20 /* auto send E1-Y16 on loss-of-CAS */
-
-/* 8370 BOP (Bit Oriented Protocol) command fragments */
-#define RBOP_OFF 0x00 /* BOP Rx disabled */
-#define RBOP_25 0xE0 /* BOP Rx requires 25 BOPs */
-#define TBOP_OFF 0x00 /* BOP Tx disabled */
-#define TBOP_25 0x0B /* BOP Tx sends 25 BOPs */
-#define TBOP_CONT 0x0F /* BOP Tx sends continuously */
-
-/* T1.403 Bit-Oriented ESF Data-Link Message codes */
-#define T1BOP_OOF 0x00 /* Yellow alarm status */
-#define T1BOP_LINE_UP 0x07 /* line loopback activate */
-#define T1BOP_LINE_DOWN 0x1C /* line loopback deactivate */
-#define T1BOP_PAY_UP 0x0A /* payload loopback activate */
-#define T1BOP_PAY_DOWN 0x19 /* payload loopback deactivate */
-#define T1BOP_NET_UP 0x09 /* network loopback activate */
-#define T1BOP_NET_DOWN 0x12 /* network loopback deactivate */
-
-/* Unix & Linux reserve 16 device-private IOCTLs */
-#if BSD
-# define LMCIOCGSTAT _IOWR('i', 240, struct status)
-# define LMCIOCGCFG _IOWR('i', 241, struct config)
-# define LMCIOCSCFG _IOW('i', 242, struct config)
-# define LMCIOCREAD _IOWR('i', 243, struct ioctl)
-# define LMCIOCWRITE _IOW('i', 244, struct ioctl)
-# define LMCIOCTL _IOWR('i', 245, struct ioctl)
-#endif
-
-struct iohdr /* all LMCIOCs begin with this */
- {
- char ifname[IFNAMSIZ]; /* interface name, e.g. "lmc0" */
- u_int32_t cookie; /* interface version number */
- u_int16_t direction; /* missing in Linux IOCTL */
- u_int16_t length; /* missing in Linux IOCTL */
- struct iohdr *iohdr; /* missing in Linux IOCTL */
- u_int32_t spare; /* pad this struct to **32 bytes** */
- };
-
-#define DIR_IO 0
-#define DIR_IOW 1 /* copy data user->kernel */
-#define DIR_IOR 2 /* copy data kernel->user */
-#define DIR_IOWR 3 /* copy data kernel<->user */
-
-struct hssi_snmp
- {
- u_int16_t sigs; /* MII16_HSSI & MII16_HSSI_MODEM */
- };
-
-struct ssi_snmp
- {
- u_int16_t sigs; /* MII16_SSI & MII16_SSI_MODEM */
- };
-
-struct t3_snmp
- {
- u_int16_t febe; /* 8 bits - Far End Block err cnt */
- u_int16_t lcv; /* 16 bits - BPV err cnt */
- u_int16_t pcv; /* 8 bits - P-bit err cnt */
- u_int16_t ccv; /* 8 bits - C-bit err cnt */
- u_int16_t line; /* line status bit vector */
- u_int16_t loop; /* loop status bit vector */
- };
-
-struct t1_snmp
- {
- u_int16_t prm[4]; /* T1.403 Performance Report Msg */
- u_int16_t febe; /* 10 bits - E1 FAR CRC err cnt */
- u_int16_t lcv; /* 16 bits - BPV + EXZ err cnt */
- u_int16_t fe; /* 12 bits - Ft/Fs/FPS/FAS err cnt */
- u_int16_t crc; /* 10 bits - CRC6/CRC4 err cnt */
- u_int16_t line; /* line status bit vector */
- u_int16_t loop; /* loop status bit vector */
- };
-
-/* SNMP trunk MIB Send codes */
-#define TSEND_NORMAL 1 /* Send data (normal or looped) */
-#define TSEND_LINE 2 /* Send 'line loopback activate' */
-#define TSEND_PAYLOAD 3 /* Send 'payload loop activate' */
-#define TSEND_RESET 4 /* Send 'loopback deactivate' */
-#define TSEND_QRS 5 /* Send Quasi Random Signal */
-
-/* ANSI T1.403 Performance Report Msg -- once a second from the far end */
-#define T1PRM_FE 0x8000 /* Frame Sync Bit Error Event >= 1 */
-#define T1PRM_SE 0x4000 /* Severely Err Framing Event >= 1 */
-#define T1PRM_LB 0x2000 /* Payload Loopback Activated */
-#define T1PRM_G1 0x1000 /* CRC Error Event = 1 */
-#define T1PRM_R 0x0800 /* Reserved */
-#define T1PRM_G2 0x0400 /* 1 < CRC Error Event <= 5 */
-#define T1PRM_SEQ 0x0300 /* modulo 4 counter */
-#define T1PRM_G3 0x0080 /* 5 < CRC Error Event <= 10 */
-#define T1PRM_LV 0x0040 /* Line Code Violation Event >= 1 */
-#define T1PRM_G4 0x0020 /* 10 < CRC Error Event <= 100 */
-#define T1PRM_U 0x0018 /* Under study for synchronization */
-#define T1PRM_G5 0x0004 /* 100 < CRC Error Event <= 319 */
-#define T1PRM_SL 0x0002 /* Slip Event >= 1 */
-#define T1PRM_G6 0x0001 /* CRC Error Event >= 320 */
-
-/* SNMP Line Status */
-#define TLINE_NORM 0x0001 /* no alarm present */
-#define TLINE_RX_RAI 0x0002 /* receiving RAI = Yellow alarm */
-#define TLINE_TX_RAI 0x0004 /* sending RAI = Yellow alarm */
-#define TLINE_RX_AIS 0x0008 /* receiving AIS = blue alarm */
-#define TLINE_TX_AIS 0x0010 /* sending AIS = blue alarm */
-#define TLINE_LOF 0x0020 /* near end LOF = red alarm */
-#define TLINE_LOS 0x0040 /* near end loss of Signal */
-#define TLINE_LOOP 0x0080 /* near end is looped */
-#define T1LINE_RX_TS16_AIS 0x0100 /* near end receiving TS16 AIS */
-#define T1LINE_RX_TS16_LOMF 0x0200 /* near end sending TS16 LOMF */
-#define T1LINE_TX_TS16_LOMF 0x0400 /* near end receiving TS16 LOMF */
-#define T1LINE_RX_TEST 0x0800 /* near end receiving QRS Signal */
-#define T1LINE_SEF 0x1000 /* near end severely errored frame */
-#define T3LINE_RX_IDLE 0x0100 /* near end receiving IDLE signal */
-#define T3LINE_SEF 0x0200 /* near end severely errored frame */
-
-/* SNMP Loopback Status */
-#define TLOOP_NONE 0x01 /* no loopback */
-#define TLOOP_NEAR_PAYLOAD 0x02 /* near end payload loopback */
-#define TLOOP_NEAR_LINE 0x04 /* near end line loopback */
-#define TLOOP_NEAR_OTHER 0x08 /* near end looped somehow */
-#define TLOOP_NEAR_INWARD 0x10 /* near end looped inward */
-#define TLOOP_FAR_PAYLOAD 0x20 /* far end payload loopback */
-#define TLOOP_FAR_LINE 0x40 /* far end line loopback */
-
-/* event counters record interesting statistics */
-struct event_cntrs
- {
- struct timeval reset_time; /* time when cntrs were reset */
- u_int64_t ibytes; /* Rx bytes with good status */
- u_int64_t obytes; /* Tx bytes */
- u_int64_t ipackets; /* Rx packets with good status */
- u_int64_t opackets; /* Tx packets */
- u_int32_t ierrors; /* Rx packets with bad status */
- u_int32_t oerrors; /* Tx packets with bad status */
- u_int32_t idiscards; /* Rx packets discarded */
- u_int32_t odiscards; /* Tx packets discarded */
- u_int32_t fifo_over; /* Rx fifo overruns */
- u_int32_t fifo_under; /* Tx fifo underruns */
- u_int32_t missed; /* Rx pkts missed: no DMA descs */
- u_int32_t overruns; /* Rx pkts missed: fifo overrun */
- u_int32_t fdl_pkts; /* Rx T1 Facility Data Link pkts */
- u_int32_t crc_errs; /* Rx T1 frame CRC errors */
- u_int32_t lcv_errs; /* Rx T1 T3 Line Coding Violation */
- u_int32_t frm_errs; /* Rx T1 T3 Frame bit errors */
- u_int32_t febe_errs; /* Rx T1 T3 Far End Bit Errors */
- u_int32_t par_errs; /* Rx T3 P-bit parity errors */
- u_int32_t cpar_errs; /* Rx T3 C-bit parity errors */
- u_int32_t mfrm_errs; /* Rx T3 Multi-frame bit errors */
- u_int32_t rxdma; /* Rx out of kernel buffers */
- u_int32_t txdma; /* Tx out of DMA desciptors */
- u_int32_t lck_watch; /* try_lock conflict in watchdog */
- u_int32_t lck_ioctl; /* try_lock conflict in ioctl */
- u_int32_t lck_intr; /* try_lock conflict in interrupt */
- };
-
-/* sc->status is the READ ONLY status of the card. */
-/* Accessed using socket IO control calls or netgraph control messages. */
-struct status
- {
- struct iohdr iohdr; /* common ioctl header */
- u_int32_t card_type; /* PCI device number */
- u_int16_t ieee[3]; /* IEEE MAC-addr from Tulip SROM */
- u_int16_t oper_status; /* actual state: up, down, test */
- u_int32_t tx_speed; /* measured TX bits/sec */
- u_int32_t cable_type; /* SSI only: cable type */
- u_int32_t line_pkg; /* actual line pkg in use */
- u_int32_t line_prot; /* actual line proto in use */
- u_int32_t ticks; /* incremented by watchdog @ 1 Hz */
- struct event_cntrs cntrs; /* event counters */
- union
- {
- struct hssi_snmp hssi; /* data for RFC-???? HSSI MIB */
- struct t3_snmp t3; /* data for RFC-2496 T3 MIB */
- struct ssi_snmp ssi; /* data for RFC-1659 RS232 MIB */
- struct t1_snmp t1; /* data for RFC-2495 T1 MIB */
- } snmp;
- };
-
-/* line protocol package codes fnobl */
-#define PKG_RAWIP 1 /* driver yyyyy */
-#define PKG_SPPP 2 /* fbsd, nbsd, obsd yyynn */
-#define PKG_P2P 3 /* bsd/os nnnyn */
-#define PKG_NG 4 /* fbsd ynnnn */
-#define PKG_GEN_HDLC 5 /* linux nnnny */
-
-/* line protocol codes fnobl */
-#define PROT_PPP 1 /* Point-to-Point Protocol yyyyy */
-#define PROT_C_HDLC 2 /* Cisco HDLC Protocol yyyyy */
-#define PROT_FRM_RLY 3 /* Frame Relay Protocol ynnyy */
-#define PROT_X25 4 /* X.25/LAPB Protocol nnnny */
-#define PROT_ETH_HDLC 5 /* raw Ether pkts in HDLC nnnny */
-#define PROT_IP_HDLC 6 /* raw IP4/6 pkts in HDLC yyyyy */
-
-/* oper_status codes (same as SNMP status codes) */
-#define STATUS_UP 1 /* may/will tx/rx pkts */
-#define STATUS_DOWN 2 /* can't/won't tx/rx pkts */
-#define STATUS_TEST 3 /* currently not used */
-
-struct synth /* programmable oscillator params */
- {
- unsigned n :7; /* numerator (3..127) */
- unsigned m :7; /* denominator (3..127) */
- unsigned v :1; /* mul by 1|8 */
- unsigned x :2; /* div by 1|2|4|8 */
- unsigned r :2; /* div by 1|2|4|8 */
- unsigned prescale :13; /* log(final divisor): 2, 4 or 9 */
- } __attribute__ ((packed));
-
-#define SYNTH_FREF 20e6 /* reference xtal = 20 MHz */
-#define SYNTH_FMIN 50e6 /* internal VCO min 50 MHz */
-#define SYNTH_FMAX 250e6 /* internal VCO max 250 MHz */
-
-/* sc->config is the READ/WRITE configuration of the card. */
-/* Accessed using socket IO control calls or netgraph control messages. */
-struct config
- {
- struct iohdr iohdr; /* common ioctl header */
- u_int32_t crc_len; /* ALL: CRC-16 or CRC-32 or none */
- u_int32_t loop_back; /* ALL: many kinds of loopbacks */
- u_int32_t tx_clk_src; /* T1, HSSI: ST, RT, int, ext */
- u_int32_t format; /* T3, T1: ckt framing format */
- u_int32_t time_slots; /* T1: 64Kb time slot config */
- u_int32_t cable_len; /* T3, T1: cable length in meters */
- u_int32_t scrambler; /* T3: payload scrambler config */
- u_int32_t dte_dce; /* SSI, HSSIc: drive TXCLK */
- struct synth synth; /* SSI, HSSIc: synth oscil params */
- u_int32_t rx_gain; /* T1: receiver gain limit 0-50 dB */
- u_int32_t tx_pulse; /* T1: transmitter pulse shape */
- u_int32_t tx_lbo; /* T1: transmitter atten 0-22.5 dB */
- u_int32_t debug; /* ALL: extra printout */
- u_int32_t line_pkg; /* ALL: use this line pkg */
- u_int32_t line_prot; /* SPPP: use this line proto */
- u_int32_t keep_alive; /* SPPP: use keep-alive packets */
- };
-
-#define CFG_CRC_0 0 /* no CRC */
-#define CFG_CRC_16 2 /* X^16+X^12+X^5+1 (default) */
-#define CFG_CRC_32 4 /* X^32+X^26+X^23+X^22+X^16+X^12+ */
- /* X^11+X^10+X^8+X^7+X^5+X^4+X^2+X+1 */
-#define CFG_LOOP_NONE 1 /* SNMP don't loop back anything */
-#define CFG_LOOP_PAYLOAD 2 /* SNMP loop outward thru framer */
-#define CFG_LOOP_LINE 3 /* SNMP loop outward thru LIU */
-#define CFG_LOOP_OTHER 4 /* SNMP loop inward thru LIU */
-#define CFG_LOOP_INWARD 5 /* SNMP loop inward thru framer */
-#define CFG_LOOP_DUAL 6 /* SNMP loop inward & outward */
-#define CFG_LOOP_TULIP 16 /* ALL: loop inward thru Tulip */
-#define CFG_LOOP_PINS 17 /* HSSIc, SSI: loop inward-pins */
-#define CFG_LOOP_LL 18 /* HSSI, SSI: assert LA/LL mdm pin */
-#define CFG_LOOP_RL 19 /* HSSI, SSI: assert LB/RL mdm pin */
-
-#define CFG_CLKMUX_ST 1 /* TX clk <- Send timing */
-#define CFG_CLKMUX_INT 2 /* TX clk <- internal source */
-#define CFG_CLKMUX_RT 3 /* TX clk <- Receive (loop) timing */
-#define CFG_CLKMUX_EXT 4 /* TX clk <- ext connector */
-
-/* values 0-31 are Bt8370 CR0 register values (LSB is zero if E1). */
-/* values 32-99 are reserved for other T1E1 formats, (even number if E1) */
-/* values 100 and up are used for T3 frame formats. */
-#define CFG_FORMAT_T1SF 9 /* T1-SF AMI */
-#define CFG_FORMAT_T1ESF 27 /* T1-ESF+CRC B8ZS X^6+X+1 */
-#define CFG_FORMAT_E1FAS 0 /* E1-FAS HDB3 TS0 */
-#define CFG_FORMAT_E1FASCRC 8 /* E1-FAS+CRC HDB3 TS0 X^4+X+1 */
-#define CFG_FORMAT_E1FASCAS 16 /* E1-FAS +CAS HDB3 TS0 & TS16 */
-#define CFG_FORMAT_E1FASCRCCAS 24 /* E1-FAS+CRC+CAS HDB3 TS0 & TS16 */
-#define CFG_FORMAT_E1NONE 32 /* E1-NO framing HDB3 */
-#define CFG_FORMAT_T3CPAR 100 /* T3-C-Bit par B3ZS */
-#define CFG_FORMAT_T3M13 101 /* T3-M13 format B3ZS */
-
-/* format aliases that improve code readability */
-#define FORMAT_T1ANY ((sc->config.format & 1)==1)
-#define FORMAT_E1ANY ((sc->config.format & 1)==0)
-#define FORMAT_E1CAS ((sc->config.format & 0x11)==0x10)
-#define FORMAT_E1CRC ((sc->config.format & 0x09)==0x08)
-#define FORMAT_E1NONE (sc->config.format == CFG_FORMAT_E1NONE)
-#define FORMAT_T1ESF (sc->config.format == CFG_FORMAT_T1ESF)
-#define FORMAT_T1SF (sc->config.format == CFG_FORMAT_T1SF)
-#define FORMAT_T3CPAR (sc->config.format == CFG_FORMAT_T3CPAR)
-
-#define CFG_SCRAM_OFF 1 /* DS3 payload scrambler off */
-#define CFG_SCRAM_DL_KEN 2 /* DS3 DigitalLink/Kentrox X^43+1 */
-#define CFG_SCRAM_LARS 3 /* DS3 Larscom X^20+X^17+1 w/28ZS */
-
-#define CFG_DTE 1 /* HSSIc, SSI: rcv TXCLK; rcv DCD */
-#define CFG_DCE 2 /* HSSIc, SSI: drv TXCLK; drv DCD */
-
-#define CFG_GAIN_SHORT 0x24 /* 0-20 dB of equalized gain */
-#define CFG_GAIN_MEDIUM 0x2C /* 0-30 dB of equalized gain */
-#define CFG_GAIN_LONG 0x34 /* 0-40 dB of equalized gain */
-#define CFG_GAIN_EXTEND 0x3F /* 0-64 dB of equalized gain */
-#define CFG_GAIN_AUTO 0xFF /* auto-set based on cable length */
-
-#define CFG_PULSE_T1DSX0 0 /* T1 DSX 0- 40 meters */
-#define CFG_PULSE_T1DSX1 2 /* T1 DSX 40- 80 meters */
-#define CFG_PULSE_T1DSX2 4 /* T1 DSX 80-120 meters */
-#define CFG_PULSE_T1DSX3 6 /* T1 DSX 120-160 meters */
-#define CFG_PULSE_T1DSX4 8 /* T1 DSX 160-200 meters */
-#define CFG_PULSE_E1COAX 10 /* E1 75 ohm coax pair */
-#define CFG_PULSE_E1TWIST 12 /* E1 120 ohm twisted pairs */
-#define CFG_PULSE_T1CSU 14 /* T1 CSU 200-2000 meters; set LBO */
-#define CFG_PULSE_AUTO 0xFF /* auto-set based on cable length */
-
-#define CFG_LBO_0DB 0 /* T1CSU LBO = 0.0 dB; FCC opt A */
-#define CFG_LBO_7DB 16 /* T1CSU LBO = 7.5 dB; FCC opt B */
-#define CFG_LBO_15DB 32 /* T1CSU LBO = 15.0 dB; FCC opt C */
-#define CFG_LBO_22DB 48 /* T1CSU LBO = 22.5 dB; final span */
-#define CFG_LBO_AUTO 0xFF /* auto-set based on cable length */
-
-struct ioctl
- {
- struct iohdr iohdr; /* common ioctl header */
- u_int32_t cmd; /* command */
- u_int32_t address; /* command address */
- u_int32_t data; /* command data */
- char *ucode; /* user-land address of ucode */
- };
-
-#define IOCTL_RW_PCI 1 /* RW: Tulip PCI config registers */
-#define IOCTL_RW_CSR 2 /* RW: Tulip Control & Status Regs */
-#define IOCTL_RW_SROM 3 /* RW: Tulip Serial Rom */
-#define IOCTL_RW_BIOS 4 /* RW: Tulip Boot rom */
-#define IOCTL_RW_MII 5 /* RW: MII registers */
-#define IOCTL_RW_FRAME 6 /* RW: Framer registers */
-#define IOCTL_WO_SYNTH 7 /* WO: Synthesized oscillator */
-#define IOCTL_WO_DAC 8 /* WO: Digital/Analog Converter */
-
-#define IOCTL_XILINX_RESET 16 /* reset Xilinx: all FFs set to 0 */
-#define IOCTL_XILINX_ROM 17 /* load Xilinx program from ROM */
-#define IOCTL_XILINX_FILE 18 /* load Xilinx program from file */
-
-#define IOCTL_SET_STATUS 50 /* set mdm ctrl bits (internal use)*/
-#define IOCTL_SNMP_SEND 51 /* trunk MIB send code */
-#define IOCTL_SNMP_LOOP 52 /* trunk MIB loop configuration */
-#define IOCTL_SNMP_SIGS 53 /* RS232-like modem control sigs */
-#define IOCTL_RESET_CNTRS 54 /* reset event counters */
-
-/* storage for these strings is allocated here! */
-static const char *ssi_cables[] =
- {
- "V.10/EIA423",
- "V.11/EIA530A",
- "RESERVED",
- "X.21",
- "V.35",
- "V.36/EIA449",
- "V.28/EIA232",
- "NO CABLE",
- NULL,
- };
-
-/***************************************************************************/
-/* Declarations above here are shared with the user lmcconfig program. */
-/* Declarations below here are private to the kernel device driver. */
-/***************************************************************************/
-
-#if (_KERNEL || KERNEL || __KERNEL__)
-
-#define SNDQ_MAXLEN 32 /* packets awaiting transmission */
-#define DESCS_PER_PKT 4 /* DMA descriptors per TX pkt */
-#define NUM_TX_DESCS (DESCS_PER_PKT * SNDQ_MAXLEN)
-/* Increase DESCS_PER_PKT if status.cntrs.txdma increments. */
-
-/* A Tulip DMA descriptor can point to two chunks of memory.
- * Each chunk has a max length of 2047 bytes (ask the VMS guys...).
- * 2047 isn't a multiple of a cache line size (32 bytes typically).
- * So back off to 2048-32 = 2016 bytes per chunk (2 chunks per descr).
- */
-#define MAX_CHUNK_LEN 2016
-#define MAX_DESC_LEN (2 * MAX_CHUNK_LEN)
-
-/* Tulip DMA descriptor; THIS STRUCT MUST MATCH THE HARDWARE */
-struct dma_desc
- {
- u_int32_t status; /* hardware->to->software */
-#if (BYTE_ORDER == LITTLE_ENDIAN) /* left-to-right packing by compiler */
- unsigned length1:11; /* buffer1 length */
- unsigned length2:11; /* buffer2 length */
- unsigned control:10; /* software->to->hardware */
-#else /* right-to-left packing by compiler */
- unsigned control:10; /* software->to->hardware */
- unsigned length2:11; /* buffer2 length */
- unsigned length1:11; /* buffer1 length */
-#endif
- u_int32_t address1; /* buffer1 bus address */
- u_int32_t address2; /* buffer2 bus address */
- bus_dmamap_t map; /* bus dmamap for this descriptor */
-# define TLP_BUS_DSL_VAL (sizeof(bus_dmamap_t) & TLP_BUS_DSL)
- } __attribute__ ((packed));
-
-/* Tulip DMA descriptor status bits */
-#define TLP_DSTS_OWNER 0x80000000
-#define TLP_DSTS_RX_DESC_ERR 0x00004000
-#define TLP_DSTS_RX_FIRST_DESC 0x00000200
-#define TLP_DSTS_RX_LAST_DESC 0x00000100
-#define TLP_DSTS_RX_MII_ERR 0x00000008
-#define TLP_DSTS_RX_DRIBBLE 0x00000004
-#define TLP_DSTS_TX_UNDERRUN 0x00000002
-#define TLP_DSTS_RX_OVERRUN 0x00000001 /* not documented in rev AF */
-#define TLP_DSTS_RX_BAD (TLP_DSTS_RX_MII_ERR | \
- TLP_DSTS_RX_DRIBBLE | \
- TLP_DSTS_RX_DESC_ERR | \
- TLP_DSTS_RX_OVERRUN)
-
-/* Tulip DMA descriptor control bits */
-#define TLP_DCTL_TX_INTERRUPT 0x0200
-#define TLP_DCTL_TX_LAST_SEG 0x0100
-#define TLP_DCTL_TX_FIRST_SEG 0x0080
-#define TLP_DCTL_TX_NO_CRC 0x0010
-#define TLP_DCTL_END_RING 0x0008
-#define TLP_DCTL_TX_NO_PAD 0x0002
-
-/* DMA descriptors are kept in a ring.
- * Ring is empty when (read == write).
- * Ring is full when (read == wrap(write+1)),
- * The ring also contains a tailq of data buffers.
- */
-struct desc_ring
- {
- struct dma_desc *read; /* next descriptor to be read */
- struct dma_desc *write; /* next descriptor to be written */
- struct dma_desc *first; /* first descriptor in ring */
- struct dma_desc *last; /* last descriptor in ring */
- struct dma_desc *temp; /* temporary write pointer for tx */
- u_int32_t dma_addr; /* bus address for desc array */
- int size_descs; /* bus_dmamap_sync needs this */
- int num_descs; /* used to set rx quota */
-#if BSD
- struct mbuf *head; /* tail-queue of mbufs */
- struct mbuf *tail;
- bus_dma_tag_t tag; /* bus_dma tag for desc array */
- bus_dmamap_t map; /* bus_dma map for desc array */
- bus_dma_segment_t segs[2]; /* bus_dmamap_load() or bus_dmamem_alloc() */
- int nsegs; /* bus_dmamap_load() or bus_dmamem_alloc() */
-#endif
- };
-
-/* break circular definition */
-typedef struct softc softc_t;
-
-/* card-dependent methods */
-struct card
- {
- void (* config)(softc_t *);
- void (* ident)(softc_t *);
- int (* watchdog)(softc_t *); /* must not sleep */
- int (* ioctl)(softc_t *, struct ioctl *); /* can sleep */
- };
-
-/* flag bits in sc->flags */
-#define FLAG_IFNET 0x00000002 /* IFNET is attached */
-#define FLAG_NETDEV 0x00000004 /* NETDEV is registered */
-#define FLAG_NETGRAPH 0x00000008 /* NETGRAPH is attached */
-
-/* Accessing Tulip CSRs:
- * There are two ways: IO instruction (default) and memory reference.
- * IO refs are used if IOREF_CSR is defined; otherwise memory refs are used.
- * MEMORY REFERENCES DO NOT WORK in BSD/OS: page faults happen.
- */
-#define IOREF_CSR 1 /* access Tulip CSRs with IO cycles if 1 */
-
-#if defined(DEVICE_POLLING)
-# define DEV_POLL 1
-#else
-# define DEV_POLL 0
-#endif
-
-#if defined(ALTQ) && ALTQ
-# define ALTQ_PRESENT 1
-#else
-# define ALTQ_PRESENT 0
-#endif
-
-/* This is the instance data, or "software context" for the device driver. */
-/* NetBSD, OpenBSD and BSD/OS want struct device first in the softc. */
-/* FreeBSD wants struct ifnet first in the softc. */
-struct softc
- {
-
-
- /* State for kernel-resident Line Protocols */
-#if IFNET
- struct ifnet *ifp;
- struct ifmedia ifm; /* hooks for ifconfig(8) */
-# if NSPPP
- struct sppp *sppp;
-# elif P2P
- struct p2pcom p2pcom;
- struct p2pcom *p2p;
-# endif
-#endif
-
-
-#if NETGRAPH
- node_p ng_node; /* pointer to our node struct */
- hook_p ng_hook; /* non-zero means NETGRAPH owns device */
- struct ifaltq ng_sndq;
- struct ifaltq ng_fastq;
-#endif
-
- struct callout callout; /* watchdog needs this */
- device_t dev; /* base device pointer */
- bus_space_tag_t csr_tag; /* bus_space needs this */
- bus_space_handle_t csr_handle;/* bus_space_needs this */
- void *irq_cookie; /* bus_teardown_intr needs this */
- struct resource *irq_res; /* bus_release_resource needs this */
- int irq_res_id; /* bus_release_resource needs this */
- struct resource *csr_res; /* bus_release_resource needs this */
- int csr_res_id; /* bus_release resource needs this */
- int csr_res_type; /* bus_release resource needs this */
- struct mbuf *tx_mbuf; /* hang mbuf here while building dma descs */
-# ifdef DEVICE_POLLING
- int quota; /* used for incoming packet flow control */
-# endif
- struct mtx top_mtx; /* lock card->watchdog vs core_ioctl */
- struct mtx bottom_mtx; /* lock for buf queues & descriptor rings */
-
-
- /* Top-half state used by all card types; lock with top_lock, */
- const char *dev_desc; /* string describing type of board */
- struct status status; /* driver status lmcconfig can read */
- struct config config; /* driver config lmcconfig can read/write */
- struct card *card; /* card methods: config, ioctl, watchdog */
- u_int32_t gpio_dir; /* s/w copy of GPIO direction register */
- u_int16_t led_state; /* last value written to mii16 */
- u_int32_t flags; /* driver-global flags */
-
- /* Top-half state used by card-specific watchdogs; lock with top_lock. */
- u_int32_t last_mii16; /* SSI, HSSI: MII reg 16 one second ago */
- u_int32_t last_stat16; /* T3: framer reg 16 one second ago */
- u_int32_t last_alm1; /* T1E1: framer reg 47 one second ago */
- u_int32_t last_FEAC; /* last FEAC msg code received */
- u_int32_t loop_timer; /* seconds until loopback expires */
-
- /* Bottom-half state used by the interrupt code; lock with bottom_lock. */
- struct desc_ring txring; /* tx descriptor ring state */
- struct desc_ring rxring; /* rx descriptor ring state */
- }; /* end of softc */
-
-/* Hide the minor differences between OS versions */
-
- typedef void intr_return_t;
-# define READ_PCI_CFG(sc, addr) pci_read_config ((sc)->dev, addr, 4)
-# define WRITE_PCI_CFG(sc, addr, data) pci_write_config((sc)->dev, addr, data, 4)
-# define READ_CSR(csr) bus_space_read_4 (sc->csr_tag, sc->csr_handle, csr)
-# define WRITE_CSR(csr, val) bus_space_write_4(sc->csr_tag, sc->csr_handle, csr, val)
-# define NAME_UNIT device_get_nameunit(sc->dev)
-# define DRIVER_DEBUG ((sc->config.debug) || (sc->ifp->if_flags & IFF_DEBUG))
-# define TOP_TRYLOCK mtx_trylock(&sc->top_mtx)
-# define TOP_UNLOCK mtx_unlock (&sc->top_mtx)
-# define BOTTOM_TRYLOCK mtx_trylock(&sc->bottom_mtx)
-# define BOTTOM_UNLOCK mtx_unlock (&sc->bottom_mtx)
-# define CHECK_CAP priv_check(curthread, PRIV_DRIVER)
-# define DISABLE_INTR /* nothing */
-# define ENABLE_INTR /* nothing */
-# define IRQ_NONE /* nothing */
-# define IRQ_HANDLED /* nothing */
-# define IFP2SC(ifp) (ifp)->if_softc
-# define COPY_BREAK MHLEN
-# define SLEEP(usecs) tsleep(sc, PCATCH | PZERO, DEVICE_NAME, 1+(usecs/tick))
-# define DMA_SYNC(map, size, flags) bus_dmamap_sync(ring->tag, map, flags)
-# define DMA_LOAD(map, addr, size) bus_dmamap_load(ring->tag, map, addr, size, fbsd_dmamap_load, ring, 0)
-# if (NBPFILTER != 0)
-# define LMC_BPF_MTAP(mbuf) BPF_MTAP(sc->ifp, mbuf)
-# define LMC_BPF_ATTACH(dlt, len) bpfattach(sc->ifp, dlt, len)
-# define LMC_BPF_DETACH bpfdetach(sc->ifp)
-# endif
-# define IF_DROP(ifq) _IF_DROP(ifq)
-# define IF_QFULL(ifq) _IF_QFULL(ifq)
-# define IFF_RUNNING IFF_DRV_RUNNING
-
-
-#if (NBPFILTER == 0)
-# define LMC_BPF_MTAP(mbuf) /* nothing */
-# define LMC_BPF_ATTACH(dlt, len) /* nothing */
-# define LMC_BPF_DETACH /* nothing */
-#endif
-
-#define HSSI_DESC "SBE/LMC HSSI Card"
-#define T3_DESC "SBE/LMC T3 Card"
-#define SSI_DESC "SBE/LMC SSI Card"
-#define T1E1_DESC "SBE/LMC T1E1 Card"
-
-/* procedure prototypes */
-
-static void shift_srom_bits(softc_t *, u_int32_t, u_int32_t);
-static u_int16_t read_srom(softc_t *, u_int8_t);
-static void write_srom(softc_t *, u_int8_t, u_int16_t);
-
-static u_int8_t read_bios(softc_t *, u_int32_t);
-static void write_bios_phys(softc_t *, u_int32_t, u_int8_t);
-static void write_bios(softc_t *, u_int32_t, u_int8_t);
-static void erase_bios(softc_t *);
-
-static void shift_mii_bits(softc_t *, u_int32_t, u_int32_t);
-static u_int16_t read_mii(softc_t *, u_int8_t);
-static void write_mii(softc_t *, u_int8_t, u_int16_t);
-
-static void set_mii16_bits(softc_t *, u_int16_t);
-static void clr_mii16_bits(softc_t *, u_int16_t);
-static void set_mii17_bits(softc_t *, u_int16_t);
-static void clr_mii17_bits(softc_t *, u_int16_t);
-
-static void led_off(softc_t *, u_int16_t);
-static void led_on(softc_t *, u_int16_t);
-static void led_inv(softc_t *, u_int16_t);
-
-static void write_framer(softc_t *, u_int16_t, u_int8_t);
-static u_int8_t read_framer(softc_t *, u_int16_t);
-
-static void make_gpio_input(softc_t *, u_int32_t);
-static void make_gpio_output(softc_t *, u_int32_t);
-static u_int32_t read_gpio(softc_t *);
-static void set_gpio_bits(softc_t *, u_int32_t);
-static void clr_gpio_bits(softc_t *, u_int32_t);
-
-static void reset_xilinx(softc_t *);
-static void load_xilinx_from_rom(softc_t *);
-static int load_xilinx_from_file(softc_t *, char *, u_int32_t);
-
-static void shift_synth_bits(softc_t *, u_int32_t, u_int32_t);
-static void write_synth(softc_t *, struct synth *);
-
-static void write_dac(softc_t *, u_int16_t);
-
-static void hssi_config(softc_t *);
-static void hssi_ident(softc_t *);
-static int hssi_watchdog(softc_t *);
-static int hssi_ioctl(softc_t *, struct ioctl *);
-
-static void t3_config(softc_t *);
-static void t3_ident(softc_t *);
-static int t3_watchdog(softc_t *);
-static void t3_send_dbl_feac(softc_t *, int, int);
-static int t3_ioctl(softc_t *, struct ioctl *);
-
-static void ssi_config(softc_t *);
-static void ssi_ident(softc_t *);
-static int ssi_watchdog(softc_t *);
-static int ssi_ioctl(softc_t *, struct ioctl *);
-
-static void t1_config(softc_t *);
-static void t1_ident(softc_t *);
-static int t1_watchdog(softc_t *);
-static void t1_send_bop(softc_t *, int);
-static int t1_ioctl(softc_t *, struct ioctl *);
-
-#if IFNET
-static void lmc_raw_input(struct ifnet *, struct mbuf *);
-#endif /* IFNET */
-
-#if BSD
-static void mbuf_enqueue(struct desc_ring *, struct mbuf *);
-static struct mbuf* mbuf_dequeue(struct desc_ring *);
-static void fbsd_dmamap_load(void *, bus_dma_segment_t *, int, int);
-static int create_ring(softc_t *, struct desc_ring *, int);
-static void destroy_ring(softc_t *, struct desc_ring *);
-static int rxintr_cleanup(softc_t *);
-static int rxintr_setup(softc_t *);
-static int txintr_cleanup(softc_t *);
-static int txintr_setup_mbuf(softc_t *, struct mbuf *);
-static int txintr_setup(softc_t *);
-#endif /* BSD */
-
-
-static void check_intr_status(softc_t *);
-static void core_interrupt(void *, int);
-static void user_interrupt(softc_t *, int);
-#if BSD
-# if (defined(__FreeBSD__) && defined(DEVICE_POLLING))
-static int fbsd_poll(struct ifnet *, enum poll_cmd, int);
-# endif
-static intr_return_t bsd_interrupt(void *);
-#endif /* BSD */
-
-static void set_status(softc_t *, int);
-#if P2P
-static int p2p_getmdm(struct p2pcom *, caddr_t);
-static int p2p_mdmctl(struct p2pcom *, int);
-#endif
-#if NSPPP
-static void sppp_tls(struct sppp *);
-static void sppp_tlf(struct sppp *);
-#endif
-
-static void config_proto(softc_t *, struct config *);
-static int core_ioctl(softc_t *, u_long, caddr_t);
-static void core_watchdog(softc_t *);
-
-#if IFNET
-static int lmc_raw_ioctl(struct ifnet *, u_long, caddr_t);
-static int lmc_ifnet_ioctl(struct ifnet *, u_long, caddr_t);
-static void lmc_ifnet_start(struct ifnet *);
-static int lmc_raw_output(struct ifnet *, struct mbuf *,
- const struct sockaddr *, struct route *);
-static void setup_ifnet(struct ifnet *);
-static int lmc_ifnet_attach(softc_t *);
-static void lmc_ifnet_detach(softc_t *);
-#endif /* IFNET */
-
-#if NETGRAPH
-static int ng_constructor(node_p);
-static int ng_rcvmsg(node_p, item_p, hook_p);
-static int ng_shutdown(node_p);
-static int ng_newhook(node_p, hook_p, const char *);
-static int ng_connect(hook_p);
-static int ng_rcvdata(hook_p, item_p);
-static int ng_disconnect(hook_p);
-# if (IFNET == 0)
-static void ng_watchdog(void *);
-# endif
-static int ng_attach(softc_t *);
-static void ng_detach(softc_t *);
-#endif /* NETGRAPH */
-
-static int startup_card(softc_t *);
-static void shutdown_card(void *);
-static int attach_card(softc_t *, const char *);
-static void detach_card(softc_t *);
-
-static int fbsd_probe(device_t);
-static int fbsd_detach(device_t);
-static int fbsd_shutdown(device_t);
-static int fbsd_attach(device_t);
-
-
-
-
-
-#endif /* KERNEL */
-
-#endif /* IF_LMC_H */
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
index ec0292ba0dadc..1cff574188f52 100644
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -226,7 +226,6 @@ SUBDIR= \
${_linux64} \
linuxkpi \
${_lio} \
- lmc \
lpt \
mac_biba \
mac_bsdextended \
diff --git a/sys/modules/lmc/Makefile b/sys/modules/lmc/Makefile
deleted file mode 100644
index e5076744d8dbd..0000000000000
--- a/sys/modules/lmc/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-# $FreeBSD$
-
-KMOD = if_lmc
-.PATH: ${SRCTOP}/sys/dev/lmc
-
-SRCS = if_lmc.c if_lmc.h
-SRCS += device_if.h bus_if.h pci_if.h
-SRCS += opt_inet.h opt_inet6.h
-SRCS += opt_netgraph.h
-SRCS += opt_bpf.h
-
-opt_netgraph.h:
- echo "#define NETGRAPH 1" > ${.TARGET}
-
-.include <bsd.kmod.mk>
diff --git a/tools/kerneldoc/subsys/Doxyfile-dev_lmc b/tools/kerneldoc/subsys/Doxyfile-dev_lmc
deleted file mode 100644
index 4485a6f17096b..0000000000000
--- a/tools/kerneldoc/subsys/Doxyfile-dev_lmc
+++ /dev/null
@@ -1,21 +0,0 @@
-# Doxyfile 1.5.2
-
-# $FreeBSD$
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-PROJECT_NAME = "FreeBSD kernel LMC device code"
-OUTPUT_DIRECTORY = $(DOXYGEN_DEST_PATH)/dev_lmc/
-EXTRACT_ALL = YES # for undocumented src, no warnings enabled
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-INPUT = $(DOXYGEN_SRC_PATH)/dev/lmc/ \
- $(NOTREVIEWED)
-
-GENERATE_TAGFILE = dev_lmc/dev_lmc.tag
-
-@INCLUDE_PATH = $(DOXYGEN_INCLUDE_PATH)
-@INCLUDE = common-Doxyfile
-
diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile
index 17f1b7b9414d4..206f69c021647 100644
--- a/usr.sbin/Makefile
+++ b/usr.sbin/Makefile
@@ -162,7 +162,6 @@ SUBDIR.${MK_MAN_UTILS}+= manctl
SUBDIR.${MK_NAND}+= nandsim
SUBDIR.${MK_NAND}+= nandtool
SUBDIR.${MK_NETGRAPH}+= flowctl
-SUBDIR.${MK_NETGRAPH}+= lmcconfig
SUBDIR.${MK_NETGRAPH}+= ngctl
SUBDIR.${MK_NETGRAPH}+= nghook
SUBDIR.${MK_NIS}+= rpc.yppasswdd
diff --git a/usr.sbin/lmcconfig/Makefile b/usr.sbin/lmcconfig/Makefile
deleted file mode 100644
index be00544600e54..0000000000000
--- a/usr.sbin/lmcconfig/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# $FreeBSD$
-
-PROG= lmcconfig
-MAN= lmcconfig.8
-
-LIBADD= netgraph
-
-WARNS?= 3
-
-.include <bsd.prog.mk>
diff --git a/usr.sbin/lmcconfig/Makefile.depend b/usr.sbin/lmcconfig/Makefile.depend
deleted file mode 100644
index 3f4cb50e1709e..0000000000000
--- a/usr.sbin/lmcconfig/Makefile.depend
+++ /dev/null
@@ -1,18 +0,0 @@
-# $FreeBSD$
-# Autogenerated - do NOT edit!
-
-DIRDEPS = \
- gnu/lib/csu \
- include \
- include/xlocale \
- lib/${CSU_DIR} \
- lib/libc \
- lib/libcompiler_rt \
- lib/libnetgraph \
-
-
-.include <dirdeps.mk>
-
-.if ${DEP_RELDIR} == ${_DEP_RELDIR}
-# local dependencies - needed for -jN in clean tree
-.endif
diff --git a/usr.sbin/lmcconfig/lmcconfig.8 b/usr.sbin/lmcconfig/lmcconfig.8
deleted file mode 100644
index 6eac2574c8b1b..0000000000000
--- a/usr.sbin/lmcconfig/lmcconfig.8
+++ /dev/null
@@ -1,723 +0,0 @@
-.\" Copyright (c) 2003 David Boggs. (boggs@boggs.palo-alto.ca.us)
-.\" All rights reserved.
-.\"
-.\" BSD License:
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" GNU General Public License:
-.\"
-.\" This program is free software; you can redistribute it and/or modify it
-.\" under the terms of the GNU General Public License as published by the Free
-.\" Software Foundation; either version 2 of the License, or (at your option)
-.\" any later version.
-.\"
-.\" This program is distributed in the hope that it will be useful, but WITHOUT
-.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-.\" more details.
-.\"
-.\" You should have received a copy of the GNU General Public License along with
-.\" this program; if not, write to the Free Software Foundation, Inc., 59
-.\" Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-.\"
-.\" $FreeBSD$
-.\"
-.Dd October 3, 2005
-.Dt LMCCONFIG 8
-.Os
-.Sh NAME
-.Nm lmcconfig
-.Nd configuration program for
-.Tn SBE
-(formerly
-.Tn LMC )
-wide-area network interface cards
-.Sh SYNOPSIS
-.Nm
-.Ar interface
-.Op Fl abBcCdDeEfhLmMpPrsStTuwxXyYzZ?
-.Nm
-.Ar interface
-.Fl 1
-.Op Fl aABceEfFgiIlLpPstTuUxX
-.Nm
-.Ar interface
-.Fl 3
-.Op Fl aABcefFlLsSv
-.Sh DESCRIPTION
-The
-.Nm
-utility
-is the configuration program for the
-.Xr lmc 4
-wide-area network device driver.
-It sets control values, such as T3 framing format,
-and it displays status, such as that of integrated modems,
-that are beyond the scope of
-.Xr ifconfig 8 .
-.Pp
-The
-.Nm
-utility
-displays the interface status when no parameters are specified;
-see example below.
-For this case only, if no
-.Ar interface
-is specified, it defaults to
-.Dq Li lmc0 .
-.Pp
-Only the super-user may modify the configuration of a network interface.
-.Pp
-The following options are available:
-.Bl -tag -width indent
-.It Ar interface
-This is the name of the interface; the default is
-.Dq Li lmc0 .
-If
-.Xr netgraph 4
-is present and the interface name ends with a colon
-then Netgraph control messages are used,
-otherwise the
-.Xr ifnet 9
-kernel interface and socket
-.Xr ioctl 2
-system calls are used.
-.It Fl 1
-All parameters after this apply to the T1E1 card.
-.It Fl 3
-All parameters after this apply to the T3 card.
-.El
-.Ss Commands for all cards
-The following parameters apply to more than one card type.
-.Bl -tag -width indent
-.It Fl a Ar number
-Set Transmitter clock source to
-.Ar number .
-.Pp
-.Bl -column "1" "External connector" "T1E1, HSSIc" -offset 2m -compact
-.It "1" Ta "TxClk from modem" Ta "T1E1, HSSI" Ta "default"
-.It "2" Ta "Internal source" Ta "T1E1, HSSI"
-.It "3" Ta "RxClk from modem" Ta "T1E1, HSSIc" Ta "loop timed"
-.It "4" Ta "External connector" Ta "T1E1, HSSIc"
-.El
-.Pp
-An HSSI card normally takes its Tx clock from the modem connector
-(it is a DTE) but can use the PCI bus clock (typically 33 MHz)
-for loopback and null modem testing; values 3 and 4 are only
-applicable to a few rare CompactPCI/HSSI cards.
-.Pp
-A T1E1 card uses an on-board synthesized oscillator
-if the value is 1 or 2; it
-.Em loop times
-(uses the clock recovered by the receiver as the transmitter clock)
-if the value is 3; and it uses a clock from a header connector on
-the card if the value is 4.
-.Pp
-TxClk source is not applicable to other card types.
-.It Fl b
-Read BIOS ROM.
-Print the first 256 locations.
-The BIOS ROM is not used and not present on some cards.
-.It Fl B
-Write BIOS ROM.
-Write the first 256 locations with an address pattern.
-.It Fl c
-Use HDLC's 16-bit CRC polynomial: X^16+X^12+X^5+1 (default).
-.It Fl C
-Use HDLC's 32-bit CRC polynomial:
-X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X+1
-.It Fl d
-Clear the driver-level debug flag.
-Non-critical log messages are suppressed.
-.It Fl D
-Set the driver-level debug flag.
-The driver generates more log messages.
-The driver also generates more log messages if the interface-level debug
-flag is set by
-.Xr ifconfig 8 .
-.It Fl e
-Set DTE (Data Terminal Equipment) mode (default).
-An SSI card transmitter uses the Tx clock signal from the modem connector
-and receives the Data Carrier Detect pin (DCD).
-DTE/DCE is not applicable to other card types except
-a few rare CompactPCI/HSSI cards.
-.It Fl E
-Set DCE (Data Communication Equipment) mode.
-An SSI card transmitter uses an on-board synthesized oscillator
-and drives the Data Carrier Detect pin (DCD).
-.It Fl f Ar number
-Set the frequency of the built-in synthesized oscillator to
-.Ar number
-bits/second.
-The nearest frequency that the synthesizer can generate will be used.
-Only SSI cards and a few rare CompactPCI/HSSI cards have synthesizers.
-.It Fl F
-Set SPPP line protocol to Frame-Relay.
-Only works for
-.Fx 5.4
-and later.
-.It Fl h
-Print help (usage message).
-.It Fl i
-Set interface name (e.g.\&
-.Dq Li lmc0 ) .
-.It Fl L Ar number
-Set loopback mode to
-.Ar number .
-.Pp
-.Bl -column "99" "payload" "inward thru drvrs/rcvrsxxx" "HSSI, SSI" -offset 1m -compact
-.It "1" Ta "none" Ta "default" Ta \&
-.It "2" Ta "payload" Ta "outward thru framer" Ta "T1E1. T3"
-.It "3" Ta "line" Ta "outward thru line if" Ta "T1E1, T3, HSSIc"
-.It "4" Ta "other" Ta "inward thru line if" Ta "T1E1, T3"
-.It "5" Ta "inward" Ta "inward thru framer" Ta "T1E1, T3"
-.It "6" Ta "dual" Ta "inward and outward" Ta "T1E1, T3"
-.It "16" Ta "tulip" Ta "inward thru Tulip chip" Ta "all cards"
-.It "17" Ta "pins" Ta "inward thru drvrs/rcvrs" Ta "SSI"
-.It "18" Ta "LA/LL" Ta "assert LA/LL modem pin" Ta "HSSI, SSI"
-.It "19" Ta "LB/RL" Ta "assert LB/RL modem pin" Ta "HSSI, SSI"
-.El
-.It Fl m
-Read Tulip MII registers.
-Print the 32 16-bit registers in the Media Independent Interface.
-.It Fl M Ar addr Ar data
-Write Tulip MII register.
-Write
-.Ar data
-into register
-.Ar addr .
-.It Fl p
-Read Tulip PCI configuration registers.
-Print the first 16 32-bit registers in the PCI configuration space.
-.It Fl P Ar addr Ar data
-Write Tulip PCI configuration register.
-Write
-.Ar data
-into register
-.Ar addr .
-.It Fl s
-Read Tulip SROM.
-Print the 64 16-bit locations.
-The PCI subsystem vendor and device IDs are kept here.
-.It Fl S Ar number
-Write Tulip SROM.
-Initializes the Tulip SROM to card type
-.Ar number .
-.Pp
-.Bl -column "9" -offset 1m -compact
-.It 3 Ta HSSI
-.It 4 Ta T3
-.It 5 Ta SSI
-.It 6 Ta T1E1
-.It 7 Ta HSSIc
-.It 8 Ta SDSL
-.It 0 Ta auto-set from MII PHYID
-.El
-.Pp
-If
-.Ar number
-is zero, then the card type is computed from the gate array
-microcode version field in the MII PHYID register.
-.Em CAUTION :
-if the SROM is incorrect, the card will be unusable!
-This command is
-.Em so
-dangerous that
-.Nm
-must be edited and recompiled to enable it.
-.It Fl t
-Read Tulip CSRs.
-Print the 16 32-bit control and status registers.
-.It Fl T Ar addr Ar data
-Write Tulip CSR.
-Write
-.Ar data
-into CSR number
-.Ar addr .
-Note that
-.Ar addr
-is a CSR number (0-15) not a byte offset into CSR space.
-.It Fl u
-Reset event counters to zero.
-The driver counts events like packets in and out, errors, discards, etc.
-The time when the counters are reset is remembered.
-.It Fl U
-Reset gate array.
-Not needed during normal operation; just for testing.
-.It Fl v
-Set verbose mode: print more stuff.
-.It Fl V
-Print the card configuration \[em] see the
-.Sx EXAMPLES
-section.
-.It Fl w
-Load gate array from on-board ROM.
-Not needed during normal operation; just for testing.
-.It Fl W Ar filename
-Load gate array microcode from
-.Ar filename .
-.It Fl x
-Select RAWIP mode \[em] bypass line protocol code.
-.It Fl X
-Select line protocol code rather than RAWIP mode.
-.It Fl y
-Disable SPPP keep-alive packets.
-.It Fl Y
-Enable SPPP keep-alive packets.
-.It Fl z
-Set SPPP line protocol to Cisco-HDLC.
-.It Fl Z
-Set SPPP line protocol to PPP.
-.It Fl ?\&
-Print help (usage message).
-.El
-.Ss Commands for T1E1 cards
-The following parameters apply to the T1E1 card type:
-.Bl -tag -width indent
-.It Fl a Sm Cm y | a | b Sm
-Stop sending alarm signal.
-.Pp
-.Bl -column "y" "Yellow Alarm" "unframed all ones; aka AIS" -offset 1m -compact
-.It "y" Ta "Yellow Alarm" Ta "varies with framing"
-.It "a" Ta "Red Alarm" Ta "unframed all ones; aka AIS"
-.It "b" Ta "Blue Alarm" Ta "unframed all ones"
-.El
-.Pp
-Red alarm, also known as AIS (Alarm Indication Signal),
-and Blue alarm are identical in T1.
-.It Fl A Sm Cm y | a | b Sm
-Start sending alarm signal (see table above).
-.It Fl B Ar number
-Send a Bit Oriented Protocol (BOP) message with code
-.Ar number .
-BOP codes are six bits.
-.It Fl c Ar number
-Set cable length to
-.Ar number
-meters (default: 10 meters).
-This is used to set receiver sensitivity
-and transmitter line build-out.
-.It Fl d
-Print the status of the on-board DSU/CSU \[em] see the
-.Sx EXAMPLES
-section.
-.It Fl e Ar number
-Set the framing format to
-.Ar number :
-.Pp
-.Bl -column "99" -offset 1m -compact
-.It 9 Ta T1-SF/AMI
-.It 27 Ta T1-ESF/B8ZS (default)
-.It 0 Ta E1-FAS
-.It 8 Ta E1-FAS+CRC
-.It 16 Ta E1-FAS+CAS
-.It 24 Ta E1-FAS+CRC+CAS
-.It 32 Ta E1-NO-framing
-.El
-.It Fl E Ar number
-Enable 64Kb time slots (TSs) for the T1E1 card.
-The
-.Ar number
-argument
-is a 32-bit hex number (default 0xFFFFFFFF).
-The LSB is TS0 and the MSB is TS31.
-TS0 and TS25-31 are ignored in T1 mode.
-TS0 and TS16 are determined by the framing format in E1 mode.
-.It Fl f
-Read framer registers.
-Print the 512 8-bit registers in the framer chip.
-.It Fl F Ar addr Ar data
-Write framer register.
-Write
-.Ar data
-into register
-.Ar addr .
-.It Fl g Ar number
-Set receiver gain range to
-.Ar number :
-.Pp
-.Bl -column "0x00" "Medium" "auto-set based on cable length (default)" -offset 1m -compact
-.It "0x24" Ta "Short" Ta "0 to 20 dB of equalized gain"
-.It "0x2C" Ta "Medium" Ta "0 to 30 dB of equalized gain"
-.It "0x34" Ta "Long" Ta "0 to 40 dB of equalized gain"
-.It "0x3F" Ta "Extend" Ta "0 to 64 dB of equalized gain (wide open)"
-.It "0xFF" Ta "Auto" Ta "auto-set based on cable length (default)"
-.El
-.Pp
-This sets the level at which
-.Em Loss-Of-Signal
-is declared.
-.It Fl i
-Send a
-.Em CSU loopback deactivate
-inband command (T1-SF only).
-.It Fl I
-Send a
-.Em CSU loopback activate
-inband command (T1-SF only).
-.It Fl l
-Send a
-.Em line loopback deactivate
-BOP message (T1-ESF only).
-.It Fl L
-Send a
-.Em line loopback activate
-BOP message (T1-ESF only).
-.It Fl p
-Send a
-.Em payload loopback deactivate
-BOP message (T1-ESF only).
-.It Fl P
-Send a
-.Em payload loopback activate
-BOP message (T1-ESF only).
-.It Fl s
-Print the status of the on-board DSU/CSU \[em] see the
-.Sx EXAMPLES
-section.
-.It Fl t
-Stop sending test pattern.
-.It Fl T Ar number
-Start sending test pattern
-.Ar number :
-.Pp
-.Bl -column "99" -offset 1m -compact
-.It 0 Ta unframed X^11+X^9+1
-.It 1 Ta unframed X^15+X^14+1
-.It 2 Ta unframed X^20+X^17+1
-.It 3 Ta unframed X^23+X^18+1
-.It 4 Ta unframed X^11+X^9+1 with 7ZS
-.It 5 Ta unframed X^15+X^14+1 with 7ZS
-.It 6 Ta unframed X^20+X^17+1 with 14ZS (QRSS)
-.It 7 Ta unframed X^23+X^18+1 with 14ZS
-.It 8 Ta framed X^11+X^9+1
-.It 9 Ta framed X^15+X^14+1
-.It 10 Ta framed X^20+X^17+1
-.It 11 Ta framed X^23+X^18+1
-.It 12 Ta framed X^11+X^9+1 with 7ZS
-.It 13 Ta framed X^15+X^14+1 with 7ZS
-.It 14 Ta framed X^20+X^17+1 with 14ZS (QRSS)
-.It 15 Ta framed X^23+X^18+1 with 14ZS
-.El
-.It Fl u Ar number
-Set transmit pulse shape to
-.Ar number :
-.Pp
-.Bl -column "99" -offset 1m -compact
-.It 0 Ta T1 DSX 0 to 40 meters
-.It 2 Ta T1 DSX 40 to 80 meters
-.It 4 Ta T1 DSX 80 to 120 meters
-.It 6 Ta T1 DSX 120 to 160 meters
-.It 8 Ta T1 DSX 160 to 200 meters
-.It 10 Ta E1 75-ohm coax pair
-.It 12 Ta E1 120-ohm twisted pairs
-.It 14 Ta T1 CSU 200 to 2000 meters; set LBO
-.It 255 Ta auto-set based on cable length and framing format (default)
-.El
-.It Fl U Ar number
-Set transmit line build-out to
-.Ar number :
-.Pp
-.Bl -column "255" "22.5 dB" "FCC option A" -offset 1m -compact
-.It " 0" Ta "0 dB" Ta "FCC option A"
-.It " 16" Ta "7.5 dB" Ta "FCC option B"
-.It " 32" Ta "15 dB" Ta "FCC option C"
-.It " 48" Ta "22.5 dB" Ta "final span"
-.It "255" Ta "auto-set based on cable length (default)" Ta \&
-.El
-.Pp
-This is only applicable if the pulse shape is T1-CSU.
-.It Fl v
-Set verbose mode: print more stuff.
-.It Fl x
-Disable transmitter outputs.
-.It Fl X
-Enable transmitter outputs.
-.El
-.Ss Commands for T3 cards
-The following parameters apply to the T3 card type:
-.Bl -tag -width indent
-.It Fl a Sm Cm y | a | b | i Sm
-Stop sending alarm signal.
-.Pp
-.Bl -column "y" "Yellow Alarm" "framed 1010... aka AIS" -offset 1m -compact
-.It "y" Ta "Yellow Alarm" Ta "X-bits set to 0"
-.It "a" Ta "Red Alarm" Ta "framed 1010... aka AIS"
-.It "b" Ta "Blue Alarm" Ta "unframed all-ones"
-.It "i" Ta "Idle signal" Ta "framed 11001100..."
-.El
-.It Fl A Sm Cm y | a | b | i Sm
-Start sending alarm signal (see table above).
-.It Fl B Ar number
-Send a BOP (Bit Oriented Protocol) message with code
-.Ar number .
-BOP codes are six bits.
-.It Fl c Ar number
-Set cable length to
-.Ar number
-meters (default: 10 meters).
-This is used to set receiver sensitivity
-and transmitter line build-out.
-.It Fl d
-Print the status of the on-board T3 DSU \[em] see the
-.Sx EXAMPLES
-section.
-.It Fl e Ar number
-Set the framing format to
-.Ar number :
-.Pp
-.Bl -column "100" -offset 1m -compact
-.It 100 Ta T3-C-bit parity
-.It 101 Ta T3-M13 format
-.El
-.It Fl f
-Read framer registers.
-Print the 22 8-bit registers in the framer chip.
-.It Fl F Ar addr Ar data
-Write framer register.
-Write
-.Ar data
-into register
-.Ar addr .
-.It Fl l
-Send a
-.Em line loopback deactivate
-BOP message.
-.It Fl L
-Send a
-.Em line loopback activate
-BOP message.
-.It Fl s
-Print the status of the on-board T3 DSU \[em] see the
-.Sx EXAMPLES
-section.
-.It Fl S Ar number
-Set payload scrambler polynomial to
-.Ar number :
-.Pp
-.Bl -column "9" -offset 1m -compact
-.It 1 Ta payload scrambler disabled
-.It 2 Ta X^43+1: DigitalLink and Kentrox
-.It 3 Ta X^20+X^17+1 w/28ZS: Larscom
-.El
-Payload scrambler polynomials are not standardized.
-.It Fl v
-Set verbose mode: print more stuff.
-.It Fl V Ar number
-Set transmit frequency offset to
-.Ar number .
-Some T3 cards can offset the transmitter frequency from 44.736 MHz.
-.Ar Number
-is in the range (0..4095); 2048 is zero offset; step size is about 3 Hz.
-A
-.Ar number
-is written to a Digital-Analog Converter (DAC) which connects
-to a Voltage Controlled Crystal Oscillator (VCXO).
-.El
-.Ss Event Counters
-The device driver counts many interesting events such as
-packets in and out, errors and discards.
-The table below lists the event counters and describes what they count.
-.Bl -tag -width ".Va underruns"
-.It Va ibytes
-Bytes received in packets with good ending status.
-.It Va obytes
-Bytes transmitted.
-.It Va ipackets
-Packets received with good ending status.
-.It Va opackets
-Packets transmitted.
-.It Va ierrors
-Packets received with bad ending status.
-.It Va oerrors
-Packets transmitted with bad ending status.
-.It Va idiscards
-Packets received but discarded because
-the input queue was full or the interface was down.
-.It Va odiscards
-Packets presented for transmission but discarded because
-the output queue was full or the interface was down.
-.It Va txdma
-Packets presented for transmission but queued and retried later
-because no DMA descriptors were available.
-This can happen during normal operation and is not an indication of trouble.
-.It Va fifo-overrun
-Packets that started to arrive, but were aborted because
-the card was unable to DMA data to memory fast enough
-to prevent the receiver fifo from overflowing.
-.It Va fifo-underrun
-Packets that started to transmit but were aborted because
-the card was unable to DMA data from the memory fast enough
-to prevent the transmitter fifo from underflowing.
-When this happens, the transmitter threshold is increased,
-so that more bytes are required to be in the fifo
-before the transmitter is started.
-.It Va missed
-Packets that are missed because the receiver is stopped.
-.It Va overruns
-Packets that are missed because the receiver
-had no DMA descriptors available.
-.It Va fdl_pkts
-Packets received on the T1 Facility Data Link.
-.It Va crc-errs
-Cyclic Redundancy Checksum errors detected by the CRC-6 in
-T1 Extended SuperFrames (ESF) or the CRC-4 in E1 frames.
-.It Va lcv-errs
-Line Coding Violation errors:
-Alternate Mark Inversion (AMI) errors for T1-SF,
-Bipolar 8-Zero Substitution (B8ZS) errors for T1-ESF, or
-High Density Bipolar with 3-Zero Substitution (HDB3) errors for E1 or
-Bipolar 3-Zero Substitution (B3ZS) errors for T3.
-.It Va frm-errs
-T1 or T3 bit errors in the frame alignment signal.
-.It Va febe-errs
-Far End Block Errors:
-T1 or T3 bit errors detected by the device at the far end of the link.
-.It Va par-errs
-T3 bit errors detected by the hop-by-hop parity mechanism.
-.It Va cpar-errs
-T3 bit errors detected by the end-to-end parity mechanism.
-.It Va mfrm-errs
-T3 bit errors in the multi-frame alignment signal.
-.El
-.Ss Transmit Speed
-The hardware counts transmit clocks divided by 2048.
-The software computes
-.Dq "Tx speed"
-from this (see
-.Sx EXAMPLES
-below).
-The transmit clock is the bit rate of the circuit divided by two if the
-circuit is idle and divided by four if the circuit is carrying a packet.
-So an idle circuit reports a Tx speed equal to its bit rate,
-and a busy circuit reports a Tx speed equal to half its bit rate.
-.Pp
-This
-.Dq "bit rate"
-does not include circuit-level overhead bits
-(such as T1 or T3 frame bits) but does include HDLC stuff bits.
-An idle T1 circuit with a raw bit rate of 1544000 and a
-bit-rate-minus-overhead of 1536000 will report a
-.Dq "Tx speed"
-of ((1536000 bitand 4095) plus or minus 4096).
-Sometimes it will even get the correct answer of 1536000, and
-if the link is fully loaded it will report about 768000 bits/sec.
-.Pp
-It is not a perfect bit rate meter (the circuit must be idle),
-but it is a useful circuit utilization meter if you know the
-circuit bit rate and do some arithmetic.
-Software recalculates
-Tx speed once a second; the measurement period has some jitter.
-.Sh EXAMPLES
-When
-.Dq Li lmc0
-is a T1E1 card,
-.Dq Li lmcconfig lmc0
-generates the following output:
-.Bd -literal -offset 2m
-Card name: lmc0
-Card type: SBE/LMC T1E1 card
-Link status: Up
-Tx Speed: 1548288
-Line Prot/Pkg: Frame-Relay/SPPP
-SPPP Keep-alives: OFF
-CRC length: 16 bits
-Loopback: None
-Tx Clk src: Internal source
-Format-Frame/Code: T1-ESF/B8ZS
-TimeSlot [31-0]: 0x01FFFFFE
-Cable length: 10 meters
-Tx pulse shape: auto-set to T1-DSX: 0 to 40 meters
-Rx gain max: auto-set to 20.0 dB
-Current time: Thu Sep 29 21:48:51 2005
-Cntrs reset: Thu Sep 29 16:21:05 2005
-RX bytes: 15053836
-RX packets: 23271
-TX bytes: 1732169
-TX packets: 20526
-Rx fdl pkts: 5443
-.Ed
-.Pp
-When
-.Dq Li lmc0
-is a T1E1 card,
-.Dq Li "lmcconfig lmc0 -1 -d"
-generates the following output:
-.Bd -literal -offset 2m
-Format-Frame/Code: T1-ESF/B8ZS
-TimeSlot [31-0]: 0x01FFFFFE
-Tx Clk src: Internal source
-Tx Speed: 1548288
-Tx pulse shape: T1-DSX: 0 to 40 meters
-Tx outputs: Enabled
-Line impedance: 100 ohms
-Max line loss: 20.0 dB
-Cur line loss: 3.1 dB
-Invert data: No
-Line loop: No
-Payload loop: No
-Framer loop: No
-Analog loop: No
-Tx AIS: No
-Rx AIS: No
-Tx BOP RAI: No
-Rx BOP RAI: No
-Rx LOS analog: No
-Rx LOS digital: No
-Rx LOF: No
-Tx QRS: No
-Rx QRS: No
-LCV errors: 0
-CRC errors: 0
-Frame errors: 0
-Sev Err Frms: 0
-Change of Frm align: 0
-Loss of Frame events: 0
-Last Tx BOP msg: 0x00 (Yellow Alarm (far end LOF))
-Last Rx BOP msg: 0x00 (Yellow Alarm (far end LOF))
-SNMP Near-end performance data:
- LCV=0 LOS=0 FE=0 CRC=0 AIS=0 SEF=0 OOF=0 RAI=0
-ANSI Far-end performance reports:
- SEQ=1 CRC=0 SE=0 FE=0 LV=0 SL=0 LB=0
- SEQ=0 CRC=0 SE=0 FE=0 LV=0 SL=0 LB=0
- SEQ=3 CRC=0 SE=0 FE=0 LV=0 SL=0 LB=0
- SEQ=2 CRC=0 SE=0 FE=0 LV=0 SL=0 LB=0
-.Ed
-.Sh DIAGNOSTICS
-Messages indicating the specified interface does not exist, or
-the user is not privileged and tried to alter an interface's configuration.
-.Sh SEE ALSO
-.Xr ioctl 2 ,
-.Xr lmc 4 ,
-.Xr netgraph 4 ,
-.Xr ifconfig 8 ,
-.Xr ifnet 9
-.Pp
-.Pa http://www.sbei.com/
-.Sh HISTORY
-This is a total rewrite of the program
-.Nm lmcctl
-by
-.An Andrew Stanley-Jones .
-.Sh AUTHORS
-.An David Boggs Aq Mt boggs@boggs.palo-alto.ca.us
diff --git a/usr.sbin/lmcconfig/lmcconfig.c b/usr.sbin/lmcconfig/lmcconfig.c
deleted file mode 100644
index 65356a2184b7d..0000000000000
--- a/usr.sbin/lmcconfig/lmcconfig.c
+++ /dev/null
@@ -1,2553 +0,0 @@
-/*
- * First author: Michael Graff.
- * Copyright (c) 1997-2000 Lan Media Corp. (www.lanmedia.com).
- * All rights reserved.
- *
- * Second author: Andrew Stanley-Jones.
- * Copyright (c) 2000-2002 SBE Corp. (www.sbei.com).
- * All rights reserved.
- *
- * Third author: David Boggs.
- * Copyright (c) 2002-2004 David Boggs. (boggs@boggs.palo-alto.ca.us).
- * All rights reserved.
- *
- * BSD License:
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * GNU General Public License:
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Description:
- *
- * This program configures the Unix/Linux device driver for SBE Corp's
- * wanADAPT and wanPMC series of Wide Area Network Interface Cards.
- * There is a man page for this program; go find it.
- *
- * If Netgraph is present (FreeBSD only):
- * cc -o lmcconfig -l netgraph -D NETGRAPH lmcconfig.c
- * If Netgraph is NOT present:
- * cc -o lmcconfig lmcconfig.c
- * Install the executable program in /usr/local/sbin/lmcconfig.
- *
- * $FreeBSD$
- */
-
-#include <sys/param.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-
-#include <errno.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <time.h>
-#include <unistd.h>
-#if defined(NETGRAPH)
-# include <netgraph.h>
-#endif
-#include <net/if.h>
-
-#include <dev/lmc/if_lmc.h>
-
-/* program global variables */
-char * progname; /* name of this program */
-char * ifname; /* interface name */
-int fdcs; /* ifnet File Desc or ng Ctl Socket */
-struct status status; /* card status (read only) */
-struct config config; /* card configuration (read/write) */
-int netgraph = 0; /* non-zero if netgraph present */
-int summary = 0; /* print summary at end */
-int update = 0; /* update driver config */
-int verbose = 0; /* verbose output */
-u_int8_t checksum; /* gate array ucode file checksum */
-
-/* Functions currently unused. Keep compiler happy and provide prototypes. */
-void ioctl_snmp_loop(u_int32_t);
-void init_srom(int);
-
-static void
-usage(void)
-{
- fprintf(stderr, "Usage: %s interface [-abBcCdDeEfhiLmMpPsStTuUvVwWxXyYzZ?]\n", progname);
- fprintf(stderr, "or\n");
- fprintf(stderr, "Usage: %s interface -1 [-aABcdeEfFgiIlLpPstTuUvxX]\n", progname);
- fprintf(stderr, "or\n");
- fprintf(stderr, "Usage: %s interface -3 [-aABcdefFlLsSvV]\n\n", progname);
- fprintf(stderr, "\tInterface is the interface name, e.g. '%s'\n", ifname);
-#if defined(NETGRAPH)
- fprintf(stderr, "\tIf interface name ends with ':' then use netgraph\n");
-#endif
- fprintf(stderr, "\t-1 following parameters apply to T1E1 cards\n");
- fprintf(stderr, "\t-3 following parameters apply to T3 cards\n");
- fprintf(stderr, "\t-a <number> Set Tx clock source, where:\n");
- fprintf(stderr, "\t 1:modem Tx clk 2:int src 3:modem Rx Clk 4:ext conn\n");
- fprintf(stderr, "\t-b Read and print bios rom addrs 0-255\n");
- fprintf(stderr, "\t-B Write bios rom with address pattern\n");
- fprintf(stderr, "\t-c Set 16-bit CRC (default)\n");
- fprintf(stderr, "\t-C Set 32-bit CRC\n");
- fprintf(stderr, "\t-d Clear driver DEBUG flag\n");
- fprintf(stderr, "\t-D Set driver DEBUG flag (more log msgs)\n");
- fprintf(stderr, "\t-e Set DTE mode (default)\n");
- fprintf(stderr, "\t-E Set DCE mode\n");
- fprintf(stderr, "\t-f <number> Set synth osc freq in bits/sec\n");
- fprintf(stderr, "\t-F Set SPPP line protocol to Frame-Relay\n");
- fprintf(stderr, "\t-h Help: this usage message\n");
- fprintf(stderr, "\t-i Interface name (eg, lmc0)\n");
- fprintf(stderr, "\t-L <number> Set loopback: 1:none 2:payload 3:line 4:other\n");
- fprintf(stderr, "\t 5:inward 6:dual 16:Tulip 17:pins 18:LA/LL 19:LB/RL\n");
- fprintf(stderr, "\t-m Read and print MII regs\n");
- fprintf(stderr, "\t-M <addr> <data> Write MII reg\n");
- fprintf(stderr, "\t-p Read and print PCI config regs\n");
- fprintf(stderr, "\t-P <addr> <data> Write PCI config reg\n");
- fprintf(stderr, "\t-s Read and print Tulip SROM\n");
- fprintf(stderr, "\t-S <number> Initialize Tulip SROM\n");
- fprintf(stderr, "\t-t Read and print Tulip Control/Status regs\n");
- fprintf(stderr, "\t-T <addr> <data> Write Tulip Control/status reg\n");
- fprintf(stderr, "\t-u Reset event counters\n");
- fprintf(stderr, "\t-U Reset gate array\n");
- fprintf(stderr, "\t-v Set verbose printout mode\n");
- fprintf(stderr, "\t-V Print card configuration\n");
- fprintf(stderr, "\t-w Load gate array from ROM\n");
- fprintf(stderr, "\t-W <filename> Load gate array from file\n");
- fprintf(stderr, "\t-x select RAWIP mode and bypass line protocols\n");
- fprintf(stderr, "\t-X Select line protocols: SPPP, P2P or HDLC\n");
- fprintf(stderr, "\t-y disable SPPP keep-alive packets\n");
- fprintf(stderr, "\t-Y enable SPPP keep-alive packets\n");
- fprintf(stderr, "\t-z Set SPPP line protocol to Cisco-HDLC\n");
- fprintf(stderr, "\t-Z Set SPPP line protocol to PPP\n");
-
- fprintf(stderr, "The -1 switch precedes T1/E1 commands.\n");
- fprintf(stderr, "\t-a <y|b|a> Stop sending Yellow|Blue|AIS signal\n");
- fprintf(stderr, "\t-A <y|b|a> Start sending Yellow|Blue|AIS signal\n");
- fprintf(stderr, "\t-B <number> Send BOP msg 25 times\n");
- fprintf(stderr, "\t-c <number> Set cable length in meters\n");
- fprintf(stderr, "\t-d Print status of T1 DSU/CSU\n");
- fprintf(stderr, "\t-e <number> Set framing format, where:\n");
- fprintf(stderr, "\t 27:T1-ESF 9:T1-SF 0:E1-FAS 8:E1-FAS+CRC\n");
- fprintf(stderr, "\t 16:E1-FAS+CAS 24:E1-FAS+CRC+CAS 32:E1-NO-FRAMING\n");
- fprintf(stderr, "\t-E <32-bit hex number> 1 activates a channel and 0 deactivates it.\n");
- fprintf(stderr, "\t Use this to config a link in fractional T1/E1 mode\n");
- fprintf(stderr, "\t-f Read and print Framer/LIU registers\n");
- fprintf(stderr, "\t-F <addr> <data> Write Framer/LIU register\n");
- fprintf(stderr, "\t-g <number> Set receiver gain, where:\n");
- fprintf(stderr, "\t 0:short range 1:medium range\n");
- fprintf(stderr, "\t 2:long range 3:extended range\n");
- fprintf(stderr, "\t 4:auto-set based on cable length\n");
- fprintf(stderr, "\t-i Send 'CSU Loop Down' inband msg\n");
- fprintf(stderr, "\t-I Send 'CSU Loop Up' inband msg\n");
- fprintf(stderr, "\t-l Send 'Line Loop Down' BOP msg\n");
- fprintf(stderr, "\t-L Send 'Line Loop Up' BOP msg\n");
- fprintf(stderr, "\t-p Send 'Payload Loop Down' BOP msg\n");
- fprintf(stderr, "\t-P Send 'Payload Loop Up' BOP msg\n");
- fprintf(stderr, "\t-s Print status of T1 DSU/CSU\n");
- fprintf(stderr, "\t-t Stop sending test pattern\n");
- fprintf(stderr, "\t-T <number> Start sending test pattern, where:\n");
- fprintf(stderr, "\t 0:unframed 2^11 1:unframed 2^15\n");
- fprintf(stderr, "\t 2:unframed 2^20 3:unframed 2^23\n");
- fprintf(stderr, "\t 4:unframed 2^11 w/ZS 5:unframed 2^15 w/ZS\n");
- fprintf(stderr, "\t 6:unframed QRSS 7:unframed 2^23 w/ZS\n");
- fprintf(stderr, "\t 8: framed 2^11 9: framed 2^15\n");
- fprintf(stderr, "\t 10: framed 2^20 11: framed 2^23\n");
- fprintf(stderr, "\t 12: framed 2^11 w/ZS 13: framed 2^15 w/ZS\n");
- fprintf(stderr, "\t 14: framed QRSS 15: framed 2^23 w/ZS\n");
- fprintf(stderr, "\t-u <number> Set transmitter pulse shape, where:\n");
- fprintf(stderr, "\t 0:T1-DSX 0-40m 1:T1-DSX 40-80m\n");
- fprintf(stderr, "\t 2:T1-DSX 80-120m 3:T1-DSX 120-160m\n");
- fprintf(stderr, "\t 4:T1-DSX 160-200m 5:E1-G.703 75ohm coax\n");
- fprintf(stderr, "\t 6:E1-G.703 120ohm TP 7:T1-CSU Long range\n");
- fprintf(stderr, "\t 8:auto-set based on cable length (T1 only)\n");
- fprintf(stderr, "\t-U <number> Set line build out where:\n");
- fprintf(stderr, "\t 0:0dB 1:7.5dB 2:15dB 3:22.5dB\n");
- fprintf(stderr, "\t 4:auto-set based on cable length\n");
- fprintf(stderr, "\t-v Set verbose printout mode\n");
- fprintf(stderr, "\t-x disable Transmitter outputs\n");
- fprintf(stderr, "\t-X enable Transmitter outputs\n");
-
- fprintf(stderr, "The -3 switch precedes T3 commands.\n");
- fprintf(stderr, "\t-a <y|b|a|i> Stop sending Yellow|Blue|AIS|Idle signal\n");
- fprintf(stderr, "\t-A <y|b|a|i> Start sending Yellow|Blue|AIS|Idle signal\n");
- fprintf(stderr, "\t-B <bopcode> Send BOP msg 10 times\n");
- fprintf(stderr, "\t-c <number> Set cable length in meters\n");
- fprintf(stderr, "\t-d Print status of T3 DSU/CSU\n");
- fprintf(stderr, "\t-e <number> Set T3 frame format, where:\n");
- fprintf(stderr, "\t 100:C-Bit Parity 101:M13\n");
- fprintf(stderr, "\t-f Read and print Framer registers\n");
- fprintf(stderr, "\t-F <addr> <data> Write Framer register\n");
- fprintf(stderr, "\t-l Send 'Line Loop Down' BOP msg\n");
- fprintf(stderr, "\t-L Send 'Line Loop Up' BOP msg\n");
- fprintf(stderr, "\t-s Print status of T3 DSU/CSU\n");
- fprintf(stderr, "\t-S <number> Set DS3 scrambler mode, where:\n");
- fprintf(stderr, "\t 1:OFF 2:DigitalLink|Kentrox 3:Larse\n");
- fprintf(stderr, "\t-v Set verbose printout mode\n");
- fprintf(stderr, "\t-V <number> Write to T3 VCXO freq control DAC\n");
-}
-
-static void
-call_driver(unsigned long cmd, struct iohdr *iohdr)
-{
- int error = 0;
-
- strlcpy(iohdr->ifname, ifname, sizeof(iohdr->ifname));
- iohdr->cookie = NGM_LMC_COOKIE;
- iohdr->iohdr = iohdr;
-
- /* Exchange data with a running device driver. */
-#if defined(NETGRAPH)
- if (netgraph)
- {
- NgSendMsg(fdcs, ifname, NGM_LMC_COOKIE, cmd, iohdr, IOCPARM_LEN(cmd));
- if (cmd & IOC_OUT)
- {
- int replen = sizeof(struct ng_mesg) + IOCPARM_LEN(cmd);
- char rep[replen]; /* storage for the reply */
- struct ng_mesg *reply = (struct ng_mesg *)rep;
- int rl = NgRecvMsg(fdcs, reply, replen, NULL);
- if (rl == replen)
- bcopy(&reply->data, iohdr, IOCPARM_LEN(cmd));
- else
- {
- fprintf(stderr, "%s: NgRecvMsg returned %d bytes, expected %d\n",
- progname, rl, replen);
- exit(1);
- }
- }
- }
- else
-#endif
- {
- if ((error = ioctl(fdcs, cmd, (caddr_t)iohdr)) < 0)
- {
- fprintf(stderr, "%s: ioctl() returned error code %d: %s\n",
- progname, errno, strerror(errno));
- if (errno == ENETDOWN)
- printf("Type: 'ifconfig %s up' then try again.\n", ifname);
- exit(1);
- }
- }
-
- if (iohdr->cookie != NGM_LMC_COOKIE)
- {
- fprintf(stderr, "%s: cookie = 0x%08X, expected 0x%08X\n", progname, iohdr->cookie, NGM_LMC_COOKIE);
- fprintf(stderr, "%s: This version of %s is incompatible with the device driver\n", progname, progname);
- exit(1);
- }
-}
-
-static u_int32_t
-read_pci_config(u_int8_t addr)
-{
- struct ioctl ioctl;
-
- ioctl.iohdr.direction = DIR_IOWR;
- ioctl.iohdr.length = sizeof(struct ioctl);
- ioctl.cmd = IOCTL_RW_PCI;
- ioctl.address = addr;
-
- call_driver(LMCIOCREAD, &ioctl.iohdr);
-
- return ioctl.data;
-}
-
-static void
-write_pci_config(u_int8_t addr, u_int32_t data)
-{
- struct ioctl ioctl;
-
- ioctl.iohdr.direction = DIR_IOW;
- ioctl.iohdr.length = sizeof(struct ioctl);
- ioctl.cmd = IOCTL_RW_PCI;
- ioctl.address = addr;
- ioctl.data = data;
-
- call_driver(LMCIOCWRITE, &ioctl.iohdr);
-}
-
-static u_int32_t
-read_csr(u_int8_t addr)
-{
- struct ioctl ioctl;
-
- ioctl.iohdr.direction = DIR_IOWR;
- ioctl.iohdr.length = sizeof(struct ioctl);
- ioctl.cmd = IOCTL_RW_CSR;
- ioctl.address = addr;
-
- call_driver(LMCIOCREAD, &ioctl.iohdr);
-
- return ioctl.data;
-}
-
-static void
-write_csr(u_int8_t addr, u_int32_t data)
-{
- struct ioctl ioctl;
-
- ioctl.iohdr.direction = DIR_IOW;
- ioctl.iohdr.length = sizeof(struct ioctl);
- ioctl.cmd = IOCTL_RW_CSR;
- ioctl.address = addr;
- ioctl.data = data;
-
- call_driver(LMCIOCWRITE, &ioctl.iohdr);
-}
-
-static u_int16_t
-read_srom(u_int8_t addr)
-{
- struct ioctl ioctl;
-
- ioctl.iohdr.direction = DIR_IOWR;
- ioctl.iohdr.length = sizeof(struct ioctl);
- ioctl.cmd = IOCTL_RW_SROM;
- ioctl.address = addr;
-
- call_driver(LMCIOCREAD, &ioctl.iohdr);
-
- return ioctl.data;
-}
-
-static void
-write_srom(u_int8_t addr, u_int16_t data)
-{
- struct ioctl ioctl;
-
- ioctl.iohdr.direction = DIR_IOW;
- ioctl.iohdr.length = sizeof(struct ioctl);
- ioctl.cmd = IOCTL_RW_SROM;
- ioctl.address = addr;
- ioctl.data = data;
-
- call_driver(LMCIOCWRITE, &ioctl.iohdr);
-}
-
-static u_int8_t
-read_bios_rom(u_int32_t addr)
-{
- struct ioctl ioctl;
-
- ioctl.iohdr.direction = DIR_IOWR;
- ioctl.iohdr.length = sizeof(struct ioctl);
- ioctl.cmd = IOCTL_RW_BIOS;
- ioctl.address = addr;
-
- call_driver(LMCIOCREAD, &ioctl.iohdr);
-
- return ioctl.data;
-}
-
-static void
-write_bios_rom(u_int32_t addr, u_int8_t data)
-{
- struct ioctl ioctl;
-
- ioctl.iohdr.direction = DIR_IOW;
- ioctl.iohdr.length = sizeof(struct ioctl);
- ioctl.cmd = IOCTL_RW_BIOS;
- ioctl.address = addr;
- ioctl.data = data;
-
- call_driver(LMCIOCWRITE, &ioctl.iohdr);
-}
-
-static u_int16_t
-read_mii(u_int8_t addr)
-{
- struct ioctl ioctl;
-
- ioctl.iohdr.direction = DIR_IOWR;
- ioctl.iohdr.length = sizeof(struct ioctl);
- ioctl.cmd = IOCTL_RW_MII;
- ioctl.address = addr;
-
- call_driver(LMCIOCREAD, &ioctl.iohdr);
-
- return ioctl.data;
-}
-
-static void
-write_mii(u_int8_t addr, u_int16_t data)
-{
- struct ioctl ioctl;
-
- ioctl.iohdr.direction = DIR_IOW;
- ioctl.iohdr.length = sizeof(struct ioctl);
- ioctl.cmd = IOCTL_RW_MII;
- ioctl.address = addr;
- ioctl.data = data;
-
- call_driver(LMCIOCWRITE, &ioctl.iohdr);
-}
-
-static unsigned char
-read_framer(u_int16_t addr)
-{
- struct ioctl ioctl;
-
- ioctl.iohdr.direction = DIR_IOWR;
- ioctl.iohdr.length = sizeof(struct ioctl);
- ioctl.cmd = IOCTL_RW_FRAME;
- ioctl.address = addr;
-
- call_driver(LMCIOCREAD, &ioctl.iohdr);
-
- return ioctl.data;
-}
-
-static void
-write_framer(u_int16_t addr, u_int8_t data)
-{
- struct ioctl ioctl;
-
- ioctl.iohdr.direction = DIR_IOW;
- ioctl.iohdr.length = sizeof(struct ioctl);
- ioctl.cmd = IOCTL_RW_FRAME;
- ioctl.address = addr;
- ioctl.data = data;
-
- call_driver(LMCIOCWRITE, &ioctl.iohdr);
-}
-
-static void
-write_synth(struct synth synth)
-{
- struct ioctl ioctl;
-
- ioctl.iohdr.direction = DIR_IOW;
- ioctl.iohdr.length = sizeof(struct ioctl);
- ioctl.cmd = IOCTL_WO_SYNTH;
- bcopy(&synth, &ioctl.data, sizeof(synth));
-
- call_driver(LMCIOCWRITE, &ioctl.iohdr);
-}
-
-static void
-write_dac(u_int16_t data)
-{
- struct ioctl ioctl;
-
- ioctl.iohdr.direction = DIR_IOW;
- ioctl.iohdr.length = sizeof(struct ioctl);
- ioctl.cmd = IOCTL_WO_DAC;
- ioctl.data = data;
-
- call_driver(LMCIOCWRITE, &ioctl.iohdr);
-}
-
-static void
-reset_xilinx(void)
-{
- struct ioctl ioctl;
-
- ioctl.iohdr.direction = DIR_IOWR;
- ioctl.iohdr.length = sizeof(struct ioctl);
- ioctl.cmd = IOCTL_XILINX_RESET;
-
- call_driver(LMCIOCTL, &ioctl.iohdr);
-}
-
-static void
-load_xilinx_from_rom(void)
-{
- struct ioctl ioctl;
-
- ioctl.iohdr.direction = DIR_IOWR;
- ioctl.iohdr.length = sizeof(struct ioctl);
- ioctl.cmd = IOCTL_XILINX_ROM;
-
- call_driver(LMCIOCTL, &ioctl.iohdr);
-}
-
-static void
-load_xilinx_from_file(char *ucode, u_int32_t len)
-{
- struct ioctl ioctl;
-
- ioctl.iohdr.direction = DIR_IOWR;
- ioctl.iohdr.length = sizeof(struct ioctl);
- ioctl.cmd = IOCTL_XILINX_FILE;
- ioctl.data = len;
- ioctl.ucode = ucode;
-
- call_driver(LMCIOCTL, &ioctl.iohdr);
-}
-
-static void
-ioctl_snmp_send(u_int32_t send)
-{
- struct ioctl ioctl;
-
- ioctl.iohdr.direction = DIR_IOWR;
- ioctl.iohdr.length = sizeof(struct ioctl);
- ioctl.cmd = IOCTL_SNMP_SEND;
- ioctl.data = send;
-
- call_driver(LMCIOCTL, &ioctl.iohdr);
-}
-
-void
-ioctl_snmp_loop(u_int32_t loop)
-{
- struct ioctl ioctl;
-
- ioctl.iohdr.direction = DIR_IOWR;
- ioctl.iohdr.length = sizeof(struct ioctl);
- ioctl.cmd = IOCTL_SNMP_LOOP;
- ioctl.data = loop;
-
- call_driver(LMCIOCTL, &ioctl.iohdr);
-}
-
-static void
-ioctl_reset_cntrs(void)
-{
- struct ioctl ioctl;
-
- ioctl.iohdr.direction = DIR_IOWR;
- ioctl.iohdr.length = sizeof(struct ioctl);
- ioctl.cmd = IOCTL_RESET_CNTRS;
-
- call_driver(LMCIOCTL, &ioctl.iohdr);
-}
-
-static void
-ioctl_read_config(void)
-{
- config.iohdr.direction = DIR_IOWR;
- config.iohdr.length = sizeof(struct config);
-
- call_driver(LMCIOCGCFG, &config.iohdr);
-}
-
-static void
-ioctl_write_config(void)
-{
- config.iohdr.direction = DIR_IOW;
- config.iohdr.length = sizeof(struct config);
-
- call_driver(LMCIOCSCFG, &config.iohdr);
-}
-
-static void
-ioctl_read_status(void)
-{
- status.iohdr.direction = DIR_IOWR;
- status.iohdr.length = sizeof(struct status);
-
- call_driver(LMCIOCGSTAT, &status.iohdr);
-}
-
-static void
-print_card_name(void)
-{
- printf("Card name:\t\t%s\n", ifname);
-}
-
-static void
-print_card_type(void)
-{
- printf("Card type:\t\t");
- switch(status.card_type)
- {
- case TLP_CSID_HSSI:
- printf("HSSI (lmc5200)\n");
- break;
- case TLP_CSID_T3:
- printf("T3 (lmc5245)\n");
- break;
- case TLP_CSID_SSI:
- printf("SSI (lmc1000)\n");
- break;
- case TLP_CSID_T1E1:
- printf("T1E1 (lmc1200)\n");
- break;
- case TLP_CSID_HSSIc:
- printf("HSSI (lmc5200C)\n");
- break;
- default:
- printf("unknown card_type: %d\n", status.card_type);
- break;
- }
-}
-
-static void
-print_status(void)
-{
- char *status_string;
-
- if (status.oper_status == STATUS_UP)
- status_string = "Up";
- else if (status.oper_status == STATUS_DOWN)
- status_string = "Down";
- else if (status.oper_status == STATUS_TEST)
- status_string = "Test";
- else
- status_string = "Unknown";
- printf("Link status:\t\t%s\n", status_string);
-}
-
-static void
-print_tx_speed(void)
-{
- printf("Tx Speed:\t\t%u\n", status.tx_speed);
-}
-
-static void
-print_debug(void)
-{
- if (config.debug != 0)
- printf("Debug:\t\t\t%s\n", "On");
-}
-
-static void
-print_line_prot(void)
-{
- char *on = "On", *off = "Off";
-
- printf("Line Prot/Pkg:\t\t");
- switch (status.line_prot)
- {
- case 0:
- printf("NotSet/");
- break;
- case PROT_PPP:
- printf("PPP/");
- break;
- case PROT_C_HDLC:
- printf("Cisco-HDLC/");
- break;
- case PROT_FRM_RLY:
- printf("Frame-Relay/");
- break;
- case PROT_IP_HDLC:
- printf("IP-in-HDLC/");
- break;
- case PROT_ETH_HDLC:
- printf("Ether-in-HDLC/");
- break;
- case PROT_X25:
- printf("X25+LAPB/");
- break;
- default:
- printf("unknown line_prot: %d/", status.line_prot);
- break;
- }
-
- switch (status.line_pkg)
- {
- case 0:
- printf("NotSet\n");
- break;
- case PKG_RAWIP:
- printf("Driver\n");
- break;
- case PKG_NG:
- printf("Netgraph\n");
- break;
- case PKG_GEN_HDLC:
- printf("GenHDLC\n");
- break;
- case PKG_SPPP:
- printf("SPPP\n");
- break;
- case PKG_P2P:
- printf("P2P\n");
- break;
- default:
- printf("unknown line_pkg: %d\n", status.line_pkg);
- break;
- }
-
- if (status.line_pkg == PKG_SPPP)
- printf("SPPP Keep-alives:\t%s\n",
- config.keep_alive ? on : off);
-}
-
-static void
-print_crc_len(void)
-{
- printf("CRC length:\t\t");
- if (config.crc_len == CFG_CRC_0)
- printf("no CRC\n");
- else if (config.crc_len == CFG_CRC_16)
- printf("16 bits\n");
- else if (config.crc_len == CFG_CRC_32)
- printf("32 bits\n");
- else
- printf("bad crc_len: %d\n", config.crc_len);
-}
-
-static void
-print_loop_back(void)
-{
- printf("Loopback:\t\t");
- switch (config.loop_back)
- {
- case CFG_LOOP_NONE:
- printf("None\n");
- break;
- case CFG_LOOP_PAYLOAD:
- printf("Outward thru framer (payload loop)\n");
- break;
- case CFG_LOOP_LINE:
- printf("Outward thru line interface (line loop)\n");
- break;
- case CFG_LOOP_OTHER:
- printf("Inward thru line interface\n");
- break;
- case CFG_LOOP_INWARD:
- printf("Inward thru framer\n");
- break;
- case CFG_LOOP_DUAL:
- printf("Inward & outward (dual loop)\n");
- break;
- case CFG_LOOP_TULIP:
- printf("Inward thru Tulip chip\n");
- break;
- case CFG_LOOP_PINS:
- printf("Inward thru drvrs/rcvrs\n");
- break;
- case CFG_LOOP_LL:
- printf("LA/LL asserted\n");
- break;
- case CFG_LOOP_RL:
- printf("LB/RL asserted\n");
- break;
- default:
- printf("unknown loop_back: %d\n", config.loop_back);
- break;
- }
-}
-
-static void
-print_tx_clk_src(void)
-{
- printf("Tx Clk src:\t\t");
- switch (config.tx_clk_src)
- {
- case CFG_CLKMUX_ST:
- printf("Tx Clk from modem\n");
- break;
- case CFG_CLKMUX_INT:
- printf("Internal source\n");
- break;
- case CFG_CLKMUX_RT:
- printf("Rx Clk from modem (loop timed)\n");
- break;
- case CFG_CLKMUX_EXT:
- printf("External connector\n");
- break;
- default:
- printf("unknown tx_clk_src: %d\n", config.tx_clk_src);
- break;
- }
-}
-
-static void
-print_format(void)
-{
- printf("Format-Frame/Code:\t");
- switch (config.format)
- {
- case CFG_FORMAT_T1SF:
- printf("T1-SF/AMI\n");
- break;
- case CFG_FORMAT_T1ESF:
- printf("T1-ESF/B8ZS\n");
- break;
- case CFG_FORMAT_E1FAS:
- printf("E1-FAS/HDB3\n");
- break;
- case CFG_FORMAT_E1FASCRC:
- printf("E1-FAS+CRC/HDB3\n");
- break;
- case CFG_FORMAT_E1FASCAS:
- printf("E1-FAS+CAS/HDB3\n");
- break;
- case CFG_FORMAT_E1FASCRCCAS:
- printf("E1-FAS+CRC+CAS/HDB3\n");
- break;
- case CFG_FORMAT_E1NONE:
- printf("E1-NOFRAMING/HDB3\n");
- break;
- case CFG_FORMAT_T3CPAR:
- printf("T3-CParity/B3ZS\n");
- break;
- case CFG_FORMAT_T3M13:
- printf("T3-M13/B3ZS\n");
- break;
- default:
- printf("unknown format: %d\n", config.format);
- break;
- }
-}
-
-static void
-print_dte_dce(void)
-{
- printf("DTE or DCE:\t\t");
- switch(config.dte_dce)
- {
- case CFG_DTE:
- printf("DTE (receiving TxClk)\n");
- break;
- case CFG_DCE:
- printf("DCE (driving TxClk)\n");
- break;
- default:
- printf("unknown dte_dce: %d\n", config.dte_dce);
- break;
- }
-}
-
-static void
-print_synth_freq(void)
-{
- double Fref = 20e6;
- double Fout, Fvco;
-
- /* decode the synthesizer params */
- Fvco = (Fref * (config.synth.n<<(3*config.synth.v)))/config.synth.m;
- Fout = Fvco / (1<<(config.synth.x+config.synth.r+config.synth.prescale));
-
- printf("Synth freq:\t\t%.0f\n", Fout);
-}
-
-static void
-synth_freq(unsigned long target)
-{
- unsigned int n, m, v, x, r;
- double Fout, Fvco, Ftarg;
- double newdiff, olddiff;
- double bestF=0.0, bestV=0.0;
- unsigned prescale = (target < 50000) ? 9:4;
-
- Ftarg = target<<prescale;
- for (n=3; n<=127; n++)
- for (m=3; m<=127; m++)
- for (v=0; v<=1; v++)
- for (x=0; x<=3; x++)
- for (r=0; r<=3; r++)
- {
- Fvco = (SYNTH_FREF * (n<<(3*v)))/m;
- if (Fvco < SYNTH_FMIN || Fvco > SYNTH_FMAX) continue;
- Fout = Fvco / (1<<(x+r));
- if (Fout >= Ftarg)
- newdiff = Fout - Ftarg;
- else
- newdiff = Ftarg - Fout;
- if (bestF >= Ftarg)
- olddiff = bestF - Ftarg;
- else
- olddiff = Ftarg - bestF;
- if ((newdiff < olddiff) ||
- ((newdiff == olddiff) && (Fvco < bestV)))
- {
- config.synth.n = n;
- config.synth.m = m;
- config.synth.v = v;
- config.synth.x = x;
- config.synth.r = r;
- config.synth.prescale = prescale;
- bestF = Fout;
- bestV = Fvco;
- }
- }
-#if 0
- printf("Fbest=%.0f, Ftarg=%u, Fout=%.0f\n", bestF>>prescale, target, bestF);
- printf("N=%u, M=%u, V=%u, X=%u, R=%u\n", config.synth.n,
- config.synth.m, config.synth.v, config.synth.x, config.synth.r);
-#endif
-}
-
-static void
-print_cable_len(void)
-{
- printf("Cable length:\t\t%d meters\n", config.cable_len);
-}
-
-static void
-print_cable_type(void)
-{
- printf("Cable type:\t\t");
- if (status.cable_type > 7)
- printf("unknown cable_type: %d\n", status.cable_type);
- else
- printf("%s\n", ssi_cables[status.cable_type]);
-}
-
-static void
-print_time_slots(void)
-{
- printf("TimeSlot [31-0]:\t0x%08X\n", config.time_slots);
-}
-
-static void
-print_scrambler(void)
-{
- printf("Scrambler:\t\t");
- if (config.scrambler == CFG_SCRAM_OFF)
- printf("off\n");
- else if (config.scrambler == CFG_SCRAM_DL_KEN)
- printf("DigLink/Kentrox: X^43+1\n");
- else if (config.scrambler == CFG_SCRAM_LARS)
- printf("Larse: X^20+X^17+1 w/28ZS\n");
- else
- printf("unknown scrambler: %d\n", config.scrambler);
-}
-
-static double
-vga_dbs(u_int8_t vga)
-{
- if (vga < 0x0F) return 0.0;
- if ((vga >= 0x0F) && (vga <= 0x1B)) return 0.0 + 0.77 * (vga - 0x0F);
- if ((vga >= 0x1C) && (vga <= 0x33)) return 10.0 + 1.25 * (vga - 0x1C);
- if ((vga >= 0x34) && (vga <= 0x39)) return 40.0 + 1.67 * (vga - 0x34);
- if ((vga >= 0x3A) && (vga < 0x3F)) return 50.0 + 2.80 * (vga - 0x3A);
- return 64.0;
-}
-
-static void
-print_rx_gain(void)
-{
- printf("Rx gain max:\t\t");
-
- if (config.rx_gain == CFG_GAIN_AUTO)
- printf("auto-set to %02.1f dB\n",
- vga_dbs(read_framer(Bt8370_VGA_MAX) & 0x3F));
- else
- printf("up to %02.1f dB\n", vga_dbs(config.rx_gain));
-}
-
-static void
-print_tx_lbo(void)
-{
- u_int8_t saved_lbo = config.tx_lbo;
-
- printf("LBO = ");
- if (config.tx_lbo == CFG_LBO_AUTO)
- {
- config.tx_lbo = read_framer(Bt8370_TLIU_CR) & 0x30;
- printf("auto-set to ");
- }
-
- switch (config.tx_lbo)
- {
- case CFG_LBO_0DB:
- printf("0 dB\n");
- break;
- case CFG_LBO_7DB:
- printf("7.5 dB\n");
- break;
- case CFG_LBO_15DB:
- printf("15 dB\n");
- break;
- case CFG_LBO_22DB:
- printf("22.5 dB\n");
- break;
- default:
- printf("unknown tx_lbo: %d\n", config.tx_lbo);
- break;
- }
-
- if (saved_lbo == CFG_LBO_AUTO)
- config.tx_lbo = saved_lbo;
-}
-
-static void
-print_tx_pulse(void)
-{
- u_int8_t saved_pulse = config.tx_pulse;
-
- printf("Tx pulse shape:\t\t");
- if (config.tx_pulse == CFG_PULSE_AUTO)
- {
- config.tx_pulse = read_framer(Bt8370_TLIU_CR) & 0x0E;
- printf("auto-set to ");
- }
-
- switch (config.tx_pulse)
- {
- case CFG_PULSE_T1DSX0:
- printf("T1-DSX: 0 to 40 meters\n");
- break;
- case CFG_PULSE_T1DSX1:
- printf("T1-DSX: 40 to 80 meters\n");
- break;
- case CFG_PULSE_T1DSX2:
- printf("T1-DSX: 80 to 120 meters\n");
- break;
- case CFG_PULSE_T1DSX3:
- printf("T1-DSX: 120 to 160 meters\n");
- break;
- case CFG_PULSE_T1DSX4:
- printf("T1-DSX: 160 to 200 meters\n");
- break;
- case CFG_PULSE_E1COAX:
- printf("E1: Twin Coax\n");
- break;
- case CFG_PULSE_E1TWIST:
- printf("E1: Twisted Pairs\n");
- break;
- case CFG_PULSE_T1CSU:
- printf("T1-CSU; ");
- print_tx_lbo();
- break;
- default:
- printf("unknown tx_pulse: %d\n", config.tx_pulse);
- break;
- }
-
- if (saved_pulse == CFG_PULSE_AUTO)
- config.tx_pulse = saved_pulse;
-}
-
-static void
-print_ssi_sigs(void)
-{
- u_int32_t mii16 = status.snmp.ssi.sigs;
- char *on = "On", *off = "Off";
-
- printf("Modem signals:\t\tDTR=%s DSR=%s RTS=%s CTS=%s\n",
- (mii16 & MII16_SSI_DTR) ? on : off,
- (mii16 & MII16_SSI_DSR) ? on : off,
- (mii16 & MII16_SSI_RTS) ? on : off,
- (mii16 & MII16_SSI_CTS) ? on : off);
- printf("Modem signals:\t\tDCD=%s RI=%s LL=%s RL=%s TM=%s\n",
- (mii16 & MII16_SSI_DCD) ? on : off,
- (mii16 & MII16_SSI_RI) ? on : off,
- (mii16 & MII16_SSI_LL) ? on : off,
- (mii16 & MII16_SSI_RL) ? on : off,
- (mii16 & MII16_SSI_TM) ? on : off);
-}
-
-static void
-print_hssi_sigs(void)
-{
- u_int32_t mii16 = status.snmp.hssi.sigs;
- char *on = "On", *off = "Off";
-
- printf("Modem signals:\t\tTA=%s CA=%s\n",
- (mii16 & MII16_HSSI_TA) ? on : off,
- (mii16 & MII16_HSSI_CA) ? on : off);
- printf("Modem signals:\t\tLA=%s LB=%s LC=%s TM=%s\n",
- (mii16 & MII16_HSSI_LA) ? on : off,
- (mii16 & MII16_HSSI_LB) ? on : off,
- (mii16 & MII16_HSSI_LC) ? on : off,
- (mii16 & MII16_HSSI_TM) ? on : off);
-}
-
-static void
-print_events(void)
-{
- const char *reset_time;
- time_t now;
-
- now = time(NULL);
- printf("Current time:\t\t%s", ctime(&now));
- if (status.cntrs.reset_time.tv_sec < 1000)
- reset_time = "Never\n";
- else
- reset_time = ctime(&status.cntrs.reset_time.tv_sec);
- printf("Cntrs reset:\t\t%s", reset_time);
-
- if (status.cntrs.ibytes) printf("Rx bytes:\t\t%ju\n", (uintmax_t)status.cntrs.ibytes);
- if (status.cntrs.obytes) printf("Tx bytes:\t\t%ju\n", (uintmax_t)status.cntrs.obytes);
- if (status.cntrs.ipackets) printf("Rx packets:\t\t%ju\n", (uintmax_t)status.cntrs.ipackets);
- if (status.cntrs.opackets) printf("Tx packets:\t\t%ju\n", (uintmax_t)status.cntrs.opackets);
- if (status.cntrs.ierrors) printf("Rx errors:\t\t%u\n", status.cntrs.ierrors);
- if (status.cntrs.oerrors) printf("Tx errors:\t\t%u\n", status.cntrs.oerrors);
- if (status.cntrs.idiscards) printf("Rx discards:\t\t%u\n", status.cntrs.idiscards);
- if (status.cntrs.odiscards) printf("Tx discards:\t\t%u\n", status.cntrs.odiscards);
- if (status.cntrs.fifo_over) printf("Rx fifo overruns:\t%u\n", status.cntrs.fifo_over);
- if (status.cntrs.fifo_under) printf("Tx fifo underruns:\t%u\n", status.cntrs.fifo_under);
- if (status.cntrs.missed) printf("Rx missed:\t\t%u\n", status.cntrs.missed);
- if (status.cntrs.overruns) printf("Rx overruns:\t\t%u\n", status.cntrs.overruns);
- if (status.cntrs.fdl_pkts) printf("Rx FDL pkts:\t\t%u\n", status.cntrs.fdl_pkts);
- if (status.cntrs.crc_errs) printf("Rx CRC:\t\t\t%u\n", status.cntrs.crc_errs);
- if (status.cntrs.lcv_errs) printf("Rx line code:\t\t%u\n", status.cntrs.lcv_errs);
- if (status.cntrs.frm_errs) printf("Rx F-bits:\t\t%u\n", status.cntrs.frm_errs);
- if (status.cntrs.febe_errs) printf("Rx FEBE:\t\t%u\n", status.cntrs.febe_errs);
- if (status.cntrs.par_errs) printf("Rx P-parity:\t\t%u\n", status.cntrs.par_errs);
- if (status.cntrs.cpar_errs) printf("Rx C-parity:\t\t%u\n", status.cntrs.cpar_errs);
- if (status.cntrs.mfrm_errs) printf("Rx M-bits:\t\t%u\n", status.cntrs.mfrm_errs);
- if (config.debug)
- { /* These events are hard to explain and may worry users, */
- if (status.cntrs.rxdma) printf("Rx no buffs:\t\t%u\n", status.cntrs.rxdma);
- if (status.cntrs.txdma) printf("Tx no descs:\t\t%u\n", status.cntrs.txdma);
- if (status.cntrs.lck_watch) printf("Lck watch:\t\t%u\n", status.cntrs.lck_watch);
- if (status.cntrs.lck_ioctl) printf("Lck ioctl:\t\t%u\n", status.cntrs.lck_ioctl);
- if (status.cntrs.lck_intr) printf("Lck intr:\t\t%u\n", status.cntrs.lck_intr);
- }
-}
-
-static void
-print_summary(void)
-{
- switch(status.card_type)
- {
- case TLP_CSID_HSSI:
- {
- print_card_name();
- print_card_type();
- print_debug();
- print_status();
- print_tx_speed();
- print_line_prot();
- print_crc_len();
- print_loop_back();
- print_tx_clk_src();
- print_hssi_sigs();
- print_events();
- break;
- }
- case TLP_CSID_T3:
- {
- print_card_name();
- print_card_type();
- print_debug();
- print_status();
- print_tx_speed();
- print_line_prot();
- print_crc_len();
- print_loop_back();
- print_format();
- print_cable_len();
- print_scrambler();
- print_events();
- break;
- }
- case TLP_CSID_SSI:
- {
- print_card_name();
- print_card_type();
- print_debug();
- print_status();
- print_tx_speed();
- print_line_prot();
- print_crc_len();
- print_loop_back();
- print_dte_dce();
- print_synth_freq();
- print_cable_type();
- print_ssi_sigs();
- print_events();
- break;
- }
- case TLP_CSID_T1E1:
- {
- print_card_name();
- print_card_type();
- print_debug();
- print_status();
- print_tx_speed();
- print_line_prot();
- print_crc_len();
- print_loop_back();
- print_tx_clk_src();
- print_format();
- print_time_slots();
- print_cable_len();
- print_tx_pulse();
- print_rx_gain();
- print_events();
- break;
- }
- case TLP_CSID_HSSIc:
- {
- print_card_name();
- print_card_type();
- print_debug();
- print_status();
- print_line_prot();
- print_tx_speed();
- print_crc_len();
- print_loop_back();
- print_tx_clk_src();
- print_dte_dce();
- print_synth_freq();
- print_hssi_sigs();
- print_events();
- break;
- }
- default:
- {
- printf("%s: Unknown card type: %d\n", ifname, status.card_type);
- break;
- }
- }
-}
-
-static char *
-print_t3_bop(int bop_code)
-{
- switch(bop_code)
- {
- case 0x00:
- return "far end LOF";
- case 0x0E:
- return "far end LOS";
- case 0x16:
- return "far end AIS";
- case 0x1A:
- return "far end IDL";
- case 0x07:
- return "Line Loopback activate";
- case 0x1C:
- return "Line Loopback deactivate";
- case 0x1B:
- return "Entire DS3 line";
- default:
- return "Unknown BOP code";
- }
-}
-
-static void
-print_t3_snmp(void)
-{
- printf("SNMP performance data:\n");
- printf(" LCV=%d", status.snmp.t3.lcv);
- printf(" LOS=%d", (status.snmp.t3.line & TLINE_LOS) ? 1 : 0);
- printf(" PCV=%d", status.snmp.t3.pcv);
- printf(" CCV=%d", status.snmp.t3.ccv);
- printf(" AIS=%d", (status.snmp.t3.line & TLINE_RX_AIS) ? 1 : 0);
- printf(" SEF=%d", (status.snmp.t3.line & T1LINE_SEF) ? 1 : 0);
- printf(" OOF=%d", (status.snmp.t3.line & TLINE_LOF) ? 1 : 0);
- printf(" FEBE=%d", status.snmp.t3.febe);
- printf(" RAI=%d", (status.snmp.t3.line & TLINE_RX_RAI) ? 1 : 0);
- printf("\n");
-}
-
-static void
-print_t3_dsu(void)
-{
- char *no = "No", *yes = "Yes";
- u_int16_t mii16 = read_mii(16);
- u_int8_t ctl1 = read_framer(T3CSR_CTL1);
- u_int8_t ctl8 = read_framer(T3CSR_CTL8);
- u_int8_t stat9 = read_framer(T3CSR_STAT9);
- u_int8_t ctl12 = read_framer(T3CSR_CTL12);
- u_int8_t stat16 = read_framer(T3CSR_STAT16);
-
- printf("Framing: \t\t%s\n", ctl1 & CTL1_M13MODE ? "M13" : "CPAR");
- print_tx_speed();
- printf("Scrambler: \t\t%s\n", mii16 & MII16_DS3_SCRAM ? yes : no);
- printf("Scram poly: \t\t%s\n", mii16 & MII16_DS3_POLY ? "X^20" : "X^43");
- printf("Cable length \t\t%s\n", mii16 & MII16_DS3_ZERO ? "Short" : "Long");
- printf("Line loop: \t\t%s\n", mii16 & MII16_DS3_LNLBK ? yes : no);
- printf("Payload loop: \t\t%s\n", ctl12 & CTL12_RTPLOOP ? yes : no);
- printf("Frame loop: \t\t%s\n", ctl1 & CTL1_3LOOP ? yes : no);
- printf("Host loop: \t\t%s\n", mii16 & MII16_DS3_TRLBK ? yes : no);
- printf("Transmit RAI: \t\t%s\n", ctl1 & CTL1_XTX ? no : yes);
- printf("Receive RAI \t\t%s\n", stat16 & STAT16_XERR ? yes : no);
- printf("Transmit AIS: \t\t%s\n", ctl1 & CTL1_TXAIS ? yes : no);
- printf("Receive AIS: \t\t%s\n", stat16 & STAT16_RAIS ? yes : no);
- printf("Transmit IDLE: \t\t%s\n", ctl1 & CTL1_TXIDL ? yes : no);
- printf("Receive IDLE: \t\t%s\n", stat16 & STAT16_RIDL ? yes : no);
- printf("Transmit BLUE: \t\t%s\n", ctl8 & CTL8_TBLU ? yes : no);
- printf("Receive BLUE: \t\t%s\n", stat9 & STAT9_RBLU ? yes : no);
- printf("Loss of Signal:\t\t%s\n", stat16 & STAT16_RLOS ? yes : no);
- printf("Loss of Frame: \t\t%s\n", stat16 & STAT16_ROOF ? yes : no);
- printf("Sev Err Frms: \t\t%s\n", stat16 & STAT16_SEF ? yes : no);
- printf("Code errors: \t\t%d\n", read_framer(T3CSR_CVLO) + (read_framer(T3CSR_CVHI)<<8));
- printf("C-Par errors: \t\t%d\n", read_framer(T3CSR_CERR));
- printf("P-Par errors: \t\t%d\n", read_framer(T3CSR_PERR));
- printf("F-Bit errors: \t\t%d\n", read_framer(T3CSR_FERR));
- printf("M-Bit errors: \t\t%d\n", read_framer(T3CSR_MERR));
- printf("FarEndBitErrs: \t\t%d\n", read_framer(T3CSR_FEBE));
- printf("Last Tx FEAC msg:\t0x%02X (%s)\n",
- read_framer(T3CSR_TX_FEAC) & 0x3F,
- print_t3_bop(read_framer(T3CSR_TX_FEAC) & 0x3F));
- printf("Last dbl FEAC msg;\t0x%02X (%s)\n",
- read_framer(T3CSR_DBL_FEAC) & 0x3F,
- print_t3_bop(read_framer(T3CSR_DBL_FEAC) & 0x3F));
- printf("Last Rx FEAC msg:\t0x%02X (%s)\n",
- read_framer(T3CSR_RX_FEAC) & 0x3F,
- print_t3_bop(read_framer(T3CSR_RX_FEAC) & 0x3F));
- print_t3_snmp();
-}
-
-static void
-t3_cmd(int argc, char **argv)
-{
- int ch;
-
- while ((ch = getopt(argc, argv, "a:A:B:c:de:fF:lLsS:vV:")) != -1)
- {
- switch (ch)
- {
- case 'a': /* stop alarms */
- {
- switch (optarg[0])
- {
- case 'a': /* Stop sending AIS Signal */
- {
- write_mii(16,
- read_mii(16) & ~MII16_DS3_FRAME);
- write_framer(T3CSR_CTL1,
- read_framer(T3CSR_CTL1) & ~CTL1_TXAIS);
- if (verbose) printf("Stop sending Alarm Indication Signal (AIS)\n");
- break;
- }
- case 'b': /* Stop sending Blue signal */
- {
- write_mii(16,
- read_mii(16) & ~MII16_DS3_FRAME);
- write_framer(T3CSR_CTL8,
- read_framer(T3CSR_CTL8) & ~CTL8_TBLU);
- if (verbose) printf("Stop sending Blue signal\n");
- break;
- }
- case 'i': /* Stop sending IDLE signal */
- {
- write_framer(T3CSR_CTL1,
- read_framer(T3CSR_CTL1) & ~CTL1_TXIDL);
- if (verbose) printf("Stop sending IDLE signal\n");
- break;
- }
- case 'y': /* Stop sending Yellow alarm */
- {
- write_framer(T3CSR_CTL1,
- read_framer(T3CSR_CTL1) | CTL1_XTX);
- if (verbose) printf("Stop sending Yellow alarm\n");
- break;
- }
- default:
- printf("Unknown alarm: %c\n", optarg[0]);
- break;
- }
- break;
- }
- case 'A': /* start alarms */
- {
- switch (optarg[0])
- {
- case 'a': /* Start sending AIS Signal */
- {
- write_mii(16,
- read_mii(16) | MII16_DS3_FRAME);
- write_framer(T3CSR_CTL1,
- read_framer(T3CSR_CTL1) | CTL1_TXAIS);
- if (verbose) printf("Sending AIS signal (framed 1010..)\n");
- break;
- }
- case 'b': /* Start sending Blue signal */
- {
- write_mii(16,
- read_mii(16) | MII16_DS3_FRAME);
- write_framer(T3CSR_CTL8,
- read_framer(T3CSR_CTL8) | CTL8_TBLU);
- if (verbose) printf("Sending Blue signal (unframed all 1s)\n");
- break;
- }
- case 'i': /* Start sending IDLE signal */
- {
- write_framer(T3CSR_CTL1,
- read_framer(T3CSR_CTL1) | CTL1_TXIDL);
- if (verbose) printf("Sending IDLE signal (framed 1100..)\n");
- break;
- }
- case 'y': /* Start sending Yellow alarm */
- {
- write_framer(T3CSR_CTL1,
- read_framer(T3CSR_CTL1) & ~CTL1_XTX);
- if (verbose) printf("Sending Yellow alarm (X-bits=0)\n");
- break;
- }
- default:
- printf("Unknown alarm: %c\n", optarg[0]);
- break;
- }
- break;
- }
- case 'B': /* send BOP msg */
- {
- u_int8_t bop = strtoul(optarg, NULL, 0);
- write_framer(T3CSR_TX_FEAC, 0xC0 + bop);
- if (verbose) printf("Sent '0x%02X' BOP msg 10 times\n", bop);
- break;
- }
- case 'c': /* set cable length */
- {
- config.cable_len = strtoul(optarg, NULL, 0);
- if (verbose) print_cable_len();
- update = 1;
- break;
- }
- case 'd': /* DSU status */
- case 's': /* deprecated */
- {
- print_t3_dsu();
- break;
- }
- case 'e': /* set framimg format */
- {
- config.format = strtoul(optarg, NULL, 0);
- if (verbose) print_format();
- update = 1;
- break;
- }
- case 'f': /* read and print framer regs */
- {
- int i;
- printf("TXC03401 regs:\n");
- printf(" 0 1 2 3 4 5 6 7");
- for (i=0; i<21; i++)
- {
- if (i%8 == 0) printf("\n%02X: ", i);
- printf("%02X ", read_framer(i));
- }
- printf("\n\n");
- break;
- }
- case 'F': /* write framer reg */
- {
- u_int32_t addr = strtoul(optarg, NULL, 0);
- u_int32_t data = strtoul(argv[optind++], NULL, 0);
- write_framer(addr, data);
- if (verbose)
- {
- data = read_framer(addr);
- printf("Write framer register: addr = 0x%02X data = 0x%02X\n", addr, data);
- }
- break;
- }
- case 'l': /* send DS3 line loopback deactivate BOP cmd */
- {
- ioctl_snmp_send(TSEND_RESET);
- if (verbose) printf("Sent 'DS3 Line Loopback deactivate' BOP cmd\n");
- break;
- }
- case 'L': /* send DS3 line loopback activate BOP cmd */
- {
- ioctl_snmp_send(TSEND_LINE);
- if (verbose) printf("Sent 'DS3 Line Loopback activate' BOP cmd\n");
- break;
- }
- case 'S': /* set scrambler */
- {
- config.scrambler = strtoul(optarg, NULL, 0);
- if (verbose) print_scrambler();
- update = 1;
- break;
- }
- case 'v': /* set verbose mode */
- {
- verbose = 1;
- break;
- }
- case 'V': /* set T3 freq control DAC */
- {
- u_int32_t dac = strtoul(optarg, NULL, 0);
- write_dac(dac);
- if (verbose) printf("VCXO DAC value is %d\n", dac);
- break;
- }
- default:
- {
- printf("Unknown command char: %c\n", ch);
- exit(1);
- } /* case */
- } /* switch */
- } /* while */
-} /* proc */
-
-static void
-print_test_pattern(int patt)
-{
- printf("Test Pattern:\t\t");
- switch (patt)
- {
- case 0:
- printf("unframed X^11+X^9+1\n");
- break;
- case 1:
- printf("unframed X^15+X^14+1\n");
- break;
- case 2:
- printf("unframed X^20+X^17+1\n");
- break;
- case 3:
- printf("unframed X^23+X^18+1\n");
- break;
- case 4:
- printf("unframed X^11+X^9+1 w/7ZS\n");
- break;
- case 5:
- printf("unframed X^15+X^14+1 w/7ZS\n");
- break;
- case 6:
- printf("unframed X^20+X^17+1 w/14ZS (QRSS)\n");
- break;
- case 7:
- printf("unframed X^23+X^18+1 w/14ZS\n");
- break;
- case 8:
- printf("framed X^11+X^9+1\n");
- break;
- case 9:
- printf("framed X^15+X^14+1\n");
- break;
- case 10:
- printf("framed X^20+X^17+1\n");
- break;
- case 11:
- printf("framed X^23+X^18+1\n");
- break;
- case 12:
- printf("framed X^11+X^9+1 w/7ZS\n");
- break;
- case 13:
- printf("framed X^15+X^14+1 w/7ZS\n");
- break;
- case 14:
- printf("framed X^20+X^17+1 w/14ZS (QRSS)\n");
- break;
- case 15:
- printf("framed X^23+X^18+1 w/14ZS\n");
- break;
- }
-}
-
-static char *
-print_t1_bop(int bop_code)
-{
- switch(bop_code)
- {
- case 0x00:
- return "Yellow Alarm (far end LOF)";
- case 0x07:
- return "Line Loop up";
- case 0x1C:
- return "Line Loop down";
- case 0x0A:
- return "Payload Loop up";
- case 0x19:
- return "Payload Loop down";
- case 0x09:
- return "Network Loop up";
- case 0x12:
- return "Network Loop down";
- default:
- return "Unknown BOP code";
- }
-}
-
-static void
-print_far_report(int index)
-{
- u_int16_t far = status.snmp.t1.prm[index];
-
- printf(" SEQ=%d ", (far & T1PRM_SEQ)>>8);
- if (far & T1PRM_G1) printf("CRC=1");
- else if (far & T1PRM_G2) printf("CRC=1 to 5");
- else if (far & T1PRM_G3) printf("CRC=5 to 10");
- else if (far & T1PRM_G4) printf("CRC=10 to 100");
- else if (far & T1PRM_G5) printf("CRC=100 to 319");
- else if (far & T1PRM_G6) printf("CRC>=320");
- else printf("CRC=0");
- printf(" SE=%d", (far & T1PRM_SE) ? 1 : 0);
- printf(" FE=%d", (far & T1PRM_FE) ? 1 : 0);
- printf(" LV=%d", (far & T1PRM_LV) ? 1 : 0);
- printf(" SL=%d", (far & T1PRM_SL) ? 1 : 0);
- printf(" LB=%d", (far & T1PRM_LB) ? 1 : 0);
- printf("\n");
-}
-
-static void
-print_t1_snmp(void)
-{
- printf("SNMP Near-end performance data:\n");
- printf(" LCV=%d", status.snmp.t1.lcv);
- printf(" LOS=%d", (status.snmp.t1.line & TLINE_LOS) ? 1 : 0);
- printf(" FE=%d", status.snmp.t1.fe);
- printf(" CRC=%d", status.snmp.t1.crc);
- printf(" AIS=%d", (status.snmp.t1.line & TLINE_RX_AIS) ? 1 : 0);
- printf(" SEF=%d", (status.snmp.t1.line & T1LINE_SEF) ? 1 : 0);
- printf(" OOF=%d", (status.snmp.t1.line & TLINE_LOF) ? 1 : 0);
- printf(" RAI=%d",(status.snmp.t1.line & TLINE_RX_RAI) ? 1 : 0);
- printf("\n");
- if (config.format == CFG_FORMAT_T1ESF)
- {
- printf("ANSI Far-end performance reports:\n");
- print_far_report(0);
- print_far_report(1);
- print_far_report(2);
- print_far_report(3);
- }
-}
-
-static void
-print_t1_dsu(void)
-{
- char *no = "No", *yes = "Yes";
- u_int16_t mii16 = read_mii(16);
- u_int8_t isr0 = read_framer(Bt8370_ISR0);
- u_int8_t loop = read_framer(Bt8370_LOOP);
- u_int8_t vga_max = read_framer(Bt8370_VGA_MAX) & 0x3F;
- u_int8_t alm1 = read_framer(Bt8370_ALM1);
- u_int8_t alm3 = read_framer(Bt8370_ALM3);
- u_int8_t talm = read_framer(Bt8370_TALM);
- u_int8_t tpatt = read_framer(Bt8370_TPATT);
- u_int8_t tpulse = read_framer(Bt8370_TLIU_CR);
- u_int8_t vga;
- u_int8_t saved_pulse, saved_lbo;
-
- /* d/c write required before read */
- write_framer(Bt8370_VGA, 0);
- vga = read_framer(Bt8370_VGA) & 0x3F;
-
- print_format();
- print_time_slots();
- print_tx_clk_src();
- print_tx_speed();
-
- saved_pulse = config.tx_pulse;
- config.tx_pulse = tpulse & 0x0E;
- saved_lbo = config.tx_lbo;
- config.tx_lbo = tpulse & 0x30;
- print_tx_pulse();
- config.tx_pulse = saved_pulse;
- config.tx_lbo = saved_lbo;
-
- printf("Tx outputs: \t\t%sabled\n", (mii16 & MII16_T1_XOE) ? "En" : "Dis");
- printf("Line impedance:\t\t%s ohms\n", (mii16 & MII16_T1_Z) ? "120" : "100");
- printf("Max line loss: \t\t%4.1f dB\n", vga_dbs(vga_max));
- printf("Cur line loss: \t\t%4.1f dB\n", vga_dbs(vga));
- printf("Invert data: \t\t%s\n", (mii16 & MII16_T1_INVERT) ? yes : no);
- printf("Line loop: \t\t%s\n", (loop & LOOP_LINE) ? yes : no);
- printf("Payload loop: \t\t%s\n", (loop & LOOP_PAYLOAD) ? yes : no);
- printf("Framer loop: \t\t%s\n", (loop & LOOP_FRAMER) ? yes : no);
- printf("Analog loop: \t\t%s\n", (loop & LOOP_ANALOG) ? yes : no);
- printf("Tx AIS: \t\t%s\n", ((talm & TALM_TAIS) ||
- ((talm & TALM_AUTO_AIS) && (alm1 & ALM1_RLOS))) ? yes : no);
- printf("Rx AIS: \t\t%s\n", (alm1 & ALM1_RAIS) ? yes : no);
- if (((config.format & 1)==0) && (config.format != CFG_FORMAT_E1NONE))
- {
- printf("Tx RAI: \t\t%s\n", ((talm & TALM_TYEL) ||
- ((talm & TALM_AUTO_YEL) && (alm3 & ALM3_FRED))) ? yes : no);
- printf("Rx RAI: \t\t%s\n", (alm1 & ALM1_RYEL) ? yes : no);
- }
- if (config.format == CFG_FORMAT_T1ESF)
- {
- printf("Tx BOP RAI: \t\t%s\n", (alm1 & ALM1_RLOF) ? yes : no);
- printf("Rx BOP RAI: \t\t%s\n", (alm1 & ALM1_RMYEL) ? yes : no);
- }
- if ((config.format & 0x11) == 0x10) /* E1CAS */
- {
- printf("Rx TS16 AIS: \t\t%s\n", (alm3 & ALM3_RMAIS) ? yes : no);
- printf("Tx TS16 RAI; \t\t%s\n",
- ((talm & TALM_AUTO_MYEL) && (alm3 & ALM3_SRED)) ? yes : no);
- }
- printf("Rx LOS analog: \t\t%s\n", (alm1 & ALM1_RALOS) ? yes : no);
- printf("Rx LOS digital:\t\t%s\n", (alm1 & ALM1_RLOS) ? yes : no);
- printf("Rx LOF: \t\t%s\n", (alm1 & ALM1_RLOF) ? yes : no);
- printf("Tx QRS: \t\t%s\n", (tpatt & 0x10) ? yes : no);
- printf("Rx QRS: \t\t%s\n", (isr0 & 0x10) ? yes : no);
- printf("LCV errors: \t\t%d\n",
- read_framer(Bt8370_LCV_LO) + (read_framer(Bt8370_LCV_HI)<<8));
- if (config.format != CFG_FORMAT_E1NONE)
- {
- if ((config.format & 1)==0) printf("Far End Block Errors:\t%d\n",
- read_framer(Bt8370_FEBE_LO) + (read_framer(Bt8370_FEBE_HI)<<8));
- printf("CRC errors: \t\t%d\n",
- read_framer(Bt8370_CRC_LO) + (read_framer(Bt8370_CRC_HI)<<8));
- printf("Frame errors: \t\t%d\n",
- read_framer(Bt8370_FERR_LO) + (read_framer(Bt8370_FERR_HI)<<8));
- printf("Sev Err Frms: \t\t%d\n", read_framer(Bt8370_AERR) & 0x03);
- printf("Change of Frm align:\t%d\n", (read_framer(Bt8370_AERR) & 0x0C)>>2);
- printf("Loss of Frame events:\t%d\n", (read_framer(Bt8370_AERR) & 0xF0)>>4);
- }
- if (config.format == CFG_FORMAT_T1ESF)
- {
- printf("Last Tx BOP msg:\t0x%02X (%s)\n",
- read_framer(Bt8370_TBOP), print_t1_bop(read_framer(Bt8370_TBOP)));
- printf("Last Rx BOP msg:\t0x%02X (%s)\n",
- read_framer(Bt8370_RBOP), print_t1_bop(read_framer(Bt8370_RBOP)&0x3F));
- }
- print_t1_snmp();
-}
-
-static void
-t1_cmd(int argc, char **argv)
-{
- int ch;
-
- while ((ch = getopt(argc, argv, "a:A:B:c:de:E:fF:g:iIlLpPstT:u:U:vxX")) != -1)
- {
- switch (ch)
- {
- case 'a': /* stop alarms */
- {
- switch (optarg[0])
- {
- case 'y': /* Stop sending Yellow Alarm */
- {
- if ((config.format == CFG_FORMAT_T1SF) ||
- (config.format == CFG_FORMAT_E1NONE))
- printf("No Yellow alarm for this frame format\n");
- else if (config.format == CFG_FORMAT_T1ESF)
- write_framer(Bt8370_BOP, 0xE0); /* rbop 25, tbop off */
- else
- {
- u_int8_t talm = read_framer(Bt8370_TALM);
- write_framer(Bt8370_TALM, talm & ~TALM_TYEL);
- }
- if (verbose) printf("Stop sending Yellow alarm\n");
- break;
- }
- case 'a': /* Stop sending AIS */
- case 'b': /* Stop sending Blue Alarm */
- {
- u_int8_t talm = read_framer(Bt8370_TALM);
- write_framer(Bt8370_TALM, talm & ~TALM_TAIS);
- if (verbose) printf("Stop sending AIS/Blue signal\n");
- break;
- }
- default:
- printf("Unknown alarm: %c\n", optarg[0]);
- }
- break;
- }
- case 'A': /* start alarms */
- {
- switch (optarg[0])
- {
- case 'y': /* Start sending Yellow Alarm */
- {
- if ((config.format == CFG_FORMAT_T1SF) ||
- (config.format == CFG_FORMAT_E1NONE))
- printf("No Yellow alarm for this frame format\n");
- else if (config.format == CFG_FORMAT_T1ESF)
- {
- write_framer(Bt8370_BOP, 0x0F); /* rbop off, tbop cont */
- write_framer(Bt8370_TBOP, T1BOP_OOF);
- }
- else
- {
- u_int8_t talm = read_framer(Bt8370_TALM);
- write_framer(Bt8370_TALM, talm | TALM_TYEL);
- }
- if (verbose) printf("Sending Yellow alarm\n");
- break;
- }
- case 'a': /* Start sending AIS */
- case 'b': /* Start sending Blue Alarm */
- {
- u_int8_t talm = read_framer(Bt8370_TALM);
- write_framer(Bt8370_TALM, talm | TALM_TAIS);
- if (verbose) printf("Sending AIS/Blue signal\n");
- break;
- }
- default:
- printf("Unknown alarm: %c\n", optarg[0]);
- }
- break;
- }
- case 'B': /* send BOP msg */
- {
- u_int8_t bop = strtoul(optarg, NULL, 0);
- if (config.format == CFG_FORMAT_T1ESF)
- {
- write_framer(Bt8370_BOP, 0x0B); /* rbop off, tbop 25 */
- write_framer(Bt8370_TBOP, bop); /* start sending BOP msg */
- sleep(1); /* sending 25 BOP msgs takes about 100 ms. */
- write_framer(Bt8370_BOP, 0xE0); /* rbop 25, tbop off */
- if (verbose) printf("Sent '0x%02X' BOP msg 25 times\n", bop);
- }
- else
- printf("BOP msgs only work in T1-ESF format\n");
- break;
- }
- case 'c': /* set cable length */
- {
- config.cable_len = strtoul(optarg, NULL, 0);
- if (verbose) print_cable_len();
- update = 1;
- break;
- }
- case 'd': /* DSU status */
- case 's': /* deprecated */
- {
- print_t1_dsu();
- break;
- }
- case 'e': /* set framimg format */
- {
- config.format = strtoul(optarg, NULL, 0);
- if (verbose) print_format();
- update = 1;
- break;
- }
- case 'E': /* set time slots */
- {
- config.time_slots = strtoul(optarg, NULL, 16);
- if (verbose) print_time_slots();
- update = 1;
- break;
- }
- case 'f': /* read and print framer regs */
- {
- int i;
- printf("Bt8370 regs:\n");
- printf(" 0 1 2 3 4 5 6 7 8 9 A B C D E F");
- for (i=0; i<512; i++)
- {
- if (i%16 == 0) printf("\n%03X: ", i);
- printf("%02X ", read_framer(i));
- }
- printf("\n\n");
- break;
- }
- case 'F': /* write framer reg */
- {
- u_int32_t addr = strtoul(optarg, NULL, 0);
- u_int32_t data = strtoul(argv[optind++], NULL, 0);
- write_framer(addr, data);
- if (verbose)
- {
- data = read_framer(addr);
- printf("Write framer register: addr = 0x%02X data = 0x%02X\n", addr, data);
- }
- break;
- }
- case 'g': /* set receiver gain */
- {
- config.rx_gain = strtoul(optarg, NULL, 0);
- if (verbose) print_rx_gain();
- update = 1;
- break;
- }
- case 'i': /* send CSU loopback deactivate inband cmd */
- {
- if (config.format == CFG_FORMAT_T1SF)
- {
- if (verbose) printf("Sending 'CSU loop down' inband cmd for 10 secs...");
- ioctl_snmp_send(TSEND_RESET);
- sleep(10);
- ioctl_snmp_send(TSEND_NORMAL);
- if (verbose) printf("done\n");
- }
- else
- printf("Inband loopback cmds only work in T1-SF format");
- break;
- }
- case 'I': /* send CSU loopback activate inband cmd */
- {
- if (config.format == CFG_FORMAT_T1SF)
- {
- if (verbose) printf("Sending 'CSU loop up' inband cmd for 10 secs...");
- ioctl_snmp_send(TSEND_LINE);
- sleep(10);
- ioctl_snmp_send(TSEND_NORMAL);
- if (verbose) printf("done\n");
- }
- else
- printf("Inband loopback cmds only work in T1-SF format");
- break;
- }
- case 'l': /* send line loopback deactivate BOP msg */
- {
- if (config.format == CFG_FORMAT_T1ESF)
- {
- ioctl_snmp_send(TSEND_RESET);
- if (verbose) printf("Sent 'Line Loop Down' BOP cmd\n");
- }
- else
- printf("BOP msgs only work in T1-ESF format\n");
- break;
- }
- case 'L': /* send line loopback activate BOP msg */
- {
- if (config.format == CFG_FORMAT_T1ESF)
- {
- ioctl_snmp_send(TSEND_LINE);
- if (verbose) printf("Sent 'Line Loop Up' BOP cmd\n");
- }
- else
- printf("BOP msgs only work in T1-ESF format\n");
- break;
- }
- case 'p': /* send payload loopback deactivate BOP msg */
- {
- if (config.format == CFG_FORMAT_T1ESF)
- {
- ioctl_snmp_send(TSEND_RESET);
- if (verbose) printf("Sent 'Payload Loop Down' BOP cmd\n");
- }
- else
- printf("BOP msgs only work in T1-ESF format\n");
- break;
- }
- case 'P': /* send payload loopback activate BOP msg */
- {
- if (config.format == CFG_FORMAT_T1ESF)
- {
- ioctl_snmp_send(TSEND_PAYLOAD);
- if (verbose) printf("Sent 'Payload Loop Up' BOP cmd\n");
- }
- else
- printf("BOP msgs only work in T1-ESF format\n");
- break;
- }
- case 't': /* stop sending test pattern */
- {
- ioctl_snmp_send(TSEND_NORMAL);
- if (verbose) printf("Stop sending test pattern\n");
- break;
- }
- case 'T': /* start sending test pattern */
- {
- u_int8_t patt = strtoul(optarg, NULL, 0);
- write_framer(Bt8370_TPATT, 0x10 + patt);
- write_framer(Bt8370_RPATT, 0x30 + patt);
- if (verbose) print_test_pattern(patt);
- break;
- }
- case 'u': /* set transmit pulse shape */
- {
- config.tx_pulse = strtoul(optarg, NULL, 0);
- if (verbose) print_tx_pulse();
- update = 1;
- break;
- }
- case 'U': /* set tx line build-out */
- {
- if (config.tx_pulse == CFG_PULSE_T1CSU)
- {
- config.tx_lbo = strtoul(optarg, NULL, 0);
- if (verbose) print_tx_pulse();
- update = 1;
- }
- else
- printf("LBO only meaningful if Tx Pulse is T1CSU\n");
- break;
- }
- case 'v': /* set verbose mode */
- {
- verbose = 1;
- break;
- }
- case 'x': /* disable transmitter outputs */
- {
- write_mii(16, read_mii(16) & ~MII16_T1_XOE);
- if (verbose) printf("Transmitter outputs disabled\n");
- break;
- }
- case 'X': /* enable transmitter outputs */
- {
- write_mii(16, read_mii(16) | MII16_T1_XOE);
- if (verbose) printf("Transmitter outputs enabled\n");
- break;
- }
- default:
- {
- printf("Unknown command char: %c\n", ch);
- exit(1);
- } /* case */
- } /* switch */
- } /* while */
-} /* proc */
-
-/* used when reading Motorola S-Record format ROM files */
-static unsigned char
-read_hex(FILE *f)
-{
- unsigned char a, b, c;
- for (a=0, b=0; a<2; a++)
- {
- c = fgetc(f);
- c -= 48;
- if (c > 9) c -= 7;
- b = (b<<4) | (c & 0xF);
- }
- checksum += b;
- return b;
-}
-
-static void
-load_xilinx(char *name)
-{
- FILE *f;
- char *ucode;
- int i, length;
- int c;
-
- if (verbose) printf("Load firmware from file %s...\n", name);
- if ((f = fopen(name, "r")) == NULL)
- {
- perror("Failed to open file");
- exit(1);
- }
-
- ucode = (char *)malloc(8192); bzero(ucode, 8192);
-
- c = fgetc(f);
- if (c == 'X')
- { /* Xilinx raw bits file (foo.rbt) */
- /* skip seven lines of boiler plate */
- for (i=0; i<7;) if ((c=fgetc(f))=='\n') i++;
- /* build a dense bit array */
- i = length = 0;
- while ((c=fgetc(f))!=EOF)
- { /* LSB first */
- if (c=='1') ucode[length] |= 1<<i++;
- if (c=='0') i++;
- if (i==8) { i=0; length++; }
- }
- }
- else if (c == 'S')
- { /* Motarola S records (foo.exo) */
- int blklen;
- length = 0;
- ungetc(c, f);
- while ((c = fgetc(f)) != EOF)
- {
- if (c != 'S')
- {
- printf("I'm confused; I expected an 'S'\n");
- exit(1);
- }
- c = fgetc(f);
- if (c == '9') break;
- else if (c == '1')
- {
- checksum = 0;
- blklen = read_hex(f) -3;
- read_hex(f); /* hi blkaddr */
- read_hex(f); /* lo blkaddr */
- for (i=0; i<blklen; i++)
- ucode[length++] = read_hex(f);
- read_hex(f); /* process but ignore checksum */
- if (checksum != 0xFF)
- {
- printf("File checksum error\n");
- exit(1);
- }
- c = fgetc(f); /* throw away eol */
- c = fgetc(f); /* throw away eol */
- }
- else
- {
- printf("I'm confused; I expected a '1' or a '9'\n");
- exit(1);
- }
- } /* while */
- } /* Motorola S-Record */
- else
- {
- printf("Unknown file type giving up\n");
- exit(1);
- }
-
- load_xilinx_from_file(ucode, length);
-}
-
-/* 32-bit CRC calculated right-to-left over 8-bit bytes */
-static u_int32_t
-crc32(char *bufp, int len)
-{
- int bit, i;
- u_int32_t data;
- u_int32_t crc = 0xFFFFFFFFL;
- u_int32_t poly = 0xEDB88320L;
-
- for (i = 0; i < len; i++)
- for (data = *bufp++, bit = 0; bit < 8; bit++, data >>= 1)
- crc = (crc >> 1) ^ (((crc ^ data) & 1) ? poly : 0);
-
- return crc;
-}
-
-/* 8-bit CRC calculated left-to-right over 16-bit words */
-static u_int8_t
-crc8(u_int16_t *bufp, int len)
-{
- int bit, i;
- u_int16_t data;
- u_int8_t crc = 0xFF;
- u_int8_t poly = 0x07;
-
- for (i = 0; i < len; i++)
- for (data = *bufp++, bit = 15; bit >= 0; bit--)
- {
- if ((i==8) && (bit==7)) break;
- crc = (crc << 1) ^ ((((crc >> 7) ^ (data >> bit)) & 1) ? poly : 0);
- }
- return crc;
-}
-
-/* HSSI=3, DS3=4, SSI=5, T1E1=6, HSSIc=7, SDSL=8 */
-void
-init_srom(int board)
-{
- int i;
- u_int16_t srom[64];
-
- /* zero the entire rom */
- for (i=0; i<64; i++) srom[i] = 0;
-
- srom[0] = 0x1376; /* subsys vendor id */
- srom[1] = board ? board : (read_mii(3)>>4 & 0xF) +1;
- srom[8] = crc8(srom, 9);
- /* Tulip hardware checks this checksum */
- srom[10] = 0x6000; /* ethernet address */
- srom[11] = 0x0099; /* ethernet address */
- srom[12] = 0x0000; /* ethernet address */
- /* srom checksum is low 16 bits of Ethernet CRC-32 */
- srom[63] = crc32((char *)srom, 126) ^ 0xFFFFFFFFL;
-
- /* write the SROM */
-#if 1 /* really write it */
- for (i=0; i<64; i++) write_srom(i, srom[i]);
-#else /* print what would be written */
- printf(" 0 1 2 3 4 5 6 7 8 9 A B C D E F");
- for (i=0; i<64; i++)
- {
- if (i%8 == 0) printf("\n%02X: ", i<<1);
- printf("%02X %02X ", srom[i] & 0xFF, srom[i]>>8);
- }
- printf("\n\n");
-#endif
-}
-
-int
-main(int argc, char **argv)
-{
- int i, error, ch;
- char *optstring = "13a:bBcCdDeEf:Fhi:L:mM:pP:sS:tT:uUvVwW:xXyYzZ?";
-
- progname = (char *)argv[0];
-
- /* Here is the overall plan:
- * 1) Read the interface name from the command line.
- * 2) Open the device; decide if netgraph is being used.
- * 3) Read the current interface configuration from the driver.
- * 4) Read the command line args and carry out their actions.
- * 5) Write the modified interface configuration to the driver.
- */
-
- /* 1) Read the interface name from the command line. */
-#if __linux__
- ifname = (argc==1) ? "hdlc0" : (char *) argv[1];
-#else
- ifname = (argc==1) ? DEVICE_NAME"0" : (char *) argv[1];
-#endif
-
- /* 2) Open the device; decide if netgraph is being used, */
- /* use netgraph if ifname ends with ":" */
- for (i=0; i<16; i++) if (ifname[i] == 0) break;
-
- /* Get a socket type file descriptor. */
-#if defined(NETGRAPH)
- if ((netgraph = (ifname[i-1] == ':')))
- error = NgMkSockNode(NULL, &fdcs, NULL);
- else
-#endif
- error = fdcs = socket(AF_INET, SOCK_DGRAM, 0);
- if (error < 0)
- {
- fprintf(stderr, "%s: %s() failed: %s\n", progname,
- netgraph? "NgMkSockNode" : "socket", strerror(errno));
- exit(1);
- }
-
- /* 3) Read the current interface configuration from the driver. */
- ioctl_read_config();
- ioctl_read_status();
-
- summary = (argc <= 2); /* print summary at end */
- update = 0; /* write to card at end */
-
- /* 4) Read the command line args and carry out their actions. */
- optind = 2;
- while (((ch = getopt(argc, argv, optstring)) != -1) && (argc > 2))
- {
- switch (ch)
- {
- case '1': /* T1 commands */
- {
- if (verbose) printf("Doing T1 settings\n");
- if (status.card_type != TLP_CSID_T1E1)
- {
- printf("T1 settings only apply to T1E1 cards\n");
- exit(1);
- }
- t1_cmd(argc, argv);
- break;
- }
- case '3': /* T3 commands */
- {
- if (verbose) printf("Doing T3 settings\n");
- if (status.card_type != TLP_CSID_T3)
- {
- printf("T3 settings only apply to T3 cards\n");
- exit(1);
- }
- t3_cmd(argc, argv);
- break;
- }
- case 'a': /* clock source */
- {
- if ((status.card_type != TLP_CSID_T1E1) ||
- (status.card_type != TLP_CSID_HSSI) ||
- (status.card_type != TLP_CSID_HSSIc))
- {
- if (verbose) print_tx_clk_src();
- config.tx_clk_src = strtoul(optarg, NULL, 0);
- update = 1;
- }
- else
- printf("txclksrc only applies to T1E1 and HSSI card types\n");
- break;
- }
- case 'b': /* read bios rom */
- {
- int i;
- printf("Bios ROM:\n");
- printf(" 0 1 2 3 4 5 6 7 8 9 A B C D E F");
- for (i=0; i<256; i++)
- {
- if (i%16 == 0) printf("\n%02X: ", i);
- printf("%02X ", read_bios_rom(i));
- }
- printf("\n\n");
- break;
- }
- case 'B': /* write bios rom */
- {
- int i;
- for (i=0; i<256; i++) write_bios_rom(i, 255-i);
- if (verbose) printf("wrote (0..255) to bios rom addrs (0..255)\n");
- break;
- }
- case 'c': /* set crc_len = 16 */
- {
- config.crc_len = CFG_CRC_16;
- if (verbose) print_crc_len();
- update = 1;
- break;
- }
- case 'C': /* set crc_len = 32 */
- {
- config.crc_len = CFG_CRC_32;
- if (verbose) print_crc_len();
- update = 1;
- break;
- }
- case 'd': /* clear DEBUG flag */
- {
- config.debug = 0;
- if (verbose) printf("DEBUG flag cleared\n");
- update = 1;
- break;
- }
- case 'D': /* set DEBUG flag */
- {
- config.debug = 1;
- if (verbose) printf("DEBUG flag set\n");
- update = 1;
- break;
- }
- case 'e': /* set DTE (default) */
- {
- if ((status.card_type == TLP_CSID_SSI) ||
- (status.card_type == TLP_CSID_HSSIc))
- {
- config.dte_dce = CFG_DTE;
- if (verbose) print_dte_dce();
- update = 1;
- }
- else
- printf("DTE cmd only applies to SSI & HSSIc cards\n");
- break;
- }
- case 'E': /* set DCE */
- {
- if ((status.card_type == TLP_CSID_SSI) ||
- (status.card_type == TLP_CSID_HSSIc))
- {
- config.dte_dce = CFG_DCE;
- if (verbose) print_dte_dce();
- update = 1;
- }
- else
- printf("DCE cmd only applies to SSI & HSSIc cards\n");
- break;
- }
- case 'f': /* set synth osc freq */
- {
- if ((status.card_type == TLP_CSID_SSI) ||
- (status.card_type == TLP_CSID_HSSIc))
- {
- synth_freq(strtoul(optarg, NULL, 0));
- write_synth(config.synth);
- if (verbose) print_synth_freq();
- }
- else
- printf("synth osc freq only applies to SSI & HSSIc cards\n");
- break;
- }
- case 'F': /* set SPPP line protocol to Frame-Relay */
- {
- config.line_prot = PROT_FRM_RLY;
- config.keep_alive = 1; /* required for LMI operation */
- if (verbose) printf("SPPP line protocol set to Frame-Relay\n");
- update = 1;
- break;
- }
- case 'h': /* help */
- case '?':
- {
- usage();
- exit(0);
- }
- case 'i': /* interface name */
- {
- /* already scanned this */
- break;
- }
- case 'L': /* set loopback modes */
- {
- config.loop_back = strtoul(optarg, NULL, 0);
- if (verbose) print_loop_back();
- update = 1;
- break;
- }
- case 'm': /* read and print MII regs */
- {
- printf("MII regs:\n");
- printf(" 0 1 2 3 4 5 6 7");
- for (i=0; i<32; i++)
- {
- u_int16_t mii = read_mii(i);
- if (i%8 == 0) printf("\n%02X: ", i);
- printf("%04X ", mii);
- }
- printf("\n\n");
- break;
- }
- case 'M': /* write MII reg */
- {
- u_int32_t addr = strtoul(optarg, NULL, 0);
- u_int32_t data = strtoul(argv[optind++], NULL, 0);
- write_mii(addr, data);
- if (verbose)
- {
- data = read_mii(addr);
- printf("Write mii register: addr = 0x%02X data = 0x%04X\n", addr, data);
- }
- break;
- }
- case 'p': /* read and print PCI config regs */
- {
- int i;
- printf("21140A PCI Config regs:\n");
- printf(" 0 1 2 3");
- for (i=0; i<16; i++)
- {
- if (i%4 == 0) printf("\n%X: ", i);
- printf("%08X ", read_pci_config(i<<2));
- }
- printf("\n\n");
- break;
- }
- case 'P': /* write PCI config reg */
- {
- u_int32_t addr = strtoul(optarg, NULL, 0);
- u_int32_t data = strtoul(argv[optind++], NULL, 0);
- write_pci_config(addr, data);
- if (verbose)
- {
- data = read_pci_config(addr);
- printf("Write PCI config reg: addr = 0x%02X data = 0x%08X\n", addr, data);
- }
- break;
- }
- case 's': /* read and print Tulip SROM */
- {
- int i;
- printf("21140A SROM:\n");
- printf(" 0 1 2 3 4 5 6 7 8 9 A B C D E F");
- for (i=0; i<64; i++)
- {
- u_int16_t srom = read_srom(i);
- if (i%8 == 0) printf("\n%02X: ", i<<1);
- printf("%02X %02X ", srom & 0xFF, srom>>8);
- }
- printf("\n\n");
- break;
- }
- case 'S': /* write Tulip SROM loc */
- {
-#if 0 /* write a single location -- not too useful */
- u_int32_t addr = strtoul(optarg, NULL, 0);
- u_int32_t data = strtoul(argv[optind++], NULL, 0);
- write_mii(addr, data);
- data = read_mii(addr);
- printf("Write SROM: addr = 0x%02X data = 0x%04X\n", addr, data);
-#endif
-#if 0 /* write the whole SROM -- very dangerous */
- init_srom(strtoul(optarg, NULL, 0));
-#endif
- printf("Caution! Recompile %s to enable this.\n", progname);
- break;
- }
- case 't': /* read and print Tulip CSRs */
- {
- int i;
- printf("21140A CSRs:\n");
- printf(" 0 1 2 3");
- for (i=0; i<16; i++)
- {
- if (i%4 == 0) printf("\n%X: ", i);
- printf("%08X ", read_csr(i));
- }
- printf("\n\n");
- break;
- }
- case 'T': /* write Tulip CSR */
- {
- u_int32_t addr = strtoul(optarg, NULL, 0);
- u_int32_t data = strtoul(argv[optind++], NULL, 0);
- write_csr(addr, data);
- if (verbose)
- {
- data = read_csr(addr);
- printf("Write 21140A CSR: addr = 0x%02X data = 0x%08X\n", addr, data);
- }
- break;
- }
- case 'u': /* reset event counters */
- {
- ioctl_reset_cntrs();
- if (verbose) printf("Event counters reset\n");
- break;
- }
- case 'U': /* reset gate array */
- {
- reset_xilinx();
- if (verbose) printf("gate array reset\n");
- break;
- }
- case 'v': /* set verbose mode */
- {
- verbose = 1;
- break;
- }
- case 'V': /* print card configuration */
- {
- summary = 1;
- break;
- }
- case 'w': /* load gate array microcode from ROM */
- {
- load_xilinx_from_rom();
- if (verbose) printf("gate array configured from on-board ROM\n");
- break;
- }
- case 'W': /* load gate array microcode from file */
- {
- load_xilinx(optarg);
- if (verbose) printf("gate array configured from file %s\n", optarg);
- break;
- }
- case 'x': /* select RAWIP protocol */
- {
- config.line_pkg = PKG_RAWIP;
- if (verbose) printf("RAWIP mode selected\n");
- update = 1;
- break;
- }
- case 'X': /* Select in-kernel line protocol packages */
- {
- config.line_pkg = 0;
- if (verbose) printf("line protocol mode selected\n");
- update = 1;
- break;
- }
- case 'y': /* disable SPPP keep-alive packets */
- {
- if ((config.line_pkg == PKG_SPPP) &&
- (config.line_prot == PROT_FRM_RLY))
- printf("keep-alives must be ON for Frame-Relay/SPPP\n");
- else
- {
- config.keep_alive = 0;
- if (verbose) printf("SPPP keep-alive packets disabled\n");
- update = 1;
- }
- break;
- }
- case 'Y': /* enable SPPP keep-alive packets */
- {
- config.keep_alive = 1;
- if (verbose) printf("SPPP keep-alive packets enabled\n");
- update = 1;
- break;
- }
- case 'z': /* set SPPP line protocol to Cisco HDLC */
- {
- config.line_prot = PROT_C_HDLC;
- config.keep_alive = 1;
- if (verbose) printf("SPPP line protocol set to Cisco-HDLC\n");
- update = 1;
- break;
- }
- case 'Z': /* set SPPP line protocol to PPP */
- {
- config.line_prot = PROT_PPP;
- config.keep_alive = 0;
- if (verbose) printf("SPPP line protocol set to PPP\n");
- update = 1;
- break;
- }
- default:
- {
- printf("Unknown command char: %c\n", ch);
- exit(1);
- }
- } /* switch */
- } /* while */
-
- if (summary) print_summary();
-
- /* 5) Write the modified interface configuration to the driver. */
- if (update) ioctl_write_config();
-
- exit(0);
-}