summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorharti <harti@FreeBSD.org>2003-06-12 14:28:32 +0000
committerharti <harti@FreeBSD.org>2003-06-12 14:28:32 +0000
commit246f3d9c06479bf59cbc5e791ced767d5b60e0f4 (patch)
tree3f8a4620133052a2e118843e2b2fec28dc923450
parentd8249cec9108e9a7b3fb23e7d8c48578beba3a91 (diff)
downloadFreeBSD-src-246f3d9c06479bf59cbc5e791ced767d5b60e0f4.zip
FreeBSD-src-246f3d9c06479bf59cbc5e791ced767d5b60e0f4.tar.gz
This is a driver for the physical layer chips used in ATM interfaces.
It currently supports the PMC Sierra Lite, Ultra and 622 chips and the IDT 77105. The driver handles media options and state in a consistent manner for ATM drivers. The next commit to the midway driver will make it use utopia.
-rw-r--r--etc/mtree/BSD.include.dist2
-rw-r--r--include/Makefile2
-rw-r--r--share/man/man4/Makefile1
-rw-r--r--share/man/man4/utopia.4131
-rw-r--r--share/man/man7/hier.74
-rw-r--r--share/man/man9/Makefile2
-rw-r--r--share/man/man9/utopia.9305
-rw-r--r--sys/dev/utopia/idtphy.h119
-rw-r--r--sys/dev/utopia/suni.h1515
-rw-r--r--sys/dev/utopia/utopia.c1082
-rw-r--r--sys/dev/utopia/utopia.h175
-rw-r--r--sys/modules/Makefile1
-rw-r--r--sys/modules/utopia/Makefile8
13 files changed, 3345 insertions, 2 deletions
diff --git a/etc/mtree/BSD.include.dist b/etc/mtree/BSD.include.dist
index 91181f0..9df1229 100644
--- a/etc/mtree/BSD.include.dist
+++ b/etc/mtree/BSD.include.dist
@@ -30,6 +30,8 @@
..
usb
..
+ utopia
+ ..
wi
..
..
diff --git a/include/Makefile b/include/Makefile
index 8a4b261..a932002 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -32,7 +32,7 @@ LDIRS= cam geom net netatalk netatm netgraph netinet netinet6 netipsec \
pccard posix4 sys vm
LSUBDIRS= cam/scsi dev/an dev/ic dev/iicbus dev/firewire dev/ofw \
- dev/ppbus dev/smbus dev/usb dev/wi fs/devfs \
+ dev/ppbus dev/smbus dev/usb dev/wi dev/utopia fs/devfs \
fs/fdescfs fs/fifofs fs/msdosfs fs/ntfs fs/nullfs fs/nwfs fs/portalfs \
fs/procfs fs/smbfs fs/umapfs fs/unionfs isofs/cd9660 \
netatm/ipatm netatm/sigpvc netatm/spans netatm/uni \
diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index 8171ba2..a7b0d57 100644
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -256,6 +256,7 @@ MAN= aac.4 \
urio.4 \
usb.4 \
uscanner.4 \
+ utopia.4 \
uvisor.4 \
uvscom.4 \
vga.4 \
diff --git a/share/man/man4/utopia.4 b/share/man/man4/utopia.4
new file mode 100644
index 0000000..ff93994
--- /dev/null
+++ b/share/man/man4/utopia.4
@@ -0,0 +1,131 @@
+.\" Copyright (c) 2003
+.\" Fraunhofer Institute for Open Communication Systems (FhG Fokus).
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" Author: Hartmut Brandt <harti@freebsd.org>
+.\"
+.\" $FreeBSD$
+.Dd May 8, 2003
+.Dt UTOPIA 4
+.Os FreeBSD
+.Sh NAME
+.Nm utopia
+.Nd Driver module for ATM PHY chips
+.Sh SYNOPSIS
+.Cd device utopia
+.Sh DESCRIPTION
+This module is used by all ATM drivers for cards that use S/Uni and IDT77105
+chips to provide uniform functionality.
+The module implements status monitoring
+in either interrupt or polling mode, media option handling and application
+access to chip registers.
+.Pp
+The driver implements several sysctls that accessible under the
+.Cm hw.atm.XXX
+tree, where
+.Cm XXX
+is the name of the ATM interface:
+.Bl -tag -width XXX
+.It Cm phy_regs
+When reading this sysctl an array of 8-bit unsigned integers is returned
+containing all accessible chip registers starting at register 0.
+A register can be written by writing three 8-bit unsigned integers to the
+sysctl: the register number, the new value and a bit mask.
+This changes all bits in the register for which the corresponding bit in the
+mask is one to the bit values from value.
+Note, that not all registers may
+be writeable.
+.It Cm phy_loopback
+allows to put the interface in one of several loopback modes.
+Not all modes and all combinations of modes are supported on all chips.
+The possible modes are:
+.Bl -tag -width XXX
+.It Dv UTP_LOOP_NONE (0x00)
+No loopback, normal operation.
+.It Dv UTP_LOOP_TIME (0x01)
+Timing source loopback. When this is set the transmitter's clock is
+derived from the receiver's clock.
+.It Dv UTP_LOOP_DIAG (0x02)
+Diagnostic loopback. In this mode the receiver's input is connected to the
+transmitter's output. The receiver gets back everything that is sent. The
+transmitter operates normally.
+.It Dv UTP_LOOP_LINE (0x04)
+Serial line loopback. This connects the line receiver to the line transmitter.
+The chip transmits all cells back that it receives. The receiver operates
+normally.
+.It Dv UTP_LOOP_PARAL (0x08)
+Parallel diagnostic loopback. This feeds back all transmitted cells into the
+receiver between the parallel/serial converters. The transmitter
+operates normally.
+.It Dv UTP_LOOP_TWIST (0x10)
+Twisted pair diagnostic loopback. Connects the high speed receive data to the
+high speed transmit data. All received data is sent back. The receiver
+operates normally.
+.It Dv UTP_LOOP_PATH (0x20)
+Diagnostic path loopback. This connectes the receiver input to the transmitter
+output just between the path overhead processor and the byte mux. The
+transmitter operates normally.
+.El
+.It Cm phy_type
+This is the detected type of the phy chip. Currently the following chips are
+supported:
+.Bl -tag -width XXX
+.It Dv UTP_TYPE_UNKNOWN (0)
+The module could not determine the type of the PHY chip.
+.It Dv UTP_TYPE_SUNI_LITE (1)
+PMC-5346 (S/Uni-Lite)
+.It Dv UTP_TYPE_SUNI_ULTRA (2)
+PMC-5350 (S/Uni-Ultra)
+.It Dv UTP_TYPE_SUNI_622 (3)
+PMC-5355 (S/Uni-622)
+.It Dv UTP_TYPE_IDT77105 (4)
+IDT77105 (25.6MBit UTP interface)
+.El
+.It Cm phy_name
+This is a string describing the type of the PHY chip.
+.El
+.Pp
+The
+.Nm
+module also interfaces with the ifmedia system.
+The module reports the current state of the carrier and will issue a
+warning message when the carrier state changes.
+While the physical media itself cannot be changed, several media options can:
+.Bl -tag -width XXX
+.It Cm SDH
+If the PHY is a S/Uni this flag switches the interface into SDH mode.
+If this option is not set (the default) the interface is in Sonet mode.
+.It Cm noscramb
+If the PHY is a S/Uni disable scrambling.
+This may be useful for debugging purposes.
+.It Cm unassigned
+Normally the interface emits idle cells when there are no other cells to
+transmit. This changes the default cell type to unassigned cells. This
+may be needed for interworking with public networks. Works only for S/Unis.
+.El
+.Sh SEE ALSO
+.Xr en 4,
+.Xr utopia 9
+.Sh AUTHOR
+.An Harti Brandt Aq harti@freebsd.org .
diff --git a/share/man/man7/hier.7 b/share/man/man7/hier.7
index de7c2f3..1c08fe8 100644
--- a/share/man/man7/hier.7
+++ b/share/man/man7/hier.7
@@ -189,6 +189,10 @@ see
.Xr ppbus 4
.It Pa usb/
The USB subsystem
+.It Pa utopia/
+Physical chip driver for ATM interfaces;
+see
+.Xr utopia 4
.It Pa wi/
The
.Xr wi 4
diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
index a511017..85c2bc4 100644
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -66,7 +66,7 @@ MAN= BUF_LOCK.9 BUF_LOCKFREE.9 BUF_LOCKINIT.9 BUF_REFCNT.9 \
spl.9 store.9 style.9 suser.9 swi.9 sx.9 \
sysctl_add_oid.9 sysctl_ctx_init.9 \
taskqueue.9 thread_exit.9 time.9 timeout.9 tvtohz.9 \
- ucred.9 uidinfo.9 uio.9 \
+ ucred.9 uidinfo.9 uio.9 utopia.9 \
vaccess.9 vaccess_acl_posix1e.9 vcount.9 \
vfs_busy.9 vfs_getnewfsid.9 vfs_getvfs.9 \
vfs_mount.9 vfs_mountedon.9 vfs_rootmountalloc.9 \
diff --git a/share/man/man9/utopia.9 b/share/man/man9/utopia.9
new file mode 100644
index 0000000..8716bd6
--- /dev/null
+++ b/share/man/man9/utopia.9
@@ -0,0 +1,305 @@
+.\" Copyright (c) 2003
+.\" Fraunhofer Institute for Open Communication Systems (FhG Fokus).
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" Author: Hartmut Brandt <harti@freebsd.org>
+.\"
+.\" $FreeBSD$
+.Dd May 8, 2003
+.Dt UTOPIA 9
+.Os FreeBSD
+.Sh NAME
+.Nm utopia
+.Nd Driver module for ATM PHY chips
+.Sh SYNOPSIS
+.In dev/utopia/utopia.h
+.Ft int
+.Fn utopia_attach "struct utopia *utp" "struct ifatm *ifatm" "struct ifmedia *media" "struct mtx *lock" "struct sysctl_ctx_list *ctx" "struct sysctl_oid_list *tree" "const struct utopia_methods *vtab"
+.Ft void
+.Fn utopia_detach "struct utopia *utp"
+.Ft int
+.Fn utopia_start "struct utopia *utp"
+.Ft void
+.Fn utopia_stop "struct utopia *utp"
+.Ft void
+.Fn utopia_init_media "struct utopia *utp"
+.Ft void
+.Fn utopia_reset_media "struct utopia *utp"
+.Ft int
+.Fn utopia_reset "struct utopia *utp"
+.Ft int
+.Fn utopia_set_sdh "struct utopia *utp" "int sdh"
+.Ft int
+.Fn utopia_set_unass "struct utopia *utp" "int unass"
+.Ft int
+.Fn utopia_set_noscramb "struct utopia *utp" "int noscramb"
+.Ft int
+.Fn utopia_update_carrier "struct utopia *utp"
+.Ft int
+.Fn utopia_set_loopback "struct utopia *utp" "u_int mode"
+.Ft void
+.Fn utopia_intr "struct utopia *utp"
+.Sh DESCRIPTION
+This module is used by all ATM drivers for cards that use a number of known
+PHY chips to provide uniform functionality.
+The module implements status monitoring in either interrupt or polling mode,
+media option handling and application access to PHY registers.
+.Pp
+To use this interface a driver must implement two functions for reading and
+writing PHY registers and initialize the following structure with pointers
+to these functions:
+.Bd -literal -offset indent
+struct utopia_methods {
+ int (*readregs)(struct ifatm *, u_int reg,
+ uint8_t *val, u_int *n);
+ int (*writereg)(struct ifatm *, u_int reg,
+ u_int mask, u_int val);
+};
+.Ed
+.Pp
+The
+.Fn readregs
+function should read PHY registers starting at register
+.Fa reg .
+The maximum number of registers to read is given by the integer pointed
+to by
+.Fa n .
+The function should either return 0 on success or an error code.
+In the first case
+.Fa *n
+should be set to the actual number of registers red.
+The
+.Fn writereg
+function should write one register.
+It must change all bits for which the corresponding bit in
+.Fa mask
+is 1 to the value of the corresponding bit in
+.Fa val .
+It returns either 0 on success or an error code.
+.Pp
+The ATM driver's private state block (softc) must begin with a
+.Vt "struct ifatm" .
+.Pp
+The
+.Vt "struct utopia"
+holds the current state of the PHY chip and contains the following fields:
+.Bd -literal -offset indent
+struct utopia {
+ struct ifatm *ifatm; /* driver data */
+ struct ifmedia *media; /* driver supplied */
+ struct mtx *lock; /* driver supplied */
+ const struct utopia_methods *methods;
+ LIST_ENTRY(utopia) link; /* list of these structures */
+ u_int flags; /* flags set by the driver */
+ u_int state; /* current state */
+ u_int carrier; /* carrier state */
+ u_int loopback; /* loopback mode */
+ const struct utopia_chip *chip; /* chip operations */
+};
+.Ed
+The public accessible fields have the following functions:
+.Bl -tag -width XXX
+.It Va ifatm
+Pointer to the driver's private data (softc).
+.It Va media
+Pointer to the driver's media structure.
+.Ir Va lock
+Pointer to a mutex provided by the driver. This mutex is used to synchronize
+with the kernel thread that handles device polling. It is locked in several
+places:
+.Bl -enum -offset indent
+.It
+In
+.Fn utopia_detach
+the mutex is locked to sleep and wait for the kernel thread to remove the
+.Vt "struct utopia"
+from the list of all utopia devices.
+Before returning to the caller the mutex is unlocked.
+.It
+In the
+.Nm
+kernel thread the mutex is locked and the
+.Fn utopia_carrier_update
+function is called with this mutex locked.
+This will result in the driver's
+.Fn readregs
+function beeing called with the mutex locked.
+.It
+In the sysctl handlers the mutex will be locked before calling into the driver's
+.Fn readreg
+or
+.Fn writereg
+functions.
+.El
+.It Va flags
+Flags set by either the driver or the utopia module. The following flags are
+defined:
+.Bl -tag -width XXX
+.It Dv UTP_FL_NORESET
+If this flag is set the module will not try to write the
+SUNI master reset register. (set by the driver)
+.It Dv UTP_FL_POLL_CARRIER
+If this flag is set the module will periodically poll the carrier state
+(as opposed to interrupt driven carrier state changes). (set by the driver)
+.El
+.It Va state
+Flags describing the current state of the phy chip. These are managed
+by the module:
+.Bl -tag -width XXX
+.It Dv UTP_ST_ACTIVE
+The driver is active and the phy registers can be accessed.
+This is set by calling
+.Fn utopia_start ,
+which should be called either in the attach routine of the driver or
+in the network interface initialisation routine (depending on whether the
+registers are accessible all the time or only when the interface is up).
+.It Dv UTP_ST_SDH
+Interface is in SDH mode as opposed to SONET mode.
+.It Dv UTP_ST_UNASS
+Interface is producing unassigned cells instead of idle cells.
+.It Dv UTP_ST_NOSCRAMB
+Cell scrambling is switched off.
+.It Dv UTP_ST_DETACH
+(internal use) interface is currently detaching.
+.It Dv UTP_ST_ATTACHED
+The attach routine has been run successfully.
+.El
+.It Va carrier
+The carrier state of the interface. This field can have one of three values:
+.Bl -tag -width XXX
+.It Dv UTP_CARR_UNKNOWN
+Carrier state is still unknown.
+.It Dv UTP_CARR_OK
+Carrier has been detected.
+.It Dv UTP_CARR_LOST
+Carrier has been lost.
+.El
+.It Va loopback
+This is the current loopback mode of the interface. Note, that not all
+chips support all loopback modes. Refer to the chip documentation. The
+following modes may be supported:
+.Bl -tag -width XXX
+.It Dv UTP_LOOP_NONE
+No loopback, normal operation.
+.It Dv UTP_LOOP_TIME
+Timing source loopback. The transmitter clock is driven by the receive clock.
+.It Dv UTP_LOOP_DIAG
+Diagnostic loopback.
+.It Dv UTP_LOOP_LINE
+Serial line loopback.
+.It Dv UTP_LOOP_PARAL
+Parallel diagnostic loopback.
+.It Dv UTP_LOOP_TWIST
+Twisted pair diagnostic loopback.
+.It Dv UTP_LOOP_PATH
+Diagnostic path loopback.
+.El
+.It Va chip
+This points the a function vector for chip specific functions. Two fields
+in this vector a publically available:
+.Bl -tag -width XXX
+.It Va type
+This is the type of the detected PHY chip.
+One of:
+.Bl -tag -width XXX
+.It Dv UTP_TYPE_UNKNOWN (0)
+.It Dv UTP_TYPE_SUNI_LITE (1)
+.It Dv UTP_TYPE_SUNI_ULTRA (2)
+.It Dv UTP_TYPE_SUNI_622 (3)
+.It Dv UTP_TYPE_IDT77105 (4)
+.El
+.It Va name
+This is a string with the name of the PHY chip.
+.El
+.El
+.Pp
+The following functions are used by the driver during attach/detach and/or
+initialisation/stopping the interface:
+.Bl -tag -width XXX
+.It Fn utopia_attach
+Attach the PHY chip. This is called with a preallocated
+.Vt "struct utopia"
+(which may be part of the driver's softc).
+The module initializes all fields of the utopia state and the media field.
+User settable flags should be set after the call to
+.Fn utopia_attach .
+This function may fail due to the inability to install the sysctl handlers.
+In this case it will return -1.
+On success 0 is returned and the
+.Dv UTP_ST_ATTACHED
+flag is set.
+.It Fn utopia_detach
+Remove the utopia attachment from the system. This cancels all outstanding polling
+timeouts.
+.It Fn utopia_start
+Start operation of that PHY. This should be called at a time
+when the PHY registers are known to be accessible. This may be either in
+the driver's attach function or when the interface is set running.
+.It Fn utopia_stop
+Stop operation of the PHY attachment. This may be called either in the detach
+function of the driver or when the interface is brought down.
+.It Fn utopia_init_media
+This must be called if the media field in the ATM MIB was changed. The function
+makes sure, that the ifmedia fields contain the same information as the
+ATM MIB.
+.It Fn utopia_reset_media
+This may be called to remove all media information from the ifmedia field.
+.El
+.Pp
+The following functions can be used to modify the PHY state while the interface
+is running:
+.Bl -tag -width XXX
+.It Fn utopia_reset
+Reset the operational parameters to the default state (SONET, idle cells,
+scrambling enabled). Returns 0 on success, an error code otherwise leaving
+the state undefined.
+.It Fn utopia_set_sdh
+If the argument is zero the chip is switched to Sonet mode, if it is non-zero
+the chip is switched to SDH mode. Returns 0 on success, an error code otherwise
+leaving the previous state.
+.It Fn utopia_set_unass
+If the argument is zero the chip is switched to produce idle cells, if it is
+non-zero the chip is switched to produce unassigned cells. Returns 0 on success,
+an error code otherwise leaving the previous state.
+.It Fn utopia_set_noscramb
+If the argument is zero enables scrambling, if it is
+non-zero disables scrambling. Returns 0 on success,
+an error code otherwise leaving the previous state.
+.It Fn utopia_update_carrier
+Check the carrier state and update the carrier field in the state structure.
+This will generate a message to the netgraph stack if the carrier state changes.
+For chips that are polled this is called automatically, for interrupt
+driven attachments this must be called on interrupts from the PHY chip.
+.It Fn utopia_set_loopback
+Set the loopback mode of the chip. Returns 0 on success, an error code
+otherwise leaving the previous state.
+.It Fn utopia_intr
+Called when an interrupt from the PHY chip is detected. This resets the
+interrupt state by reading all registers and, if the interrupt was from the
+RSOP, checks the carrier state.
+.El
+.Sh SEE ALSO
+.Xr utopia 4
+.Sh AUTHOR
+.An Harti Brandt Aq harti@freebsd.org .
diff --git a/sys/dev/utopia/idtphy.h b/sys/dev/utopia/idtphy.h
new file mode 100644
index 0000000..0d55e7e
--- /dev/null
+++ b/sys/dev/utopia/idtphy.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2003
+ * Fraunhofer Institute for Open Communication Systems (FhG Fokus).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author: Hartmut Brandt <harti@freebsd.org>
+ *
+ * $FreeBSD$
+ *
+ * Register definitions for the following chips:
+ * IDT 77105
+ */
+#ifndef _DEV_UTOPIA_IDTPHY_H
+#define _DEV_UTOPIA_IDTPHY_H
+
+#define IDTPHY_REGO_MCR 0x00
+#define IDTPHY_REGN_MCR "Master Control Register"
+#define IDTPHY_REGX_MCR "\020\010UPLO\7DREC\6ECEI\5TDPC\4DRIC\3HALTTX\2BYTEM\1EI"
+#define IDTPHY_REGM_MCR_UPL0 0x80
+#define IDTPHY_REGM_MCR_DREC 0x40
+#define IDTPHY_REGM_MCR_ECEI 0x20
+#define IDTPHY_REGM_MCR_TDPC 0x10
+#define IDTPHY_REGM_MCR_DRIC 0x08
+#define IDTPHY_REGM_MCR_HALTTX 0x04
+#define IDTPHY_REGM_MCR_BYTEM 0x02
+#define IDTPHY_REGM_MCR_EI 0x01
+
+#define IDTPHY_REGO_ISTAT 0x01
+#define IDTPHY_REGN_ISTAT "Interrupt Status"
+#define IDTPHY_REGX_ISTAT "\020\7GOOD\6HECE\5SCRE\4TPE\3RSCC\2RSE\1RFO"
+#define IDTPHY_REGM_ISTAT_GOOD 0x40 /* good signal bit */
+#define IDTPHY_REGM_ISTAT_HECE 0x20 /* HEC error */
+#define IDTPHY_REGM_ISTAT_SCRE 0x10 /* short cell received error */
+#define IDTPHY_REGM_ISTAT_TPE 0x08 /* transmit parity error */
+#define IDTPHY_REGM_ISTAT_RSCC 0x04 /* receive signal condition change */
+#define IDTPHY_REGM_ISTAT_RSE 0x02 /* receive symbol error */
+#define IDTPHY_REGM_ISTAT_RFO 0x01 /* read FIFO overrun */
+
+#define IDTPHY_REGO_DIAG 0x02
+#define IDTPHY_REGN_DIAG "Diagnostic Control"
+#define IDTPHY_REGX_DIAG "\020\010FTD\7ROS\6MULTI\5RFLUSH\4ITPE\3IHECE\11\3\0NORM\11\3\2PLOOP\11\3\3LLOOP"
+#define IDTPHY_REGM_DIAG_FTD 0x80 /* Force TxClav Deassert */
+#define IDTPHY_REGM_DIAG_ROS 0x40 /* RxClav Operation Select */
+#define IDTPHY_REGM_DIAG_MULTI 0x20 /* Multi-phy operation */
+#define IDTPHY_REGM_DIAG_RFLUSH 0x10 /* clear receive Fifo */
+#define IDTPHY_REGM_DIAG_ITPE 0x08 /* insert transmit payload error */
+#define IDTPHY_REGM_DIAG_IHECE 0x04 /* insert transmit HEC error */
+#define IDTPHY_REGM_DIAG_LOOP 0x03 /* loopback mode */
+#define IDTPHY_REGM_DIAG_LOOP_NONE 0x00 /* normal */
+#define IDTPHY_REGM_DIAG_LOOP_PHY 0x02 /* PHY loopback */
+#define IDTPHY_REGM_DIAG_LOOP_LINE 0x03 /* Line loopback */
+
+#define IDTPHY_REGO_LHEC 0x03
+#define IDTPHY_REGN_LHEC "LED Driver and HEC Status/Control"
+#define IDTPHY_REGX_LHEC "\020\7DRHEC\6DTHEC\11\x18\0CYC1\11\x18\1CYC2\11\x18\2CYC4\11\x18\3CYC8\3FIFOE\2TXLED\1RXLED"
+#define IDTPHY_REGM_LHEC_DRHEC 0x40 /* disable receive HEC */
+#define IDTPHY_REGM_LHEC_DTHEC 0x20 /* disable transmit HEC */
+#define IDTPHY_REGM_LHEC_RXREF 0x18 /* RxRef pulse width */
+#define IDTPHY_REGM_LHEC_RXREF1 0x00 /* 1 pulse */
+#define IDTPHY_REGM_LHEC_RXREF2 0x08 /* 2 pulse */
+#define IDTPHY_REGM_LHEC_RXREF4 0x10 /* 4 pulse */
+#define IDTPHY_REGM_LHEC_RXREF8 0x18 /* 8 pulse */
+#define IDTPHY_REGM_LHEC_FIFOE 0x04 /* Fifo empty */
+#define IDTPHY_REGM_LHEC_TXLED 0x02 /* Tx LED status */
+#define IDTPHY_REGM_LHEC_RXLED 0x01 /* Rx LED status */
+
+#define IDTPHY_REGO_CNT 0x04 /* +0x05 */
+#define IDTPHY_REGN_CNT "Counter"
+
+#define IDTPHY_REGO_CNTS 0x06
+#define IDTPHY_REGN_CNTS "Counter select"
+#define IDTPHY_REGX_CNTS "\020\4SEC\3TX\2RX\1HECE"
+#define IDTPHY_REGM_CNTS_SEC 0x08 /* symbol error counter */
+#define IDTPHY_REGM_CNTS_TX 0x04 /* Tx cells */
+#define IDTPHY_REGM_CNTS_RX 0x02 /* Rx cells */
+#define IDTPHY_REGM_CNTS_HECE 0x01 /* HEC errors */
+
+#define IDTPHY_PRINT_77105 \
+ { /* 00 */ \
+ UTP_REGT_BITS, IDTPHY_REGO_MCR, \
+ IDTPHY_REGN_MCR, IDTPHY_REGX_MCR }, \
+ { /* 01 */ \
+ UTP_REGT_BITS, IDTPHY_REGO_ISTAT, \
+ IDTPHY_REGN_ISTAT, IDTPHY_REGX_ISTAT }, \
+ { /* 02 */ \
+ UTP_REGT_BITS, IDTPHY_REGO_DIAG, \
+ IDTPHY_REGN_DIAG, IDTPHY_REGX_DIAG }, \
+ { /* 03 */ \
+ UTP_REGT_BITS, IDTPHY_REGO_LHEC, \
+ IDTPHY_REGN_LHEC, IDTPHY_REGX_LHEC }, \
+ { /* 04, 05 */ \
+ UTP_REGT_INT16, IDTPHY_REGO_CNT, \
+ IDTPHY_REGN_CNT, NULL }, \
+ { /* 06 */ \
+ UTP_REGT_BITS, IDTPHY_REGO_CNTS, \
+ IDTPHY_REGN_CNTS, IDTPHY_REGX_CNTS }
+
+#endif /* _DEV_UTOPIA_IDTPHY_H */
diff --git a/sys/dev/utopia/suni.h b/sys/dev/utopia/suni.h
new file mode 100644
index 0000000..ac8e997
--- /dev/null
+++ b/sys/dev/utopia/suni.h
@@ -0,0 +1,1515 @@
+/*
+ * Copyright (c) 2003
+ * Fraunhofer Institute for Open Communication Systems (FhG Fokus).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author: Hartmut Brandt <harti@freebsd.org>
+ *
+ * $FreeBSD$
+ *
+ * Register definitions for the following chips:
+ * PMC-Sierra PMC-5346 (S/UNI-LITE)
+ * PMC-Sierra PMC-5350 (S/UNI-ULTRA)
+ * PMC-Sierra PMC-5355 (S/UNI-622)
+ *
+ * All definitions ending with _ULTRA are for the ULTRA chip only, all
+ * definitions ending with _LITE are for the LITE chip only. Some registers
+ * are only in the ULTRA and the definitions are not suffixed. All other
+ * definitions are for all chips.
+ */
+#ifndef _DEV_UTOPIA_SUNI_H
+#define _DEV_UTOPIA_SUNI_H
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_MRESET "Master Reset and Identity/Load Meters"
+#define SUNI_REGO_MRESET 0x00
+#define SUNI_REGM_MRESET_RESET 0x80
+#define SUNI_REGM_MRESET_TYPE 0x70
+#define SUNI_REGM_MRESET_TYPE_622 0x10
+#define SUNI_REGM_MRESET_TYPE_LITE 0x30
+#define SUNI_REGM_MRESET_TYPE_ULTRA 0x70
+#define SUNI_REGM_MRESET_TIP_ULTRA 0x08
+#define SUNI_REGM_MRESET_ID_ULTRA 0x07
+#define SUNI_REGM_MRESET_ID_LITE 0x0f
+#define SUNI_REGM_MRESET_ID_622 0x0f
+#define SUNI_REGX_MRESET_ULTRA "\020\10RESET\12\x70\12TYPE\4TIP\12\7\12ID"
+#define SUNI_REGX_MRESET_LITE "\020\10RESET\12\x70\12TYPE\12\xf\12ID"
+#define SUNI_REGX_MRESET_622 "\020\10RESET\12\x70\12TYPE\12\xf\12ID"
+
+/* lite, ultra */
+#define SUNI_REGN_MCONFIG "Master Configuration"
+#define SUNI_REGO_MCONFIG 0x01
+#define SUNI_REGM_MCONFIG_AUTOFEBE 0x40
+#define SUNI_REGM_MCONFIG_AUTOLRDI 0x20
+#define SUNI_REGM_MCONFIG_AUTOPRDI 0x10
+#define SUNI_REGM_MCONFIG_TCAINV 0x08
+#define SUNI_REGM_MCONFIG_RCAINV 0x04
+#define SUNI_REGM_MCONFIG_RXDINV_LITE 0x02
+#define SUNI_REGM_MCONFIG_TFP_IN_ULTRA 0x01
+#define SUNI_REGM_MCONFIG_RESERVED 0x00
+#define SUNI_REGX_MCONFIG_LITE "\020\7AUTOFEBE\6AUTOLRDI\5AUTOPRDI\4TCAINV\3RCAINV\2RXDINV"
+#define SUNI_REGX_MCONFIG_ULTRA "\020\7AUTOFEBE\6AUTOLRDI\5AUTOPRDI\4TCAINV\3RCAINV\1TFPI_IN"
+
+/* 622 */
+#define SUNI_REGM_MCONFIG_TPTBEN_622 0x80
+#define SUNI_REGM_MCONFIG_TSTBEN_622 0x40
+#define SUNI_REGM_MCONFIG_SDH_C1_622 0x20
+#define SUNI_REGM_MCONFIG_FIXPTR_622 0x10
+#define SUNI_REGM_MCONFIG_TMODE_622 0x0C
+#define SUNI_REGM_MCONFIG_TMODE_STS1_BYTE 0x00
+#define SUNI_REGM_MCONFIG_TMODE_STS3c 0x04
+#define SUNI_REGM_MCONFIG_TMODE_STS1_BIT 0x08
+#define SUNI_REGM_MCONFIG_TMODE_STS12c 0x0C
+#define SUNI_REGM_MCONFIG_RMODE_622 0x03
+#define SUNI_REGM_MCONFIG_RMODE_STS1_BYTE 0x00
+#define SUNI_REGM_MCONFIG_RMODE_STS3c 0x01
+#define SUNI_REGM_MCONFIG_RMODE_STS1_BIT 0x02
+#define SUNI_REGM_MCONFIG_RMODE_STS12c 0x03
+#define SUNI_REGX_MCONFIG_622 "\020\10TPTBEN\7TSTBEN\6SDH_C1\5FIXPTR\11\x0C\0x00XSTS1BYTE\11\0x0C\0x04XSTS3c\11\0x0C\0x08XSTS1BIT\11\0x0C\0x0CXSTS12c\11\0x03\0x00RSTS1BYTE\11\0x03\0x01RSTS3c\11\0x03\0x02RSTS1BIT\11\0x03\0x03RSTS12c"
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_MISTATUS "Master Interrupt Status"
+#define SUNI_REGO_MISTATUS 0x02
+#define SUNI_REGM_MISTATUS_CSUI_ULTRA 0x80
+#define SUNI_REGM_MISTATUS_TROOLI_LITE 0x80
+#define SUNI_REGM_MISTATUS_SUNII_622 0x80
+#define SUNI_REGM_MISTATUS_LCDI 0x40
+#define SUNI_REGM_MISTATUS_STBI_622 0x40
+#define SUNI_REGM_MISTATUS_CRUI_ULTRA 0x20
+#define SUNI_REGM_MISTATUS_RDOOLI_LITE 0x20
+#define SUNI_REGM_MISTATUS_RESERVED_622 0x20
+#define SUNI_REGM_MISTATUS_TACPI 0x10
+#define SUNI_REGM_MISTATUS_RACPI 0x08
+#define SUNI_REGM_MISTATUS_RPOPI 0x04
+#define SUNI_REGM_MISTATUS_RLOPI 0x02
+#define SUNI_REGM_MISTATUS_RSOPI 0x01
+#define SUNI_REGX_MISTATUS_LITE "\020\10TROOLI\7LCDI\6RDOOLI\5TACPI\4RACPI\3RPOPI\2RLOPI\1RSOPI"
+#define SUNI_REGX_MISTATUS_ULTRA "\020\10CSUI\7LCDI\6CRUI\5TACPI\4RACPI\3RPOPI\2RLOPI\1RSOPI"
+#define SUNI_REGX_MISTATUS_622 "\020\10S/UNII\7STBI\5TACPI\4RACPI\3RPOPI\2RLOPI\1RSOPI"
+
+/* ultra */
+#define SUNI_REGN_MMCTRL "Master Mode Control"
+#define SUNI_REGO_MMCTRL 0x03
+#define SUNI_REGM_MMCTRL_51 0x02
+#define SUNI_REGM_MMCTRL_155 0x03
+#define SUNI_REGX_MMCTRL "\020\11\3\00251MBIT\11\3\003155MBIT"
+
+/* 622 */
+#define SUNI_REGN_PISO "PISO Interrupt"
+#define SUNI_REGO_PISO 0x03
+#define SUNI_REGM_PISO_PAEE 0x02
+#define SUNI_REGM_PISO_PAEI 0x01
+#define SUNI_REGX_PISO "\020\2PAEE\1PAEI"
+
+/* ultra/lite */
+#define SUNI_REGN_MCLKM "Master Clock Monitor"
+#define SUNI_REGO_MCLKM 0x04
+#define SUNI_REGM_MCLKM_RFCLKA 0x10 /* ultra */
+#define SUNI_REGM_MCLKM_TFCLKA 0x08 /* ultra */
+#define SUNI_REGM_MCLKM_RRCLKA 0x08 /* lite */
+#define SUNI_REGM_MCLKM_REFCLKA 0x04 /* ultra */
+#define SUNI_REGM_MCLKM_TRCLKA 0x04 /* lite */
+#define SUNI_REGM_MCLKM_RCLKA 0x02
+#define SUNI_REGM_MCLKM_TCLKA 0x01
+#define SUNI_REGX_MCLKM_LITE "\020\4RRCLKA\3TRCLKA\2RCLKA\1TCLKA"
+#define SUNI_REGX_MCLKM_ULTRA "\020\5RFCLKA\4TFCLKA\3REFCLKA\2RCLKA\1TCLKA"
+
+/* 622 */
+#define SUNI_REGN_MCTRLM "Master Control/Monitor"
+#define SUNI_REGO_MCTRLM 0x04
+#define SUNI_REGM_MCTRLM_TCAINV 0x80
+#define SUNI_REGM_MCTRLM_RCAINV 0x40
+#define SUNI_REGM_MCTRLM_LLE 0x20
+#define SUNI_REGM_MCTRLM_DLE 0x10
+#define SUNI_REGM_MCTRLM_LOOPT 0x08
+#define SUNI_REGM_MCTRLM_DPLE 0x04
+#define SUNI_REGM_MCTRLM_PICLKA 0x02
+#define SUNI_REGM_MCTRLM_TCLKA 0x01
+#define SUNI_REGX_MCTRLM "\020\10TCAINV\7RCAINV\6LLE\5DLE\4LOOPT\3DPLE\2PICLKA\1TCLKA"
+
+/* ultra/lite */
+#define SUNI_REGN_MCTRL "Master Control"
+#define SUNI_REGO_MCTRL 0x05
+#define SUNI_REGM_MCTRL_LCDE 0x80
+#define SUNI_REGM_MCTRL_LCDV 0x40
+#define SUNI_REGM_MCTRL_FIXPTR 0x20
+#define SUNI_REGM_MCTRL_TPLE 0x10 /* ultra */
+#define SUNI_REGM_MCTRL_PDLE 0x08 /* ultra */
+#define SUNI_REGM_MCTRL_LLE 0x04
+#define SUNI_REGM_MCTRL_SDLE 0x02 /* ultra */
+#define SUNI_REGM_MCTRL_DLE 0x02 /* lite */
+#define SUNI_REGM_MCTRL_LOOPT 0x01
+#define SUNI_REGX_MCTRL_ULTRA "\020\10LCDE\7LCDV\6FIXPTR\5TPLE\4PDLE\3LLE\2SDLE\1LOOPT"
+#define SUNI_REGX_MCTRL_LITE "\020\10LCDE\7LCDV\6FIXPTR\3LLE\2DLE\1LOOPT"
+
+/* 622 */
+#define SUNI_REGN_MALARM "Master Auto Alarm"
+#define SUNI_REGO_MALARM 0x05
+#define SUNI_REGM_MALARM_AUTOFEBE 0x04
+#define SUNI_REGM_MALARM_AUTOLRDI 0x02
+#define SUNI_REGM_MALARM_AUTOPRDI 0x01
+#define SUNI_REGX_MALARM "\020\4AUTOFEBE\2AUTOLRDI\1AUTOPRDI"
+
+/* ultra/lite */
+#define SUNI_REGN_CLKSYN "Clock Synthesis Control and Status"
+#define SUNI_REGO_CLKSYN 0x06
+#define SUNI_REGM_CLKSYN_TROOLI 0x20 /* ultra */
+#define SUNI_REGM_CLKSYN_TROOLV 0x08
+#define SUNI_REGM_CLKSYN_TROOLE 0x02
+#define SUNI_REGM_CLKSYN_TREFSEL 0x01 /* lite */
+#define SUNI_REGM_CLKSYN_RESERVED 0x00
+#define SUNI_REGX_CLKSYN_ULTRA "\020\6TROOLI\4TROOLV\2TROOLE"
+#define SUNI_REGX_CLKSYN_LITE "\020\4TROOLV\2TROOLE\1TREFSEL"
+
+/* 622 */
+#define SUNI_REGN_POUT "Parallel Output Port"
+#define SUNI_REGO_POUT 0x06
+#define SUNI_REGM_POUT_POP 0x3f
+#define SUNI_REGX_POUT "\020\12\x3f\12POP"
+
+/* ultra/lite */
+#define SUNI_REGN_CLKREC "Clock Recovery Control and Status"
+#define SUNI_REGO_CLKREC_LITE 0x07
+#define SUNI_REGO_CLKREC_ULTRA 0x08
+#define SUNI_REGM_CLKREC_RROOLI 0x40 /* ultra */
+#define SUNI_REGM_CLKREC_RDOOLI 0x20 /* ultra */
+#define SUNI_REGM_CLKREC_RROOLV 0x10
+#define SUNI_REGM_CLKREC_RDOOLV 0x08
+#define SUNI_REGM_CLKREC_RROOLE 0x04 /* ultra */
+#define SUNI_REGM_CLKREC_RDOOLE 0x02
+#define SUNI_REGM_CLKREC_RREFSEL 0x01 /* lite */
+#define SUNI_REGM_CLKREC_RESERVED 0x00
+#define SUNI_REGX_CLKREC_ULTRA "\020\7RROOLI\6RDOOLI\5RROOLV\4RDOOLV\3RROOLE\2RDOOLE"
+#define SUNI_REGX_CLKREC_LITE "\020\5RROOLV\4RDOOLV\2RDOOLE\1RREFSEL"
+
+/* 622 */
+#define SUNI_REGN_PIN "Parallel Input Port"
+#define SUNI_REGO_PIN 0x07
+
+/* 622 */
+#define SUNI_REGN_PINV "Parallel Input Port Value"
+#define SUNI_REGO_PINV 0x08
+#define SUNI_REGM_PINV_PIPV 0x0f
+#define SUNI_REGX_PINV "\020\12\0x0f\12PIPIV"
+
+/* ultra */
+#define SUNI_REGN_CLKRECCFG "Clock Recovery Configuration"
+#define SUNI_REGO_CLKRECCFG 0x09
+#define SUNI_REGM_CLKRECCFG_RESERVED 0x07
+#define SUNI_REGX_CLKRECCFG "\020"
+
+/* 622 */
+#define SUNI_REGN_PINE "Parallel Input Port Enable"
+#define SUNI_REGO_PINE 0x09
+
+/* ultra */
+#define SUNI_REGN_LTXCFG1 "Line Transmitter Configuration 1"
+#define SUNI_REGO_LTXCFG1 0x0A
+#define SUNI_REGM_LTXCFG1_VREFSEL 0x80
+#define SUNI_REGM_LTXCFG1_OEN 0x20
+#define SUNI_REGM_LTXCFG1_OTQ 0x10
+#define SUNI_REGM_LTXCFG1_RESERVED 0x0C
+#define SUNI_REGX_LTXCFG1 "\020\10VREFSEL\6OEN\5OTQ"
+
+/* 622 */
+#define SUNI_REGN_XC1 "Transmit C1"
+#define SUNI_REGO_XC1 0x0A
+
+/* ultra */
+#define SUNI_REGN_LTXCFG2 "Line Transmitter Configuration 2"
+#define SUNI_REGO_LTXCFG2 0x0B
+#define SUNI_REGM_LTXCFG2_RESERVED 0xFF
+#define SUNI_REGX_LTXCFG2 "\020"
+
+/* 622 */
+#define SUNI_REGN_APSCS "APS Control/Status"
+#define SUNI_REGO_APSCS 0x0B
+#define SUNI_REGM_APSCS_PSBFE 0x80
+#define SUNI_REGM_APSCS_COAPSE 0x40
+#define SUNI_REGM_APSCS_Z1E 0x20
+#define SUNI_REGM_APSCS_Zi1 0x10
+#define SUNI_REGM_APSCS_PSBFI 0x08
+#define SUNI_REGM_APSCS_COAPSI 0x04
+#define SUNI_REGM_APSCS_RESERVED 0x02
+#define SUNI_REGM_APSCS_PSBFV 0x01
+#define SUNI_REGX_APSCS "\020\10PSBFE\7COAPSE\6Z1E\5Z1I\4PSBFI\3COAPSI\1PSBFV"
+
+/* ultra */
+#define SUNI_REGN_LRXCFG "Line Receiver Configuration"
+#define SUNI_REGO_LRXCFG 0x0C
+#define SUNI_REGM_LRXCFG_RESERVED 0x01
+#define SUNI_REGX_LRXCFG "\020"
+
+/* 622 */
+#define SUNI_REGN_RK1 "Receive K1"
+#define SUNI_REGO_RK1 0x0C
+
+/* 622 */
+#define SUNI_REGN_RK2 "Receive K2"
+#define SUNI_REGO_RK2 0x0D
+
+/* 622 */
+#define SUNI_REGN_RZ1 "Receive Z1"
+#define SUNI_REGO_RZ1 0x0E
+
+/* 622 */
+#define SUNI_REGN_XZ1 "Transmit Z1"
+#define SUNI_REGO_XZ1 0x0F
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_RSOPCIE "RSOP Control/Interrupt Enable"
+#define SUNI_REGO_RSOPCIE 0x10
+#define SUNI_REGO_RSOPCIE_BIPWORD_622 0x80
+#define SUNI_REGM_RSOPCIE_DDS 0x40
+#define SUNI_REGM_RSOPCIE_FOOF 0x20
+#define SUNI_REGM_RSOPCIE_RESV 0x10
+#define SUNI_REGM_RSOPCIE_ALGO2_622 0x10
+#define SUNI_REGM_RSOPCIE_BIPEE 0x08
+#define SUNI_REGM_RSOPCIE_LOSE 0x04
+#define SUNI_REGM_RSOPCIE_LOFE 0x02
+#define SUNI_REGM_RSOPCIE_OOFE 0x01
+#define SUNI_REGX_RSOPCIE "\020\7DDS\6FOOF\4BIPEE\3LOSE\2LOFE\1OOFE"
+#define SUNI_REGX_RSOPCIE_622 "\020\10BIPWORD\7DDS\6FOOF\5ALGO2\4BIPEE\3LOSE\2LOFE\1OOFE"
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_RSOPSIS "RSOP Status/Interrupt Status"
+#define SUNI_REGO_RSOPSIS 0x11
+#define SUNI_REGM_RSOPSIS_BIPEI 0x40
+#define SUNI_REGM_RSOPSIS_LOSI 0x20
+#define SUNI_REGM_RSOPSIS_LOFI 0x10
+#define SUNI_REGM_RSOPSIS_OOFI 0x08
+#define SUNI_REGM_RSOPSIS_LOSV 0x04
+#define SUNI_REGM_RSOPSIS_LOFV 0x02
+#define SUNI_REGM_RSOPSIS_OOFV 0x01
+#define SUNI_REGX_RSOPSIS "\020\7BIPEI\6LOSI\5LOFI\4OOFI\3LOSV\2LOFV\1OOFV"
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_RSOP_BIP8 "RSOP Section BIP-8"
+#define SUNI_REGO_RSOP_BIP8 0x12 /* +0x13 */
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_TSOPCTRL "TSOP Control"
+#define SUNI_REGO_TSOPCTRL 0x14
+#define SUNI_REGM_TSOPCTRL_DS 0x40
+#define SUNI_REGM_TSOPCTRL_LAIS 0x01
+#define SUNI_REGM_TSOPCTRL_RESERVED 0x00
+#define SUNI_REGX_TSOPCTRL "\020\7DS\1LAIS"
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_TSOPDIAG "TSOP Diagnostics"
+#define SUNI_REGO_TSOPDIAG 0x15
+#define SUNI_REGM_TSOPDIAG_DLOS 0x04
+#define SUNI_REGM_TSOPDIAG_DBIP8 0x02
+#define SUNI_REGM_TSOPDIAG_DFP 0x01
+#define SUNI_REGX_TSOPDIAG "\020\3DLOS\2DBIP8\1DFP"
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_RLOPCTRL "RLOP Control/Status"
+#define SUNI_REGO_RLOPCTRL 0x18
+#define SUNI_REGO_RLOPCTRL_BIPWORD 0x80
+#define SUNI_REGO_RLOPCTRL_ALLONES_622 0x40
+#define SUNI_REGO_RLOPCTRL_AISDET_622 0x20
+#define SUNI_REGO_RLOPCTRL_LRDIDET_622 0x10
+#define SUNI_REGO_RLOPCTRL_BIPWORDO_622 0x08
+#define SUNI_REGO_RLOPCTRL_LAISV 0x02
+#define SUNI_REGO_RLOPCTRL_RDIV 0x01
+#define SUNI_REGO_RLOPCTRL_RESERVED 0x00
+#define SUNI_REGX_RLOPCTRL "\020\10BIPWORD\2LAISV\1RDIV"
+#define SUNI_REGX_RLOPCTRL_622 "\020\10BIPWORD\7ALLONES\6AISDET\5LRDIDET\4BIPWORDO\2LAISV\1RDIV"
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_RLOPINTR "RLOP Interrupt Enable/Interrupt Status"
+#define SUNI_REGO_RLOPINTR 0x19
+#define SUNI_REGO_RLOPINTR_FEBEE 0x80
+#define SUNI_REGO_RLOPINTR_BIPEE 0x40
+#define SUNI_REGO_RLOPINTR_LAISE 0x20
+#define SUNI_REGO_RLOPINTR_RDIE 0x10
+#define SUNI_REGO_RLOPINTR_FEBEI 0x08
+#define SUNI_REGO_RLOPINTR_BIPEI 0x04
+#define SUNI_REGO_RLOPINTR_LAISI 0x02
+#define SUNI_REGO_RLOPINTR_RDII 0x01
+#define SUNI_REGX_RLOPINTR "\020\10FEBEE\7BIPEE\6LAISE\5DRIE\4FEBEI\3BIPEI\2LAISI\1RDII"
+
+/* lite, ultra */
+#define SUNI_REGN_RLOPBIP8_24 "RLOP Line BIP-8/24"
+#define SUNI_REGO_RLOPBIP8_24 0x1A /* +1B,1C */
+#define SUNI_REGM_RLOPBIP8_24 0x0F
+
+/* 622 */
+#define SUNI_REGN_RLOPBIP8_24_96 "RLOP Line BIP-8/24/96"
+#define SUNI_REGO_RLOPBIP8_24_96 0x1A /* +1B,1C */
+#define SUNI_REGM_RLOPBIP8_24_96 0x0F
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_RLOPFEBE "RLOP Line FEBE"
+#define SUNI_REGO_RLOPFEBE 0x1D /* +1E,1F */
+#define SUNI_REGM_RLOPFEBE 0x0F
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_TLOPCTRL "TLOP Control"
+#define SUNI_REGO_TLOPCTRL 0x20
+#define SUNI_REGM_TLOPCTRL_APSREG_622 0x20
+#define SUNI_REGM_TLOPCTRL_RDI 0x01
+#define SUNI_REGM_TLOPCTRL_RESERVED 0x00
+#define SUNI_REGX_TLOPCTRL "\020\1RDI"
+#define SUNI_REGX_TLOPCTRL_622 "\020\6APSREG\1LRDI"
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_TLOPDIAG "TLOP Diagnostics"
+#define SUNI_REGO_TLOPDIAG 0x21
+#define SUNI_REGM_TLOPDIAG_DBIP 0x01
+#define SUNI_REGX_TLOPDIAG "\020\1DBIP"
+
+/* 622 */
+#define SUNI_REGN_TLOP_XK1 "TLOP Transmit K1"
+#define SUNI_REGO_TLOP_XK1 0x22
+
+/* 622 */
+#define SUNI_REGN_TLOP_XK2 "TLOP Transmit K2"
+#define SUNI_REGO_TLOP_XK2 0x23
+
+/* 622 */
+#define SUNI_REGN_SSTBCTRL "SSTB Control"
+#define SUNI_REGO_SSTBCTRL 0x28
+#define SUNI_REGM_SSTBCTRL_RRAMACC 0x40
+#define SUNI_REGM_SSTBCTRL_RTIUIE 0x20
+#define SUNI_REGM_SSTBCTRL_RTIMIE 0x10
+#define SUNI_REGM_SSTBCTRL_PER5 0x08
+#define SUNI_REGM_SSTBCTRL_TNULL 0x04
+#define SUNI_REGM_SSTBCTRL_NOSYNC 0x02
+#define SUNI_REGM_SSTBCTRL_LEN16 0x01
+#define SUNI_REGX_SSTBCTRL "\020\7RRAMACC\6RTIUIE\5RTIMIE\4PER5\3TNULL\2NOSYNC\1LEN16"
+
+/* 622 */
+#define SUNI_REGN_SSTBSTIS "SSTB Section Trace Identifier Status"
+#define SUNI_REGO_SSTBSTIS 0x29
+#define SUNI_REGM_SSTBSTIS_BUSY 0x80
+#define SUNI_REGM_SSTBSTIS_RTIUI 0x08
+#define SUNI_REGM_SSTBSTIS_RTIUV 0x04
+#define SUNI_REGM_SSTBSTIS_RTIMI 0x02
+#define SUNI_REGM_SSTBSTIS_RTIMV 0x01
+#define SUNI_REGX_SSTBSTIS "\020\10BUSY\4RTIUI\3RTIUV\2RTIMI\1RTIMV"
+
+/* 622 */
+#define SUNI_REGN_SSTBIAR "SSTB Indirect Address Register"
+#define SUNI_REGO_SSTBIAR 0x2A
+#define SUNI_REGM_SSTBIAR_RWB 0x80
+#define SUNI_REGM_SSTBIAR_A 0x7F
+#define SUNI_REGX_SSTBIAR "\020\10RWB\12\x7f\20"
+
+/* 622 */
+#define SUNI_REGN_SSTBIDR "SSTB Indirect Data Register"
+#define SUNI_REGO_SSTBIDR 0x2B
+
+#if 0 /* see chip errata */
+/* 622 */
+#define SUNI_REGN_SSTBECSM "SSTB Expected Clock Synchronization Message"
+#define SUNI_REGO_SSTBECSM 0x2C
+#endif
+
+/* 622 */
+#define SUNI_REGN_SSTBCSMS "SSTB Clock Synchronisation Message Status"
+#define SUNI_REGO_SSTBCSMS 0x2D
+#define SUNI_REGM_SSTBCSMS_RCSMUIE 0x80
+#define SUNI_REGM_SSTBCSMS_RCSMMIE 0x40
+#define SUNI_REGM_SSTBCSMS_RCSMUI 0x08
+#define SUNI_REGM_SSTBCSMS_RCSMUV 0x04
+#define SUNI_REGM_SSTBCSMS_RCSMMI 0x02
+#define SUNI_REGM_SSTBCSMS_RCSMMV 0x01
+#define SUNI_REGX_SSTBCSMS "\020\10RCSMUIE\7RCSMMIE\4RCSMUI\3RCSMUV\2RCSMMI\1RCSMMV"
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_RPOPCTRL "RPOP Status/Control"
+#define SUNI_REGO_RPOPCTRL 0x30
+#define SUNI_REGM_RPOPCTRL_LOP 0x20
+#define SUNI_REGM_RPOPCTRL_PAIS 0x08
+#define SUNI_REGM_RPOPCTRL_PRDI 0x04
+#define SUNI_REGM_RPOPCTRL_NEWPTRI_622 0x02
+#define SUNI_REGM_RPOPCTRL_NEWPTRE_622 0x01
+#define SUNI_REGM_RPOPCTRL_RESERVED 0x00
+#define SUNI_REGX_RPOPCTRL "\020\6LOP\4PAIS\3PRDI"
+#define SUNI_REGX_RPOPCTRL_622 "\020\6LOP\4PAIS\3PRDI\2NEWPTRI\1NEWPTRE"
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_RPOPISTAT "RPOP Interrupt Status"
+#define SUNI_REGO_RPOPISTAT 0x31
+#define SUNI_REGM_RPOPISTAT_PSLI 0x80
+#define SUNI_REGM_RPOPISTAT_LOPI 0x20
+#define SUNI_REGM_RPOPISTAT_PAISI 0x08
+#define SUNI_REGM_RPOPISTAT_PRDII 0x04
+#define SUNI_REGM_RPOPISTAT_BIPEI 0x02
+#define SUNI_REGM_RPOPISTAT_FEBEI 0x01
+#define SUNI_REGX_RPOPISTAT "\02010PSLI\6LOPI\4PAISI\3PRDII\2BIPEI\1FEBEI"
+
+/* 622 */
+#define SUNI_REGN_RPOPPIS "RPOP Pointer Interrupt Status"
+#define SUNI_REGO_RPOPPIS 0x32
+#define SUNI_REGM_RPOPPIS_ILLJREQI 0x80
+#define SUNI_REGM_RPOPPIS_DISCOPAI 0x20
+#define SUNI_REGM_RPOPPIS_INVNDFI 0x10
+#define SUNI_REGM_RPOPPIS_ILLPTRI 0x08
+#define SUNI_REGM_RPOPPIS_NSEI 0x04
+#define SUNI_REGM_RPOPPIS_PSEI 0x02
+#define SUNI_REGM_RPOPPIS_NDFI 0x01
+#define SUNI_REGX_RPOPPIS "\020\10ILLJREQI\6DISCOPAI\5INVNDFI\4ILLPTRI\3NSEI\2PSEI\1NDFI"
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_RPOPIEN "RPOP Interrupt Enable"
+#define SUNI_REGO_RPOPIEN 0x33
+#define SUNI_REGM_RPOPIEN_PSLE 0x80
+#define SUNI_REGM_RPOPIEN_LOPE 0x20
+#define SUNI_REGM_RPOPIEN_PAISE 0x08
+#define SUNI_REGM_RPOPIEN_PRDIE 0x04
+#define SUNI_REGM_RPOPIEN_BIPEE 0x02
+#define SUNI_REGM_RPOPIEN_FEBEE 0x01
+#define SUNI_REGM_RPOPIEN_RESERVED 0x00
+#define SUNI_REGX_RPOPIEN "\02010PSLE\6LOPE\4PAISE\3PRDIE\2BIPEE\1FEBEE"
+
+/* 622 */
+#define SUNI_REGN_RPOPPIE "RPOP Pointer Interrupt Enable"
+#define SUNI_REGO_RPOPPIE 0x34
+#define SUNI_REGM_RPOPPIE_ILLJREQE 0x80
+#define SUNI_REGM_RPOPPIE_DISCOPAE 0x20
+#define SUNI_REGM_RPOPPIE_INVNDFE 0x10
+#define SUNI_REGM_RPOPPIE_ILLPTRE 0x08
+#define SUNI_REGM_RPOPPIE_NSEE 0x04
+#define SUNI_REGM_RPOPPIE_PSEE 0x02
+#define SUNI_REGM_RPOPPIE_NDFE 0x01
+#define SUNI_REGX_RPOPPIE "\020\10ILLJREQE\6DISCOPAE\5INVNDFE\4ILLPTRE\3NSEE\2PSEE\1NDFE"
+
+/* 622 */
+#define SUNI_REGN_RPOPPTR "RPOP Pointer"
+#define SUNI_REGO_RPOPPTR 0x35 /* +36 */
+#define SUNI_REGM_RPOPPTR_RDI10 0x20
+#define SUNI_REGM_RPOPPTR_S 0x0c
+#define SUNI_REGS_RPOPPTR_S 2
+#define SUNI_REGM_RPOPPTR 0x03
+#define SUNI_REGS_RPOPPTR 0
+#define SUNI_REGX_RPOPPTR "\020\6RDI10\12\xc\20S"
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_RPOPPSL "RPOP Path Signal Label"
+#define SUNI_REGO_RPOPPSL 0x37
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_RPOPBIP8 "RPOP Path BIP-8"
+#define SUNI_REGO_RPOPBIP8 0x38 /* +39 */
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_RPOPFEBE "RPOP Path FEBE"
+#define SUNI_REGO_RPOPFEBE 0x3A /* +3B */
+
+/* 622 */
+#define SUNI_REGN_RPOPRDI "RPOP RDI"
+#define SUNI_REGO_RPOPRDI 0x3C
+#define SUNI_REGM_RPOPRDI_BLKFEBE 0x10
+#define SUNI_REGM_RPOPRDI_ARDIE 0x02
+#define SUNI_REGM_RPOPRDI_ARDIV 0x01
+#define SUNI_REGM_RPOPRDI_RESERVED 0x00
+#define SUNI_REGX_RPOPRDI "\020\5BLKFEBE\2ARDIE\1ARDIV"
+
+/* lite, ultra */
+#define SUNI_REGN_RPOPBIP8CFG "RPOP Path BIP-8 Configuration"
+#define SUNI_REGO_RPOPBIP8CFG 0x3D
+#define SUNI_REGM_RPOPBIP8CFG_BLKBIP 0x20
+#define SUNI_REGM_RPOPBIP8CFG_RESERVED 0x00
+#define SUNI_REGX_RPOPBIP8CFG "\020\6BLKBIP"
+
+/* 622 */
+#define SUNI_REGN_RPOPRING "RPOP Ring Control"
+#define SUNI_REGO_RPOPRING 0x3D
+#define SUNI_REGM_RPOPRING_SOS 0x80
+#define SUNI_REGM_RPOPRING_ENSS 0x40
+#define SUNI_REGM_RPOPRING_BLKBIP 0x20
+#define SUNI_REGM_RPOPRING_DISFS 0x10
+#define SUNI_REGM_RPOPRING_BLKBIPO 0x08
+#define SUNI_REGM_RPOPRING_RESERVED 0x00
+#define SUNI_REGX_RPOPRING "\020\10SOS\7ENSS\6BLKBIP\5DISFS\4BLKBIPO"
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_TPOPCTRL "TPOP Control/Diagnostic"
+#define SUNI_REGO_TPOPCTRL 0x40
+#define SUNI_REGM_TPOPCTRL_EXCFS 0x80 /* 622 */
+#define SUNI_REGM_TPOPCTRL_DB3 0x02
+#define SUNI_REGM_TPOPCTRL_PAIS 0x01
+#define SUNI_REGM_TPOPCTRL_RESERVED 0x00
+#define SUNI_REGX_TPOPCTRL "\020\2DB3\1PAIS"
+#define SUNI_REGX_TPOPCTRL_622 "\020\4EXCFS\2DB3\1PAIS"
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_TPOPPTRC "TPOP Pointer Control"
+#define SUNI_REGO_TPOPPTRC 0x41
+#define SUNI_REGM_TPOPPTRC_FTPTR 0x40
+#define SUNI_REGM_TPOPPTRC_SOS 0x20
+#define SUNI_REGM_TPOPPTRC_PLD 0x10
+#define SUNI_REGM_TPOPPTRC_NDF 0x08
+#define SUNI_REGM_TPOPPTRC_NSE 0x04
+#define SUNI_REGM_TPOPPTRC_PSE 0x02
+#define SUNI_REGM_TPOPPTRC_RESERVED 0x00
+#define SUNI_REGX_TPOPPTRC "\020\7FTPTR\6SOS\5PLD\4NDF\3NSE\2PSE"
+
+/* 622 */
+#define SUNI_REGN_TPOPCP "TPOP Current Pointer"
+#define SUNI_REGO_TPOPCP 0x43 /* +44 */
+#define SUNI_REGM_TPOPCP 0x03
+#define SUNI_REGS_TPOPCP 0
+#define SUNI_REGX_TPOPCP "\020"
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_TPOPAPTR "TPOP Arbitrary Pointer"
+#define SUNI_REGO_TPOPAPTR 0x45 /* +46 */
+#define SUNI_REGM_TPOPAPTR_NDF 0xF0
+#define SUNI_REGS_TPOPAPTR_NDF 4
+#define SUNI_REGM_TPOPAPTR_S 0x0C
+#define SUNI_REGS_TPOPAPTR_S 2
+#define SUNI_REGM_TPOPAPTR 0x03
+#define SUNI_REGS_TPOPAPTR 0
+#define SUNI_REGX_TPOPAPTR "\020\12\x0C\12S\12\xF0\12NDF"
+
+#define SUNI_REGM_SONET 0
+#define SUNI_REGM_SDH 2
+
+/* 622 */
+#define SUNI_REGN_TPOPPT "TPOP Path Trace"
+#define SUNI_REGO_TPOPPT 0x47
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_TPOPPSL "TPOP Path Signal Label"
+#define SUNI_REGO_TPOPPSL 0x48
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_TPOPSTATUS "TPOP Path Status"
+#define SUNI_REGO_TPOPSTATUS 0x49
+#define SUNI_REGM_TPOPSTATUS_FEBE 0xF0
+#define SUNI_REGS_TPOPSTATUS_FEBE 4
+#define SUNI_REGM_TPOPSTATUS_PRDI 0x08
+#define SUNI_REGM_TPOPSTATUS_G1 0x07
+#define SUNI_REGS_TPOPSTATUS_G1 0
+#define SUNI_REGX_TPOPSTATUS "\020\12\xF0\12FEBE\4PRDI\12\x7\12G"
+
+/* 622 */
+#define SUNI_REGN_TPOPPUC "TPOP Path User Channel"
+#define SUNI_REGO_TPOPPUC 0x4A
+
+/* 622 */
+#define SUNI_REGN_TPOPPG1 "TPOP Path Grow #1"
+#define SUNI_REGO_TPOPPG1 0x4B
+
+/* 622 */
+#define SUNI_REGN_TPOPPG2 "TPOP Path Grow #2"
+#define SUNI_REGO_TPOPPG2 0x4C
+
+/* 622 */
+#define SUNI_REGN_TPOPPG3 "TPOP Path Grow #3"
+#define SUNI_REGO_TPOPPG3 0x4D
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_RACPCTRL "RACP Control/Status"
+#define SUNI_REGO_RACPCTRL 0x50
+#define SUNI_REGM_RACPCTRL_OOCDV 0x80
+#define SUNI_REGM_RACPCTRL_FSEN 0x80
+#define SUNI_REGM_RACPCTRL_RXPTYP 0x40
+#define SUNI_REGM_RACPCTRL_PASS 0x20
+#define SUNI_REGM_RACPCTRL_DISCOR 0x10
+#define SUNI_REGM_RACPCTRL_HCSPASS 0x08
+#define SUNI_REGM_RACPCTRL_HCSADD 0x04
+#define SUNI_REGM_RACPCTRL_DDSCR 0x02
+#define SUNI_REGM_RACPCTRL_FIFORST 0x01
+#define SUNI_REGX_RACPCTRL "\020\10OOCDV\7RXPTYP\6PASS\5DISCO\4HCSPASS\3HCSADD\2DDSCR\1FIFORST"
+#define SUNI_REGX_RACPCTRL_622 "\020\10FSEN\7RXPTYP\6PASS\5DISCO\4HCSPASS\3HCSADD\2DDSCR\1FIFORST"
+
+/* lite, ultra */
+#define SUNI_REGN_RACPINTR "RACP Interrupt Enable/Status"
+#define SUNI_REGO_RACPINTR 0x51
+#define SUNI_REGM_RACPINTR_OOCDE 0x80
+#define SUNI_REGM_RACPINTR_HCSE 0x40
+#define SUNI_REGM_RACPINTR_FIFOE 0x20
+#define SUNI_REGM_RACPINTR_OOCDI 0x10
+#define SUNI_REGM_RACPINTR_CHCSI 0x08
+#define SUNI_REGM_RACPINTR_UHCSI 0x04
+#define SUNI_REGM_RACPINTR_FOVRI 0x02
+#define SUNI_REGX_RACPINTR "\020\10OOCDE\7HCSE\6FIFOE\5OOCDI\4CHCSI\3UHCSI\2FOVRI"
+
+/* 622 */
+#define SUNI_REGN_RACPIS "RACP Interrupt Status"
+#define SUNI_REGO_RACPIS 0x51
+#define SUNI_REGM_RACPIS_OCDV 0x80
+#define SUNI_REGM_RACPIS_LCDV 0x40
+#define SUNI_REGM_RACPIS_OCDI 0x20
+#define SUNI_REGM_RACPIS_LCDI 0x10
+#define SUNI_REGM_RACPIS_CHCSI 0x08
+#define SUNI_REGM_RACPIS_UHCSI 0x04
+#define SUNI_REGM_RACPIS_FOVRI 0x02
+#define SUNI_REGM_RACPIS_FUDRI 0x01
+#define SUNI_REGX_RACPIS "\020\10OCDV\7LCDV\6OCDI\5LCDI\4CHCSI\3UHCSI\2FOVRI\1FUDRI"
+
+/* lite, ultra */
+#define SUNI_REGN_RACPPATTERN "RACP Match Header Pattern"
+#define SUNI_REGO_RACPPATTERN 0x52
+#define SUNI_REGM_RACPPATTERN_GFC 0xF0
+#define SUNI_REGS_RACPPATTERN_GFC 4
+#define SUNI_REGM_RACPPATTERN_PTI 0x0E
+#define SUNI_REGS_RACPPATTERN_PTI 1
+#define SUNI_REGM_RACPPATTERN_CLP 0x01
+#define SUNI_REGS_RACPPATTERN_CLP 0
+#define SUNI_REGX_RACPPATTERN "\020\12\xF0\12GFC\12\x0E\12PTI\1CLP"
+
+/* 622 */
+#define SUNI_REGN_RACPIEC "RACP Interrupt Enable/Control"
+#define SUNI_REGO_RACPIEC 0x52
+#define SUNI_REGM_RACPIEC_OCDE 0x80
+#define SUNI_REGM_RACPIEC_LCDE 0x40
+#define SUNI_REGM_RACPIEC_HCSE 0x20
+#define SUNI_REGM_RACPIEC_FIFOE 0x10
+#define SUNI_REGM_RACPIEC_LCDDROP 0x08
+#define SUNI_REGM_RACPIEC_RCALEVEL0 0x04
+#define SUNI_REGM_RACPIEC_HCSFTR 0x03
+#define SUNI_REGX_RACPIEC "\020\10OCDE\7LCDE\6HCSE\5FIFOE\4LCDDROP\3RCALEVEL0\12\0x3\12HCSFTR"
+
+/* lite, ultra */
+#define SUNI_REGN_RACPMASK "RACP Match Header Mask"
+#define SUNI_REGO_RACPMASK 0x53
+#define SUNI_REGM_RACPMASK_MGFC 0xF0
+#define SUNI_REGS_RACPMASK_MGFC 4
+#define SUNI_REGM_RACPMASK_MPTI 0x0E
+#define SUNI_REGS_RACPMASK_MPTI 1
+#define SUNI_REGM_RACPMASK_MCLP 0x01
+#define SUNI_REGS_RACPMASK_MCLP 0
+#define SUNI_REGX_RACPMASK "\020\12\xF0\12MGFC\12\x0E\12MPTI\1MCLP"
+
+/* 622 */
+#define SUNI_REGO_RACPPATTERN_622 0x53
+
+/* lite, ultra */
+#define SUNI_REGN_RACPCHCS "RACP Correctable HCS Error Count"
+#define SUNI_REGO_RACPCHCS 0x54
+
+/* 622 */
+#define SUNI_REGO_RACPMASK_622 0x54
+
+/* lite, ultra */
+#define SUNI_REGN_RACPUHCS "RACP Uncorrectable HCS Error Count"
+#define SUNI_REGO_RACPUHCS 0x55
+
+/* 622 */
+#define SUNI_REGO_RACPCHCS_622 0x55 /* +56 */
+#define SUNI_REGM_RACPCHCS_622 0x0f
+
+/* lite, ultra */
+#define SUNI_REGN_RACPCNT "RACP Receive Cell Counter"
+#define SUNI_REGO_RACPCNT 0x56 /* +57,58 */
+#define SUNI_REGM_RACPCNT 0x07
+
+/* 622 */
+#define SUNI_REGO_RACPUHCS_622 0x57 /* +58 */
+#define SUNI_REGM_RACPUHCS_622 0x0f
+
+/* 622 */
+#define SUNI_REGO_RACPCNT_622 0x59 /* +5A,5B */
+#define SUNI_REGM_RACPCNT_622 0x1F
+
+/* lite, ultra */
+#define SUNI_REGN_RACPCFG "RACP Configuration"
+#define SUNI_REGO_RACPCFG 0x59
+#define SUNI_REGM_RACPCFG_RGFCE 0xF0
+#define SUNI_REGS_RACPCFG_RGFCE 4
+#define SUNI_REGM_RACPCFG_FSEN 0x08
+#define SUNI_REGM_RACPCFG_LEVEL0 0x04
+#define SUNI_REGM_RACPCFG_HCSFTR 0x03
+#define SUNI_REGS_RACPCFG_HCSFTR 0
+#define SUNI_REGX_RACPCFG "\020\12\xF0\20RGFCE\4FSEN\3RCALEVEL0\12\x03\12HCSFTR"
+
+/* 622 */
+#define SUNI_REGN_RACPGFC "RACP GFC Control/Misc. Control"
+#define SUNI_REGO_RACPGFC 0x5C
+#define SUNI_REGM_RACPGFC_CDDIS 0x80
+#define SUNI_REGM_RACPGFC_RXBYTEPRTY 0x40
+#define SUNI_REGM_RACPGFC_RGFCE 0x0f
+#define SUNI_REGX_RACPGFC "\020\10CDDIS\7RXBYTEPRTY\12\xf\20"
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_TACPCTRL "TACP Control/Status"
+#define SUNI_REGO_TACPCTRL 0x60
+#define SUNI_REGM_TACPCTRL_FIFOE 0x80
+#define SUNI_REGM_TACPCTRL_TSOCI 0x40
+#define SUNI_REGM_TACPCTRL_FOVRI 0x20
+#define SUNI_REGM_TACPCTRL_DHCS 0x10
+#define SUNI_REGM_TACPCTRL_HCSB 0x08 /* ultra, 622 */
+#define SUNI_REGM_TACPCTRL_HCSADD 0x04
+#define SUNI_REGM_TACPCTRL_DSCR 0x02
+#define SUNI_REGM_TACPCTRL_FIFORST 0x01
+#define SUNI_REGX_TACPCTRL_LITE "\020\10FIFOE\7TSOCI\6FOVRI\5DHCS\3HCSADD\2DSCR\1FIFORST"
+#define SUNI_REGX_TACPCTRL_ULTRA "\020\10FIFOE\7TSOCI\6FOVRI\5DHCS\4HCSB\3HCSADD\2DSCR\1FIFORST"
+#define SUNI_REGX_TACPCTRL_622 "\020\10FIFOE\7TSOCI\6FOVRI\5DHCS\4HCSB\3HCSADD\2DSCR\1FIFORST"
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_TACPIDLEH "TACP Idle/Unassigned Cell Header Pattern"
+#define SUNI_REGO_TACPIDLEH 0x61
+#define SUNI_REGM_TACPIDLEH_GFC 0xF0
+#define SUNI_REGS_TACPIDLEH_GFC 4
+#define SUNI_REGM_TACPIDLEH_PTI 0x0E
+#define SUNI_REGS_TACPIDLEH_PTI 1
+#define SUNI_REGM_TACPIDLEH_CLP 0x01
+#define SUNI_REGS_TACPIDLEH_CLP 0
+#define SUNI_REGX_TACPIDLEH "\020\12\xF0\20GFC\12\x0E\20PTI\12\x01\20CLP"
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_TACPIDLEP "TACP Idle/Unassigned Cell Payload Octet Pattern"
+#define SUNI_REGO_TACPIDLEP 0x62
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_TACPFIFOC "TACP FIFO Control"
+#define SUNI_REGO_TACPFIFOC 0x63
+#define SUNI_REGM_TACPFIFOC_TXPTYP 0x80
+#define SUNI_REGM_TACPFIFOC_TXPRTYE 0x40
+#define SUNI_REGM_TACPFIFOC_TXPRTYI 0x10
+#define SUNI_REGM_TACPFIFOC_TXPRTYI_622 0x30
+#define SUNI_REGS_TACPFIFOC_TXPRTYI_622 4
+#define SUNI_REGM_TACPFIFOC_FIFODP 0x0C
+#define SUNI_REGS_TACPFIFOC_FIFODP 2
+#define SUNI_REGM_TACPFIFOC_TCALEVEL0 0x02
+#define SUNI_REGM_TACPFIFOC_HCSCTLEB 0x01
+#define SUNI_REGM_TACPFIFOC_RESERVED 0x00
+#define SUNI_REGX_TACPFIFOC "\020\10TXPTYP\7TXPRTYE\5TXPRTYI\12\x0C\20FIFODP\2TCALEVEL0"
+#define SUNI_REGX_TACPFIFOC_622 "\020\10TXPTYP\7TXPRTYE\12\x30\12TXPRTYI\12\x0C\20FIFODP\2TCALEVEL0\1HCSCTLEB"
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_TACPCNT "TACP Transmit Cell Counter"
+#define SUNI_REGO_TACPCNT 0x64 /* +65,66 */
+#define SUNI_REGM_TACPCNT 0x07
+#define SUNI_REGM_TACPCNT_622 0x1F
+
+/* lite, ultra */
+#define SUNI_REGN_TACPCFG "TACP Configuration"
+#define SUNI_REGO_TACPCFG 0x67
+#define SUNI_REGM_TACPCFG_TGFCE 0xF0
+#define SUNI_REGS_TACPCFG_TGFCE 4
+#define SUNI_REGM_TACPCFG_FSEN 0x08
+#define SUNI_REGM_TACPCFG_H4INSB 0x04
+#define SUNI_REGM_TACPCFG_FIXBYTE 0x03
+#define SUNI_REGS_TACPCFG_FIXBYTE 0
+#define SUNI_REGX_TACPCFG "\020\12\xF0\20TGFCE\4FSEN\3H4INSB\12\x03\20FIXBYTE"
+
+/* 622 */
+#define SUNI_REGN_TACPGFC "TACP Fixed Stuff/GFC"
+#define SUNI_REGO_TACPGFC 0x67
+#define SUNI_REGO_TACPGFC_TGFCE 0xf0
+#define SUNI_REGS_TACPGFC_TGFCE 4
+#define SUNI_REGO_TACPGFC_FSEN 0x08
+#define SUNI_REGO_TACPGFC_TXBYTEPRTY 0x04
+#define SUNI_REGO_TACPGFC_FIXBYTE 0x03
+#define SUNI_REGS_TACPGFC_FIXBYTE 0
+#define SUNI_REGX_TACPGFC "\020\12\xf0\20TGFCE\4FSEN\3TXBYTEPRTY\12\x3\20FIXBYTE"
+
+/* 622 */
+#define SUNI_REGN_SPTBCTRL "SPTB Control"
+#define SUNI_REGO_SPTBCTRL 0x68
+#define SUNI_REGO_SPTBCTRL_RRAMACC 0x40
+#define SUNI_REGO_SPTBCTRL_RTIUIE 0x20
+#define SUNI_REGO_SPTBCTRL_RTIMIE 0x10
+#define SUNI_REGO_SPTBCTRL_PER5 0x08
+#define SUNI_REGO_SPTBCTRL_TNULL 0x04
+#define SUNI_REGO_SPTBCTRL_NOSYNC 0x02
+#define SUNI_REGO_SPTBCTRL_LEN16 0x01
+#define SUNI_REGX_SPTBCTRL "\020\7RRAMACC\6RTIUIE\5RTIMIE\4PER5\3TNULL\2NOSYNC\1LEN16"
+
+/* 622 */
+#define SUNI_REGN_SPTBPTIS "SPTB Path Trace Identifier Status"
+#define SUNI_REGO_SPTBPTIS 0x69
+#define SUNI_REGM_SPTBPTIS_BUSY 0x80
+#define SUNI_REGM_SPTBPTIS_RTIUI 0x08
+#define SUNI_REGM_SPTBPTIS_RTIUV 0x04
+#define SUNI_REGM_SPTBPTIS_RTIMI 0x02
+#define SUNI_REGM_SPTBPTIS_RTIMV 0x01
+#define SUNI_REGX_SPTBPTIS "\020\10BUSY\4RTIUI\3RTIUV\2RTIMI\1RTIMV"
+
+/* 622 */
+#define SUNI_REGN_SPTBIAR "SPTB Indirect Address Register"
+#define SUNI_REGO_SPTBIAR 0x6A
+#define SUNI_REGM_SPTBIAR_RWB 0x80
+#define SUNI_REGM_SPTBIAR_A 0x7f
+#define SUNI_REGX_SPTBIAR "\020\10RWB\12\x7f\20A"
+
+/* 622 */
+#define SUNI_REGN_SPTBIDR "SPTB Indirect Data Register"
+#define SUNI_REGO_SPTBIDR 0x6B
+
+/* 622 */
+#define SUNI_REGN_SPTBEPSL "SPTB Expected Path Signal Label"
+#define SUNI_REGO_SPTBEPSL 0x6C
+
+/* 622 */
+#define SUNI_REGN_SPTBPSLS "SPTB Path Signal Label Status"
+#define SUNI_REGO_SPTBPSLS 0x6D
+#define SUNI_REGM_SPTBPSLS_RPSLUIE 0x80
+#define SUNI_REGM_SPTBPSLS_RPSLMIE 0x40
+#define SUNI_REGM_SPTBPSLS_RPSLUI 0x08
+#define SUNI_REGM_SPTBPSLS_RPSLUV 0x04
+#define SUNI_REGM_SPTBPSLS_RPSLMI 0x02
+#define SUNI_REGM_SPTBPSLS_RPSLMV 0x01
+#define SUNI_REGX_SPTBPSLS "\020\10RPSLUIE\7RPSLMIE\4RPSLUI\3RPSLUV\2RPSLMI\1RPSLMV"
+
+/* ultra */
+#define SUNI_REGN_POPCCTRL "POPC Control"
+#define SUNI_REGO_POPCCTRL 0x68
+#define SUNI_REGM_POPCCTRL_PDAT 0xC0
+#define SUNI_REGS_POPCCTRL_PDAT 6
+#define SUNI_REGM_POPCCTRL_TOGGLE 0x30
+#define SUNI_REGS_POPCCTRL_TOGGLE 4
+#define SUNI_REGM_POPCCTRL_TRAFFIC 0x02
+#define SUNI_REGM_POPCCTRL_ALARM 0x01
+#define SUNI_REGX_POPCCTRL "\020\12\xC0\20PDAT\12\x30\20TOGGLE\2TRAFFIC\1ALARM"
+
+/* ultra */
+#define SUNI_REGN_POPCSTROBE0 "POPC Strobe Rate 0"
+#define SUNI_REGO_POPCSTROBE0 0x69
+
+/* ultra */
+#define SUNI_REGN_POPCSTROBE1 "POPC Strobe Rate 1"
+#define SUNI_REGO_POPCSTROBE1 0x6A
+
+/* 622 */
+#define SUNI_REGN_BERMCTRL "BERM Control"
+#define SUNI_REGO_BERMCTRL 0x70
+#define SUNI_REGM_BERMCTRL_BERTEN 0x80
+#define SUNI_REGM_BERMCTRL_BERIE 0x01
+#define SUNI_REGX_BERMCTRL "\020\10BERTEN\1BERIE"
+
+/* 622 */
+#define SUNI_REGN_BERMINT "BERM Interrupt"
+#define SUNI_REGO_BERMINT 0x71
+#define SUNI_REGM_BERMINT_TST 0xf0
+#define SUNI_REGS_BERMINT_TST 4
+#define SUNI_REGM_BERMINT_BERI 0x01
+#define SUNI_REGX_BERMINT "\020\12\xf0\20BERM_TST\1BERI"
+
+/* 622 */
+#define SUNI_REGN_BERMLAP "BERM Line BIP Accumulation Period"
+#define SUNI_REGO_BERMLAP 0x72 /* +73 */
+
+/* 622 */
+#define SUNI_REGN_BERMLT "BERM Line BIP Threshold"
+#define SUNI_REGO_BERMLT 0x74 /* +75 */
+
+/* lite, ultra, 622 */
+#define SUNI_REGN_MTEST "Master Test"
+#define SUNI_REGO_MTEST 0x80
+#define SUNI_REGM_MTEST_DS27_53_622 0x80
+#define SUNI_REGM_MTEST_BYPASS_ULTRA 0x40
+#define SUNI_REGM_MTEST_PMCATST_ULTRA 0x20
+#define SUNI_REGM_MTEST_PMCTST 0x10
+#define SUNI_REGM_MTEST_DBCTRL 0x08
+#define SUNI_REGM_MTEST_IOTST 0x04
+#define SUNI_REGM_MTEST_HIZDATA 0x02
+#define SUNI_REGM_MTEST_HIZIO 0x01
+#define SUNI_REGX_MTEST_LITE "\020\5PMCTST\4DBCTRL\3IOTST\2HIZDATA\1HIZIO"
+#define SUNI_REGX_MTEST_ULTRA "\020\7BYPASS\6PMCATST\5PMCTST\4DBCTRL\3IOTST\2HIZDATA\1HIZIO"
+#define SUNI_REGX_MTEST_622 "\020\10DS27_53\5PMCTST\4DBCTRL\3IOTST\2HIZDATA\1HIZIO"
+
+/*
+ * Printing support
+ */
+#define SUNI_PRINT_LITE \
+ { /* 00 */ \
+ UTP_REGT_BITS, SUNI_REGO_MRESET, \
+ SUNI_REGN_MRESET, SUNI_REGX_MRESET_LITE }, \
+ { /* 01 */ \
+ UTP_REGT_BITS, SUNI_REGO_MCONFIG, \
+ SUNI_REGN_MCONFIG, SUNI_REGX_MCONFIG_LITE }, \
+ { /* 02 */ \
+ UTP_REGT_BITS, SUNI_REGO_MISTATUS, \
+ SUNI_REGN_MISTATUS, SUNI_REGX_MISTATUS_LITE }, \
+ /* 03 unused */ \
+ { /* 04 */ \
+ UTP_REGT_BITS, SUNI_REGO_MCLKM, \
+ SUNI_REGN_MCLKM, SUNI_REGX_MCLKM_LITE }, \
+ { /* 05 */ \
+ UTP_REGT_BITS, SUNI_REGO_MCTRL, \
+ SUNI_REGN_MCTRL, SUNI_REGX_MCTRL_LITE }, \
+ { /* 06 */ \
+ UTP_REGT_BITS, SUNI_REGO_CLKSYN, \
+ SUNI_REGN_CLKSYN, SUNI_REGX_CLKSYN_LITE }, \
+ { /* 07 */ \
+ UTP_REGT_BITS, SUNI_REGO_CLKREC_LITE, \
+ SUNI_REGN_CLKREC, SUNI_REGX_CLKREC_LITE }, \
+ /* 08-0F unused */ \
+ { /* 10 */ \
+ UTP_REGT_BITS, SUNI_REGO_RSOPCIE, \
+ SUNI_REGN_RSOPCIE, SUNI_REGX_RSOPCIE }, \
+ { /* 11 */ \
+ UTP_REGT_BITS, SUNI_REGO_RSOPSIS, \
+ SUNI_REGN_RSOPSIS, SUNI_REGX_RSOPSIS }, \
+ { /* 12, 13 */ \
+ UTP_REGT_INT16, SUNI_REGO_RSOP_BIP8, \
+ SUNI_REGN_RSOP_BIP8, NULL }, \
+ { /* 14 */ \
+ UTP_REGT_BITS, SUNI_REGO_TSOPCTRL, \
+ SUNI_REGN_TSOPCTRL, SUNI_REGX_TSOPCTRL }, \
+ { /* 15 */ \
+ UTP_REGT_BITS, SUNI_REGO_TSOPDIAG, \
+ SUNI_REGN_TSOPDIAG, SUNI_REGX_TSOPDIAG }, \
+ /* 16-17 unused */ \
+ { /* 18 */ \
+ UTP_REGT_BITS, SUNI_REGO_RLOPCTRL, \
+ SUNI_REGN_RLOPCTRL, SUNI_REGX_RLOPCTRL }, \
+ { /* 19 */ \
+ UTP_REGT_BITS, SUNI_REGO_RLOPINTR, \
+ SUNI_REGN_RLOPINTR, SUNI_REGX_RLOPINTR }, \
+ { /* 1A, 1B, 1C */ \
+ UTP_REGT_INT20, SUNI_REGO_RLOPBIP8_24, \
+ SUNI_REGN_RLOPBIP8_24, NULL }, \
+ { /* 1D, 1E, 1F */ \
+ UTP_REGT_INT20, SUNI_REGO_RLOPFEBE, \
+ SUNI_REGN_RLOPFEBE, NULL }, \
+ { /* 20 */ \
+ UTP_REGT_BITS, SUNI_REGO_TLOPCTRL, \
+ SUNI_REGN_TLOPCTRL, SUNI_REGX_TLOPCTRL }, \
+ { /* 21 */ \
+ UTP_REGT_BITS, SUNI_REGO_TLOPDIAG, \
+ SUNI_REGN_TLOPDIAG, SUNI_REGX_TLOPDIAG }, \
+ /* 22-2F unused */ \
+ { /* 30 */ \
+ UTP_REGT_BITS, SUNI_REGO_RPOPCTRL, \
+ SUNI_REGN_RPOPCTRL, SUNI_REGX_RPOPCTRL }, \
+ { /* 31 */ \
+ UTP_REGT_BITS, SUNI_REGO_RPOPISTAT, \
+ SUNI_REGN_RPOPISTAT, SUNI_REGX_RPOPISTAT }, \
+ /* 32 unused */ \
+ { /* 33 */ \
+ UTP_REGT_BITS, SUNI_REGO_RPOPIEN, \
+ SUNI_REGN_RPOPIEN, SUNI_REGX_RPOPIEN }, \
+ /* 34-36 unused */ \
+ { /* 37 */ \
+ UTP_REGT_INT8, SUNI_REGO_RPOPPSL, \
+ SUNI_REGN_RPOPPSL, NULL }, \
+ { /* 38, 39 */ \
+ UTP_REGT_INT16, SUNI_REGO_RPOPBIP8, \
+ SUNI_REGN_RPOPBIP8, NULL }, \
+ { /* 3A, 3B */ \
+ UTP_REGT_INT16, SUNI_REGO_RPOPFEBE, \
+ SUNI_REGN_RPOPFEBE, NULL }, \
+ /* 3C unused */ \
+ { /* 3D */ \
+ UTP_REGT_BITS, SUNI_REGO_RPOPBIP8CFG, \
+ SUNI_REGN_RPOPBIP8CFG, SUNI_REGX_RPOPBIP8CFG }, \
+ /* 3E-3F unused */ \
+ { /* 40 */ \
+ UTP_REGT_BITS, SUNI_REGO_TPOPCTRL, \
+ SUNI_REGN_TPOPCTRL, SUNI_REGX_TPOPCTRL }, \
+ { /* 41 */ \
+ UTP_REGT_BITS, SUNI_REGO_TPOPPTRC, \
+ SUNI_REGN_TPOPPTRC, SUNI_REGX_TPOPPTRC }, \
+ /* 42-44 unused */ \
+ { /* 45, 46 */ \
+ UTP_REGT_INT10BITS, SUNI_REGO_TPOPAPTR, \
+ SUNI_REGN_TPOPAPTR, SUNI_REGX_TPOPAPTR }, \
+ /* 47 unused */ \
+ { /* 48 */ \
+ UTP_REGT_INT8, SUNI_REGO_TPOPPSL, \
+ SUNI_REGN_TPOPPSL, NULL }, \
+ { /* 49 */ \
+ UTP_REGT_BITS, SUNI_REGO_TPOPSTATUS, \
+ SUNI_REGN_TPOPSTATUS, SUNI_REGX_TPOPSTATUS }, \
+ /* 4A-4F unused */ \
+ { /* 50 */ \
+ UTP_REGT_BITS, SUNI_REGO_RACPCTRL, \
+ SUNI_REGN_RACPCTRL, SUNI_REGX_RACPCTRL }, \
+ { /* 51 */ \
+ UTP_REGT_BITS, SUNI_REGO_RACPINTR, \
+ SUNI_REGN_RACPINTR, SUNI_REGX_RACPINTR }, \
+ { /* 52 */ \
+ UTP_REGT_BITS, SUNI_REGO_RACPPATTERN, \
+ SUNI_REGN_RACPPATTERN, SUNI_REGX_RACPPATTERN }, \
+ { /* 53 */ \
+ UTP_REGT_BITS, SUNI_REGO_RACPMASK, \
+ SUNI_REGN_RACPMASK, SUNI_REGX_RACPMASK }, \
+ { /* 54 */ \
+ UTP_REGT_INT8, SUNI_REGO_RACPCHCS, \
+ SUNI_REGN_RACPCHCS, NULL }, \
+ { /* 55 */ \
+ UTP_REGT_INT8, SUNI_REGO_RACPUHCS, \
+ SUNI_REGN_RACPUHCS, NULL }, \
+ { /* 56, 57, 58 */ \
+ UTP_REGT_INT19, SUNI_REGO_RACPCNT, \
+ SUNI_REGN_RACPCNT, NULL }, \
+ { /* 59 */ \
+ UTP_REGT_BITS, SUNI_REGO_RACPCFG, \
+ SUNI_REGN_RACPCFG, SUNI_REGX_RACPCFG }, \
+ /* 5A-5F unused */ \
+ { /* 60 */ \
+ UTP_REGT_BITS, SUNI_REGO_TACPCTRL, \
+ SUNI_REGN_TACPCTRL, SUNI_REGX_TACPCTRL_LITE }, \
+ { /* 61 */ \
+ UTP_REGT_BITS, SUNI_REGO_TACPIDLEH, \
+ SUNI_REGN_TACPIDLEH, SUNI_REGX_TACPIDLEH }, \
+ { /* 62 */ \
+ UTP_REGT_INT8, SUNI_REGO_TACPIDLEP, \
+ SUNI_REGN_TACPIDLEP, NULL }, \
+ { /* 63 */ \
+ UTP_REGT_BITS, SUNI_REGO_TACPFIFOC, \
+ SUNI_REGN_TACPFIFOC, SUNI_REGX_TACPFIFOC }, \
+ { /* 64, 65, 66 */ \
+ UTP_REGT_INT19, SUNI_REGO_TACPCNT, \
+ SUNI_REGN_TACPCNT, NULL }, \
+ { /* 67 */ \
+ UTP_REGT_BITS, SUNI_REGO_TACPGFC, \
+ SUNI_REGN_TACPGFC, SUNI_REGX_TACPGFC }, \
+ /* 68-7f unused */ \
+ { /* 80 */ \
+ UTP_REGT_BITS, SUNI_REGO_MTEST, \
+ SUNI_REGN_MTEST, SUNI_REGX_MTEST_LITE }
+
+#define SUNI_PRINT_ULTRA \
+ { /* 00 */ \
+ UTP_REGT_BITS, SUNI_REGO_MRESET, \
+ SUNI_REGN_MRESET, SUNI_REGX_MRESET_ULTRA }, \
+ { /* 01 */ \
+ UTP_REGT_BITS, SUNI_REGO_MCONFIG, \
+ SUNI_REGN_MCONFIG, SUNI_REGX_MCONFIG_ULTRA }, \
+ { /* 02 */ \
+ UTP_REGT_BITS, SUNI_REGO_MISTATUS, \
+ SUNI_REGN_MISTATUS, SUNI_REGX_MISTATUS_ULTRA }, \
+ { /* 03 */ \
+ UTP_REGT_BITS, SUNI_REGO_MMCTRL, \
+ SUNI_REGN_MMCTRL, SUNI_REGX_MMCTRL }, \
+ { /* 04 */ \
+ UTP_REGT_BITS, SUNI_REGO_MCLKM, \
+ SUNI_REGN_MCLKM, SUNI_REGX_MCLKM_ULTRA }, \
+ { /* 05 */ \
+ UTP_REGT_BITS, SUNI_REGO_MCTRL, \
+ SUNI_REGN_MCTRL, SUNI_REGX_MCTRL_ULTRA }, \
+ { /* 06 */ \
+ UTP_REGT_BITS, SUNI_REGO_CLKSYN, \
+ SUNI_REGN_CLKSYN, SUNI_REGX_CLKSYN_ULTRA }, \
+ /* 07 unused */ \
+ { /* 08 */ \
+ UTP_REGT_BITS, SUNI_REGO_CLKREC_ULTRA, \
+ SUNI_REGN_CLKREC, SUNI_REGX_CLKREC_ULTRA }, \
+ { /* 09 */ \
+ UTP_REGT_BITS, SUNI_REGO_CLKRECCFG, \
+ SUNI_REGN_CLKRECCFG, SUNI_REGX_CLKRECCFG }, \
+ { /* 0A */ \
+ UTP_REGT_BITS, SUNI_REGO_LTXCFG1, \
+ SUNI_REGN_LTXCFG1, SUNI_REGX_LTXCFG1 }, \
+ { /* 0B */ \
+ UTP_REGT_BITS, SUNI_REGO_LTXCFG2, \
+ SUNI_REGN_LTXCFG2, SUNI_REGX_LTXCFG2 }, \
+ { /* 0C */ \
+ UTP_REGT_BITS, SUNI_REGO_LRXCFG, \
+ SUNI_REGN_LRXCFG, SUNI_REGX_LRXCFG }, \
+ /* 0D-0F unused */ \
+ { /* 10 */ \
+ UTP_REGT_BITS, SUNI_REGO_RSOPCIE, \
+ SUNI_REGN_RSOPCIE, SUNI_REGX_RSOPCIE }, \
+ { /* 11 */ \
+ UTP_REGT_BITS, SUNI_REGO_RSOPSIS, \
+ SUNI_REGN_RSOPSIS, SUNI_REGX_RSOPSIS }, \
+ { /* 12, 13 */ \
+ UTP_REGT_INT16, SUNI_REGO_RSOP_BIP8, \
+ SUNI_REGN_RSOP_BIP8, NULL }, \
+ { /* 14 */ \
+ UTP_REGT_BITS, SUNI_REGO_TSOPCTRL, \
+ SUNI_REGN_TSOPCTRL, SUNI_REGX_TSOPCTRL }, \
+ { /* 15 */ \
+ UTP_REGT_BITS, SUNI_REGO_TSOPDIAG, \
+ SUNI_REGN_TSOPDIAG, SUNI_REGX_TSOPDIAG }, \
+ /* 16-17 unused */ \
+ { /* 18 */ \
+ UTP_REGT_BITS, SUNI_REGO_RLOPCTRL, \
+ SUNI_REGN_RLOPCTRL, SUNI_REGX_RLOPCTRL }, \
+ { /* 19 */ \
+ UTP_REGT_BITS, SUNI_REGO_RLOPINTR, \
+ SUNI_REGN_RLOPINTR, SUNI_REGX_RLOPINTR }, \
+ { /* 1A, 1B, 1C */ \
+ UTP_REGT_INT20, SUNI_REGO_RLOPBIP8_24, \
+ SUNI_REGN_RLOPBIP8_24, NULL }, \
+ { /* 1D, 1E, 1F */ \
+ UTP_REGT_INT20, SUNI_REGO_RLOPFEBE, \
+ SUNI_REGN_RLOPFEBE, NULL }, \
+ { /* 20 */ \
+ UTP_REGT_BITS, SUNI_REGO_TLOPCTRL, \
+ SUNI_REGN_TLOPCTRL, SUNI_REGX_TLOPCTRL }, \
+ { /* 21 */ \
+ UTP_REGT_BITS, SUNI_REGO_TLOPDIAG, \
+ SUNI_REGN_TLOPDIAG, SUNI_REGX_TLOPDIAG }, \
+ /* 22-2F unused */ \
+ { /* 30 */ \
+ UTP_REGT_BITS, SUNI_REGO_RPOPCTRL, \
+ SUNI_REGN_RPOPCTRL, SUNI_REGX_RPOPCTRL }, \
+ { /* 31 */ \
+ UTP_REGT_BITS, SUNI_REGO_RPOPISTAT, \
+ SUNI_REGN_RPOPISTAT, SUNI_REGX_RPOPISTAT }, \
+ /* 32 unused */ \
+ { /* 33 */ \
+ UTP_REGT_BITS, SUNI_REGO_RPOPIEN, \
+ SUNI_REGN_RPOPIEN, SUNI_REGX_RPOPIEN }, \
+ /* 34-36 unused */ \
+ { /* 37 */ \
+ UTP_REGT_INT8, SUNI_REGO_RPOPPSL, \
+ SUNI_REGN_RPOPPSL, NULL }, \
+ { /* 38, 39 */ \
+ UTP_REGT_INT16, SUNI_REGO_RPOPBIP8, \
+ SUNI_REGN_RPOPBIP8, NULL }, \
+ { /* 3A, 3B */ \
+ UTP_REGT_INT16, SUNI_REGO_RPOPFEBE, \
+ SUNI_REGN_RPOPFEBE, NULL }, \
+ /* 3C unused */ \
+ { /* 3D */ \
+ UTP_REGT_BITS, SUNI_REGO_RPOPBIP8CFG, \
+ SUNI_REGN_RPOPBIP8CFG, SUNI_REGX_RPOPBIP8CFG }, \
+ /* 3E-3F unused */ \
+ { /* 40 */ \
+ UTP_REGT_BITS, SUNI_REGO_TPOPCTRL, \
+ SUNI_REGN_TPOPCTRL, SUNI_REGX_TPOPCTRL }, \
+ { /* 41 */ \
+ UTP_REGT_BITS, SUNI_REGO_TPOPPTRC, \
+ SUNI_REGN_TPOPPTRC, SUNI_REGX_TPOPPTRC }, \
+ /* 42-44 unused */ \
+ { /* 45, 46 */ \
+ UTP_REGT_INT10BITS, SUNI_REGO_TPOPAPTR, \
+ SUNI_REGN_TPOPAPTR, SUNI_REGX_TPOPAPTR }, \
+ /* 47 unused */ \
+ { /* 48 */ \
+ UTP_REGT_INT8, SUNI_REGO_TPOPPSL, \
+ SUNI_REGN_TPOPPSL, NULL }, \
+ { /* 49 */ \
+ UTP_REGT_BITS, SUNI_REGO_TPOPSTATUS, \
+ SUNI_REGN_TPOPSTATUS, SUNI_REGX_TPOPSTATUS }, \
+ /* 4A-4F unused */ \
+ { /* 50 */ \
+ UTP_REGT_BITS, SUNI_REGO_RACPCTRL, \
+ SUNI_REGN_RACPCTRL, SUNI_REGX_RACPCTRL }, \
+ { /* 51 */ \
+ UTP_REGT_BITS, SUNI_REGO_RACPINTR, \
+ SUNI_REGN_RACPINTR, SUNI_REGX_RACPINTR }, \
+ { /* 52 */ \
+ UTP_REGT_BITS, SUNI_REGO_RACPPATTERN, \
+ SUNI_REGN_RACPPATTERN, SUNI_REGX_RACPPATTERN }, \
+ { /* 53 */ \
+ UTP_REGT_BITS, SUNI_REGO_RACPMASK, \
+ SUNI_REGN_RACPMASK, SUNI_REGX_RACPMASK }, \
+ { /* 54 */ \
+ UTP_REGT_INT8, SUNI_REGO_RACPCHCS, \
+ SUNI_REGN_RACPCHCS, NULL }, \
+ { /* 55 */ \
+ UTP_REGT_INT8, SUNI_REGO_RACPUHCS, \
+ SUNI_REGN_RACPUHCS, NULL }, \
+ { /* 56, 57, 58 */ \
+ UTP_REGT_INT19, SUNI_REGO_RACPCNT, \
+ SUNI_REGN_RACPCNT, NULL }, \
+ { /* 59 */ \
+ UTP_REGT_BITS, SUNI_REGO_RACPCFG, \
+ SUNI_REGN_RACPCFG, SUNI_REGX_RACPCFG }, \
+ /* 5A-5F unused */ \
+ { /* 60 */ \
+ UTP_REGT_BITS, SUNI_REGO_TACPCTRL, \
+ SUNI_REGN_TACPCTRL, SUNI_REGX_TACPCTRL_ULTRA }, \
+ { /* 61 */ \
+ UTP_REGT_BITS, SUNI_REGO_TACPIDLEH, \
+ SUNI_REGN_TACPIDLEH, SUNI_REGX_TACPIDLEH }, \
+ { /* 62 */ \
+ UTP_REGT_INT8, SUNI_REGO_TACPIDLEP, \
+ SUNI_REGN_TACPIDLEP, NULL }, \
+ { /* 63 */ \
+ UTP_REGT_BITS, SUNI_REGO_TACPFIFOC, \
+ SUNI_REGN_TACPFIFOC, SUNI_REGX_TACPFIFOC }, \
+ { /* 64, 65, 66 */ \
+ UTP_REGT_INT19, SUNI_REGO_TACPCNT, \
+ SUNI_REGN_TACPCNT, NULL }, \
+ { /* 67 */ \
+ UTP_REGT_BITS, SUNI_REGO_TACPGFC, \
+ SUNI_REGN_TACPGFC, SUNI_REGX_TACPGFC }, \
+ { /* 68 */ \
+ UTP_REGT_BITS, SUNI_REGO_POPCCTRL, \
+ SUNI_REGN_POPCCTRL, SUNI_REGX_POPCCTRL }, \
+ { /* 69 */ \
+ UTP_REGT_INT8, SUNI_REGO_POPCSTROBE0, \
+ SUNI_REGN_POPCSTROBE0, NULL }, \
+ { /* 6A */ \
+ UTP_REGT_INT8, SUNI_REGO_POPCSTROBE1, \
+ SUNI_REGN_POPCSTROBE1, NULL }, \
+ /* 6B-7f unused */ \
+ { /* 80 */ \
+ UTP_REGT_BITS, SUNI_REGO_MTEST, \
+ SUNI_REGN_MTEST, SUNI_REGX_MTEST_ULTRA }
+
+#define SUNI_PRINT_622 \
+ { /* 00 */ \
+ UTP_REGT_BITS, SUNI_REGO_MRESET, \
+ SUNI_REGN_MRESET, SUNI_REGX_MRESET_622 }, \
+ { /* 01 */ \
+ UTP_REGT_BITS, SUNI_REGO_MCONFIG, \
+ SUNI_REGN_MCONFIG, SUNI_REGX_MCONFIG_622 }, \
+ { /* 02 */ \
+ UTP_REGT_BITS, SUNI_REGO_MISTATUS, \
+ SUNI_REGN_MISTATUS, SUNI_REGX_MISTATUS_622 }, \
+ { /* 03 */ \
+ UTP_REGT_BITS, SUNI_REGO_PISO, \
+ SUNI_REGN_PISO, SUNI_REGX_PISO }, \
+ { /* 04 */ \
+ UTP_REGT_BITS, SUNI_REGO_MCTRLM, \
+ SUNI_REGN_MCTRLM, SUNI_REGX_MCTRLM }, \
+ { /* 05 */ \
+ UTP_REGT_BITS, SUNI_REGO_MALARM, \
+ SUNI_REGN_MALARM, SUNI_REGX_MALARM }, \
+ { /* 06 */ \
+ UTP_REGT_BITS, SUNI_REGO_POUT, \
+ SUNI_REGN_POUT, SUNI_REGX_POUT }, \
+ { /* 07 */ \
+ UTP_REGT_INT8, SUNI_REGO_PIN, \
+ SUNI_REGN_PIN, NULL }, \
+ { /* 08 */ \
+ UTP_REGT_BITS, SUNI_REGO_PINV, \
+ SUNI_REGN_PINV, SUNI_REGX_PINV }, \
+ { /* 09 */ \
+ UTP_REGT_INT8, SUNI_REGO_PINE, \
+ SUNI_REGN_PINE, NULL }, \
+ { /* 0A */ \
+ UTP_REGT_INT8, SUNI_REGO_XC1, \
+ SUNI_REGN_XC1, NULL }, \
+ { /* 0B */ \
+ UTP_REGT_BITS, SUNI_REGO_APSCS, \
+ SUNI_REGN_APSCS, SUNI_REGX_APSCS }, \
+ { /* 0C */ \
+ UTP_REGT_INT8, SUNI_REGO_RK1, \
+ SUNI_REGN_RK1, NULL }, \
+ { /* 0D */ \
+ UTP_REGT_INT8, SUNI_REGO_RK2, \
+ SUNI_REGN_RK2, NULL }, \
+ { /* 0E */ \
+ UTP_REGT_INT8, SUNI_REGO_RZ1, \
+ SUNI_REGN_RZ1, NULL }, \
+ { /* 0F */ \
+ UTP_REGT_INT8, SUNI_REGO_XZ1, \
+ SUNI_REGN_XZ1, NULL }, \
+ { /* 10 */ \
+ UTP_REGT_BITS, SUNI_REGO_RSOPCIE, \
+ SUNI_REGN_RSOPCIE, SUNI_REGX_RSOPCIE_622 }, \
+ { /* 11 */ \
+ UTP_REGT_BITS, SUNI_REGO_RSOPSIS, \
+ SUNI_REGN_RSOPSIS, SUNI_REGX_RSOPSIS }, \
+ { /* 12, 13 */ \
+ UTP_REGT_INT16, SUNI_REGO_RSOP_BIP8, \
+ SUNI_REGN_RSOP_BIP8, NULL }, \
+ { /* 14 */ \
+ UTP_REGT_BITS, SUNI_REGO_TSOPCTRL, \
+ SUNI_REGN_TSOPCTRL, SUNI_REGX_TSOPCTRL }, \
+ { /* 15 */ \
+ UTP_REGT_BITS, SUNI_REGO_TSOPDIAG, \
+ SUNI_REGN_TSOPDIAG, SUNI_REGX_TSOPDIAG }, \
+ /* 16-17 unused */ \
+ { /* 18 */ \
+ UTP_REGT_BITS, SUNI_REGO_RLOPCTRL, \
+ SUNI_REGN_RLOPCTRL, SUNI_REGX_RLOPCTRL_622 }, \
+ { /* 19 */ \
+ UTP_REGT_BITS, SUNI_REGO_RLOPINTR, \
+ SUNI_REGN_RLOPINTR, SUNI_REGX_RLOPINTR }, \
+ { /* 1A, 1B, 1C */ \
+ UTP_REGT_INT20, SUNI_REGO_RLOPBIP8_24_96, \
+ SUNI_REGN_RLOPBIP8_24_96, NULL }, \
+ { /* 1D, 1E, 1F */ \
+ UTP_REGT_INT20, SUNI_REGO_RLOPFEBE, \
+ SUNI_REGN_RLOPFEBE, NULL }, \
+ { /* 20 */ \
+ UTP_REGT_BITS, SUNI_REGO_TLOPCTRL, \
+ SUNI_REGN_TLOPCTRL, SUNI_REGX_TLOPCTRL_622 }, \
+ { /* 21 */ \
+ UTP_REGT_BITS, SUNI_REGO_TLOPDIAG, \
+ SUNI_REGN_TLOPDIAG, SUNI_REGX_TLOPDIAG }, \
+ { /* 22 */ \
+ UTP_REGT_INT8, SUNI_REGO_TLOP_XK1, \
+ SUNI_REGN_TLOP_XK1, NULL }, \
+ { /* 23 */ \
+ UTP_REGT_INT8, SUNI_REGO_TLOP_XK2, \
+ SUNI_REGN_TLOP_XK2, NULL }, \
+ /* 24-27 unused */ \
+ { /* 28 */ \
+ UTP_REGT_BITS, SUNI_REGO_SSTBCTRL, \
+ SUNI_REGN_SSTBCTRL, SUNI_REGX_SSTBCTRL }, \
+ { /* 29 */ \
+ UTP_REGT_BITS, SUNI_REGO_SSTBSTIS, \
+ SUNI_REGN_SSTBSTIS, SUNI_REGX_SSTBSTIS }, \
+ { /* 2A */ \
+ UTP_REGT_BITS, SUNI_REGO_SSTBIAR, \
+ SUNI_REGN_SSTBIAR, SUNI_REGX_SSTBIAR }, \
+ { /* 2B */ \
+ UTP_REGT_INT8, SUNI_REGO_SSTBIDR, \
+ SUNI_REGN_SSTBIDR, NULL }, \
+ /* 2C unused (see chip errata) */ \
+ { /* 2D */ \
+ UTP_REGT_BITS, SUNI_REGO_SSTBCSMS, \
+ SUNI_REGN_SSTBCSMS, SUNI_REGX_SSTBCSMS }, \
+ /* 2E-2F unused */ \
+ { /* 30 */ \
+ UTP_REGT_BITS, SUNI_REGO_RPOPCTRL, \
+ SUNI_REGN_RPOPCTRL, SUNI_REGX_RPOPCTRL_622 }, \
+ { /* 31 */ \
+ UTP_REGT_BITS, SUNI_REGO_RPOPISTAT, \
+ SUNI_REGN_RPOPISTAT, SUNI_REGX_RPOPISTAT }, \
+ { /* 32 */ \
+ UTP_REGT_BITS, SUNI_REGO_RPOPPIS, \
+ SUNI_REGN_RPOPPIS, SUNI_REGX_RPOPPIS }, \
+ { /* 33 */ \
+ UTP_REGT_BITS, SUNI_REGO_RPOPIEN, \
+ SUNI_REGN_RPOPIEN, SUNI_REGX_RPOPIEN }, \
+ { /* 34 */ \
+ UTP_REGT_BITS, SUNI_REGO_RPOPPIE, \
+ SUNI_REGN_RPOPPIE, SUNI_REGX_RPOPPIE }, \
+ { /* 35, 36 */ \
+ UTP_REGT_INT10BITS, SUNI_REGO_RPOPPTR, \
+ SUNI_REGN_RPOPPTR, SUNI_REGX_RPOPPTR }, \
+ { /* 37 */ \
+ UTP_REGT_INT8, SUNI_REGO_RPOPPSL, \
+ SUNI_REGN_RPOPPSL, NULL }, \
+ { /* 38, 39 */ \
+ UTP_REGT_INT16, SUNI_REGO_RPOPBIP8, \
+ SUNI_REGN_RPOPBIP8, NULL }, \
+ { /* 3A, 3B */ \
+ UTP_REGT_INT16, SUNI_REGO_RPOPFEBE, \
+ SUNI_REGN_RPOPFEBE, NULL }, \
+ { /* 3C */ \
+ UTP_REGT_BITS, SUNI_REGO_RPOPRDI, \
+ SUNI_REGN_RPOPRDI, SUNI_REGX_RPOPRDI }, \
+ { /* 3D */ \
+ UTP_REGT_BITS, SUNI_REGO_RPOPRING, \
+ SUNI_REGN_RPOPRING, SUNI_REGX_RPOPRING }, \
+ /* 3E-3F unused */ \
+ { /* 40 */ \
+ UTP_REGT_BITS, SUNI_REGO_TPOPCTRL, \
+ SUNI_REGN_TPOPCTRL, SUNI_REGX_TPOPCTRL_622 }, \
+ { /* 41 */ \
+ UTP_REGT_BITS, SUNI_REGO_TPOPPTRC, \
+ SUNI_REGN_TPOPPTRC, SUNI_REGX_TPOPPTRC }, \
+ /* 42 unused */ \
+ { /* 43, 44 */ \
+ UTP_REGT_INT10BITS, SUNI_REGO_TPOPCP, \
+ SUNI_REGN_TPOPCP, SUNI_REGX_TPOPCP }, \
+ { /* 45, 46 */ \
+ UTP_REGT_INT10BITS, SUNI_REGO_TPOPAPTR, \
+ SUNI_REGN_TPOPAPTR, SUNI_REGX_TPOPAPTR }, \
+ { /* 47 */ \
+ UTP_REGT_INT8, SUNI_REGO_TPOPPT, \
+ SUNI_REGN_TPOPPT, NULL }, \
+ { /* 48 */ \
+ UTP_REGT_INT8, SUNI_REGO_TPOPPSL, \
+ SUNI_REGN_TPOPPSL, NULL }, \
+ { /* 49 */ \
+ UTP_REGT_BITS, SUNI_REGO_TPOPSTATUS, \
+ SUNI_REGN_TPOPSTATUS, SUNI_REGX_TPOPSTATUS }, \
+ { /* 4A */ \
+ UTP_REGT_INT8, SUNI_REGO_TPOPPUC, \
+ SUNI_REGN_TPOPPUC, NULL }, \
+ { /* 4B */ \
+ UTP_REGT_INT8, SUNI_REGO_TPOPPG1, \
+ SUNI_REGN_TPOPPG1, NULL }, \
+ { /* 4C */ \
+ UTP_REGT_INT8, SUNI_REGO_TPOPPG2, \
+ SUNI_REGN_TPOPPG2, NULL }, \
+ { /* 4D */ \
+ UTP_REGT_INT8, SUNI_REGO_TPOPPG3, \
+ SUNI_REGN_TPOPPG3, NULL }, \
+ /* 4E-4F unused */ \
+ { /* 50 */ \
+ UTP_REGT_BITS, SUNI_REGO_RACPCTRL, \
+ SUNI_REGN_RACPCTRL, SUNI_REGX_RACPCTRL_622 }, \
+ { /* 51 */ \
+ UTP_REGT_BITS, SUNI_REGO_RACPIS, \
+ SUNI_REGN_RACPIS, SUNI_REGX_RACPIS }, \
+ { /* 52 */ \
+ UTP_REGT_BITS, SUNI_REGO_RACPIEC, \
+ SUNI_REGN_RACPIEC, SUNI_REGX_RACPIEC }, \
+ { /* 53 */ \
+ UTP_REGT_BITS, SUNI_REGO_RACPPATTERN_622, \
+ SUNI_REGN_RACPPATTERN, SUNI_REGX_RACPPATTERN }, \
+ { /* 54 */ \
+ UTP_REGT_BITS, SUNI_REGO_RACPMASK_622, \
+ SUNI_REGN_RACPMASK, SUNI_REGX_RACPMASK }, \
+ { /* 55, 56 */ \
+ UTP_REGT_INT12, SUNI_REGO_RACPCHCS_622, \
+ SUNI_REGN_RACPCHCS, NULL }, \
+ { /* 57, 58 */ \
+ UTP_REGT_INT12, SUNI_REGO_RACPUHCS_622, \
+ SUNI_REGN_RACPUHCS, NULL }, \
+ { /* 59, 5A, 5B */ \
+ UTP_REGT_INT21, SUNI_REGO_RACPCNT_622, \
+ SUNI_REGN_RACPCNT, NULL }, \
+ { /* 5C */ \
+ UTP_REGT_BITS, SUNI_REGO_RACPGFC, \
+ SUNI_REGN_RACPGFC, SUNI_REGX_RACPGFC }, \
+ /* 5D-5F unused */ \
+ { /* 60 */ \
+ UTP_REGT_BITS, SUNI_REGO_TACPCTRL, \
+ SUNI_REGN_TACPCTRL, SUNI_REGX_TACPCTRL_622 }, \
+ { /* 61 */ \
+ UTP_REGT_BITS, SUNI_REGO_TACPIDLEH, \
+ SUNI_REGN_TACPIDLEH, SUNI_REGX_TACPIDLEH }, \
+ { /* 62 */ \
+ UTP_REGT_INT8, SUNI_REGO_TACPIDLEP, \
+ SUNI_REGN_TACPIDLEP, NULL }, \
+ { /* 63 */ \
+ UTP_REGT_BITS, SUNI_REGO_TACPFIFOC, \
+ SUNI_REGN_TACPFIFOC, SUNI_REGX_TACPFIFOC_622 }, \
+ { /* 64, 65, 66 */ \
+ UTP_REGT_INT21, SUNI_REGO_TACPCNT, \
+ SUNI_REGN_TACPCNT, NULL }, \
+ { /* 67 */ \
+ UTP_REGT_BITS, SUNI_REGO_TACPGFC, \
+ SUNI_REGN_TACPGFC, SUNI_REGX_TACPGFC }, \
+ { /* 68 */ \
+ UTP_REGT_BITS, SUNI_REGO_SPTBCTRL, \
+ SUNI_REGN_SPTBCTRL, SUNI_REGX_SPTBCTRL }, \
+ { /* 69 */ \
+ UTP_REGT_BITS, SUNI_REGO_SPTBPTIS, \
+ SUNI_REGN_SPTBPTIS, SUNI_REGX_SPTBPTIS }, \
+ { /* 6A */ \
+ UTP_REGT_BITS, SUNI_REGO_SPTBIAR, \
+ SUNI_REGN_SPTBIAR, SUNI_REGX_SPTBIAR }, \
+ { /* 6B */ \
+ UTP_REGT_INT8, SUNI_REGO_SPTBIDR, \
+ SUNI_REGN_SPTBIDR, NULL }, \
+ { /* 6C */ \
+ UTP_REGT_INT8, SUNI_REGO_SPTBEPSL, \
+ SUNI_REGN_SPTBEPSL, NULL }, \
+ { /* 6D */ \
+ UTP_REGT_BITS, SUNI_REGO_SPTBPSLS, \
+ SUNI_REGN_SPTBPSLS, SUNI_REGX_SPTBPSLS }, \
+ /* 6E-6F unused */ \
+ { /* 70 */ \
+ UTP_REGT_BITS, SUNI_REGO_BERMCTRL, \
+ SUNI_REGN_BERMCTRL, SUNI_REGX_BERMCTRL }, \
+ { /* 71 */ \
+ UTP_REGT_BITS, SUNI_REGO_BERMINT, \
+ SUNI_REGN_BERMINT, SUNI_REGX_BERMINT }, \
+ { /* 72, 73 */ \
+ UTP_REGT_INT16, SUNI_REGO_BERMLAP, \
+ SUNI_REGN_BERMLAP, NULL }, \
+ { /* 74, 75 */ \
+ UTP_REGT_INT16, SUNI_REGO_BERMLT, \
+ SUNI_REGN_BERMLT, NULL }, \
+ /* 76-7f unused */ \
+ { /* 80 */ \
+ UTP_REGT_BITS, SUNI_REGO_MTEST, \
+ SUNI_REGN_MTEST, SUNI_REGX_MTEST_622 }
+
+#endif /* _DEV_UTOPIA_SUNI_H */
diff --git a/sys/dev/utopia/utopia.c b/sys/dev/utopia/utopia.c
new file mode 100644
index 0000000..ce63186
--- /dev/null
+++ b/sys/dev/utopia/utopia.c
@@ -0,0 +1,1082 @@
+/*
+ * Copyright (c) 2003
+ * Fraunhofer Institute for Open Communication Systems (FhG Fokus).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author: Hartmut Brandt <harti@freebsd.org>
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/unistd.h>
+#include <sys/kernel.h>
+#include <sys/kthread.h>
+#include <sys/proc.h>
+#include <sys/bus.h>
+#include <sys/malloc.h>
+#include <sys/sysctl.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <net/if_var.h>
+#include <net/if_media.h>
+#include <net/if_atm.h>
+
+#include <dev/utopia/suni.h>
+#include <dev/utopia/idtphy.h>
+#include <dev/utopia/utopia.h>
+
+#define READREGS(UTOPIA, REG, VALP, NP) \
+ (UTOPIA)->methods->readregs((UTOPIA)->ifatm, REG, VALP, NP)
+#define WRITEREG(UTOPIA, REG, MASK, VAL) \
+ (UTOPIA)->methods->writereg((UTOPIA)->ifatm, REG, MASK, VAL)
+
+/*
+ * Global list of all registered interfaces
+ */
+static struct mtx utopia_list_mtx;
+static LIST_HEAD(, utopia) utopia_list = LIST_HEAD_INITIALIZER(utopia_list);
+
+#define UTP_RLOCK_LIST() mtx_lock(&utopia_list_mtx)
+#define UTP_RUNLOCK_LIST() mtx_unlock(&utopia_list_mtx)
+#define UTP_WLOCK_LIST() mtx_lock(&utopia_list_mtx)
+#define UTP_WUNLOCK_LIST() mtx_unlock(&utopia_list_mtx)
+
+#define UTP_LOCK(UTP) mtx_lock((UTP)->lock)
+#define UTP_UNLOCK(UTP) mtx_unlock((UTP)->lock)
+#define UTP_LOCK_ASSERT(UTP) mtx_assert((UTP)->lock, MA_OWNED)
+
+static struct proc *utopia_kproc;
+
+static void utopia_dump(struct utopia *) __unused;
+
+/*
+ * Debugging - dump all registers.
+ */
+static void
+utopia_dump(struct utopia *utp)
+{
+ uint8_t regs[256];
+ u_int n = 256, i;
+ int err;
+
+ if ((err = READREGS(utp, SUNI_REGO_MRESET, regs, &n)) != 0) {
+ printf("SUNI read error %d\n", err);
+ return;
+ }
+ for (i = 0; i < n; i++) {
+ if (i % 16 == 0)
+ printf("%02x:", i);
+ if (i % 16 == 8)
+ printf(" ");
+ printf(" %02x", regs[i]);
+ if (i % 16 == 15)
+ printf("\n");
+ }
+ if (i % 16 != 0)
+ printf("\n");
+}
+
+/*
+ * Update the carrier status
+ */
+static void
+utopia_check_carrier(struct utopia *utp, u_int carr_ok)
+{
+ int old;
+
+ old = utp->carrier;
+ if (carr_ok) {
+ /* carrier */
+ utp->carrier = UTP_CARR_OK;
+ if (old != UTP_CARR_OK) {
+ if_printf(&utp->ifatm->ifnet, "carrier detected\n");
+ }
+ } else {
+ /* no carrier */
+ utp->carrier = UTP_CARR_LOST;
+ if (old == UTP_CARR_OK) {
+ if_printf(&utp->ifatm->ifnet, "carrier lost\n");
+ }
+ }
+}
+
+static int
+utopia_update_carrier_default(struct utopia *utp)
+{
+ int err;
+ uint8_t reg;
+ u_int n = 1;
+
+ if ((err = READREGS(utp, SUNI_REGO_RSOPSIS, &reg, &n)) != 0) {
+ utp->carrier = UTP_CARR_UNKNOWN;
+ return (err);
+ }
+ utopia_check_carrier(utp, !(reg & SUNI_REGM_RSOPSIS_LOSV));
+ return (0);
+}
+
+/*
+ * enable/disable scrambling
+ */
+static int
+utopia_set_noscramb_default(struct utopia *utp, int noscramb)
+{
+ int err;
+
+ if (noscramb) {
+ err = WRITEREG(utp, SUNI_REGO_TACPCTRL,
+ SUNI_REGM_TACPCTRL_DSCR, SUNI_REGM_TACPCTRL_DSCR);
+ if (err)
+ return (err);
+ err = WRITEREG(utp, SUNI_REGO_RACPCTRL,
+ SUNI_REGM_RACPCTRL_DDSCR, SUNI_REGM_RACPCTRL_DDSCR);
+ if (err)
+ return (err);
+ utp->state |= UTP_ST_NOSCRAMB;
+ } else {
+ err = WRITEREG(utp, SUNI_REGO_TACPCTRL,
+ SUNI_REGM_TACPCTRL_DSCR, 0);
+ if (err)
+ return (err);
+ err = WRITEREG(utp, SUNI_REGO_RACPCTRL,
+ SUNI_REGM_RACPCTRL_DDSCR, 0);
+ if (err)
+ return (err);
+ utp->state &= ~UTP_ST_NOSCRAMB;
+ }
+ return (0);
+}
+
+/*
+ * set SONET/SDH mode
+ */
+static int
+utopia_set_sdh_default(struct utopia *utp, int sdh)
+{
+ int err;
+
+ if (sdh)
+ err = WRITEREG(utp, SUNI_REGO_TPOPAPTR + 1,
+ SUNI_REGM_TPOPAPTR_S,
+ SUNI_REGM_SDH << SUNI_REGS_TPOPAPTR_S);
+ else
+ err = WRITEREG(utp, SUNI_REGO_TPOPAPTR + 1,
+ SUNI_REGM_TPOPAPTR_S,
+ SUNI_REGM_SONET << SUNI_REGS_TPOPAPTR_S);
+ if (err != 0)
+ return (err);
+
+ utp->state &= ~UTP_ST_SDH;
+ if (sdh)
+ utp->state |= UTP_ST_SDH;
+
+ return (0);
+}
+
+/*
+ * set idle/unassigned cells
+ */
+static int
+utopia_set_unass_default(struct utopia *utp, int unass)
+{
+ int err;
+
+ if (unass)
+ err = WRITEREG(utp, SUNI_REGO_TACPIDLEH,
+ 0xff, (0 << SUNI_REGS_TACPIDLEH_CLP));
+ else
+ err = WRITEREG(utp, SUNI_REGO_TACPIDLEH,
+ 0xff, (1 << SUNI_REGS_TACPIDLEH_CLP));
+ if (err != 0)
+ return (err);
+
+ utp->state &= ~UTP_ST_UNASS;
+ if (unass)
+ utp->state |= UTP_ST_UNASS;
+
+ return (0);
+}
+
+/*
+ * Set loopback mode for the Lite
+ */
+static int
+utopia_set_loopback_lite(struct utopia *utp, u_int mode)
+{
+ int err;
+ uint32_t val;
+ u_int nmode;
+
+ val = 0;
+ nmode = mode;
+ if (mode & UTP_LOOP_TIME) {
+ nmode &= ~UTP_LOOP_TIME;
+ val |= SUNI_REGM_MCTRL_LOOPT;
+ }
+ if (mode & UTP_LOOP_DIAG) {
+ nmode &= ~UTP_LOOP_DIAG;
+ val |= SUNI_REGM_MCTRL_DLE;
+ }
+ if (mode & UTP_LOOP_LINE) {
+ nmode &= ~UTP_LOOP_LINE;
+ if (val & SUNI_REGM_MCTRL_DLE)
+ return (EINVAL);
+ val |= SUNI_REGM_MCTRL_LLE;
+ }
+ if (nmode != 0)
+ return (EINVAL);
+
+ err = WRITEREG(utp, SUNI_REGO_MCTRL,
+ SUNI_REGM_MCTRL_LLE | SUNI_REGM_MCTRL_DLE | SUNI_REGM_MCTRL_LOOPT,
+ val);
+ if (err)
+ return (err);
+ utp->loopback = mode;
+
+ return (0);
+}
+
+/*
+ * Set loopback mode for the Ultra
+ */
+static int
+utopia_set_loopback_ultra(struct utopia *utp, u_int mode)
+{
+ int err;
+ uint32_t val;
+ u_int nmode;
+
+ val = 0;
+ nmode = mode;
+ if (mode & UTP_LOOP_TIME) {
+ nmode &= ~UTP_LOOP_TIME;
+ val |= SUNI_REGM_MCTRL_LOOPT;
+ }
+ if (mode & UTP_LOOP_DIAG) {
+ nmode &= ~UTP_LOOP_DIAG;
+ if (val & SUNI_REGM_MCTRL_LOOPT)
+ return (EINVAL);
+ val |= SUNI_REGM_MCTRL_SDLE;
+ }
+ if (mode & UTP_LOOP_LINE) {
+ nmode &= ~UTP_LOOP_LINE;
+ if (val & (SUNI_REGM_MCTRL_LOOPT | SUNI_REGM_MCTRL_SDLE))
+ return (EINVAL);
+ val |= SUNI_REGM_MCTRL_LLE;
+ }
+ if (mode & UTP_LOOP_PARAL) {
+ nmode &= ~UTP_LOOP_PARAL;
+ val |= SUNI_REGM_MCTRL_PDLE;
+ }
+ if (mode & UTP_LOOP_TWIST) {
+ nmode &= ~UTP_LOOP_TWIST;
+ val |= SUNI_REGM_MCTRL_TPLE;
+ }
+ if (nmode != 0)
+ return (EINVAL);
+
+ err = WRITEREG(utp, SUNI_REGO_MCTRL,
+ SUNI_REGM_MCTRL_LLE | SUNI_REGM_MCTRL_SDLE | SUNI_REGM_MCTRL_LOOPT |
+ SUNI_REGM_MCTRL_PDLE | SUNI_REGM_MCTRL_TPLE, val);
+ if (err)
+ return (err);
+ utp->loopback = mode;
+
+ return (0);
+}
+
+/*
+ * Set loopback mode for the Ultra
+ */
+static int
+utopia_set_loopback_622(struct utopia *utp, u_int mode)
+{
+ int err;
+ uint32_t val;
+ uint8_t config;
+ int smode;
+ u_int nmode;
+ u_int n = 1;
+
+ val = 0;
+ nmode = mode;
+ if (mode & UTP_LOOP_PATH) {
+ nmode &= ~UTP_LOOP_PATH;
+ val |= SUNI_REGM_MCTRLM_DPLE;
+ }
+
+ err = READREGS(utp, SUNI_REGO_MCONFIG, &config, &n);
+ if (err != 0)
+ return (err);
+ smode = ((config & SUNI_REGM_MCONFIG_TMODE_622) ==
+ SUNI_REGM_MCONFIG_TMODE_STS1_BIT &&
+ (config & SUNI_REGM_MCONFIG_RMODE_622) ==
+ SUNI_REGM_MCONFIG_RMODE_STS1_BIT);
+
+ if (mode & UTP_LOOP_TIME) {
+ if (!smode)
+ return (EINVAL);
+ nmode &= ~UTP_LOOP_TIME;
+ val |= SUNI_REGM_MCTRLM_LOOPT;
+ }
+ if (mode & UTP_LOOP_DIAG) {
+ nmode &= ~UTP_LOOP_DIAG;
+ if (val & SUNI_REGM_MCTRLM_LOOPT)
+ return (EINVAL);
+ val |= SUNI_REGM_MCTRLM_DLE;
+ }
+ if (mode & UTP_LOOP_LINE) {
+ nmode &= ~UTP_LOOP_LINE;
+ if (val & (SUNI_REGM_MCTRLM_LOOPT | SUNI_REGM_MCTRLM_DLE))
+ return (EINVAL);
+ val |= SUNI_REGM_MCTRLM_LLE;
+ }
+ if (nmode != 0)
+ return (EINVAL);
+
+ err = WRITEREG(utp, SUNI_REGO_MCTRLM,
+ SUNI_REGM_MCTRLM_LLE | SUNI_REGM_MCTRLM_DLE |
+ SUNI_REGM_MCTRLM_DPLE | SUNI_REGM_MCTRL_LOOPT, val);
+ if (err)
+ return (err);
+ utp->loopback = mode;
+
+ return (0);
+}
+
+/*
+ * Set the SUNI chip to reflect the current state in utopia.
+ * Assume, that the chip has been reset.
+ */
+static int
+utopia_set_chip(struct utopia *utp)
+{
+ int err = 0;
+
+ /* set sonet/sdh */
+ err |= utopia_set_sdh(utp, utp->state & UTP_ST_SDH);
+
+ /* unassigned or idle cells */
+ err |= utopia_set_unass(utp, utp->state & UTP_ST_UNASS);
+ err |= WRITEREG(utp, SUNI_REGO_TACPIDLEP, 0xff, 0x6a);
+
+ /* loopback */
+ err |= utopia_set_loopback(utp, utp->loopback);
+
+ /* update carrier state */
+ err |= utopia_update_carrier(utp);
+
+ /* enable interrupts on LOS */
+ err |= WRITEREG(utp, SUNI_REGO_RSOPCIE,
+ SUNI_REGM_RSOPCIE_LOSE, SUNI_REGM_RSOPCIE_LOSE);
+
+ return (err ? EIO : 0);
+}
+
+/*
+ * Reset the SUNI chip to reflect the current state of utopia.
+ */
+static int
+utopia_reset_default(struct utopia *utp)
+{
+ int err = 0;
+
+ if (!(utp->flags & UTP_FL_NORESET)) {
+ err |= WRITEREG(utp, SUNI_REGO_MRESET, SUNI_REGM_MRESET_RESET,
+ SUNI_REGM_MRESET_RESET);
+ err |= WRITEREG(utp, SUNI_REGO_MRESET, SUNI_REGM_MRESET_RESET,
+ 0);
+ }
+
+ /* disable test mode */
+ err |= WRITEREG(utp, SUNI_REGO_MTEST, 0xff, 0x00);
+
+ err |= utopia_set_chip(utp);
+
+ return (err ? EIO : 0);
+}
+
+/*
+ * Reset the SUNI chip to reflect the current state of utopia.
+ */
+static int
+utopia_reset_622(struct utopia *utp)
+{
+ int err = 0;
+
+ if (!(utp->flags & UTP_FL_NORESET)) {
+ err |= WRITEREG(utp, SUNI_REGO_MRESET, SUNI_REGM_MRESET_RESET,
+ SUNI_REGM_MRESET_RESET);
+ err |= WRITEREG(utp, SUNI_REGO_MRESET, SUNI_REGM_MRESET_RESET,
+ 0);
+ }
+
+ /* disable test mode */
+ err |= WRITEREG(utp, SUNI_REGO_MTEST, 0xff,
+ SUNI_REGM_MTEST_DS27_53_622);
+
+ err |= utopia_set_chip(utp);
+
+ return (err ? EIO : 0);
+}
+
+/*
+ * Handle interrupt on lite chip
+ */
+static void
+utopia_intr_default(struct utopia *utp)
+{
+ uint8_t regs[SUNI_REGO_MTEST];
+ u_int n = SUNI_REGO_MTEST;
+ int err;
+
+ /* Read all registers. This acks the interrupts */
+ if ((err = READREGS(utp, SUNI_REGO_MRESET, regs, &n)) != 0) {
+ printf("SUNI read error %d\n", err);
+ return;
+ }
+ if (n <= SUNI_REGO_RSOPSIS) {
+ printf("%s: could not read RSOPSIS", __func__);
+ return;
+ }
+ /* check for LOSI (loss of signal) */
+ if ((regs[SUNI_REGO_MISTATUS] & SUNI_REGM_MISTATUS_RSOPI) &&
+ (regs[SUNI_REGO_RSOPSIS] & SUNI_REGM_RSOPSIS_LOSI))
+ utopia_check_carrier(utp, !(regs[SUNI_REGO_RSOPSIS]
+ & SUNI_REGM_RSOPSIS_LOSV));
+}
+
+static const struct utopia_chip chip_622 = {
+ UTP_TYPE_SUNI_622,
+ "Suni/622 (PMC-5355)",
+ 256,
+ utopia_reset_622,
+ utopia_set_sdh_default,
+ utopia_set_unass_default,
+ utopia_set_noscramb_default,
+ utopia_update_carrier_default,
+ utopia_set_loopback_622,
+ utopia_intr_default,
+};
+static const struct utopia_chip chip_lite = {
+ UTP_TYPE_SUNI_LITE,
+ "Suni/Lite (PMC-5346)",
+ 256,
+ utopia_reset_default,
+ utopia_set_sdh_default,
+ utopia_set_unass_default,
+ utopia_set_noscramb_default,
+ utopia_update_carrier_default,
+ utopia_set_loopback_lite,
+ utopia_intr_default,
+};
+static const struct utopia_chip chip_ultra = {
+ UTP_TYPE_SUNI_ULTRA,
+ "Suni/Ultra (PMC-5350)",
+ 256,
+ utopia_reset_default,
+ utopia_set_sdh_default,
+ utopia_set_unass_default,
+ utopia_set_noscramb_default,
+ utopia_update_carrier_default,
+ utopia_set_loopback_ultra,
+ utopia_intr_default,
+};
+
+/*
+ * Reset IDT77105. There is really no way to reset this thing by acessing
+ * the registers. Load the registers with default values.
+ */
+static int
+idt77105_reset(struct utopia *utp)
+{
+ int err = 0;
+ u_int n;
+ uint8_t val[2];
+
+ err |= WRITEREG(utp, IDTPHY_REGO_MCR, 0xff,
+ IDTPHY_REGM_MCR_DRIC | IDTPHY_REGM_MCR_EI);
+ n = 1;
+ err |= READREGS(utp, IDTPHY_REGO_ISTAT, val, &n);
+ err |= WRITEREG(utp, IDTPHY_REGO_DIAG, 0xff, 0);
+ err |= WRITEREG(utp, IDTPHY_REGO_LHEC, 0xff, 0);
+
+ err |= WRITEREG(utp, IDTPHY_REGO_CNTS, 0xff, IDTPHY_REGM_CNTS_SEC);
+ n = 2;
+ err |= READREGS(utp, IDTPHY_REGO_CNT, val, &n);
+
+ err |= WRITEREG(utp, IDTPHY_REGO_CNTS, 0xff, IDTPHY_REGM_CNTS_TX);
+ n = 2;
+ err |= READREGS(utp, IDTPHY_REGO_CNT, val, &n);
+
+ err |= WRITEREG(utp, IDTPHY_REGO_CNTS, 0xff, IDTPHY_REGM_CNTS_RX);
+ n = 2;
+ err |= READREGS(utp, IDTPHY_REGO_CNT, val, &n);
+
+ err |= WRITEREG(utp, IDTPHY_REGO_CNTS, 0xff, IDTPHY_REGM_CNTS_HECE);
+ n = 2;
+ err |= READREGS(utp, IDTPHY_REGO_CNT, val, &n);
+
+ err |= WRITEREG(utp, IDTPHY_REGO_MCR, IDTPHY_REGM_MCR_DREC,
+ IDTPHY_REGM_MCR_DREC);
+ err |= WRITEREG(utp, IDTPHY_REGO_DIAG, IDTPHY_REGM_DIAG_RFLUSH,
+ IDTPHY_REGM_DIAG_RFLUSH);
+
+ /* loopback */
+ err |= utopia_set_loopback(utp, utp->loopback);
+
+ /* update carrier state */
+ err |= utopia_update_carrier(utp);
+
+ return (err ? EIO : 0);
+}
+
+static int
+unknown_inval(struct utopia *utp, int what __unused)
+{
+ return (EINVAL);
+}
+
+static int
+idt77105_update_carrier(struct utopia *utp)
+{
+ int err;
+ uint8_t reg;
+ u_int n = 1;
+
+ if ((err = READREGS(utp, IDTPHY_REGO_ISTAT, &reg, &n)) != 0) {
+ utp->carrier = UTP_CARR_UNKNOWN;
+ return (err);
+ }
+ utopia_check_carrier(utp, reg & IDTPHY_REGM_ISTAT_GOOD);
+ return (0);
+}
+
+static int
+idt77105_set_loopback(struct utopia *utp, u_int mode)
+{
+ int err;
+
+ switch (mode) {
+ case UTP_LOOP_NONE:
+ err = WRITEREG(utp, IDTPHY_REGO_DIAG,
+ IDTPHY_REGM_DIAG_LOOP, IDTPHY_REGM_DIAG_LOOP_NONE);
+ break;
+
+ case UTP_LOOP_DIAG:
+ err = WRITEREG(utp, IDTPHY_REGO_DIAG,
+ IDTPHY_REGM_DIAG_LOOP, IDTPHY_REGM_DIAG_LOOP_PHY);
+ break;
+
+ case UTP_LOOP_LINE:
+ err = WRITEREG(utp, IDTPHY_REGO_DIAG,
+ IDTPHY_REGM_DIAG_LOOP, IDTPHY_REGM_DIAG_LOOP_LINE);
+ break;
+
+ default:
+ return (EINVAL);
+ }
+ if (err)
+ return (err);
+ utp->loopback = mode;
+ return (0);
+}
+
+/*
+ * Handle interrupt on IDT77105 chip
+ */
+static void
+idt77105_intr(struct utopia *utp)
+{
+ uint8_t reg;
+ u_int n = 1;
+ int err;
+
+ /* Interrupt status and ack the interrupt */
+ if ((err = READREGS(utp, IDTPHY_REGO_ISTAT, &reg, &n)) != 0) {
+ printf("IDT77105 read error %d\n", err);
+ return;
+ }
+ /* check for signal condition */
+ utopia_check_carrier(utp, reg & IDTPHY_REGM_ISTAT_GOOD);
+}
+
+static const struct utopia_chip chip_idt77105 = {
+ UTP_TYPE_IDT77105,
+ "IDT77105",
+ 7,
+ idt77105_reset,
+ unknown_inval,
+ unknown_inval,
+ unknown_inval,
+ idt77105_update_carrier,
+ idt77105_set_loopback,
+ idt77105_intr,
+};
+
+static int
+unknown_reset(struct utopia *utp __unused)
+{
+ return (EIO);
+}
+
+static int
+unknown_update_carrier(struct utopia *utp)
+{
+ utp->carrier = UTP_CARR_UNKNOWN;
+ return (0);
+}
+
+static int
+unknown_set_loopback(struct utopia *utp __unused, u_int mode __unused)
+{
+ return (EINVAL);
+}
+
+static void
+unknown_intr(struct utopia *utp __unused)
+{
+}
+
+static const struct utopia_chip chip_unknown = {
+ UTP_TYPE_UNKNOWN,
+ "unknown",
+ 0,
+ unknown_reset,
+ unknown_inval,
+ unknown_inval,
+ unknown_inval,
+ unknown_update_carrier,
+ unknown_set_loopback,
+ unknown_intr,
+};
+
+/*
+ * Callbacks for the ifmedia infrastructure.
+ */
+static int
+utopia_media_change(struct ifnet *ifp)
+{
+ struct ifatm *ifatm = (struct ifatm *)ifp->if_softc;
+ struct utopia *utp = ifatm->phy;
+ int error = 0;
+
+ UTP_LOCK(utp);
+ if (utp->chip->type != UTP_TYPE_UNKNOWN && utp->state & UTP_ST_ACTIVE) {
+ if (utp->media->ifm_media & IFM_ATM_SDH) {
+ if (!(utp->state & UTP_ST_SDH))
+ error = utopia_set_sdh(utp, 1);
+ } else {
+ if (utp->state & UTP_ST_SDH)
+ error = utopia_set_sdh(utp, 0);
+ }
+ if (utp->media->ifm_media & IFM_ATM_UNASSIGNED) {
+ if (!(utp->state & UTP_ST_UNASS))
+ error = utopia_set_unass(utp, 1);
+ } else {
+ if (utp->state & UTP_ST_UNASS)
+ error = utopia_set_unass(utp, 0);
+ }
+ if (utp->media->ifm_media & IFM_ATM_NOSCRAMB) {
+ if (!(utp->state & UTP_ST_NOSCRAMB))
+ error = utopia_set_noscramb(utp, 1);
+ } else {
+ if (utp->state & UTP_ST_NOSCRAMB)
+ error = utopia_set_noscramb(utp, 0);
+ }
+ } else
+ error = EIO;
+ UTP_UNLOCK(utp);
+ return (error);
+}
+
+/*
+ * Look at the carrier status.
+ */
+static void
+utopia_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
+{
+ struct utopia *utp = ((struct ifatm *)ifp->if_softc)->phy;
+
+ UTP_LOCK(utp);
+ if (utp->chip->type != UTP_TYPE_UNKNOWN && utp->state & UTP_ST_ACTIVE) {
+ ifmr->ifm_active = IFM_ATM | utp->ifatm->mib.media;
+
+ switch (utp->carrier) {
+
+ case UTP_CARR_OK:
+ ifmr->ifm_status = IFM_AVALID | IFM_ACTIVE;
+ break;
+
+ case UTP_CARR_LOST:
+ ifmr->ifm_status = IFM_AVALID;
+ break;
+
+ default:
+ ifmr->ifm_status = 0;
+ break;
+ }
+ if (utp->state & UTP_ST_SDH) {
+ ifmr->ifm_active |= IFM_ATM_SDH;
+ ifmr->ifm_current |= IFM_ATM_SDH;
+ }
+ if (utp->state & UTP_ST_UNASS) {
+ ifmr->ifm_active |= IFM_ATM_UNASSIGNED;
+ ifmr->ifm_current |= IFM_ATM_UNASSIGNED;
+ }
+ if (utp->state & UTP_ST_NOSCRAMB) {
+ ifmr->ifm_active |= IFM_ATM_NOSCRAMB;
+ ifmr->ifm_current |= IFM_ATM_NOSCRAMB;
+ }
+ } else {
+ ifmr->ifm_active = 0;
+ ifmr->ifm_status = 0;
+ }
+ UTP_UNLOCK(utp);
+}
+
+/*
+ * Initialize media from the mib
+ */
+void
+utopia_init_media(struct utopia *utp)
+{
+
+ ifmedia_removeall(utp->media);
+ ifmedia_add(utp->media, IFM_ATM | utp->ifatm->mib.media, 0, NULL);
+ ifmedia_set(utp->media, IFM_ATM | utp->ifatm->mib.media);
+}
+
+/*
+ * Reset all media
+ */
+void
+utopia_reset_media(struct utopia *utp)
+{
+
+ ifmedia_removeall(utp->media);
+}
+
+/*
+ * This is called by the driver as soon as the SUNI registers are accessible.
+ * This may be either in the attach routine or the init routine of the driver.
+ */
+int
+utopia_start(struct utopia *utp)
+{
+ uint8_t reg;
+ int err;
+ u_int n = 1;
+
+ if ((err = READREGS(utp, SUNI_REGO_MRESET, &reg, &n)) != 0)
+ return (err);
+
+ switch (reg & SUNI_REGM_MRESET_TYPE) {
+
+ case SUNI_REGM_MRESET_TYPE_622:
+ utp->chip = &chip_622;
+ break;
+
+ case SUNI_REGM_MRESET_TYPE_LITE:
+ utp->chip = &chip_lite;
+ break;
+
+ case SUNI_REGM_MRESET_TYPE_ULTRA:
+ utp->chip = &chip_ultra;
+ break;
+
+ default:
+ if (reg == (IDTPHY_REGM_MCR_DRIC | IDTPHY_REGM_MCR_EI))
+ utp->chip = &chip_idt77105;
+ else {
+ if_printf(&utp->ifatm->ifnet,
+ "unknown ATM-PHY chip %#x\n", reg);
+ utp->chip = &chip_unknown;
+ }
+ break;
+ }
+ utp->state |= UTP_ST_ACTIVE;
+ return (0);
+}
+
+/*
+ * Stop the chip
+ */
+void
+utopia_stop(struct utopia *utp)
+{
+ utp->state &= ~UTP_ST_ACTIVE;
+}
+
+/*
+ * Handle the sysctls
+ */
+static int
+utopia_sysctl_regs(SYSCTL_HANDLER_ARGS)
+{
+ struct utopia *utp = (struct utopia *)arg1;
+ int error;
+ u_int n;
+ uint8_t *val;
+ uint8_t new[3];
+
+ if ((n = utp->chip->nregs) == 0)
+ return (EIO);
+ val = malloc(sizeof(uint8_t) * n, M_TEMP, M_WAITOK);
+
+ UTP_LOCK(utp);
+ error = READREGS(utp, 0, val, &n);
+ UTP_UNLOCK(utp);
+
+ if (error) {
+ free(val, M_TEMP);
+ return (error);
+ }
+
+ error = SYSCTL_OUT(req, val, sizeof(uint8_t) * n);
+ free(val, M_TEMP);
+ if (error != 0 || req->newptr == NULL)
+ return (error);
+
+ error = SYSCTL_IN(req, new, sizeof(new));
+ if (error)
+ return (error);
+
+ UTP_LOCK(utp);
+ error = WRITEREG(utp, new[0], new[1], new[2]);
+ UTP_UNLOCK(utp);
+
+ return (error);
+}
+
+/*
+ * Handle the loopback sysctl
+ */
+static int
+utopia_sysctl_loopback(SYSCTL_HANDLER_ARGS)
+{
+ struct utopia *utp = (struct utopia *)arg1;
+ int error;
+ u_int loopback;
+
+ error = SYSCTL_OUT(req, &utp->loopback, sizeof(u_int));
+ if (error != 0 || req->newptr == NULL)
+ return (error);
+
+ error = SYSCTL_IN(req, &loopback, sizeof(u_int));
+ if (error)
+ return (error);
+
+ UTP_LOCK(utp);
+ error = utopia_set_loopback(utp, loopback);
+ UTP_UNLOCK(utp);
+
+ return (error);
+}
+
+/*
+ * Handle the type sysctl
+ */
+static int
+utopia_sysctl_type(SYSCTL_HANDLER_ARGS)
+{
+ struct utopia *utp = (struct utopia *)arg1;
+
+ return (SYSCTL_OUT(req, &utp->chip->type, sizeof(utp->chip->type)));
+}
+
+/*
+ * Handle the name sysctl
+ */
+static int
+utopia_sysctl_name(SYSCTL_HANDLER_ARGS)
+{
+ struct utopia *utp = (struct utopia *)arg1;
+
+ return (SYSCTL_OUT(req, utp->chip->name, strlen(utp->chip->name) + 1));
+}
+
+/*
+ * Initialize the state. This is called from the drivers attach
+ * function. The mutex must be already initialized.
+ */
+int
+utopia_attach(struct utopia *utp, struct ifatm *ifatm, struct ifmedia *media,
+ struct mtx *lock, struct sysctl_ctx_list *ctx,
+ struct sysctl_oid_list *children, const struct utopia_methods *m)
+{
+
+ bzero(utp, sizeof(*utp));
+ utp->ifatm = ifatm;
+ utp->methods = m;
+ utp->media = media;
+ utp->lock = lock;
+ utp->chip = &chip_unknown;
+
+ ifmedia_init(media,
+ IFM_ATM_SDH | IFM_ATM_UNASSIGNED | IFM_ATM_NOSCRAMB,
+ utopia_media_change, utopia_media_status);
+
+ if (SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "phy_regs",
+ CTLFLAG_RW | CTLTYPE_OPAQUE, utp, 0, utopia_sysctl_regs, "S",
+ "phy registers") == NULL)
+ return (-1);
+
+ if (SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "phy_loopback",
+ CTLFLAG_RW | CTLTYPE_UINT, utp, 0, utopia_sysctl_loopback, "IU",
+ "phy loopback mode") == NULL)
+ return (-1);
+
+ if (SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "phy_type",
+ CTLFLAG_RD | CTLTYPE_UINT, utp, 0, utopia_sysctl_type, "IU",
+ "phy type") == NULL)
+ return (-1);
+
+ if (SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "phy_name",
+ CTLFLAG_RD | CTLTYPE_STRING, utp, 0, utopia_sysctl_name, "A",
+ "phy name") == NULL)
+ return (-1);
+
+ UTP_WLOCK_LIST();
+ LIST_INSERT_HEAD(&utopia_list, utp, link);
+ UTP_WUNLOCK_LIST();
+
+ utp->state |= UTP_ST_ATTACHED;
+ return (0);
+}
+
+/*
+ * Detach. We set a flag here, wakeup the daemon and let him do it.
+ * Here we need the lock for synchronisation with the daemon.
+ */
+void
+utopia_detach(struct utopia *utp)
+{
+
+ UTP_LOCK_ASSERT(utp);
+ if (utp->state & UTP_ST_ATTACHED) {
+ utp->state |= UTP_ST_DETACH;
+ while (utp->state & UTP_ST_DETACH) {
+ wakeup(&utopia_list);
+ msleep(utp, utp->lock, PZERO, "utopia_detach", hz);
+ }
+ }
+}
+
+/*
+ * The carrier state kernel proc for those adapters that do not interrupt.
+ *
+ * We assume, that utopia_attach can safely add a new utopia while we are going
+ * through the list without disturbing us (we lock the list while getting
+ * the address of the first element, adding is always done at the head).
+ * Removing is entirely handled here.
+ */
+static void
+utopia_daemon(void *arg __unused)
+{
+ struct utopia *utp, *next;
+
+ UTP_RLOCK_LIST();
+ while (utopia_kproc != NULL) {
+ utp = LIST_FIRST(&utopia_list);
+ UTP_RUNLOCK_LIST();
+
+ while (utp != NULL) {
+ mtx_lock(&Giant); /* XXX depend on MPSAFE */
+ UTP_LOCK(utp);
+ next = LIST_NEXT(utp, link);
+ if (utp->state & UTP_ST_DETACH) {
+ LIST_REMOVE(utp, link);
+ utp->state &= ~UTP_ST_DETACH;
+ wakeup_one(utp);
+ } else if ((utp->state & UTP_ST_ACTIVE) &&
+ (utp->flags & UTP_FL_POLL_CARRIER)) {
+ utopia_update_carrier(utp);
+ }
+ UTP_UNLOCK(utp);
+ mtx_unlock(&Giant); /* XXX depend on MPSAFE */
+ utp = next;
+ }
+
+ UTP_RLOCK_LIST();
+ msleep(&utopia_list, &utopia_list_mtx, PZERO, "utopia", hz);
+ }
+ wakeup_one(&utopia_list);
+ UTP_RUNLOCK_LIST();
+ mtx_lock(&Giant);
+ kthread_exit(0);
+}
+
+/*
+ * Module initialisation
+ */
+static int
+utopia_mod_init(module_t mod, int what, void *arg)
+{
+ int err;
+ struct proc *kp;
+
+ switch (what) {
+
+ case MOD_LOAD:
+ mtx_init(&utopia_list_mtx, "utopia list mutex", NULL, MTX_DEF);
+ err = kthread_create(utopia_daemon, NULL, &utopia_kproc,
+ RFHIGHPID, 0, "utopia");
+ if (err != 0) {
+ printf("cannot created utopia thread %d\n", err);
+ return (err);
+ }
+ break;
+
+ case MOD_UNLOAD:
+ UTP_WLOCK_LIST();
+ if ((kp = utopia_kproc) != NULL) {
+ utopia_kproc = NULL;
+ wakeup_one(&utopia_list);
+ PROC_LOCK(kp);
+ UTP_WUNLOCK_LIST();
+ msleep(kp, &kp->p_mtx, PWAIT, "utopia_destroy", 0);
+ PROC_UNLOCK(kp);
+ } else
+ UTP_WUNLOCK_LIST();
+ mtx_destroy(&utopia_list_mtx);
+ break;
+ }
+ return (0);
+}
+
+static moduledata_t utopia_mod = {
+ "utopia",
+ utopia_mod_init,
+ 0
+};
+
+DECLARE_MODULE(utopia, utopia_mod, SI_SUB_INIT_IF, SI_ORDER_ANY);
+MODULE_VERSION(utopia, 1);
diff --git a/sys/dev/utopia/utopia.h b/sys/dev/utopia/utopia.h
new file mode 100644
index 0000000..59db880
--- /dev/null
+++ b/sys/dev/utopia/utopia.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2003
+ * Fraunhofer Institute for Open Communication Systems (FhG Fokus).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author: Hartmut Brandt <harti@freebsd.org>
+ *
+ * $FreeBSD$
+ */
+#ifndef _DEV_UTOPIA_UTOPIA_H
+#define _DEV_UTOPIA_UTOPIA_H
+
+/* Structure for user-level register formatting */
+struct utopia_print {
+ uint8_t type; /* register type */
+ uint8_t reg; /* register number */
+ const char *name; /* register name */
+ const char *fmt; /* format for printing */
+};
+
+/*
+ * Types of registers
+ */
+#define UTP_REGT_BITS 0x0 /* use printb to print */
+#define UTP_REGT_INT8 0x1 /* 8 bit hex number */
+#define UTP_REGT_INT10BITS 0x2 /* 10 bit hex number + 6 bit printb */
+#define UTP_REGT_INT12 0x3 /* 12 bit LE hex */
+#define UTP_REGT_INT16 0x4 /* 16 bit LE hex */
+#define UTP_REGT_INT19 0x5 /* 19 bit LE hex */
+#define UTP_REGT_INT20 0x6 /* 20 bit LE hex */
+#define UTP_REGT_INT21 0x7 /* 21 bit LE hex */
+
+/* number of additional registers per type */
+#define UTP_REG_ADD 0, 0, 1, 1, 1, 2, 2, 2
+
+/* flags field */
+#define UTP_FL_NORESET 0x0001 /* cannot write MRESET register */
+#define UTP_FL_POLL_CARRIER 0x0002 /* need to poll for carrier */
+
+/* state field */
+#define UTP_ST_ACTIVE 0x0001 /* registers accessible */
+#define UTP_ST_SDH 0x0002 /* SDH or SONET */
+#define UTP_ST_UNASS 0x0004 /* produce unassigned cells */
+#define UTP_ST_NOSCRAMB 0x0008 /* no scrambling */
+#define UTP_ST_DETACH 0x0010 /* detaching */
+#define UTP_ST_ATTACHED 0x0020 /* successful attached */
+
+/* carrier field */
+#define UTP_CARR_UNKNOWN 0
+#define UTP_CARR_OK 1
+#define UTP_CARR_LOST 2
+
+/* loopback field */
+#define UTP_LOOP_NONE 0x0000
+#define UTP_LOOP_TIME 0x0001 /* timing source loopback */
+#define UTP_LOOP_DIAG 0x0002 /* diagnostic loopback */
+#define UTP_LOOP_LINE 0x0004 /* serial line loopback */
+#define UTP_LOOP_PARAL 0x0008 /* parallel diagnostic loopback */
+#define UTP_LOOP_TWIST 0x0010 /* twisted pair diagnostic loopback */
+#define UTP_LOOP_PATH 0x0020 /* diagnostic path loopback */
+
+/* type */
+#define UTP_TYPE_UNKNOWN 0
+#define UTP_TYPE_SUNI_LITE 1
+#define UTP_TYPE_SUNI_ULTRA 2
+#define UTP_TYPE_SUNI_622 3
+#define UTP_TYPE_IDT77105 4
+
+#ifdef _KERNEL
+
+#include <sys/queue.h>
+
+/*
+ * These must be implemented by the card driver
+ */
+struct utopia_methods {
+ /* read at most n PHY registers starting at reg into val */
+ int (*readregs)(struct ifatm *, u_int reg, uint8_t *val, u_int *n);
+
+ /* change the bits given by mask to them in val in register reg */
+ int (*writereg)(struct ifatm *, u_int reg, u_int mask, u_int val);
+};
+
+/*
+ * Public state
+ */
+struct utopia {
+ struct ifatm *ifatm; /* driver data */
+ struct ifmedia *media; /* driver supplied */
+ struct mtx *lock; /* driver supplied */
+ const struct utopia_methods *methods;
+ LIST_ENTRY(utopia) link; /* list of these structures */
+ u_int flags; /* flags set by the driver */
+ u_int state; /* current state */
+ u_int carrier; /* carrier state */
+ u_int loopback; /* loopback mode */
+ const struct utopia_chip *chip; /* chip operations */
+};
+
+struct utopia_chip {
+ /* type and name of the chip */
+ u_int type;
+ const char *const name;
+
+ /* number of registers */
+ u_int nregs;
+
+ /* reset chip to known state */
+ int (*reset)(struct utopia *);
+
+ /* set SONET/SDH mode */
+ int (*set_sdh)(struct utopia *, int sdh);
+
+ /* set idle/unassigned cells */
+ int (*set_unass)(struct utopia *, int unass);
+
+ /* enable/disable scrambling */
+ int (*set_noscramb)(struct utopia *, int noscramb);
+
+ /* update carrier status */
+ int (*update_carrier)(struct utopia *);
+
+ /* set loopback mode */
+ int (*set_loopback)(struct utopia *, u_int mode);
+
+ /* handle interrupt */
+ void (*intr)(struct utopia *);
+};
+
+/*
+ * These are implemented in the common utopia code
+ */
+int utopia_attach(struct utopia *, struct ifatm *, struct ifmedia *,
+ struct mtx *, struct sysctl_ctx_list *, struct sysctl_oid_list *,
+ const struct utopia_methods *);
+void utopia_detach(struct utopia *);
+
+int utopia_start(struct utopia *);
+void utopia_stop(struct utopia *);
+
+void utopia_init_media(struct utopia *);
+void utopia_reset_media(struct utopia *);
+
+#define utopia_reset(S) ((S)->chip->reset((S)))
+#define utopia_set_sdh(S, SDH) ((S)->chip->set_sdh((S), (SDH)))
+#define utopia_set_unass(S, U) ((S)->chip->set_unass((S), (U)))
+#define utopia_set_noscramb(S, N) ((S)->chip->set_noscramb((S), (N)))
+#define utopia_update_carrier(S) ((S)->chip->update_carrier((S)))
+#define utopia_set_loopback(S, L) ((S)->chip->set_loopback((S), (L)))
+#define utopia_intr(S) ((S)->chip->intr((S)))
+
+#endif /* _KERNEL */
+
+#endif /* _DEV_UTOPIA_UTOPIA_H */
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
index 4a7fd4b..71644c6 100644
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -132,6 +132,7 @@ SUBDIR= accf_data \
urio \
usb \
uscanner \
+ utopia \
uvisor \
uvscom \
vpo \
diff --git a/sys/modules/utopia/Makefile b/sys/modules/utopia/Makefile
new file mode 100644
index 0000000..19150ce
--- /dev/null
+++ b/sys/modules/utopia/Makefile
@@ -0,0 +1,8 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../dev/utopia
+
+KMOD= utopia
+SRCS= utopia.c bus_if.h device_if.h
+
+.include <bsd.kmod.mk>
OpenPOWER on IntegriCloud