summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorTakuya ASADA <syuu@cvs.openbsd.org>2011-06-16 11:22:31 +0000
committerTakuya ASADA <syuu@cvs.openbsd.org>2011-06-16 11:22:31 +0000
commit1a37173011aa926dacdeed9b4905dcddd762260d (patch)
tree4f130233142d3061b6740b79287f9cabd0c9c584 /sys/arch
parent331a508ecdab0cd58a22c47b6fb2480222747255 (diff)
Ethernet driver merged from IIJ's contribution code.
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/octeon/conf/GENERIC7
-rw-r--r--sys/arch/octeon/conf/RAMDISK7
-rw-r--r--sys/arch/octeon/conf/files.octeon19
-rw-r--r--sys/arch/octeon/dev/cn30xxasx.c254
-rw-r--r--sys/arch/octeon/dev/cn30xxasxreg.h293
-rw-r--r--sys/arch/octeon/dev/cn30xxasxvar.h56
-rw-r--r--sys/arch/octeon/dev/cn30xxbootbusreg.h262
-rw-r--r--sys/arch/octeon/dev/cn30xxciureg.h695
-rw-r--r--sys/arch/octeon/dev/cn30xxfau.c164
-rw-r--r--sys/arch/octeon/dev/cn30xxfaureg.h48
-rw-r--r--sys/arch/octeon/dev/cn30xxfauvar.h132
-rw-r--r--sys/arch/octeon/dev/cn30xxfpa.c473
-rw-r--r--sys/arch/octeon/dev/cn30xxfpareg.h515
-rw-r--r--sys/arch/octeon/dev/cn30xxfpavar.h155
-rw-r--r--sys/arch/octeon/dev/cn30xxgmx.c1733
-rw-r--r--sys/arch/octeon/dev/cn30xxgmxreg.h1245
-rw-r--r--sys/arch/octeon/dev/cn30xxgmxvar.h187
-rw-r--r--sys/arch/octeon/dev/cn30xxipd.c400
-rw-r--r--sys/arch/octeon/dev/cn30xxipdreg.h787
-rw-r--r--sys/arch/octeon/dev/cn30xxipdvar.h77
-rw-r--r--sys/arch/octeon/dev/cn30xxnpireg.h441
-rw-r--r--sys/arch/octeon/dev/cn30xxpip.c391
-rw-r--r--sys/arch/octeon/dev/cn30xxpipreg.h987
-rw-r--r--sys/arch/octeon/dev/cn30xxpipvar.h80
-rw-r--r--sys/arch/octeon/dev/cn30xxpko.c251
-rw-r--r--sys/arch/octeon/dev/cn30xxpkoreg.h404
-rw-r--r--sys/arch/octeon/dev/cn30xxpkovar.h173
-rw-r--r--sys/arch/octeon/dev/cn30xxpow.c1079
-rw-r--r--sys/arch/octeon/dev/cn30xxpowreg.h1045
-rw-r--r--sys/arch/octeon/dev/cn30xxpowvar.h508
-rw-r--r--sys/arch/octeon/dev/cn30xxsmi.c139
-rw-r--r--sys/arch/octeon/dev/cn30xxsmireg.h95
-rw-r--r--sys/arch/octeon/dev/cn30xxsmivar.h57
-rw-r--r--sys/arch/octeon/dev/cn30xxuartreg.h131
-rw-r--r--sys/arch/octeon/dev/if_cnmac.c1689
-rw-r--r--sys/arch/octeon/dev/if_cnmacvar.h135
-rw-r--r--sys/arch/octeon/dev/octeon_iobus.c19
-rw-r--r--sys/arch/octeon/include/octeon_model.h77
-rw-r--r--sys/arch/octeon/include/octeonvar.h411
39 files changed, 15615 insertions, 6 deletions
diff --git a/sys/arch/octeon/conf/GENERIC b/sys/arch/octeon/conf/GENERIC
index 60d028bcd39..bfa8522d0e4 100644
--- a/sys/arch/octeon/conf/GENERIC
+++ b/sys/arch/octeon/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.7 2011/05/08 13:39:30 syuu Exp $
+# $OpenBSD: GENERIC,v 1.8 2011/06/16 11:22:30 syuu Exp $
#
# For further information on compiling OpenBSD kernels, see the config(8)
# man page.
@@ -39,6 +39,11 @@ com1 at uartbus0
pcibus* at iobus0
pci* at pcibus?
+cn30xxgmx* at iobus?
+cnmac* at cn30xxgmx?
+
+rgephy* at mii?
+
# IDE Controller
pciide* at pci? flags 0x0000
diff --git a/sys/arch/octeon/conf/RAMDISK b/sys/arch/octeon/conf/RAMDISK
index f61b487ae35..8128fb6b373 100644
--- a/sys/arch/octeon/conf/RAMDISK
+++ b/sys/arch/octeon/conf/RAMDISK
@@ -1,4 +1,4 @@
-# $OpenBSD: RAMDISK,v 1.8 2011/05/08 13:39:30 syuu Exp $
+# $OpenBSD: RAMDISK,v 1.9 2011/06/16 11:22:30 syuu Exp $
#
# For further information on compiling OpenBSD kernels, see the config(8)
# man page.
@@ -59,6 +59,11 @@ pciide* at pci? flags 0x0000
# IDE hard drives
wd* at pciide? flags 0x0000
+cn30xxgmx* at iobus?
+cnmac* at cn30xxgmx?
+
+rgephy* at mii?
+
pseudo-device loop 1 # network loopback
pseudo-device bpfilter 1 # packet filter
pseudo-device rd 1 # ram disk
diff --git a/sys/arch/octeon/conf/files.octeon b/sys/arch/octeon/conf/files.octeon
index 276d02ada68..2510bfa5738 100644
--- a/sys/arch/octeon/conf/files.octeon
+++ b/sys/arch/octeon/conf/files.octeon
@@ -1,4 +1,4 @@
-# $OpenBSD: files.octeon,v 1.9 2011/05/15 08:52:48 matthieu Exp $
+# $OpenBSD: files.octeon,v 1.10 2011/06/16 11:22:30 syuu Exp $
# Standard stanzas config(8) can't run without
maxpartitions 16
@@ -30,6 +30,7 @@ include "dev/isa/files.isapnp"
include "dev/mii/files.mii"
include "dev/pci/files.pci"
include "dev/pci/files.agp"
+include "dev/pckbc/files.pckbc"
include "dev/usb/files.usb"
include "dev/bluetooth/files.bluetooth"
include "dev/rasops/files.rasops"
@@ -53,9 +54,25 @@ device iobus
attach iobus at mainbus
file arch/octeon/dev/octeon_iobus.c iobus
file arch/octeon/dev/octeon_intr.c iobus
+file arch/octeon/dev/cn30xxfpa.c iobus
+file arch/octeon/dev/cn30xxpow.c iobus
+file arch/octeon/dev/cn30xxfau.c iobus
+file arch/octeon/dev/cn30xxpip.c iobus
+file arch/octeon/dev/cn30xxipd.c iobus
+file arch/octeon/dev/cn30xxpko.c iobus
+file arch/octeon/dev/cn30xxasx.c iobus
+file arch/octeon/dev/cn30xxsmi.c iobus
# On-board CF
device octcf: disk
+
+device cn30xxgmx {}
+attach cn30xxgmx at iobus
+file arch/octeon/dev/cn30xxgmx.c cn30xxgmx
+
+device cnmac: ether, ifnet, mii, ifmedia
+attach cnmac at cn30xxgmx
+file arch/octeon/dev/if_cnmac.c cnmac
attach octcf at iobus
file arch/octeon/dev/octcf.c octcf
diff --git a/sys/arch/octeon/dev/cn30xxasx.c b/sys/arch/octeon/dev/cn30xxasx.c
new file mode 100644
index 00000000000..ebe5951dfbb
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxasx.c
@@ -0,0 +1,254 @@
+/* $OpenBSD: cn30xxasx.c,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+
+#include <machine/octeonvar.h>
+
+#include <octeon/dev/cn30xxasxreg.h>
+#include <octeon/dev/cn30xxasxvar.h>
+
+#ifndef SET
+#define SET(t, f) ((t) |= (f))
+#define ISSET(t, f) ((t) & (f))
+#define CLR(t, f) ((t) &= ~(f))
+#endif
+
+#ifdef OCTEON_ETH_DEBUG
+void cn30xxasx_intr_evcnt_attach(struct cn30xxasx_softc *);
+void cn30xxasx_intr_rml(void *);
+#endif
+
+#ifdef OCTEON_ETH_DEBUG
+struct cn30xxasx_softc *__cn30xxasx_softc;
+#endif
+
+/* XXX */
+void
+cn30xxasx_init(struct cn30xxasx_attach_args *aa,
+ struct cn30xxasx_softc **rsc)
+{
+ struct cn30xxasx_softc *sc;
+ int status;
+
+ sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
+ if (sc == NULL)
+ panic("can't allocate memory: %s", __func__);
+
+ sc->sc_port = aa->aa_port;
+ sc->sc_regt = aa->aa_regt;
+
+ status = bus_space_map(sc->sc_regt, ASX0_BASE, ASX0_SIZE, 0,
+ &sc->sc_regh);
+ if (status != 0)
+ panic("can't map %s space", "asx register");
+
+ *rsc = sc;
+
+#ifdef OCTEON_ETH_DEBUG
+ cn30xxasx_intr_evcnt_attach(sc);
+ if (__cn30xxasx_softc == NULL)
+ __cn30xxasx_softc = sc;
+#endif
+}
+
+#define _ASX_RD8(sc, off) \
+ bus_space_read_8((sc)->sc_regt, (sc)->sc_regh, (off))
+#define _ASX_WR8(sc, off, v) \
+ bus_space_write_8((sc)->sc_regt, (sc)->sc_regh, (off), (v))
+
+static int cn30xxasx_enable_tx(struct cn30xxasx_softc *, int);
+static int cn30xxasx_enable_rx(struct cn30xxasx_softc *, int);
+#ifdef OCTEON_ETH_DEBUG
+static int cn30xxasx_enable_intr(struct cn30xxasx_softc *, int);
+#endif
+
+int
+cn30xxasx_enable(struct cn30xxasx_softc *sc, int enable)
+{
+
+#ifdef OCTEON_ETH_DEBUG
+ cn30xxasx_enable_intr(sc, enable);
+#endif
+ cn30xxasx_enable_tx(sc, enable);
+ cn30xxasx_enable_rx(sc, enable);
+ return 0;
+}
+
+static int
+cn30xxasx_enable_tx(struct cn30xxasx_softc *sc, int enable)
+{
+ uint64_t asx_tx_port;
+
+ asx_tx_port = _ASX_RD8(sc, ASX0_TX_PRT_EN_OFFSET);
+ if (enable)
+ SET(asx_tx_port, 1 << sc->sc_port);
+ else
+ CLR(asx_tx_port, 1 << sc->sc_port);
+ _ASX_WR8(sc, ASX0_TX_PRT_EN_OFFSET, asx_tx_port);
+ return 0;
+}
+
+static int
+cn30xxasx_enable_rx(struct cn30xxasx_softc *sc, int enable)
+{
+ uint64_t asx_rx_port;
+
+ asx_rx_port = _ASX_RD8(sc, ASX0_RX_PRT_EN_OFFSET);
+ if (enable)
+ SET(asx_rx_port, 1 << sc->sc_port);
+ else
+ CLR(asx_rx_port, 1 << sc->sc_port);
+ _ASX_WR8(sc, ASX0_RX_PRT_EN_OFFSET, asx_rx_port);
+ return 0;
+}
+
+#if defined(OCTEON_ETH_DEBUG)
+int cn30xxasx_intr_rml_verbose;
+
+static const struct octeon_evcnt_entry cn30xxasx_intr_evcnt_entries[] = {
+#define _ENTRY(name, type, parent, descr) \
+ OCTEON_EVCNT_ENTRY(struct cn30xxasx_softc, name, type, parent, descr)
+ _ENTRY(asxrxpsh, MISC, NULL, "asx tx fifo overflow"),
+ _ENTRY(asxtxpop, MISC, NULL, "asx tx fifo underflow"),
+ _ENTRY(asxovrflw, MISC, NULL, "asx rx fifo overflow"),
+#undef _ENTRY
+};
+
+void
+cn30xxasx_intr_evcnt_attach(struct cn30xxasx_softc *sc)
+{
+ OCTEON_EVCNT_ATTACH_EVCNTS(sc, cn30xxasx_intr_evcnt_entries, "asx0");
+}
+
+void
+cn30xxasx_intr_rml(void *arg)
+{
+ struct cn30xxasx_softc *sc = __cn30xxasx_softc;
+ uint64_t reg = 0;
+
+ reg = cn30xxasx_int_summary(sc);
+ if (cn30xxasx_intr_rml_verbose)
+ printf("%s: ASX_INT_REG=0x%016" PRIx64 "\n", __func__, reg);
+ if (reg & ASX0_INT_REG_TXPSH)
+ OCTEON_EVCNT_INC(sc, asxrxpsh);
+ if (reg & ASX0_INT_REG_TXPOP)
+ OCTEON_EVCNT_INC(sc, asxtxpop);
+ if (reg & ASX0_INT_REG_OVRFLW)
+ OCTEON_EVCNT_INC(sc, asxovrflw);
+}
+
+static int
+cn30xxasx_enable_intr(struct cn30xxasx_softc *sc, int enable)
+{
+ uint64_t asx_int_xxx = 0;
+
+ SET(asx_int_xxx,
+ ASX0_INT_REG_TXPSH |
+ ASX0_INT_REG_TXPOP |
+ ASX0_INT_REG_OVRFLW);
+ _ASX_WR8(sc, ASX0_INT_REG_OFFSET, asx_int_xxx);
+ _ASX_WR8(sc, ASX0_INT_EN_OFFSET, enable ? asx_int_xxx : 0);
+ return 0;
+}
+#endif
+
+int
+cn30xxasx_clk_set(struct cn30xxasx_softc *sc, int setting)
+{
+ _ASX_WR8(sc, ASX0_TX_CLK_SET0_OFFSET + 8 * sc->sc_port, setting);
+ _ASX_WR8(sc, ASX0_RX_CLK_SET0_OFFSET + 8 * sc->sc_port, setting);
+ return 0;
+}
+
+#ifdef OCTEON_ETH_DEBUG
+uint64_t
+cn30xxasx_int_summary(struct cn30xxasx_softc *sc)
+{
+ uint64_t summary;
+
+ summary = _ASX_RD8(sc, ASX0_INT_REG_OFFSET);
+ _ASX_WR8(sc, ASX0_INT_REG_OFFSET, summary);
+ return summary;
+}
+
+#define _ENTRY(x) { #x, x##_BITS, x##_OFFSET }
+
+struct cn30xxasx_dump_reg_ {
+ const char *name;
+ const char *format;
+ size_t offset;
+};
+
+void cn30xxasx_dump(void);
+
+static const struct cn30xxasx_dump_reg_ cn30xxasx_dump_regs_[] = {
+ _ENTRY(ASX0_RX_PRT_EN),
+ _ENTRY(ASX0_TX_PRT_EN),
+ _ENTRY(ASX0_INT_REG),
+ _ENTRY(ASX0_INT_EN),
+ _ENTRY(ASX0_RX_CLK_SET0),
+ _ENTRY(ASX0_RX_CLK_SET1),
+ _ENTRY(ASX0_RX_CLK_SET2),
+ _ENTRY(ASX0_PRT_LOOP),
+ _ENTRY(ASX0_TX_CLK_SET0),
+ _ENTRY(ASX0_TX_CLK_SET1),
+ _ENTRY(ASX0_TX_CLK_SET2),
+ _ENTRY(ASX0_COMP_BYP),
+ _ENTRY(ASX0_TX_HI_WATER000),
+ _ENTRY(ASX0_TX_HI_WATER001),
+ _ENTRY(ASX0_TX_HI_WATER002),
+ _ENTRY(ASX0_GMII_RX_CLK_SET),
+ _ENTRY(ASX0_GMII_RX_DAT_SET),
+ _ENTRY(ASX0_MII_RX_DAT_SET),
+};
+
+void
+cn30xxasx_dump(void)
+{
+ struct cn30xxasx_softc *sc = __cn30xxasx_softc;
+ const struct cn30xxasx_dump_reg_ *reg;
+ uint64_t tmp;
+ char buf[512];
+ int i;
+
+ for (i = 0; i < (int)nitems(cn30xxasx_dump_regs_); i++) {
+ reg = &cn30xxasx_dump_regs_[i];
+ tmp = _ASX_RD8(sc, reg->offset);
+ if (reg->format == NULL)
+ snprintf(buf, sizeof(buf), "%016" PRIx64, tmp);
+ else
+ bitmask_snprintf(tmp, reg->format, buf, sizeof(buf));
+ printf("\t%-24s: %s\n", reg->name, buf);
+ }
+}
+#endif
diff --git a/sys/arch/octeon/dev/cn30xxasxreg.h b/sys/arch/octeon/dev/cn30xxasxreg.h
new file mode 100644
index 00000000000..713bd710752
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxasxreg.h
@@ -0,0 +1,293 @@
+/*
+ * THIS FILE IS AUTOMATICALLY GENERATED
+ * DONT EDIT THIS FILE
+ */
+
+/* $OpenBSD: cn30xxasxreg.h,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Cavium Networks OCTEON CN30XX Hardware Reference Manual
+ * CN30XX-HM-1.0
+ * 13.9 ASX Registers
+ */
+
+#ifndef _CN30XXASXREG_H_
+#define _CN30XXASXREG_H_
+
+#define ASX0_RX_PRT_EN 0x00011800b0000000ULL
+#define ASX0_TX_PRT_EN 0x00011800b0000008ULL
+#define ASX0_INT_REG 0x00011800b0000010ULL
+#define ASX0_INT_EN 0x00011800b0000018ULL
+#define ASX0_RX_CLK_SET0 0x00011800b0000020ULL
+#define ASX0_RX_CLK_SET1 0x00011800b0000028ULL
+#define ASX0_RX_CLK_SET2 0x00011800b0000030ULL
+#define ASX0_PRT_LOOP 0x00011800b0000040ULL
+#define ASX0_TX_CLK_SET0 0x00011800b0000048ULL
+#define ASX0_TX_CLK_SET1 0x00011800b0000050ULL
+#define ASX0_TX_CLK_SET2 0x00011800b0000058ULL
+#define ASX0_COMP_BYP 0x00011800b0000068ULL
+#define ASX0_TX_HI_WATER000 0x00011800b0000080ULL
+#define ASX0_TX_HI_WATER001 0x00011800b0000088ULL
+#define ASX0_TX_HI_WATER002 0x00011800b0000090ULL
+#define ASX0_GMII_RX_CLK_SET 0x00011800b0000180ULL
+#define ASX0_GMII_RX_DAT_SET 0x00011800b0000188ULL
+#define ASX0_MII_RX_DAT_SET 0x00011800b0000190ULL
+
+#define ASX0_BASE 0x00011800b0000000ULL
+#define ASX0_SIZE 0x0198ULL
+
+#define ASX0_RX_PRT_EN_OFFSET 0x0000
+#define ASX0_TX_PRT_EN_OFFSET 0x0008
+#define ASX0_INT_REG_OFFSET 0x0010
+#define ASX0_INT_EN_OFFSET 0x0018
+#define ASX0_RX_CLK_SET0_OFFSET 0x0020
+#define ASX0_RX_CLK_SET1_OFFSET 0x0028
+#define ASX0_RX_CLK_SET2_OFFSET 0x0030
+#define ASX0_PRT_LOOP_OFFSET 0x0040
+#define ASX0_TX_CLK_SET0_OFFSET 0x0048
+#define ASX0_TX_CLK_SET1_OFFSET 0x0050
+#define ASX0_TX_CLK_SET2_OFFSET 0x0058
+#define ASX0_COMP_BYP_OFFSET 0x0068
+#define ASX0_TX_HI_WATER000_OFFSET 0x0080
+#define ASX0_TX_HI_WATER001_OFFSET 0x0088
+#define ASX0_TX_HI_WATER002_OFFSET 0x0090
+#define ASX0_GMII_RX_CLK_SET_OFFSET 0x0180
+#define ASX0_GMII_RX_DAT_SET_OFFSET 0x0188
+#define ASX0_MII_RX_DAT_SET_OFFSET 0x0190
+
+/* XXX */
+
+
+/*
+ * ASX_RX_PRT_EN
+ */
+#define ASX0_RX_PRT_EN_63_3 0xfffffff8
+#define ASX0_RX_PRT_EN_PRT_EN 0x00000007
+
+/*
+ * ASX0_TX_PRT_EN
+ */
+#define ASX0_TX_PRT_EN_63_3 0xfffffff8
+#define ASX0_TX_PRT_EN_PRT_EN 0x00000007
+
+/*
+ * ASX0_INT_REG
+ */
+#define ASX0_INT_REG_63_11 0xfffff800
+#define ASX0_INT_REG_TXPSH 0x00000700
+#define ASX0_INT_REG_7 0x00000080
+#define ASX0_INT_REG_TXPOP 0x00000070
+#define ASX0_INT_REG_3 0x00000008
+#define ASX0_INT_REG_OVRFLW 0x00000007
+
+/*
+ * ASX0_INT_EN
+ */
+#define ASX0_INT_EN_63_11 0xfffff800
+#define ASX0_INT_EN_TXPSH 0x00000700
+#define ASX0_INT_EN_7 0x00000080
+#define ASX0_INT_EN_TXPOP 0x00000070
+#define ASX0_INT_EN_3 0x00000008
+#define ASX0_INT_EN_OVRFLW 0x00000007
+
+/*
+ * ASX0_RX_CLK_SET
+ */
+#define ASX0_RX_CLK_SET_63_5 0xffffffe0
+#define ASX0_RX_CLK_SET_SETTING 0x0000001f
+
+/*
+ * ASX0_RRT_LOOP
+ */
+#define ASX0_PRT_LOOP_63_7 0xffffff80
+#define ASX0_PRT_LOOP_EXT_LOOP 0x00000070
+#define ASX0_PRT_LOOP_3 0x00000008
+#define ASX0_PRT_LOOP_PRT_LOOP 0x00000007
+
+/*
+ * ASX0_TX_CLK_SET
+ */
+#define ASX0_TX_CLK_SET_63_5 0xffffffe0
+#define ASX0_TX_CLK_SET_SETTING 0x0000001f
+
+/*
+ * ASX0_TX_COMP_BYP
+ */
+#define ASX0_TX_COMP_BYP_63_9 0xfffffe00
+#define ASX0_TX_COMP_BYP_BYPASS 0x00000100
+#define ASX0_TX_COMP_BYP_PCTL 0x000000f0
+#define ASX0_TX_COMP_BYP_NCTL 0x0000000f
+
+/*
+ * ASX0_TX_HI_WATER
+ */
+#define ASX0_TX_HI_WATER_63_3 0xfffffff8
+#define ASX0_TX_HI_WATER_MARK 0x00000007
+
+/*
+ * ASX0_GMXII_RX_CLK_SET
+ */
+#define ASX0_GMII_RX_CLK_SET_63_5 0xffffffe0
+#define ASX0_GMII_RX_CLK_SET_SETTING 0x0000001f
+
+/*
+ * ASX0_GMXII_RX_DAT_SET
+ */
+#define ASX0_GMII_RX_DAT_SET_63_5 0xffffffe0
+#define ASX0_GMII_RX_DAT_SET_SETTING 0x0000001f
+
+/* ---- */
+
+#define ASX0_RX_PRT_EN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x03\x3d" "63_3\0" \
+ "f\x00\x03" "PRT_EN\0"
+#define ASX0_TX_PRT_EN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x03\x3d" "63_3\0" \
+ "f\x00\x03" "PRT_EN\0"
+#define ASX0_INT_REG_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x0b\x35" "63_11\0" \
+ "f\x08\x03" "TXPSH\0" \
+ "b\x07" "7\0" \
+ "f\x04\x03" "TXPOP\0" \
+ "b\x03" "3\0" \
+ "f\x00\x03" "OVRFLW\0"
+#define ASX0_INT_EN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x0b\x35" "63_11\0" \
+ "f\x08\x03" "TXPSH\0" \
+ "b\x07" "7\0" \
+ "f\x04\x03" "TXPOP\0" \
+ "b\x03" "3\0" \
+ "f\x00\x03" "OVRFLW\0"
+#define ASX0_RX_CLK_SET0_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define ASX0_RX_CLK_SET1_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define ASX0_RX_CLK_SET2_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define ASX0_PRT_LOOP_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x07\x39" "63_7\0" \
+ "f\x04\x03" "EXT_LOOP\0" \
+ "b\x03" "3\0" \
+ "f\x00\x03" "PRT_LOOP\0"
+#define ASX0_TX_CLK_SET0_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define ASX0_TX_CLK_SET1_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define ASX0_TX_CLK_SET2_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define ASX0_COMP_BYP_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define ASX0_TX_HI_WATER000_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define ASX0_TX_HI_WATER001_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define ASX0_TX_HI_WATER002_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define ASX0_GMII_RX_CLK_SET_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x05\x3b" "63_5\0" \
+ "f\x00\x05" "SETTING\0"
+#define ASX0_GMII_RX_DAT_SET_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x05\x3b" "63_5\0" \
+ "f\x00\x05" "SETTING\0"
+#define ASX0_MII_RX_DAT_SET_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+
+#endif /* _CN30XXASXREG_H_ */
diff --git a/sys/arch/octeon/dev/cn30xxasxvar.h b/sys/arch/octeon/dev/cn30xxasxvar.h
new file mode 100644
index 00000000000..f32ad4d0cd7
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxasxvar.h
@@ -0,0 +1,56 @@
+/* $OpenBSD: cn30xxasxvar.h,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _CN30XXASXVAR_H_
+#define _CN30XXASXVAR_H_
+
+/* XXX */
+struct cn30xxasx_softc {
+ int sc_port;
+ bus_space_tag_t sc_regt;
+ bus_space_handle_t sc_regh;
+#if defined(OCTEON_DEBUG) || defined(OCTEON_ETH_DEBUG)
+ struct evcnt sc_ev_asxrxpsh;
+ struct evcnt sc_ev_asxtxpop;
+ struct evcnt sc_ev_asxovrflw;
+#endif
+};
+
+/* XXX */
+struct cn30xxasx_attach_args {
+ int aa_port;
+ bus_space_tag_t aa_regt;
+};
+
+void cn30xxasx_init(struct cn30xxasx_attach_args *,
+ struct cn30xxasx_softc **);
+int cn30xxasx_enable(struct cn30xxasx_softc *, int);
+int cn30xxasx_clk_set(struct cn30xxasx_softc *, int);
+uint64_t cn30xxasx_int_summary(struct cn30xxasx_softc *sc);
+
+#endif
diff --git a/sys/arch/octeon/dev/cn30xxbootbusreg.h b/sys/arch/octeon/dev/cn30xxbootbusreg.h
new file mode 100644
index 00000000000..bf577b1a7dd
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxbootbusreg.h
@@ -0,0 +1,262 @@
+/*
+ * THIS FILE IS AUTOMATICALLY GENERATED
+ * DONT EDIT THIS FILE
+ */
+
+/* $OpenBSD: cn30xxbootbusreg.h,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Cavium Networks OCTEON CN30XX Hardware Reference Manual
+ * CN30XX-HM-1.0
+ * 12.8 Boot-Bus Registers
+ */
+
+#ifndef _CN30XXBOOTBUSREG_H_
+#define _CN30XXBOOTBUSREG_H_
+
+/* ---- register addresses */
+
+#define MIO_BOOT_REG_CFG0 0x0001180000000000ULL
+#define MIO_BOOT_REG_CFG1 0x0001180000000008ULL
+#define MIO_BOOT_REG_CFG2 0x0001180000000010ULL
+#define MIO_BOOT_REG_CFG3 0x0001180000000018ULL
+#define MIO_BOOT_REG_CFG4 0x0001180000000020ULL
+#define MIO_BOOT_REG_CFG5 0x0001180000000028ULL
+#define MIO_BOOT_REG_CFG6 0x0001180000000030ULL
+#define MIO_BOOT_REG_CFG7 0x0001180000000038ULL
+#define MIO_BOOT_REG_TIM0 0x0001180000000040ULL
+#define MIO_BOOT_REG_TIM1 0x0001180000000048ULL
+#define MIO_BOOT_REG_TIM2 0x0001180000000050ULL
+#define MIO_BOOT_REG_TIM3 0x0001180000000058ULL
+#define MIO_BOOT_REG_TIM4 0x0001180000000060ULL
+#define MIO_BOOT_REG_TIM5 0x0001180000000068ULL
+#define MIO_BOOT_REG_TIM6 0x0001180000000070ULL
+#define MIO_BOOT_REG_TIM7 0x0001180000000078ULL
+#define MIO_BOOT_LOC_CFG0 0x0001180000000080ULL
+#define MIO_BOOT_LOC_CFG1 0x0001180000000088ULL
+#define MIO_BOOT_LOC_ADR 0x0001180000000090ULL
+#define MIO_BOOT_LOC_DAT 0x0001180000000098ULL
+#define MIO_BOOT_ERR 0x00011800000000a0ULL
+#define MIO_BOOT_INT 0x00011800000000a8ULL
+#define MIO_BOOT_THR 0x00011800000000b0ULL
+#define MIO_BOOT_BIST_STAT 0x00011800000000f8ULL
+
+/* ---- register bits */
+
+#define MIO_BOOT_REG_CFGN_XXX_63_37 0xffffffe000000000ULL
+#define MIO_BOOT_REG_CFGN_SAM 0x0000001000000000ULL
+#define MIO_BOOT_REG_CFGN_WE_EXT 0x0000000c00000000ULL
+#define MIO_BOOT_REG_CFGN_OE_EXT 0x0000000300000000ULL
+#define MIO_BOOT_REG_CFGN_EN 0x0000000080000000ULL
+#define MIO_BOOT_REG_CFGN_OR 0x0000000040000000ULL
+#define MIO_BOOT_REG_CFGN_ALE 0x0000000020000000ULL
+#define MIO_BOOT_REG_CFGN_WIDTH 0x0000000010000000ULL
+#define MIO_BOOT_REG_CFGN_SIZE 0x000000000fff0000ULL
+#define MIO_BOOT_REG_CFGN_BASE 0x000000000000ffffULL
+
+#define MIO_BOOT_REG_TIMN_PAGEM 0x8000000000000000ULL
+#define MIO_BOOT_REG_TIMN_WAITM 0x4000000000000000ULL
+#define MIO_BOOT_REG_TIMN_PAGES 0x3000000000000000ULL
+#define MIO_BOOT_REG_TIMN_ALE 0x0fc0000000000000ULL
+#define MIO_BOOT_REG_TIMN_PAGE 0x003f000000000000ULL
+#define MIO_BOOT_REG_TIMN_WAIT 0x0000fc0000000000ULL
+#define MIO_BOOT_REG_TIMN_PAUSE 0x000003f000000000ULL
+#define MIO_BOOT_REG_TIMN_WR_HLD 0x0000000fc0000000ULL
+#define MIO_BOOT_REG_TIMN_RD_HLD 0x000000003f000000ULL
+#define MIO_BOOT_REG_TIMN_WE 0x0000000000fc0000ULL
+#define MIO_BOOT_REG_TIMN_OE 0x000000000003f000ULL
+#define MIO_BOOT_REG_TIMN_CE 0x0000000000000fc0ULL
+#define MIO_BOOT_REG_TIMN_ADR 0x000000000000003fULL
+
+#define MIO_BOOT_LOC_CFGN_XXX_63_32 0xffffffff00000000ULL
+#define MIO_BOOT_LOC_CFGN_EN 0x0000000080000000ULL
+#define MIO_BOOT_LOC_CFGN_XXX_30_28 0x0000000070000000ULL
+#define MIO_BOOT_LOC_CFGN_BASE 0x000000000ffffff8ULL
+#define MIO_BOOT_LOC_CFGN_XXX_2_0 0x0000000000000007ULL
+
+#define MIO_BOOT_LOC_ADR_XXX_63_8 0xffffffffffffff00ULL
+#define MIO_BOOT_LOC_ADR_ADR 0x00000000000000f8ULL
+#define MIO_BOOT_LOC_ADR_XXX_2_0 0x0000000000000007ULL
+
+#define MIO_BOOT_ERR_XXX_63_2 0xfffffffffffffffcULL
+#define MIO_BOOT_ERR_WAIT_ERR 0x0000000000000002ULL
+#define MIO_BOOT_ERR_ADR_ERR 0x0000000000000001ULL
+
+#define MIO_BOOT_INT_XXX_63_2 0xfffffffffffffffcULL
+#define MIO_BOOT_INT_WAIT_INT 0x0000000000000002ULL
+#define MIO_BOOT_INT_ADR_INT 0x0000000000000001ULL
+
+#define MIO_BOOT_THR_XXX_63_14 0xffffffffffffc000ULL
+#define MIO_BOOT_THR_FIF_CNT 0x0000000000003f00ULL
+#define MIO_BOOT_THR_XXX_7_6 0x00000000000000c0ULL
+#define MIO_BOOT_THR_FIF_THR 0x000000000000003fULL
+
+#define MIO_BOOT_BIST_STAT_XXX_63_4 0xfffffffffffffff0ULL
+#define MIO_BOOT_BIST_STAT_NCBO_1 0x0000000000000008ULL
+#define MIO_BOOT_BIST_STAT_NCBO_0 0x0000000000000004ULL
+#define MIO_BOOT_BIST_STAT_LOC 0x0000000000000002ULL
+#define MIO_BOOT_BIST_STAT_NCBI 0x0000000000000001ULL
+
+/* ---- bitmask_snprintf */
+
+#define MIO_BOOT_REG_CFGN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x24" "SAM\0" \
+ "f\x22\x02" "WE_EXT\0" \
+ "f\x20\x02" "OE_EXT\0" \
+ "b\x1f" "EN\0" \
+ "b\x1e" "OR\0" \
+ "b\x1d" "ALE\0" \
+ "b\x1c" "WIDTH\0" \
+ "f\x10\x0c" "SIZE\0" \
+ "f\x00\x10" "BASE\0"
+#define MIO_BOOT_REG_CFG0_BITS MIO_BOOT_REG_CFGN_BITS
+#define MIO_BOOT_REG_CFG1_BITS MIO_BOOT_REG_CFGN_BITS
+#define MIO_BOOT_REG_CFG2_BITS MIO_BOOT_REG_CFGN_BITS
+#define MIO_BOOT_REG_CFG3_BITS MIO_BOOT_REG_CFGN_BITS
+#define MIO_BOOT_REG_CFG4_BITS MIO_BOOT_REG_CFGN_BITS
+#define MIO_BOOT_REG_CFG5_BITS MIO_BOOT_REG_CFGN_BITS
+#define MIO_BOOT_REG_CFG6_BITS MIO_BOOT_REG_CFGN_BITS
+#define MIO_BOOT_REG_CFG7_BITS MIO_BOOT_REG_CFGN_BITS
+
+#define MIO_BOOT_REG_TIMN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x3f" "PAGEM\0" \
+ "b\x3e" "WAITM\0" \
+ "f\x3c\x02" "PAGES\0" \
+ "f\x36\x06" "ALE\0" \
+ "f\x30\x06" "PAGE\0" \
+ "f\x2a\x06" "WAIT\0" \
+ "f\x24\x06" "PAUSE\0" \
+ "f\x1e\x06" "WR_HLD\0" \
+ "f\x18\x06" "RD_HLD\0" \
+ "f\x12\x06" "WE\0" \
+ "f\x0c\x06" "OE\0" \
+ "f\x06\x06" "CE\0" \
+ "f\x00\x06" "ADR\0"
+#define MIO_BOOT_REG_TIM0_BITS MIO_BOOT_REG_TIMN_BITS
+#define MIO_BOOT_REG_TIM1_BITS MIO_BOOT_REG_TIMN_BITS
+#define MIO_BOOT_REG_TIM2_BITS MIO_BOOT_REG_TIMN_BITS
+#define MIO_BOOT_REG_TIM3_BITS MIO_BOOT_REG_TIMN_BITS
+#define MIO_BOOT_REG_TIM4_BITS MIO_BOOT_REG_TIMN_BITS
+#define MIO_BOOT_REG_TIM5_BITS MIO_BOOT_REG_TIMN_BITS
+#define MIO_BOOT_REG_TIM6_BITS MIO_BOOT_REG_TIMN_BITS
+#define MIO_BOOT_REG_TIM7_BITS MIO_BOOT_REG_TIMN_BITS
+
+#define MIO_BOOT_LOC_CFGN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x1f" "EN\0" \
+ "f\x03\x19" "BASE\0"
+#define MIO_BOOT_LOC_CFG0_BITS MIO_BOOT_LOC_CFGN_BITS
+#define MIO_BOOT_LOC_CFG1_BITS MIO_BOOT_LOC_CFGN_BITS
+#define MIO_BOOT_LOC_CFG2_BITS MIO_BOOT_LOC_CFGN_BITS
+#define MIO_BOOT_LOC_CFG3_BITS MIO_BOOT_LOC_CFGN_BITS
+#define MIO_BOOT_LOC_CFG4_BITS MIO_BOOT_LOC_CFGN_BITS
+#define MIO_BOOT_LOC_CFG5_BITS MIO_BOOT_LOC_CFGN_BITS
+#define MIO_BOOT_LOC_CFG6_BITS MIO_BOOT_LOC_CFGN_BITS
+#define MIO_BOOT_LOC_CFG7_BITS MIO_BOOT_LOC_CFGN_BITS
+
+#define MIO_BOOT_LOC_ADR_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x03\x05" "ADR\0"
+
+#define MIO_BOOT_ERR_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x01" "WAIT_ERR\0" \
+ "b\x00" "ADR_ERR\0"
+
+#define MIO_BOOT_INT_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x01" "WAIT_INT\0" \
+ "b\x00" "ADR_INT\0"
+
+#define MIO_BOOT_THR_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x08\x06" "FIF_CNT\0" \
+ "f\x00\x06" "FIF_THR\0"
+
+#define MIO_BOOT_BIST_STAT_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x03" "NCBO_1\0" \
+ "b\x02" "NCBO_0\0" \
+ "b\x01" "LOC\0" \
+ "b\x00" "NCBI\0"
+
+/* ---- bus_space */
+
+#define MIO_BOOT_REG_CFG0_OFFSET 0x0000
+#define MIO_BOOT_REG_CFG1_OFFSET 0x0008
+#define MIO_BOOT_REG_CFG2_OFFSET 0x0010
+#define MIO_BOOT_REG_CFG3_OFFSET 0x0018
+#define MIO_BOOT_REG_CFG4_OFFSET 0x0020
+#define MIO_BOOT_REG_CFG5_OFFSET 0x0028
+#define MIO_BOOT_REG_CFG6_OFFSET 0x0030
+#define MIO_BOOT_REG_CFG7_OFFSET 0x0038
+#define MIO_BOOT_REG_TIM0_OFFSET 0x0040
+#define MIO_BOOT_REG_TIM1_OFFSET 0x0048
+#define MIO_BOOT_REG_TIM2_OFFSET 0x0050
+#define MIO_BOOT_REG_TIM3_OFFSET 0x0058
+#define MIO_BOOT_REG_TIM4_OFFSET 0x0060
+#define MIO_BOOT_REG_TIM5_OFFSET 0x0068
+#define MIO_BOOT_REG_TIM6_OFFSET 0x0070
+#define MIO_BOOT_REG_TIM7_OFFSET 0x0078
+#define MIO_BOOT_LOC_CFG0_OFFSET 0x0080
+#define MIO_BOOT_LOC_CFG1_OFFSET 0x0088
+#define MIO_BOOT_LOC_ADR_OFFSET 0x0090
+#define MIO_BOOT_LOC_DAT_OFFSET 0x0098
+#define MIO_BOOT_ERR_OFFSET 0x00a0
+#define MIO_BOOT_INT_OFFSET 0x00a8
+#define MIO_BOOT_THR_OFFSET 0x00b0
+#define MIO_BOOT_BIST_STAT_OFFSET 0x00f8
+
+#endif /* _CN30XXBOOTBUSREG_H_ */
diff --git a/sys/arch/octeon/dev/cn30xxciureg.h b/sys/arch/octeon/dev/cn30xxciureg.h
new file mode 100644
index 00000000000..f57259b10a5
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxciureg.h
@@ -0,0 +1,695 @@
+/*
+ * THIS FILE IS AUTOMATICALLY GENERATED
+ * DONT EDIT THIS FILE
+ */
+
+/* $OpenBSD: cn30xxciureg.h,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Cavium Networks OCTEON CN30XX Hardware Reference Manual
+ * CN30XX-HM-1.0
+ * 11.10 CIU Registers
+ */
+
+#ifndef _CN30XXCIUREG_H_
+#define _CN30XXCIUREG_H_
+
+/* ---- register addresses */
+
+#define CIU_INT0_SUM0 0x0001070000000000ULL
+#define CIU_INT1_SUM0 0x0001070000000008ULL
+#define CIU_INT2_SUM0 0x0001070000000010ULL
+#define CIU_INT3_SUM0 0x0001070000000018ULL
+#define CIU_INT32_SUM0 0x0001070000000100ULL
+#define CIU_INT_SUM1 0x0001070000000008ULL
+#define CIU_INT0_EN0 0x0001070000000200ULL
+#define CIU_INT1_EN0 0x0001070000000210ULL
+#define CIU_INT2_EN0 0x0001070000000220ULL
+#define CIU_INT3_EN0 0x0001070000000230ULL
+#define CIU_INT32_EN0 0x0001070000000400ULL
+#define CIU_INT0_EN1 0x0001070000000208ULL
+#define CIU_INT1_EN1 0x0001070000000218ULL
+#define CIU_INT2_EN1 0x0001070000000228ULL
+#define CIU_INT3_EN1 0x0001070000000238ULL
+#define CIU_INT32_EN1 0x0001070000000408ULL
+#define CIU_TIM0 0x0001070000000480ULL
+#define CIU_TIM1 0x0001070000000488ULL
+#define CIU_TIM2 0x0001070000000490ULL
+#define CIU_TIM3 0x0001070000000498ULL
+#define CIU_WDOG0 0x0001070000000500ULL
+#define CIU_WDOG1 0x0001070000000508ULL
+#define CIU_PP_POKE0 0x0001070000000580ULL
+#define CIU_PP_POKE1 0x0001070000000588ULL
+#define CIU_MBOX_SET0 0x0001070000000600ULL
+#define CIU_MBOX_SET1 0x0001070000000600ULL
+#define CIU_MBOX_CLR0 0x0001070000000680ULL
+#define CIU_MBOX_CLR1 0x0001070000000680ULL
+#define CIU_PP_RST 0x0001070000000700ULL
+#define CIU_PP_DBG 0x0001070000000708ULL
+#define CIU_GSTOP 0x0001070000000710ULL
+#define CIU_NMI 0x0001070000000718ULL
+#define CIU_DINT 0x0001070000000720ULL
+#define CIU_FUSE 0x0001070000000728ULL
+#define CIU_BIST 0x0001070000000730ULL
+#define CIU_SOFT_BIST 0x0001070000000738ULL
+#define CIU_SOFT_RST 0x0001070000000740ULL
+#define CIU_SOFT_PRST 0x0001070000000748ULL
+#define CIU_PCI_INTA 0x0001070000000750ULL
+
+#define CIU_INT0_SUM0_OFFSET 0x0000
+#define CIU_INT1_SUM0_OFFSET 0x0008
+#define CIU_INT2_SUM0_OFFSET 0x0010
+#define CIU_INT3_SUM0_OFFSET 0x0018
+#define CIU_INT32_SUM0_OFFSET 0x0100
+#define CIU_INT_SUM1_OFFSET 0x0008
+#define CIU_INT0_EN0_OFFSET 0x0200
+#define CIU_INT1_EN0_OFFSET 0x0210
+#define CIU_INT2_EN0_OFFSET 0x0220
+#define CIU_INT3_EN0_OFFSET 0x0230
+#define CIU_INT32_EN0_OFFSET 0x0400
+#define CIU_INT0_EN1_OFFSET 0x0208
+#define CIU_INT1_EN1_OFFSET 0x0218
+#define CIU_INT2_EN1_OFFSET 0x0228
+#define CIU_INT3_EN1_OFFSET 0x0238
+#define CIU_INT32_EN1_OFFSET 0x0408
+#define CIU_TIM0_OFFSET 0x0480
+#define CIU_TIM1_OFFSET 0x0488
+#define CIU_TIM2_OFFSET 0x0490
+#define CIU_TIM3_OFFSET 0x0498
+#define CIU_WDOG0_OFFSET 0x0500
+#define CIU_WDOG1_OFFSET 0x0508
+#define CIU_PP_POKE0_OFFSET 0x0580
+#define CIU_PP_POKE1_OFFSET 0x0588
+#define CIU_MBOX_SET0_OFFSET 0x0600
+#define CIU_MBOX_SET1_OFFSET 0x0608
+#define CIU_MBOX_CLR0_OFFSET 0x0680
+#define CIU_MBOX_CLR1_OFFSET 0x0688
+#define CIU_PP_RST_OFFSET 0x0700
+#define CIU_PP_DBG_OFFSET 0x0708
+#define CIU_GSTOP_OFFSET 0x0710
+#define CIU_NMI_OFFSET 0x0718
+#define CIU_DINT_OFFSET 0x0720
+#define CIU_FUSE_OFFSET 0x0728
+#define CIU_BIST_OFFSET 0x0730
+#define CIU_SOFT_BIST_OFFSET 0x0738
+#define CIU_SOFT_RST_OFFSET 0x0740
+#define CIU_SOFT_PRST_OFFSET 0x0748
+#define CIU_PCI_INTA_OFFSET 0x0750
+
+/* ---- register bits */
+
+/* ``interrupt bits'' shift values */
+
+#define _CIU_INT_XXX_63_SHIFT 0x3f
+#define _CIU_INT_XXX_62_SHIFT 0x3e
+#define _CIU_INT_XXX_61_SHIFT 0x3d
+#define _CIU_INT_XXX_60_SHIFT 0x3c
+#define _CIU_INT_XXX_59_SHIFT 0x3b
+#define _CIU_INT_MPI_SHIFT 0x3a
+#define _CIU_INT_PCM_SHIFT 0x39
+#define _CIU_INT_USB_SHIFT 0x38
+#define _CIU_INT_TIMER_3_SHIFT 0x37
+#define _CIU_INT_TIMER_2_SHIFT 0x36
+#define _CIU_INT_TIMER_1_SHIFT 0x35
+#define _CIU_INT_TIMER_0_SHIFT 0x34
+#define _CIU_INT_XXX_51_SHIFT 0x33
+#define _CIU_INT_IPD_DRP_SHIFT 0x32
+#define _CIU_INT_GMX_DRP_SHIFT 0x30
+#define _CIU_INT_TRACE_SHIFT 0x2f
+#define _CIU_INT_RML_SHIFT 0x2e
+#define _CIU_INT_TWSI_SHIFT 0x2d
+#define _CIU_INT_WDOG_SUM_SHIFT 0x2c
+#define _CIU_INT_PCI_MSI_63_48_SHIFT 0x2b
+#define _CIU_INT_PCI_MSI_47_32_SHIFT 0x2a
+#define _CIU_INT_PCI_MSI_31_16_SHIFT 0x29
+#define _CIU_INT_PCI_MSI_15_0_SHIFT 0x28
+#define _CIU_INT_PCI_INT_D_SHIFT 0x27
+#define _CIU_INT_PCI_INT_C_SHIFT 0x26
+#define _CIU_INT_PCI_INT_B_SHIFT 0x25
+#define _CIU_INT_PCI_INT_A_SHIFT 0x24
+#define _CIU_INT_UART_1_SHIFT 0x23
+#define _CIU_INT_UART_0_SHIFT 0x22
+#define _CIU_INT_MBOX_31_16_SHIFT 0x21
+#define _CIU_INT_MBOX_15_0_SHIFT 0x20
+#define _CIU_INT_GPIO_15_SHIFT 0x1f
+#define _CIU_INT_GPIO_14_SHIFT 0x1e
+#define _CIU_INT_GPIO_13_SHIFT 0x1d
+#define _CIU_INT_GPIO_12_SHIFT 0x1c
+#define _CIU_INT_GPIO_11_SHIFT 0x1b
+#define _CIU_INT_GPIO_10_SHIFT 0x1a
+#define _CIU_INT_GPIO_9_SHIFT 0x19
+#define _CIU_INT_GPIO_8_SHIFT 0x18
+#define _CIU_INT_GPIO_7_SHIFT 0x17
+#define _CIU_INT_GPIO_6_SHIFT 0x16
+#define _CIU_INT_GPIO_5_SHIFT 0x15
+#define _CIU_INT_GPIO_4_SHIFT 0x14
+#define _CIU_INT_GPIO_3_SHIFT 0x13
+#define _CIU_INT_GPIO_2_SHIFT 0x12
+#define _CIU_INT_GPIO_1_SHIFT 0x11
+#define _CIU_INT_GPIO_0_SHIFT 0x10
+#define _CIU_INT_WORKQ_15_SHIFT 0x0f
+#define _CIU_INT_WORKQ_14_SHIFT 0x0e
+#define _CIU_INT_WORKQ_13_SHIFT 0x0d
+#define _CIU_INT_WORKQ_12_SHIFT 0x0c
+#define _CIU_INT_WORKQ_11_SHIFT 0x0b
+#define _CIU_INT_WORKQ_10_SHIFT 0x0a
+#define _CIU_INT_WORKQ_9_SHIFT 0x09
+#define _CIU_INT_WORKQ_8_SHIFT 0x08
+#define _CIU_INT_WORKQ_7_SHIFT 0x07
+#define _CIU_INT_WORKQ_6_SHIFT 0x06
+#define _CIU_INT_WORKQ_5_SHIFT 0x05
+#define _CIU_INT_WORKQ_4_SHIFT 0x04
+#define _CIU_INT_WORKQ_3_SHIFT 0x03
+#define _CIU_INT_WORKQ_2_SHIFT 0x02
+#define _CIU_INT_WORKQ_1_SHIFT 0x01
+
+#define CIU_INTX_SUM0_XXX_63_59 0xf800000000000000ULL
+#define CIU_INTX_SUM0_MPI 0x0400000000000000ULL
+#define CIU_INTX_SUM0_PCM 0x0200000000000000ULL
+#define CIU_INTX_SUM0_USB 0x0100000000000000ULL
+#define CIU_INTX_SUM0_TIMER 0x00f0000000000000ULL
+#define CIU_INTX_SUM0_TIMER_3 0x0080000000000000ULL
+#define CIU_INTX_SUM0_TIMER_2 0x0040000000000000ULL
+#define CIU_INTX_SUM0_TIMER_1 0x0020000000000000ULL
+#define CIU_INTX_SUM0_TIMER_0 0x0010000000000000ULL
+#define CIU_INTX_SUM0_XXX_51 0x0008000000000000ULL
+#define CIU_INTX_SUM0_IPD_DRP 0x0004000000000000ULL
+#define CIU_INTX_SUM0_XXX_49 0x0002000000000000ULL
+#define CIU_INTX_SUM0_GMX_DRP 0x0001000000000000ULL
+#define CIU_INTX_SUM0_TRACE 0x0000800000000000ULL
+#define CIU_INTX_SUM0_RML 0x0000400000000000ULL
+#define CIU_INTX_SUM0_TWSI 0x0000200000000000ULL
+#define CIU_INTX_SUM0_WDOG_SUM 0x0000100000000000ULL
+#define CIU_INTX_SUM0_PCI_MSI 0x00000f0000000000ULL
+#define CIU_INTX_SUM0_PCI_MSI_63_48 0x0000080000000000ULL
+#define CIU_INTX_SUM0_PCI_MSI_47_32 0x0000040000000000ULL
+#define CIU_INTX_SUM0_PCI_MSI_31_16 0x0000020000000000ULL
+#define CIU_INTX_SUM0_PCI_MSI_15_0 0x0000010000000000ULL
+#define CIU_INTX_SUM0_PCI_INT 0x000000f000000000ULL
+#define CIU_INTX_SUM0_PCI_INT_D 0x0000008000000000ULL
+#define CIU_INTX_SUM0_PCI_INT_C 0x0000004000000000ULL
+#define CIU_INTX_SUM0_PCI_INT_B 0x0000002000000000ULL
+#define CIU_INTX_SUM0_PCI_INT_A 0x0000001000000000ULL
+#define CIU_INTX_SUM0_UART 0x0000000c00000000ULL
+#define CIU_INTX_SUM0_UART_1 0x0000000800000000ULL
+#define CIU_INTX_SUM0_UART_0 0x0000000400000000ULL
+#define CIU_INTX_SUM0_MBOX 0x0000000300000000ULL
+#define CIU_INTX_SUM0_MBOX_31_16 0x0000000200000000ULL
+#define CIU_INTX_SUM0_MBOX_15_0 0x0000000100000000ULL
+#define CIU_INTX_SUM0_GPIO 0x00000000ffff0000ULL
+#define CIU_INTX_SUM0_GPIO_15 0x0000000080000000ULL
+#define CIU_INTX_SUM0_GPIO_14 0x0000000040000000ULL
+#define CIU_INTX_SUM0_GPIO_13 0x0000000020000000ULL
+#define CIU_INTX_SUM0_GPIO_12 0x0000000010000000ULL
+#define CIU_INTX_SUM0_GPIO_11 0x0000000008000000ULL
+#define CIU_INTX_SUM0_GPIO_10 0x0000000004000000ULL
+#define CIU_INTX_SUM0_GPIO_9 0x0000000002000000ULL
+#define CIU_INTX_SUM0_GPIO_8 0x0000000001000000ULL
+#define CIU_INTX_SUM0_GPIO_7 0x0000000000800000ULL
+#define CIU_INTX_SUM0_GPIO_6 0x0000000000400000ULL
+#define CIU_INTX_SUM0_GPIO_5 0x0000000000200000ULL
+#define CIU_INTX_SUM0_GPIO_4 0x0000000000100000ULL
+#define CIU_INTX_SUM0_GPIO_3 0x0000000000080000ULL
+#define CIU_INTX_SUM0_GPIO_2 0x0000000000040000ULL
+#define CIU_INTX_SUM0_GPIO_1 0x0000000000020000ULL
+#define CIU_INTX_SUM0_GPIO_0 0x0000000000010000ULL
+#define CIU_INTX_SUM0_WORKQ 0x000000000000ffffULL
+#define CIU_INTX_SUM0_WORKQ_15 0x0000000000008000ULL
+#define CIU_INTX_SUM0_WORKQ_14 0x0000000000004000ULL
+#define CIU_INTX_SUM0_WORKQ_13 0x0000000000002000ULL
+#define CIU_INTX_SUM0_WORKQ_12 0x0000000000001000ULL
+#define CIU_INTX_SUM0_WORKQ_11 0x0000000000000800ULL
+#define CIU_INTX_SUM0_WORKQ_10 0x0000000000000400ULL
+#define CIU_INTX_SUM0_WORKQ_9 0x0000000000000200ULL
+#define CIU_INTX_SUM0_WORKQ_8 0x0000000000000100ULL
+#define CIU_INTX_SUM0_WORKQ_7 0x0000000000000080ULL
+#define CIU_INTX_SUM0_WORKQ_6 0x0000000000000040ULL
+#define CIU_INTX_SUM0_WORKQ_5 0x0000000000000020ULL
+#define CIU_INTX_SUM0_WORKQ_4 0x0000000000000010ULL
+#define CIU_INTX_SUM0_WORKQ_3 0x0000000000000008ULL
+#define CIU_INTX_SUM0_WORKQ_2 0x0000000000000004ULL
+#define CIU_INTX_SUM0_WORKQ_1 0x0000000000000002ULL
+#define CIU_INTX_SUM0_WORKQ_0 0x0000000000000001ULL
+
+#define CIU_INT_SUM1_XXX_63_1 0xfffffffffffffffeULL
+#define CIU_INT_SUM1_WDOG 0x0000000000000001ULL
+
+#define CIU_INTX_EN0_XXX_63_59 0xf800000000000000ULL
+#define CIU_INTX_EN0_MPI 0x0400000000000000ULL
+#define CIU_INTX_EN0_PCM 0x0200000000000000ULL
+#define CIU_INTX_EN0_USB 0x0100000000000000ULL
+#define CIU_INTX_EN0_TIMER 0x00f0000000000000ULL
+#define CIU_INTX_EN0_TIMER_3 0x0080000000000000ULL
+#define CIU_INTX_EN0_TIMER_2 0x0040000000000000ULL
+#define CIU_INTX_EN0_TIMER_1 0x0020000000000000ULL
+#define CIU_INTX_EN0_TIMER_0 0x0010000000000000ULL
+#define CIU_INTX_EN0_XXX_51 0x0008000000000000ULL
+#define CIU_INTX_EN0_IPD_DRP 0x0004000000000000ULL
+#define CIU_INTX_EN0_XXX_49 0x0002000000000000ULL
+#define CIU_INTX_EN0_GMX_DRP 0x0001000000000000ULL
+#define CIU_INTX_EN0_TRACE 0x0000800000000000ULL
+#define CIU_INTX_EN0_RML 0x0000400000000000ULL
+#define CIU_INTX_EN0_TWSI 0x0000200000000000ULL
+#define CIU_INTX_EN0_WDOG_SUM 0x0000100000000000ULL
+#define CIU_INTX_EN0_PCI_MSI 0x00000f0000000000ULL
+#define CIU_INTX_EN0_PCI_MSI_63_48 0x0000080000000000ULL
+#define CIU_INTX_EN0_PCI_MSI_47_32 0x0000040000000000ULL
+#define CIU_INTX_EN0_PCI_MSI_31_16 0x0000020000000000ULL
+#define CIU_INTX_EN0_PCI_MSI_15_0 0x0000010000000000ULL
+#define CIU_INTX_EN0_PCI_INT 0x000000f000000000ULL
+#define CIU_INTX_EN0_PCI_INT_D 0x0000008000000000ULL
+#define CIU_INTX_EN0_PCI_INT_C 0x0000004000000000ULL
+#define CIU_INTX_EN0_PCI_INT_B 0x0000002000000000ULL
+#define CIU_INTX_EN0_PCI_INT_A 0x0000001000000000ULL
+#define CIU_INTX_EN0_UART 0x0000000c00000000ULL
+#define CIU_INTX_EN0_UART_1 0x0000000800000000ULL
+#define CIU_INTX_EN0_UART_0 0x0000000400000000ULL
+#define CIU_INTX_EN0_MBOX 0x0000000300000000ULL
+#define CIU_INTX_EN0_MBOX_31_16 0x0000000200000000ULL
+#define CIU_INTX_EN0_MBOX_15_0 0x0000000100000000ULL
+#define CIU_INTX_EN0_GPIO 0x00000000ffff0000ULL
+#define CIU_INTX_EN0_GPIO_15 0x0000000080000000ULL
+#define CIU_INTX_EN0_GPIO_14 0x0000000040000000ULL
+#define CIU_INTX_EN0_GPIO_13 0x0000000020000000ULL
+#define CIU_INTX_EN0_GPIO_12 0x0000000010000000ULL
+#define CIU_INTX_EN0_GPIO_11 0x0000000008000000ULL
+#define CIU_INTX_EN0_GPIO_10 0x0000000004000000ULL
+#define CIU_INTX_EN0_GPIO_9 0x0000000002000000ULL
+#define CIU_INTX_EN0_GPIO_8 0x0000000001000000ULL
+#define CIU_INTX_EN0_GPIO_7 0x0000000000800000ULL
+#define CIU_INTX_EN0_GPIO_6 0x0000000000400000ULL
+#define CIU_INTX_EN0_GPIO_5 0x0000000000200000ULL
+#define CIU_INTX_EN0_GPIO_4 0x0000000000100000ULL
+#define CIU_INTX_EN0_GPIO_3 0x0000000000080000ULL
+#define CIU_INTX_EN0_GPIO_2 0x0000000000040000ULL
+#define CIU_INTX_EN0_GPIO_1 0x0000000000020000ULL
+#define CIU_INTX_EN0_GPIO_0 0x0000000000010000ULL
+#define CIU_INTX_EN0_WORKQ 0x000000000000ffffULL
+#define CIU_INTX_EN0_WORKQ_15 0x0000000000008000ULL
+#define CIU_INTX_EN0_WORKQ_14 0x0000000000004000ULL
+#define CIU_INTX_EN0_WORKQ_13 0x0000000000002000ULL
+#define CIU_INTX_EN0_WORKQ_12 0x0000000000001000ULL
+#define CIU_INTX_EN0_WORKQ_11 0x0000000000000800ULL
+#define CIU_INTX_EN0_WORKQ_10 0x0000000000000400ULL
+#define CIU_INTX_EN0_WORKQ_9 0x0000000000000200ULL
+#define CIU_INTX_EN0_WORKQ_8 0x0000000000000100ULL
+#define CIU_INTX_EN0_WORKQ_7 0x0000000000000080ULL
+#define CIU_INTX_EN0_WORKQ_6 0x0000000000000040ULL
+#define CIU_INTX_EN0_WORKQ_5 0x0000000000000020ULL
+#define CIU_INTX_EN0_WORKQ_4 0x0000000000000010ULL
+#define CIU_INTX_EN0_WORKQ_3 0x0000000000000008ULL
+#define CIU_INTX_EN0_WORKQ_2 0x0000000000000004ULL
+#define CIU_INTX_EN0_WORKQ_1 0x0000000000000002ULL
+#define CIU_INTX_EN0_WORKQ_0 0x0000000000000001ULL
+
+#define CIU_INTX_EN1_XXX_63_1 0xfffffffffffffffeULL
+#define CIU_INTX_EN1_WDOG 0x0000000000000001ULL
+
+#define CIU_TIMX_XXX_63_37 0xffffffe000000000ULL
+#define CIU_TIMX_ONE_SHOT 0x0000001000000000ULL
+#define CIU_TIMX_LEN 0x0000000fffffffffULL
+
+#define CIU_WDOGX_XXX_63_46 0xffffc00000000000ULL
+#define CIU_WDOGX_GSTOPEN 0x0000200000000000ULL
+#define CIU_WDOGX_DSTOP 0x0000100000000000ULL
+#define CIU_WDOGX_CNT 0x00000ffffff00000ULL
+#define CIU_WDOGX_LEN 0x00000000000ffff0ULL
+#define CIU_WDOGX_STATE 0x000000000000000cULL
+#define CIU_WDOGX_MODE 0x0000000000000003ULL
+
+#define CIU_PP_POKEX_XXX_63_0 0xffffffffffffffffULL
+
+#define CIU_MBOX_SETX_XXX_63_32 0xffffffff00000000ULL
+#define CIU_MBOX_SETX_SET 0x00000000ffffffffULL
+
+#define CIU_MBOX_CLRX_XXX_63_32 0xffffffff00000000ULL
+#define CIU_MBOX_CLRX_CLR 0x00000000ffffffffULL
+
+#define CIU_PP_RST_XXX_63_1 0xfffffffffffffffeULL
+#define CIU_PP_RST_RST0 0x0000000000000001ULL
+
+#define CIU_PP_DBG_XXX_63_1 0xfffffffffffffffeULL
+#define CIU_PP_DBG_PPDBG 0x0000000000000001ULL
+
+#define CIU_GSTOP_XXX_63_1 0xfffffffffffffffeULL
+#define CIU_GSTOP_GSTOP 0x0000000000000001ULL
+
+#define CIU_NMI_XXX_63_1 0xfffffffffffffffeULL
+#define CIU_NMI_NMI 0x0000000000000001ULL
+
+#define CIU_DINT_XXX_63_1 0xfffffffffffffffeULL
+#define CIU_DINT_DINT 0x0000000000000001ULL
+
+#define CIU_FUSE_XXX_63_1 0xfffffffffffffffeULL
+#define CIU_FUSE_FUSE 0x0000000000000001ULL
+
+#define CIU_BIST_XXX_63_4 0xfffffffffffffff0ULL
+#define CIU_BIST_BIST 0x000000000000000fULL
+
+#define CIU_SOFT_BIST_XXX_63_1 0xfffffffffffffffeULL
+#define CIU_SOFT_BIST_SOFT_BIST 0x0000000000000001ULL
+
+#define CIU_SOFT_RST_XXX_63_1 0xfffffffffffffffeULL
+#define CIU_SOFT_RST_SOFT_RST 0x0000000000000001ULL
+
+#define CIU_SOFT_PRST_XXX_63_1 0xfffffffffffffff8ULL
+#define CIU_SOFT_PRST_HOST64 0x0000000000000004ULL
+#define CIU_SOFT_PRST_NPI 0x0000000000000002ULL
+#define CIU_SOFT_PRST_SOFT_PRST 0x0000000000000001ULL
+
+#define CIU_PCI_INTA_XXX_63_2 0xfffffffffffffffcULL
+#define CIU_PCI_INTA_INT 0x0000000000000003ULL
+
+/* -- bitmask_snprintf(9) */
+
+#define CIU_INTX_SUM0_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x3a" "MPI\0" \
+ "b\x39" "PCM\0" \
+ "b\x38" "USB\0" \
+ "b\x37" "TIMER_3\0" \
+ "b\x36" "TIMER_2\0" \
+ "b\x35" "TIMER_1\0" \
+ "b\x34" "TIMER_0\0" \
+ "f\x34\x04" "TIMER\0" \
+ "b\x32" "IPD_DRP\0" \
+ "b\x30" "GMX_DRP\0" \
+ "b\x2f" "TRACE\0" \
+ "b\x2e" "RML\0" \
+ "b\x2d" "TWSI\0" \
+ "b\x2c" "WDOG_SUM\0" \
+ "b\x2b" "PCI_MSI_63_48\0" \
+ "b\x2a" "PCI_MSI_47_32\0" \
+ "b\x29" "PCI_MSI_31_16\0" \
+ "f\x28\x04" "PCI_MSI\0" \
+ "b\x28" "PCI_MSI_15_0\0" \
+ "b\x27" "PCI_INT_D\0" \
+ "b\x26" "PCI_INT_C\0" \
+ "b\x25" "PCI_INT_B\0" \
+ "f\x24\x04" "PCI_INT\0" \
+ "b\x24" "PCI_INT_A\0" \
+ "b\x23" "UART_1\0" \
+ "f\x22\x02" "UART\0" \
+ "b\x22" "UART_0\0" \
+ "b\x21" "MBOX_31_16\0" \
+ "f\x20\x02" "MBOX\0" \
+ "b\x20" "MBOX_15_0\0" \
+ "b\x1f" "GPIO_15\0" \
+ "b\x1e" "GPIO_14\0" \
+ "b\x1d" "GPIO_13\0" \
+ "b\x1c" "GPIO_12\0" \
+ "b\x1b" "GPIO_11\0" \
+ "b\x1a" "GPIO_10\0" \
+ "b\x19" "GPIO_9\0" \
+ "b\x18" "GPIO_8\0" \
+ "b\x17" "GPIO_7\0" \
+ "b\x16" "GPIO_6\0" \
+ "b\x15" "GPIO_5\0" \
+ "b\x14" "GPIO_4\0" \
+ "b\x13" "GPIO_3\0" \
+ "b\x12" "GPIO_2\0" \
+ "b\x11" "GPIO_1\0" \
+ "b\x10" "GPIO_0\0" \
+ "f\x10\x10" "GPIO\0" \
+ "b\x0f" "WORKQ_15\0" \
+ "b\x0e" "WORKQ_14\0" \
+ "b\x0d" "WORKQ_13\0" \
+ "b\x0c" "WORKQ_12\0" \
+ "b\x0b" "WORKQ_11\0" \
+ "b\x0a" "WORKQ_10\0" \
+ "b\x09" "WORKQ_9\0" \
+ "b\x08" "WORKQ_8\0" \
+ "b\x07" "WORKQ_7\0" \
+ "b\x06" "WORKQ_6\0" \
+ "b\x05" "WORKQ_5\0" \
+ "b\x04" "WORKQ_4\0" \
+ "b\x03" "WORKQ_3\0" \
+ "b\x02" "WORKQ_2\0" \
+ "b\x01" "WORKQ_1\0" \
+ "b\x00" "WORKQ_0\0" \
+ "f\x00\x10" "WORKQ\0"
+#define CIU_INT0_SUM0_BITS CIU_INTX_SUM0_BITS
+#define CIU_INT1_SUM0_BITS CIU_INTX_SUM0_BITS
+#define CIU_INT2_SUM0_BITS CIU_INTX_SUM0_BITS
+#define CIU_INT3_SUM0_BITS CIU_INTX_SUM0_BITS
+#define CIU_INT32_SUM0_BITS CIU_INTX_SUM0_BITS
+
+#define CIU_INT_SUM1_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x00" "WDOG\0"
+
+#define CIU_INTX_EN0_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x3a" "MPI\0" \
+ "b\x39" "PCM\0" \
+ "b\x38" "USB\0" \
+ "b\x37" "TIMER_3\0" \
+ "b\x36" "TIMER_2\0" \
+ "b\x35" "TIMER_1\0" \
+ "b\x34" "TIMER_0\0" \
+ "f\x34\x04" "TIMER\0" \
+ "b\x32" "IPD_DRP\0" \
+ "b\x30" "GMX_DRP\0" \
+ "b\x2f" "TRACE\0" \
+ "b\x2e" "RML\0" \
+ "b\x2d" "TWSI\0" \
+ "b\x2c" "WDOG_SUM\0" \
+ "b\x2b" "PCI_MSI_63_48\0" \
+ "b\x2a" "PCI_MSI_47_32\0" \
+ "b\x29" "PCI_MSI_31_16\0" \
+ "f\x28\x04" "PCI_MSI\0" \
+ "b\x28" "PCI_MSI_15_0\0" \
+ "b\x27" "PCI_INT_D\0" \
+ "b\x26" "PCI_INT_C\0" \
+ "b\x25" "PCI_INT_B\0" \
+ "f\x24\x04" "PCI_INT\0" \
+ "b\x24" "PCI_INT_A\0" \
+ "b\x23" "UART_1\0" \
+ "f\x22\x02" "UART\0" \
+ "b\x22" "UART_0\0" \
+ "b\x21" "MBOX_31_16\0" \
+ "f\x20\x02" "MBOX\0" \
+ "b\x20" "MBOX_15_0\0" \
+ "b\x1f" "GPIO_15\0" \
+ "b\x1e" "GPIO_14\0" \
+ "b\x1d" "GPIO_13\0" \
+ "b\x1c" "GPIO_12\0" \
+ "b\x1b" "GPIO_11\0" \
+ "b\x1a" "GPIO_10\0" \
+ "b\x19" "GPIO_9\0" \
+ "b\x18" "GPIO_8\0" \
+ "b\x17" "GPIO_7\0" \
+ "b\x16" "GPIO_6\0" \
+ "b\x15" "GPIO_5\0" \
+ "b\x14" "GPIO_4\0" \
+ "b\x13" "GPIO_3\0" \
+ "b\x12" "GPIO_2\0" \
+ "b\x11" "GPIO_1\0" \
+ "b\x10" "GPIO_0\0" \
+ "f\x10\x10" "GPIO\0" \
+ "b\x0f" "WORKQ_15\0" \
+ "b\x0e" "WORKQ_14\0" \
+ "b\x0d" "WORKQ_13\0" \
+ "b\x0c" "WORKQ_12\0" \
+ "b\x0b" "WORKQ_11\0" \
+ "b\x0a" "WORKQ_10\0" \
+ "b\x09" "WORKQ_9\0" \
+ "b\x08" "WORKQ_8\0" \
+ "b\x07" "WORKQ_7\0" \
+ "b\x06" "WORKQ_6\0" \
+ "b\x05" "WORKQ_5\0" \
+ "b\x04" "WORKQ_4\0" \
+ "b\x03" "WORKQ_3\0" \
+ "b\x02" "WORKQ_2\0" \
+ "b\x01" "WORKQ_1\0" \
+ "b\x00" "WORKQ_0\0" \
+ "f\x00\x10" "WORKQ\0"
+#define CIU_INT0_EN0_BITS CIU_INTX_EN0_BITS
+#define CIU_INT1_EN0_BITS CIU_INTX_EN0_BITS
+#define CIU_INT2_EN0_BITS CIU_INTX_EN0_BITS
+#define CIU_INT3_EN0_BITS CIU_INTX_EN0_BITS
+#define CIU_INT32_EN0_BITS CIU_INTX_EN0_BITS
+
+#define CIU_INTX_EN1_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x00" "WDOG\0"
+#define CIU_INT0_EN1_BITS CIU_INTX_EN1_BITS
+#define CIU_INT1_EN1_BITS CIU_INTX_EN1_BITS
+#define CIU_INT2_EN1_BITS CIU_INTX_EN1_BITS
+#define CIU_INT3_EN1_BITS CIU_INTX_EN1_BITS
+#define CIU_INT32_EN1_BITS CIU_INTX_EN1_BITS
+
+#define CIU_TIMX_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x24" "ONE_SHOT\0" \
+ "f\x00\x24" "LEN\0"
+#define CIU_TIM0_BITS CIU_TIMX_BITS
+#define CIU_TIM1_BITS CIU_TIMX_BITS
+#define CIU_TIM2_BITS CIU_TIMX_BITS
+#define CIU_TIM3_BITS CIU_TIMX_BITS
+#define CIU_TIM32_BITS CIU_TIMX_BITS
+
+#define CIU_WDOGX_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x2d" "GSTOPEN\0" \
+ "b\x2c" "DSTOP\0" \
+ "f\x14\x18" "CNT\0" \
+ "f\x04\x10" "LEN\0" \
+ "f\x02\x02" "STATE\0" \
+ "f\x00\x02" "MODE\0"
+#define CIU_WDOG0_BITS CIU_WDOGX_BITS
+#define CIU_WDOG1_BITS CIU_WDOGX_BITS
+
+#if 0
+#define CIU_PP_POKEX_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define CIU_PP_POKE0_BITS CIU_PP_POKEX_BITS
+#define CIU_PP_POKE1_BITS CIU_PP_POKEX_BITS
+#endif
+
+#define CIU_MBOX_SETX_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x20" "SET\0"
+#define CIU_MBOX_SET0_BITS CIU_MBOX_SETX_BITS
+#define CIU_MBOX_SET1_BITS CIU_MBOX_SETX_BITS
+
+#define CIU_MBOX_CLRX_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x20" "CLR\0"
+#define CIU_MBOX_CLR0_BITS CIU_MBOX_CLRX_BITS
+#define CIU_MBOX_CLR1_BITS CIU_MBOX_CLRX_BITS
+
+#define CIU_PP_RST_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x00" "RST0\0"
+
+#define CIU_PP_DBG_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x00" "PPDBG\0"
+
+#define CIU_GSTOP_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x00" "GSTOP\0"
+
+#define CIU_NMI_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x00" "NMI\0"
+
+#define CIU_DINT_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x00" "DINT\0"
+
+#define CIU_FUSE_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x00" "FUSE\0"
+
+#define CIU_BIST_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x04" "BIST\0"
+
+#define CIU_SOFT_BIST_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x00" "SOFT_BIST\0"
+
+#define CIU_SOFT_RST_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x00" "SOFT_RST\0"
+
+#define CIU_SOFT_PRST_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x02" "HOST64\0" \
+ "b\x01" "NPI\0" \
+ "b\x00" "SOFT_PRST\0"
+
+#define CIU_PCI_INTA_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x02" "INT\0"
+
+#endif /* _CN30XXCIUREG_H_ */
diff --git a/sys/arch/octeon/dev/cn30xxfau.c b/sys/arch/octeon/dev/cn30xxfau.c
new file mode 100644
index 00000000000..913de29026d
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxfau.c
@@ -0,0 +1,164 @@
+/* $OpenBSD: cn30xxfau.c,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <machine/octeonvar.h>
+
+#include <octeon/dev/cn30xxfaureg.h>
+#include <octeon/dev/cn30xxfauvar.h>
+
+static int64_t cn30xxfau_op_load(uint64_t);
+static void cn30xxfau_op_iobdma(int, uint64_t);
+static void cn30xxfau_op_store(uint64_t, int64_t);
+static int64_t cn30xxfau_op_load_paddr(int, int, int) __unused;
+static void cn30xxfau_op_iobdma_store_data(int, int, int, int, int);
+static void cn30xxfau_op_store_paddr(int, int, int64_t);
+
+
+/* ---- utilities */
+
+static int64_t
+cn30xxfau_op_load(uint64_t args)
+{
+ paddr_t addr;
+
+ addr =
+ ((uint64_t)1 << 48) |
+ ((uint64_t)(CN30XXFAU_MAJORDID & 0x1f) << 43) |
+ ((uint64_t)(CN30XXFAU_SUBDID & 0x7) << 40) |
+ ((uint64_t)(args & 0xfffffffffULL) << 0);
+ return octeon_read_csr(addr);
+}
+
+static void
+cn30xxfau_op_store(uint64_t args, int64_t value)
+{
+ paddr_t addr;
+
+ addr =
+ ((uint64_t)1 << 48) |
+ ((uint64_t)(CN30XXFAU_MAJORDID & 0x1f) << 43) |
+ ((uint64_t)(CN30XXFAU_SUBDID & 0x7) << 40) |
+ ((uint64_t)(args & 0xfffffffffULL) << 0);
+ octeon_write_csr(addr, value);
+}
+
+/* ---- operation primitives */
+
+/*
+ * 3.4 Fetch-and-Add Operations
+ */
+
+/* 3.4.1 Load Operations */
+
+/* Load Physical Address for FAU Operations */
+
+static int64_t
+cn30xxfau_op_load_paddr(int incval, int tagwait, int reg)
+{
+ uint64_t args;
+
+ args =
+ ((uint64_t)(incval & 0x3fffff) << 14) |
+ ((uint64_t)(tagwait & 0x1) << 13) |
+ ((uint64_t)(reg & 0x7ff) << 0);
+ return cn30xxfau_op_load(args);
+}
+
+/* 3.4.3 Store Operations */
+
+/* Store Physical Address for FAU Operations */
+
+static void
+cn30xxfau_op_store_paddr(int noadd, int reg, int64_t value)
+{
+ uint64_t args;
+
+ args =
+ ((uint64_t)(noadd & 0x1) << 13) |
+ ((uint64_t)(reg & 0x7ff) << 0);
+ cn30xxfau_op_store(args, value);
+}
+
+/* ---- API */
+
+void
+cn30xxfau_op_init(struct cn30xxfau_desc *fd, size_t scroff, size_t regno)
+{
+ fd->fd_scroff = scroff;
+ fd->fd_regno = regno;
+}
+
+uint64_t
+cn30xxfau_op_save(struct cn30xxfau_desc *fd)
+{
+ OCTEON_SYNCIOBDMA/* XXX */;
+ return octeon_cvmseg_read_8(fd->fd_scroff);
+}
+
+void
+cn30xxfau_op_restore(struct cn30xxfau_desc *fd, uint64_t backup)
+{
+ octeon_cvmseg_write_8(fd->fd_scroff, backup);
+}
+
+int64_t
+cn30xxfau_op_inc_8(struct cn30xxfau_desc *fd, int64_t v)
+{
+ cn30xxfau_op_iobdma_store_data(fd->fd_scroff, v, 0, OCT_FAU_OP_SIZE_64/* XXX */,
+ fd->fd_regno);
+ OCTEON_SYNCIOBDMA/* XXX */;
+ return octeon_cvmseg_read_8(fd->fd_scroff)/* XXX */;
+}
+
+int64_t
+cn30xxfau_op_incwait_8(struct cn30xxfau_desc *fd, int v)
+{
+ cn30xxfau_op_iobdma_store_data(fd->fd_scroff, v, 1, OCT_FAU_OP_SIZE_64/* XXX */,
+ fd->fd_regno);
+ /* XXX */
+ OCTEON_SYNCIOBDMA/* XXX */;
+ /* XXX */
+ return octeon_cvmseg_read_8(fd->fd_scroff)/* XXX */;
+}
+
+void
+cn30xxfau_op_add_8(struct cn30xxfau_desc *fd, int64_t v)
+{
+ cn30xxfau_op_store_paddr(0, fd->fd_regno, v);
+}
+
+void
+cn30xxfau_op_set_8(struct cn30xxfau_desc *fd, int64_t v)
+{
+ cn30xxfau_op_store_paddr(1, fd->fd_regno, v);
+}
diff --git a/sys/arch/octeon/dev/cn30xxfaureg.h b/sys/arch/octeon/dev/cn30xxfaureg.h
new file mode 100644
index 00000000000..fae0b6d49e9
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxfaureg.h
@@ -0,0 +1,48 @@
+/*
+ * THIS FILE IS AUTOMATICALLY GENERATED
+ * DONT EDIT THIS FILE
+ */
+
+/* $OpenBSD: cn30xxfaureg.h,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Cavium Networks OCTEON CN30XX Hardware Reference Manual
+ * CN30XX-HM-1.0
+ * 3.4 Fetch-and-Add Operations
+ */
+
+#ifndef _CN30XXFAUREG_H_
+#define _CN30XXFAUREG_H_
+
+/* ---- operations */
+
+#define CN30XXFAU_MAJORDID 0x1e
+#define CN30XXFAU_SUBDID 0
+
+#endif /* _CN30XXFAUREG_H_ */
diff --git a/sys/arch/octeon/dev/cn30xxfauvar.h b/sys/arch/octeon/dev/cn30xxfauvar.h
new file mode 100644
index 00000000000..568477f29c4
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxfauvar.h
@@ -0,0 +1,132 @@
+/* $OpenBSD: cn30xxfauvar.h,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _CN30XXFAUVAR_H_
+#define _CN30XXFAUVAR_H_
+
+/* ---- API */
+
+struct cn30xxfau_desc {
+ /* offset in scratch buffer */
+ size_t fd_scroff; /* XXX offset_t */
+ /* FAU register number */
+ size_t fd_regno; /* XXX offset_t */
+};
+
+void cn30xxfau_op_init(struct cn30xxfau_desc *, size_t, size_t);
+uint64_t cn30xxfau_op_save(struct cn30xxfau_desc *);
+void cn30xxfau_op_restore(struct cn30xxfau_desc *, uint64_t);
+int64_t cn30xxfau_op_inc_8(struct cn30xxfau_desc *, int64_t);
+int32_t cn30xxfau_op_inc_4(struct cn30xxfau_desc *, int32_t);
+int16_t cn30xxfau_op_inc_2(struct cn30xxfau_desc *, int16_t);
+int8_t cn30xxfau_op_inc_1(struct cn30xxfau_desc *, int8_t);
+int64_t cn30xxfau_op_incwait_8(struct cn30xxfau_desc *, int);
+int32_t cn30xxfau_op_incwait_4(struct cn30xxfau_desc *, int);
+int16_t cn30xxfau_op_incwait_2(struct cn30xxfau_desc *, int);
+int8_t cn30xxfau_op_incwait_1(struct cn30xxfau_desc *, int);
+int64_t cn30xxfau_op_get_8(struct cn30xxfau_desc *);
+int32_t cn30xxfau_op_get_4(struct cn30xxfau_desc *);
+int16_t cn30xxfau_op_get_2(struct cn30xxfau_desc *);
+int8_t cn30xxfau_op_get_1(struct cn30xxfau_desc *);
+int64_t cn30xxfau_op_getwait_8(struct cn30xxfau_desc *);
+int32_t cn30xxfau_op_getwait_4(struct cn30xxfau_desc *);
+int16_t cn30xxfau_op_getwait_2(struct cn30xxfau_desc *);
+int8_t cn30xxfau_op_getwait_1(struct cn30xxfau_desc *);
+void cn30xxfau_op_add_8(struct cn30xxfau_desc *, int64_t);
+void cn30xxfau_op_add_4(struct cn30xxfau_desc *, int32_t);
+void cn30xxfau_op_add_2(struct cn30xxfau_desc *, int16_t);
+void cn30xxfau_op_add_1(struct cn30xxfau_desc *, int8_t);
+void cn30xxfau_op_set_8(struct cn30xxfau_desc *, int64_t);
+void cn30xxfau_op_set_4(struct cn30xxfau_desc *, int32_t);
+void cn30xxfau_op_set_2(struct cn30xxfau_desc *, int16_t);
+void cn30xxfau_op_set_1(struct cn30xxfau_desc *, int8_t);
+
+/* ---- old API */
+
+/* XXX */
+#define OCT_FAU_REG_OQ_ADDR_INDEX (0)
+#define OCT_FAU_REG_ADDR_END (256)
+/* XXX */
+
+/* XXX */
+typedef enum {
+ OCT_FAU_OP_SIZE_8 = 0,
+ OCT_FAU_OP_SIZE_16 = 1,
+ OCT_FAU_OP_SIZE_32 = 2,
+ OCT_FAU_OP_SIZE_64 = 3
+} fau_op_size_t;
+/* XXX */
+
+static inline void
+cn30xxfau_op_iobdma(int index, uint64_t args)
+{
+ uint64_t value;
+
+ value =
+ ((uint64_t)(index & 0xff) << 56) |
+ ((uint64_t)1 << 48) |
+ ((uint64_t)(CN30XXFAU_MAJORDID & 0x1f) << 43) |
+ ((uint64_t)(CN30XXFAU_SUBDID & 0x7) << 40) |
+ ((uint64_t)args & 0xfffffffffULL);
+ octeon_iobdma_write_8(value);
+}
+
+/* 3.4.2 IOBDMA Operations */
+
+/* IOBDMA Store Data for FAU Operations */
+
+static inline void
+cn30xxfau_op_iobdma_store_data(int scraddr, int incval, int tagwait,
+ int size, int reg)
+{
+ uint64_t args;
+
+ args =
+ ((uint64_t)(incval & 0x3fffff) << 14) |
+ ((uint64_t)(tagwait & 0x1) << 13) |
+ ((uint64_t)(size & 0x3) << 11) |
+ ((uint64_t)(reg & 0x7ff) << 0);
+ /* use `srcaddr` as `index' */
+ cn30xxfau_op_iobdma((int)((uint32_t)scraddr >> 3) /* XXX */, args);
+}
+
+static inline void
+cn30xxfau_op_inc_fetch_8(struct cn30xxfau_desc *fd, int64_t v)
+{
+ cn30xxfau_op_iobdma_store_data(fd->fd_scroff, v, 0, OCT_FAU_OP_SIZE_64/* XXX */,
+ fd->fd_regno);
+}
+
+static inline int64_t
+cn30xxfau_op_inc_read_8(struct cn30xxfau_desc *fd)
+{
+ OCTEON_SYNCIOBDMA;
+ return octeon_cvmseg_read_8(fd->fd_scroff);
+}
+
+#endif /* _CN30XXFAUVAR_H_ */
diff --git a/sys/arch/octeon/dev/cn30xxfpa.c b/sys/arch/octeon/dev/cn30xxfpa.c
new file mode 100644
index 00000000000..1595b79807c
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxfpa.c
@@ -0,0 +1,473 @@
+/* $OpenBSD: cn30xxfpa.c,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#undef FPADEBUG
+
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/types.h>
+#include <sys/malloc.h>
+
+#include <machine/bus.h>
+#include <machine/vmparam.h>
+#include <machine/octeonvar.h>
+
+#include <octeon/dev/cn30xxfpavar.h>
+#include <octeon/dev/cn30xxfpareg.h>
+
+#ifdef FPADEBUG
+#define DPRINTF(x) printf x
+#else
+#define DPRINTF(x)
+#endif
+
+#define _DMA_NSEGS 1
+#define _DMA_BUFLEN 0x01000000
+
+/* pool descriptor */
+struct cn30xxfpa_desc {
+};
+
+struct cn30xxfpa_softc {
+ int sc_initialized;
+
+ bus_space_tag_t sc_regt;
+ bus_space_handle_t sc_regh;
+
+ bus_space_tag_t sc_opst;
+ bus_space_handle_t sc_opsh;
+
+ bus_dma_tag_t sc_dmat;
+
+ struct cn30xxfpa_desc sc_descs[8];
+
+#ifdef OCTEON_ETH_DEBUG
+ struct evcnt sc_ev_fpaq7perr;
+ struct evcnt sc_ev_fpaq7coff;
+ struct evcnt sc_ev_fpaq7und;
+ struct evcnt sc_ev_fpaq6perr;
+ struct evcnt sc_ev_fpaq6coff;
+ struct evcnt sc_ev_fpaq6und;
+ struct evcnt sc_ev_fpaq5perr;
+ struct evcnt sc_ev_fpaq5coff;
+#endif
+};
+
+void cn30xxfpa_bootstrap(struct octeon_config *);
+void cn30xxfpa_reset(void);
+void cn30xxfpa_int_enable(struct cn30xxfpa_softc *, int);
+void cn30xxfpa_buf_dma_alloc(struct cn30xxfpa_buf *);
+
+static void cn30xxfpa_init(struct cn30xxfpa_softc *);
+#ifdef notyet
+static uint64_t cn30xxfpa_iobdma(struct cn30xxfpa_softc *, int, int);
+#endif
+
+#ifdef OCTEON_ETH_DEBUG
+void cn30xxfpa_intr_evcnt_attach(struct cn30xxfpa_softc *);
+void cn30xxfpa_intr_rml(void *);
+#endif
+
+static struct cn30xxfpa_softc cn30xxfpa_softc;
+
+/* ---- global functions */
+
+void
+cn30xxfpa_bootstrap(struct octeon_config *mcp)
+{
+ struct cn30xxfpa_softc *sc = &cn30xxfpa_softc;
+
+ sc->sc_regt = mcp->mc_iobus_bust;
+ sc->sc_opst = mcp->mc_iobus_bust;
+ sc->sc_dmat = mcp->mc_iobus_dmat;
+
+ cn30xxfpa_init(sc);
+}
+
+void
+cn30xxfpa_reset(void)
+{
+ /* XXX */
+}
+
+#ifdef OCTEON_ETH_DEBUG
+int cn30xxfpa_intr_rml_verbose;
+struct evcnt cn30xxfpa_intr_evcnt;
+
+static const struct octeon_evcnt_entry cn30xxfpa_intr_evcnt_entries[] = {
+#define _ENTRY(name, type, parent, descr) \
+ OCTEON_EVCNT_ENTRY(struct cn30xxfpa_softc, name, type, parent, descr)
+ _ENTRY(fpaq7perr, MISC, NULL, "fpa q7 pointer"),
+ _ENTRY(fpaq7coff, MISC, NULL, "fpa q7 counter offset"),
+ _ENTRY(fpaq7und, MISC, NULL, "fpa q7 underflow"),
+ _ENTRY(fpaq6perr, MISC, NULL, "fpa q6 pointer"),
+ _ENTRY(fpaq6coff, MISC, NULL, "fpa q6 counter offset"),
+ _ENTRY(fpaq6und, MISC, NULL, "fpa q6 underflow"),
+ _ENTRY(fpaq5perr, MISC, NULL, "fpa q5 pointer"),
+ _ENTRY(fpaq5coff, MISC, NULL, "fpa q5 counter offset"),
+#undef _ENTRY
+};
+
+void
+cn30xxfpa_intr_evcnt_attach(struct cn30xxfpa_softc *sc)
+{
+ OCTEON_EVCNT_ATTACH_EVCNTS(sc, cn30xxfpa_intr_evcnt_entries, "fpa0");
+}
+
+void
+cn30xxfpa_intr_rml(void *arg)
+{
+ struct cn30xxfpa_softc *sc;
+ uint64_t reg;
+
+ cn30xxfpa_intr_evcnt.ev_count++;
+ sc = &cn30xxfpa_softc;
+ KASSERT(sc != NULL);
+ reg = cn30xxfpa_int_summary();
+ if (cn30xxfpa_intr_rml_verbose)
+ printf("%s: FPA_INT_SUM=0x%016" PRIx64 "\n", __func__, reg);
+ if (reg & FPA_INT_SUM_Q7_PERR)
+ OCTEON_EVCNT_INC(sc, fpaq7perr);
+ if (reg & FPA_INT_SUM_Q7_COFF)
+ OCTEON_EVCNT_INC(sc, fpaq7coff);
+ if (reg & FPA_INT_SUM_Q7_UND)
+ OCTEON_EVCNT_INC(sc, fpaq7und);
+ if (reg & FPA_INT_SUM_Q6_PERR)
+ OCTEON_EVCNT_INC(sc, fpaq6perr);
+ if (reg & FPA_INT_SUM_Q6_COFF)
+ OCTEON_EVCNT_INC(sc, fpaq6coff);
+ if (reg & FPA_INT_SUM_Q6_UND)
+ OCTEON_EVCNT_INC(sc, fpaq6und);
+ if (reg & FPA_INT_SUM_Q5_PERR)
+ OCTEON_EVCNT_INC(sc, fpaq5perr);
+ if (reg & FPA_INT_SUM_Q5_COFF)
+ OCTEON_EVCNT_INC(sc, fpaq5coff);
+}
+
+void
+cn30xxfpa_int_enable(struct cn30xxfpa_softc *sc, int enable)
+{
+ const uint64_t int_xxx =
+ FPA_INT_ENB_Q7_PERR | FPA_INT_ENB_Q7_COFF | FPA_INT_ENB_Q7_UND |
+ FPA_INT_ENB_Q6_PERR | FPA_INT_ENB_Q6_COFF | FPA_INT_ENB_Q6_UND |
+ FPA_INT_ENB_Q5_PERR | FPA_INT_ENB_Q5_COFF | FPA_INT_ENB_Q5_UND |
+ FPA_INT_ENB_Q4_PERR | FPA_INT_ENB_Q4_COFF | FPA_INT_ENB_Q4_UND |
+ FPA_INT_ENB_Q3_PERR | FPA_INT_ENB_Q3_COFF | FPA_INT_ENB_Q3_UND |
+ FPA_INT_ENB_Q2_PERR | FPA_INT_ENB_Q2_COFF | FPA_INT_ENB_Q2_UND |
+ FPA_INT_ENB_Q1_PERR | FPA_INT_ENB_Q1_COFF | FPA_INT_ENB_Q1_UND |
+ FPA_INT_ENB_Q0_PERR | FPA_INT_ENB_Q0_COFF | FPA_INT_ENB_Q0_UND |
+ FPA_INT_ENB_FED1_DBE | FPA_INT_ENB_FED1_SBE |
+ FPA_INT_ENB_FED0_DBE | FPA_INT_ENB_FED0_SBE;
+
+ bus_space_write_8(sc->sc_regt, sc->sc_regh, FPA_INT_SUM_OFFSET,
+ int_xxx);
+ if (enable)
+ bus_space_write_8(sc->sc_regt, sc->sc_regh, FPA_INT_ENB_OFFSET,
+ int_xxx);
+}
+
+uint64_t
+cn30xxfpa_int_summary(void)
+{
+ struct cn30xxfpa_softc *sc = &cn30xxfpa_softc;
+ uint64_t summary;
+
+ summary = bus_space_read_8(sc->sc_regt, sc->sc_regh, FPA_INT_SUM_OFFSET);
+ bus_space_write_8(sc->sc_regt, sc->sc_regh, FPA_INT_SUM_OFFSET, summary);
+ return summary;
+}
+#endif
+
+int
+cn30xxfpa_buf_init(int poolno, size_t size, size_t nelems,
+ struct cn30xxfpa_buf **rfb)
+{
+ struct cn30xxfpa_softc *sc = &cn30xxfpa_softc;
+ struct cn30xxfpa_buf *fb;
+ int nsegs;
+ paddr_t paddr;
+
+ nsegs = 1/* XXX */;
+ fb = malloc(sizeof(*fb) + sizeof(*fb->fb_dma_segs) * nsegs, M_DEVBUF,
+ M_WAITOK | M_ZERO);
+ if (fb == NULL)
+ return 1;
+ fb->fb_poolno = poolno;
+ fb->fb_size = size;
+ fb->fb_nelems = nelems;
+ fb->fb_len = size * nelems;
+ fb->fb_dmat = sc->sc_dmat;
+ fb->fb_dma_segs = (void *)(fb + 1);
+ fb->fb_dma_nsegs = nsegs;
+
+ cn30xxfpa_buf_dma_alloc(fb);
+
+ for (paddr = fb->fb_paddr; paddr < fb->fb_paddr + fb->fb_len;
+ paddr += fb->fb_size)
+ cn30xxfpa_buf_put_paddr(fb, paddr);
+
+ *rfb = fb;
+
+ return 0;
+}
+
+void *
+cn30xxfpa_buf_get(struct cn30xxfpa_buf *fb)
+{
+ paddr_t paddr;
+ vaddr_t addr;
+
+ paddr = cn30xxfpa_buf_get_paddr(fb);
+ if (paddr == 0)
+ addr = 0;
+ else
+ addr = fb->fb_addr + (vaddr_t/* XXX */)(paddr - fb->fb_paddr);
+ return (void *)addr;
+}
+
+void
+cn30xxfpa_buf_dma_alloc(struct cn30xxfpa_buf *fb)
+{
+ int status;
+ int nsegs;
+ caddr_t va;
+
+ status = bus_dmamap_create(fb->fb_dmat, fb->fb_len,
+ fb->fb_len / PAGE_SIZE, /* # of segments */
+ fb->fb_len, /* we don't use s/g for FPA buf */
+ PAGE_SIZE, /* OCTEON hates >PAGE_SIZE boundary */
+ 0, &fb->fb_dmah);
+ if (status != 0)
+ panic("%s failed", "bus_dmamap_create");
+
+ status = bus_dmamem_alloc(fb->fb_dmat, fb->fb_len, 128, 0,
+ fb->fb_dma_segs, fb->fb_dma_nsegs, &nsegs, 0);
+ if (status != 0 || fb->fb_dma_nsegs != nsegs)
+ panic("%s failed", "bus_dmamem_alloc");
+
+ status = bus_dmamem_map(fb->fb_dmat, fb->fb_dma_segs, fb->fb_dma_nsegs,
+ fb->fb_len, &va, 0);
+ if (status != 0)
+ panic("%s failed", "bus_dmamem_map");
+
+ status = bus_dmamap_load(fb->fb_dmat, fb->fb_dmah, va, fb->fb_len,
+ NULL, /* kernel */
+ 0);
+ if (status != 0)
+ panic("%s failed", "bus_dmamap_load");
+
+ fb->fb_addr = (vaddr_t)va;
+ fb->fb_paddr = fb->fb_dma_segs[0].ds_addr;
+}
+
+uint64_t
+cn30xxfpa_query(int poolno)
+{
+ struct cn30xxfpa_softc *sc = &cn30xxfpa_softc;
+
+ return bus_space_read_8(sc->sc_regt, sc->sc_regh,
+ FPA_QUE0_AVAILABLE_OFFSET + sizeof(uint64_t) * poolno);
+}
+
+/* ---- local functions */
+
+static void cn30xxfpa_init_bus(struct cn30xxfpa_softc *);
+static void cn30xxfpa_init_bus_space(struct cn30xxfpa_softc *);
+static void cn30xxfpa_init_regs(struct cn30xxfpa_softc *);
+
+void
+cn30xxfpa_init(struct cn30xxfpa_softc *sc)
+{
+ if (sc->sc_initialized != 0)
+ panic("%s: already initialized", __func__);
+ sc->sc_initialized = 1;
+
+ cn30xxfpa_init_bus(sc);
+ cn30xxfpa_init_regs(sc);
+#ifdef OCTEON_ETH_DEBUG
+ cn30xxfpa_int_enable(sc, 1);
+ cn30xxfpa_intr_evcnt_attach(sc);
+#endif
+}
+
+static void
+cn30xxfpa_init_bus(struct cn30xxfpa_softc *sc)
+{
+ cn30xxfpa_init_bus_space(sc);
+}
+
+static void
+cn30xxfpa_init_bus_space(struct cn30xxfpa_softc *sc)
+{
+ int status;
+
+ status = bus_space_map(sc->sc_regt, FPA_BASE, FPA_SIZE, 0, &sc->sc_regh);
+ if (status != 0)
+ panic("can't map %s space", "register");
+
+ /* CN30XX-HM-1.0 Table 4-25 */
+ status = bus_space_map(sc->sc_opst,
+ 0x0001180028000000ULL/* XXX */, 0x0200/* XXX */, 0, &sc->sc_opsh);
+ if (status != 0)
+ panic("can't map %s space", "operations");
+}
+
+static void
+cn30xxfpa_init_regs(struct cn30xxfpa_softc *sc)
+{
+
+ bus_space_write_8(sc->sc_regt, sc->sc_regh, FPA_CTL_STATUS_OFFSET,
+ FPA_CTL_STATUS_ENB);
+
+/* XXX */
+#ifdef OCTEON_ETH_DEBUG
+ bus_space_write_8(sc->sc_regt, sc->sc_regh, FPA_INT_ENB_OFFSET,
+ FPA_INT_ENB_Q7_PERR | FPA_INT_ENB_Q7_COFF | FPA_INT_ENB_Q7_UND |
+ FPA_INT_ENB_Q6_PERR | FPA_INT_ENB_Q6_COFF | FPA_INT_ENB_Q6_UND |
+ FPA_INT_ENB_Q5_PERR | FPA_INT_ENB_Q5_COFF | FPA_INT_ENB_Q5_UND |
+ FPA_INT_ENB_Q4_PERR | FPA_INT_ENB_Q4_COFF | FPA_INT_ENB_Q4_UND |
+ FPA_INT_ENB_Q3_PERR | FPA_INT_ENB_Q3_COFF | FPA_INT_ENB_Q3_UND |
+ FPA_INT_ENB_Q2_PERR | FPA_INT_ENB_Q2_COFF | FPA_INT_ENB_Q2_UND |
+ FPA_INT_ENB_Q1_PERR | FPA_INT_ENB_Q1_COFF | FPA_INT_ENB_Q1_UND |
+ FPA_INT_ENB_Q0_PERR | FPA_INT_ENB_Q0_COFF | FPA_INT_ENB_Q0_UND |
+ FPA_INT_ENB_FED1_DBE | FPA_INT_ENB_FED1_SBE |
+ FPA_INT_ENB_FED0_DBE | FPA_INT_ENB_FED0_SBE);
+#endif
+}
+
+#ifdef OCTEON_ETH_DEBUG
+void cn30xxfpa_dump_regs(void);
+void cn30xxfpa_dump_bufs(void);
+void cn30xxfpa_dump_buf(int);
+
+#define _ENTRY(x) { #x, x##_BITS, x##_OFFSET }
+
+struct cn30xxfpa_dump_reg_ {
+ const char *name;
+ const char *format;
+ size_t offset;
+};
+
+static const struct cn30xxfpa_dump_reg_ cn30xxfpa_dump_regs_[] = {
+ _ENTRY(FPA_INT_SUM),
+ _ENTRY(FPA_INT_ENB),
+ _ENTRY(FPA_CTL_STATUS),
+ _ENTRY(FPA_QUE0_AVAILABLE),
+ _ENTRY(FPA_QUE1_AVAILABLE),
+ _ENTRY(FPA_QUE2_AVAILABLE),
+ _ENTRY(FPA_QUE3_AVAILABLE),
+ _ENTRY(FPA_QUE4_AVAILABLE),
+ _ENTRY(FPA_QUE5_AVAILABLE),
+ _ENTRY(FPA_QUE6_AVAILABLE),
+ _ENTRY(FPA_QUE7_AVAILABLE),
+ _ENTRY(FPA_WART_CTL),
+ _ENTRY(FPA_WART_STATUS),
+ _ENTRY(FPA_BIST_STATUS),
+ _ENTRY(FPA_QUE0_PAGE_INDEX),
+ _ENTRY(FPA_QUE1_PAGE_INDEX),
+ _ENTRY(FPA_QUE2_PAGE_INDEX),
+ _ENTRY(FPA_QUE3_PAGE_INDEX),
+ _ENTRY(FPA_QUE4_PAGE_INDEX),
+ _ENTRY(FPA_QUE5_PAGE_INDEX),
+ _ENTRY(FPA_QUE6_PAGE_INDEX),
+ _ENTRY(FPA_QUE7_PAGE_INDEX),
+ _ENTRY(FPA_QUE_EXP),
+ _ENTRY(FPA_QUE_ACT),
+};
+
+static const char *cn30xxfpa_dump_bufs_[8] = {
+ [0] = "recv",
+ [1] = "wq",
+ [2] = "cmdbuf",
+ [3] = "gbuf",
+};
+
+void
+cn30xxfpa_dump(void)
+{
+ cn30xxfpa_dump_regs();
+ cn30xxfpa_dump_bufs();
+}
+
+void
+cn30xxfpa_dump_regs(void)
+{
+ struct cn30xxfpa_softc *sc = &cn30xxfpa_softc;
+ const struct cn30xxfpa_dump_reg_ *reg;
+ uint64_t tmp;
+ char buf[512];
+ int i;
+
+ for (i = 0; i < (int)nitems(cn30xxfpa_dump_regs_); i++) {
+ reg = &cn30xxfpa_dump_regs_[i];
+ tmp = bus_space_read_8(sc->sc_regt, sc->sc_regh, reg->offset);
+ if (reg->format == NULL) {
+ snprintf(buf, sizeof(buf), "%16" PRIx64, tmp);
+ } else {
+ bitmask_snprintf(tmp, reg->format, buf, sizeof(buf));
+ }
+ printf("\t%-24s: %s\n", reg->name, buf);
+ }
+}
+
+/*
+ * XXX assume pool 7 is unused!
+ */
+void
+cn30xxfpa_dump_bufs(void)
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ cn30xxfpa_dump_buf(i);
+}
+
+void
+cn30xxfpa_dump_buf(int pool)
+{
+ int i;
+ uint64_t ptr;
+ const char *name;
+
+ name = cn30xxfpa_dump_bufs_[pool];
+ if (name == NULL)
+ return;
+ printf("%s pool:\n", name);
+ for (i = 0; (ptr = cn30xxfpa_load(pool)) != 0; i++) {
+ printf("\t%016" PRIx64 "%s", ptr, ((i % 4) == 3) ? "\n" : "");
+ cn30xxfpa_store(ptr, OCTEON_POOL_NO_DUMP, 0);
+ }
+ if (i % 4 != 3)
+ printf("\n");
+ printf("total = %d buffers\n", i);
+ while ((ptr = cn30xxfpa_load(OCTEON_POOL_NO_DUMP)) != 0)
+ cn30xxfpa_store(ptr, pool, 0);
+}
+#endif
diff --git a/sys/arch/octeon/dev/cn30xxfpareg.h b/sys/arch/octeon/dev/cn30xxfpareg.h
new file mode 100644
index 00000000000..59b59e81420
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxfpareg.h
@@ -0,0 +1,515 @@
+/*
+ * THIS FILE IS AUTOMATICALLY GENERATED
+ * DONT EDIT THIS FILE
+ */
+
+/* $OpenBSD: cn30xxfpareg.h,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Cavium Networks OCTEON CN30XX Hardware Reference Manual
+ * CN30XX-HM-1.0
+ * 6.2 FPA Registers
+ */
+
+#ifndef _CN30XXFPAREG_H_
+#define _CN30XXFPAREG_H_
+
+/* ---- register offsets */
+
+#define FPA_INT_SUM 0x0001180028000040ULL
+#define FPA_INT_ENB 0x0001180028000048ULL
+#define FPA_CTL_STATUS 0x0001180028000050ULL
+#define FPA_QUE0_AVAILABLE 0x0001180028000098ULL
+#define FPA_QUE1_AVAILABLE 0x00011800280000a0ULL
+#define FPA_QUE2_AVAILABLE 0x00011800280000a8ULL
+#define FPA_QUE3_AVAILABLE 0x00011800280000b0ULL
+#define FPA_QUE4_AVAILABLE 0x00011800280000b8ULL
+#define FPA_QUE5_AVAILABLE 0x00011800280000c0ULL
+#define FPA_QUE6_AVAILABLE 0x00011800280000c8ULL
+#define FPA_QUE7_AVAILABLE 0x00011800280000d0ULL
+#define FPA_WART_CTL 0x00011800280000d8ULL
+#define FPA_WART_STATUS 0x00011800280000e0ULL
+#define FPA_BIST_STATUS 0x00011800280000e8ULL
+#define FPA_QUE0_PAGE_INDEX 0x00011800280000f0ULL
+#define FPA_QUE1_PAGE_INDEX 0x00011800280000f8ULL
+#define FPA_QUE2_PAGE_INDEX 0x0001180028000100ULL
+#define FPA_QUE3_PAGE_INDEX 0x0001180028000108ULL
+#define FPA_QUE4_PAGE_INDEX 0x0001180028000110ULL
+#define FPA_QUE5_PAGE_INDEX 0x0001180028000118ULL
+#define FPA_QUE6_PAGE_INDEX 0x0001180028000120ULL
+#define FPA_QUE7_PAGE_INDEX 0x0001180028000128ULL
+#define FPA_QUE_EXP 0x0001180028000130ULL
+#define FPA_QUE_ACT 0x0001180028000138ULL
+
+/* ---- register bit definitions */
+
+#define FPA_INT_SUM_XXX_63_28 0xfffffffff0000000ULL
+#define FPA_INT_SUM_Q7_PERR 0x0000000008000000ULL
+#define FPA_INT_SUM_Q7_COFF 0x0000000004000000ULL
+#define FPA_INT_SUM_Q7_UND 0x0000000002000000ULL
+#define FPA_INT_SUM_Q6_PERR 0x0000000001000000ULL
+#define FPA_INT_SUM_Q6_COFF 0x0000000000800000ULL
+#define FPA_INT_SUM_Q6_UND 0x0000000000400000ULL
+#define FPA_INT_SUM_Q5_PERR 0x0000000000200000ULL
+#define FPA_INT_SUM_Q5_COFF 0x0000000000100000ULL
+#define FPA_INT_SUM_Q5_UND 0x0000000000080000ULL
+#define FPA_INT_SUM_Q4_PERR 0x0000000000040000ULL
+#define FPA_INT_SUM_Q4_COFF 0x0000000000020000ULL
+#define FPA_INT_SUM_Q4_UND 0x0000000000010000ULL
+#define FPA_INT_SUM_Q3_PERR 0x0000000000008000ULL
+#define FPA_INT_SUM_Q3_COFF 0x0000000000004000ULL
+#define FPA_INT_SUM_Q3_UND 0x0000000000002000ULL
+#define FPA_INT_SUM_Q2_PERR 0x0000000000001000ULL
+#define FPA_INT_SUM_Q2_COFF 0x0000000000000800ULL
+#define FPA_INT_SUM_Q2_UND 0x0000000000000400ULL
+#define FPA_INT_SUM_Q1_PERR 0x0000000000000200ULL
+#define FPA_INT_SUM_Q1_COFF 0x0000000000000100ULL
+#define FPA_INT_SUM_Q1_UND 0x0000000000000080ULL
+#define FPA_INT_SUM_Q0_PERR 0x0000000000000040ULL
+#define FPA_INT_SUM_Q0_COFF 0x0000000000000020ULL
+#define FPA_INT_SUM_Q0_UND 0x0000000000000010ULL
+#define FPA_INT_SUM_FED1_DBE 0x0000000000000008ULL
+#define FPA_INT_SUM_FED1_SBE 0x0000000000000004ULL
+#define FPA_INT_SUM_FED0_DBE 0x0000000000000002ULL
+#define FPA_INT_SUM_FED0_SBE 0x0000000000000001ULL
+
+#define FPA_INT_ENB_XXX_63_28 0xfffffffff0000000ULL
+#define FPA_INT_ENB_Q7_PERR 0x0000000008000000ULL
+#define FPA_INT_ENB_Q7_COFF 0x0000000004000000ULL
+#define FPA_INT_ENB_Q7_UND 0x0000000002000000ULL
+#define FPA_INT_ENB_Q6_PERR 0x0000000001000000ULL
+#define FPA_INT_ENB_Q6_COFF 0x0000000000800000ULL
+#define FPA_INT_ENB_Q6_UND 0x0000000000400000ULL
+#define FPA_INT_ENB_Q5_PERR 0x0000000000200000ULL
+#define FPA_INT_ENB_Q5_COFF 0x0000000000100000ULL
+#define FPA_INT_ENB_Q5_UND 0x0000000000080000ULL
+#define FPA_INT_ENB_Q4_PERR 0x0000000000040000ULL
+#define FPA_INT_ENB_Q4_COFF 0x0000000000020000ULL
+#define FPA_INT_ENB_Q4_UND 0x0000000000010000ULL
+#define FPA_INT_ENB_Q3_PERR 0x0000000000008000ULL
+#define FPA_INT_ENB_Q3_COFF 0x0000000000004000ULL
+#define FPA_INT_ENB_Q3_UND 0x0000000000002000ULL
+#define FPA_INT_ENB_Q2_PERR 0x0000000000001000ULL
+#define FPA_INT_ENB_Q2_COFF 0x0000000000000800ULL
+#define FPA_INT_ENB_Q2_UND 0x0000000000000400ULL
+#define FPA_INT_ENB_Q1_PERR 0x0000000000000200ULL
+#define FPA_INT_ENB_Q1_COFF 0x0000000000000100ULL
+#define FPA_INT_ENB_Q1_UND 0x0000000000000080ULL
+#define FPA_INT_ENB_Q0_PERR 0x0000000000000040ULL
+#define FPA_INT_ENB_Q0_COFF 0x0000000000000020ULL
+#define FPA_INT_ENB_Q0_UND 0x0000000000000010ULL
+#define FPA_INT_ENB_FED1_DBE 0x0000000000000008ULL
+#define FPA_INT_ENB_FED1_SBE 0x0000000000000004ULL
+#define FPA_INT_ENB_FED0_DBE 0x0000000000000002ULL
+#define FPA_INT_ENB_FED0_SBE 0x0000000000000001ULL
+
+#define FPA_CTL_STATUS_XXX_63_18 0xfffffffffffc0000ULL
+#define FPA_CTL_STATUS_RESET 0x0000000000020000ULL
+#define FPA_CTL_STATUS_USE_LDT 0x0000000000010000ULL
+#define FPA_CTL_STATUS_USE_STT 0x0000000000008000ULL
+#define FPA_CTL_STATUS_ENB 0x0000000000004000ULL
+#define FPA_CTL_STATUS_MEM1_ERR 0x0000000000003f80ULL
+#define FPA_CTL_STATUS_MEM0_ERR 0x000000000000007fULL
+
+#define FPA_QUEX_AVAILABLE_XXX_63_29 0xffffffffe0000000ULL
+#define FPA_QUEX_AVAILABLE_QUE_SIZ 0x000000001fffffffULL
+
+#define FPA_WART_CTL_XXX_63_16 0xffffffffffff0000ULL
+#define FPA_WART_CTL_CTL 0x000000000000ffffULL
+
+#define FPA_WART_STATUS_XXX_63_32 0xffffffff00000000ULL
+#define FPA_WART_STATUS_STATUS 0x00000000ffffffffULL
+
+#define FPA_BIST_STATUS_XXX_63_5 0xffffffffffffffe0ULL
+#define FPA_BIST_STATUS_FRD 0x0000000000000010ULL
+#define FPA_BIST_STATUS_FPF0 0x0000000000000008ULL
+#define FPA_BIST_STATUS_FPF1 0x0000000000000004ULL
+#define FPA_BIST_STATUS_FFR 0x0000000000000002ULL
+#define FPA_BIST_STATUS_FDR 0x0000000000000001ULL
+
+#define FPA_QUEX_PAGE_INDEX_XXX_63_25 0xfffffffffe000000ULL
+#define FPA_QUEX_PAGE_INDEX_PG_NUM 0x0000000001ffffffULL
+
+#define FPA_QUE_EXP_XXX_63_32 0xffffffff00000000ULL
+#define FPA_QUE_EXP_XXX_31_29 0x00000000e0000000ULL
+#define FPA_QUE_EXP_EXP_QUE 0x000000001c000000ULL
+#define FPA_QUE_EXP_EXP_INDX 0x0000000003ffffffULL
+
+#define FPA_QUE_ACT_XXX_63_32 0xffffffff00000000ULL
+#define FPA_QUE_ACT_XXX_31_29 0x00000000e0000000ULL
+#define FPA_QUE_ACT_ACT_QUE 0x000000001c000000ULL
+#define FPA_QUE_ACT_ACT_INDX 0x0000000003ffffffULL
+
+/* ---- bitmask_snprintf(9) */
+
+#define FPA_INT_SUM_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x1b" "Q7_PERR\0" \
+ "b\x1a" "Q7_COFF\0" \
+ "b\x19" "Q7_UND\0" \
+ "b\x18" "Q6_PERR\0" \
+ "b\x17" "Q6_COFF\0" \
+ "b\x16" "Q6_UND\0" \
+ "b\x15" "Q5_PERR\0" \
+ "b\x14" "Q5_COFF\0" \
+ "b\x13" "Q5_UND\0" \
+ "b\x12" "Q4_PERR\0" \
+ "b\x11" "Q4_COFF\0" \
+ "b\x10" "Q4_UND\0" \
+ "b\x0f" "Q3_PERR\0" \
+ "b\x0e" "Q3_COFF\0" \
+ "b\x0d" "Q3_UND\0" \
+ "b\x0c" "Q2_PERR\0" \
+ "b\x0b" "Q2_COFF\0" \
+ "b\x0a" "Q2_UND\0" \
+ "b\x09" "Q1_PERR\0" \
+ "b\x08" "Q1_COFF\0" \
+ "b\x07" "Q1_UND\0" \
+ "b\x06" "Q0_PERR\0" \
+ "b\x05" "Q0_COFF\0" \
+ "b\x04" "Q0_UND\0" \
+ "b\x03" "FED1_DBE\0" \
+ "b\x02" "FED1_SBE\0" \
+ "b\x01" "FED0_DBE\0" \
+ "b\x00" "FED0_SBE\0"
+
+#define FPA_INT_ENB_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x1b" "Q7_PERR\0" \
+ "b\x1a" "Q7_COFF\0" \
+ "b\x19" "Q7_UND\0" \
+ "b\x18" "Q6_PERR\0" \
+ "b\x17" "Q6_COFF\0" \
+ "b\x16" "Q6_UND\0" \
+ "b\x15" "Q5_PERR\0" \
+ "b\x14" "Q5_COFF\0" \
+ "b\x13" "Q5_UND\0" \
+ "b\x12" "Q4_PERR\0" \
+ "b\x11" "Q4_COFF\0" \
+ "b\x10" "Q4_UND\0" \
+ "b\x0f" "Q3_PERR\0" \
+ "b\x0e" "Q3_COFF\0" \
+ "b\x0d" "Q3_UND\0" \
+ "b\x0c" "Q2_PERR\0" \
+ "b\x0b" "Q2_COFF\0" \
+ "b\x0a" "Q2_UND\0" \
+ "b\x09" "Q1_PERR\0" \
+ "b\x08" "Q1_COFF\0" \
+ "b\x07" "Q1_UND\0" \
+ "b\x06" "Q0_PERR\0" \
+ "b\x05" "Q0_COFF\0" \
+ "b\x04" "Q0_UND\0" \
+ "b\x03" "FED1_DBE\0" \
+ "b\x02" "FED1_SBE\0" \
+ "b\x01" "FED0_DBE\0" \
+ "b\x00" "FED0_SBE\0"
+
+#define FPA_CTL_STATUS_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x11" "RESET\0" \
+ "b\x10" "USE_LDT\0" \
+ "b\x0f" "USE_STT\0" \
+ "b\x0e" "ENB\0" \
+ "f\x07\x07" "MEM1_ERR\0" \
+ "f\x00\x07" "MEM0_ERR\0"
+
+#define FPA_QUEX_AVAILABLE_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x1d" "QUE_SIZ\0"
+#define FPA_QUE0_AVAILABLE_BITS FPA_QUEX_AVAILABLE_BITS
+#define FPA_QUE1_AVAILABLE_BITS FPA_QUEX_AVAILABLE_BITS
+#define FPA_QUE2_AVAILABLE_BITS FPA_QUEX_AVAILABLE_BITS
+#define FPA_QUE3_AVAILABLE_BITS FPA_QUEX_AVAILABLE_BITS
+#define FPA_QUE4_AVAILABLE_BITS FPA_QUEX_AVAILABLE_BITS
+#define FPA_QUE5_AVAILABLE_BITS FPA_QUEX_AVAILABLE_BITS
+#define FPA_QUE6_AVAILABLE_BITS FPA_QUEX_AVAILABLE_BITS
+#define FPA_QUE7_AVAILABLE_BITS FPA_QUEX_AVAILABLE_BITS
+
+#define FPA_WART_CTL_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x10" "CTL\0"
+
+#define FPA_WART_STATUS_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x20" "STATUS\0"
+
+#define FPA_BIST_STATUS_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x04" "FRD\0" \
+ "b\x03" "FPF0\0" \
+ "b\x02" "FPF1\0" \
+ "b\x01" "FFR\0" \
+ "b\x00" "FDR\0"
+
+#define FPA_QUEX_PAGE_INDEX_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x19" "PG_NUM\0"
+#define FPA_QUE0_PAGE_INDEX_BITS FPA_QUEX_PAGE_INDEX_BITS
+#define FPA_QUE1_PAGE_INDEX_BITS FPA_QUEX_PAGE_INDEX_BITS
+#define FPA_QUE2_PAGE_INDEX_BITS FPA_QUEX_PAGE_INDEX_BITS
+#define FPA_QUE3_PAGE_INDEX_BITS FPA_QUEX_PAGE_INDEX_BITS
+#define FPA_QUE4_PAGE_INDEX_BITS FPA_QUEX_PAGE_INDEX_BITS
+#define FPA_QUE5_PAGE_INDEX_BITS FPA_QUEX_PAGE_INDEX_BITS
+#define FPA_QUE6_PAGE_INDEX_BITS FPA_QUEX_PAGE_INDEX_BITS
+#define FPA_QUE7_PAGE_INDEX_BITS FPA_QUEX_PAGE_INDEX_BITS
+
+#define FPA_QUE_EXP_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x1a\x03" "EXP_QUE\0" \
+ "f\x00\x1a" "EXP_INDX\0"
+
+#define FPA_QUE_ACT_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x1a\x03" "ACT_QUE\0" \
+ "f\x00\x1a" "ACT_INDX\0"
+
+/* ---- operations */
+
+/*
+ * 6.1 Free Pool Unit Operations
+ */
+
+#define FPA_MAJORDID 0x5 /* 0b00101 */
+
+#define FPA_OPS_MAJORDID 0x0000f80000000000ULL
+#define FPA_OPS_MAJORDID_SHIFT 43
+#define FPA_OPS_SUBDID 0x0000070000000000ULL
+#define FPA_OPS_SUBDID_SHIFT 40
+#define FPA_OPS_XXX_39_0 0x000000ffffffffffULL
+
+/* 6.1.1 Load Operations */
+
+#define FPA_OPS_LOAD_1 0x0001000000000000ULL
+#define FPA_OPS_LOAD_MAJORDID 0x0000f80000000000ULL
+#define FPA_OPS_LOAD_SUBDID 0x0000070000000000ULL
+#define FPA_OPS_LOAD_XXX_39_0 0x000000ffffffffffULL
+
+/* 6.1.2 IOBDMA Operations */
+
+#define FPA_OPS_IOBDMA_SRCADDR 0xff00000000000000ULL
+#define FPA_OPS_IOBDMA_LEN 0x00ff000000000000ULL
+#define FPA_OPS_IOBDMA_LEN_SHIFT 48
+#define FPA_OPS_IOBDMA_MAJORDID 0x0000f80000000000ULL
+#define FPA_OPS_IOBDMA_SUBDIR 0x0000070000000000ULL
+#define FPA_OPS_IOBDMA_XXX_39_0 0x000000ffffffffffULL
+
+/* 6.1.3 Store Operations */
+
+#define FPA_OPS_STORE_1 0x0001000000000000ULL
+#define FPA_OPS_STORE_MAJORDID 0x0000f80000000000ULL
+#define FPA_OPS_STORE_SUBDID 0x0000070000000000ULL
+#define FPA_OPS_STORE_XXX_39_0 0x000000ffffffffffULL
+
+#define FPA_OPS_STORE_DATA_XXX_63_9 0xfffffffffffffe00ULL
+#define FPA_OPS_STORE_DATA_DWBCOUNT 0x00000000000001ffULL
+
+/* ---- bus_space(9) */
+
+#define FPA_BASE 0x0001180028000000ULL
+#define FPA_SIZE 0x0200
+
+#define FPA_INT_SUM_OFFSET 0x0040
+#define FPA_INT_ENB_OFFSET 0x0048
+#define FPA_CTL_STATUS_OFFSET 0x0050
+#define FPA_QUE0_AVAILABLE_OFFSET 0x0098
+#define FPA_QUE1_AVAILABLE_OFFSET 0x00a0
+#define FPA_QUE2_AVAILABLE_OFFSET 0x00a8
+#define FPA_QUE3_AVAILABLE_OFFSET 0x00b0
+#define FPA_QUE4_AVAILABLE_OFFSET 0x00b8
+#define FPA_QUE5_AVAILABLE_OFFSET 0x00c0
+#define FPA_QUE6_AVAILABLE_OFFSET 0x00c8
+#define FPA_QUE7_AVAILABLE_OFFSET 0x00d0
+#define FPA_WART_CTL_OFFSET 0x00d8
+#define FPA_WART_STATUS_OFFSET 0x00e0
+#define FPA_BIST_STATUS_OFFSET 0x00e8
+#define FPA_QUE0_PAGE_INDEX_OFFSET 0x00f0
+#define FPA_QUE1_PAGE_INDEX_OFFSET 0x00f8
+#define FPA_QUE2_PAGE_INDEX_OFFSET 0x0100
+#define FPA_QUE3_PAGE_INDEX_OFFSET 0x0108
+#define FPA_QUE4_PAGE_INDEX_OFFSET 0x0110
+#define FPA_QUE5_PAGE_INDEX_OFFSET 0x0118
+#define FPA_QUE6_PAGE_INDEX_OFFSET 0x0120
+#define FPA_QUE7_PAGE_INDEX_OFFSET 0x0128
+#define FPA_QUE_EXP_OFFSET 0x0130
+#define FPA_QUE_ACT_OFFSET 0x0138
+
+/* XXXX not use bit field */
+/**
+ * cvmx_fpa_ctl_status
+ *
+ * FPA_CTL_STATUS = FPA's Control/Status Register
+ *
+ * The FPA's interrupt enable register.
+ */
+
+#if 0
+
+#ifndef MIPS_SPACE
+#define MIPS_SPACE
+typedef enum {
+ MIPS_SPACE_XKSEG = 3LL,
+ MIPS_SPACE_XKPHYS = 2LL,
+ MIPS_SPACE_XSSEG = 1LL,
+ MIPS_SPACE_XUSEG = 0LL
+} mips_space_t;
+#endif
+
+typedef enum {
+ MIPS_XKSEG_SPACE_KSEG0 = 0LL,
+ MIPS_XKSEG_SPACE_KSEG1 = 1LL,
+ MIPS_XKSEG_SPACE_SSEG = 2LL,
+ MIPS_XKSEG_SPACE_KSEG3 = 3LL
+} mips_xkseg_space_t;
+
+// decodes <14:13> of a kseg3 window address
+typedef enum {
+ OCTEON_ADD_WIN_SCR = 0L,
+ OCTEON_ADD_WIN_DMA = 1L, // see cvmx_add_win_dma_dec_t for further decode
+ OCTEON_ADD_WIN_UNUSED = 2L,
+ OCTEON_ADD_WIN_UNUSED2 = 3L
+} octeon_add_win_dec_t;
+
+// decode within DMA space
+typedef enum {
+ OCTEON_ADD_WIN_DMA_ADD = 0L, // add store data to the write buffer entry, allocating it if necessary
+ OCTEON_ADD_WIN_DMA_SENDMEM = 1L, // send out the write buffer entry to DRAM
+ // store data must be normal DRAM memory space address in this case
+ OCTEON_ADD_WIN_DMA_SENDDMA = 2L, // send out the write buffer entry as an IOBDMA command
+ // see CVMX_ADD_WIN_DMA_SEND_DEC for data contents
+ OCTEON_ADD_WIN_DMA_SENDIO = 3L, // send out the write buffer entry as an IO write
+ // store data must be normal IO space address in this case
+ OCTEON_ADD_WIN_DMA_SENDSINGLE = 4L, // send out a single-tick command on the NCB bus
+ // no write buffer data needed/used
+} octeon_add_win_dma_dec_t;
+
+
+typedef union {
+
+ uint64_t u64;
+
+ struct {
+ mips_space_t R : 2;
+ uint64_t offset :62;
+ } sva; // mapped or unmapped virtual address
+
+ struct {
+ uint64_t zeroes :33;
+ uint64_t offset :31;
+ } suseg; // mapped USEG virtual addresses (typically)
+
+ struct {
+ uint64_t ones :33;
+ mips_xkseg_space_t sp : 2;
+ uint64_t offset :29;
+ } sxkseg; // mapped or unmapped virtual address
+
+ struct {
+ mips_space_t R : 2; // CVMX_MIPS_SPACE_XKPHYS in this case
+ uint64_t cca : 3; // ignored by octeon
+ uint64_t mbz :10;
+ uint64_t pa :49; // physical address
+ } sxkphys; // physical address accessed through xkphys unmapped virtual address
+
+ struct {
+ uint64_t mbz :15;
+ uint64_t is_io : 1; // if set, the address is uncached and resides on MCB bus
+ uint64_t did : 8; // the hardware ignores this field when is_io==0, else device ID
+ uint64_t unaddr: 4; // the hardware ignores <39:36> in Octeon I
+ uint64_t offset :36;
+ } sphys; // physical address
+
+ struct {
+ uint64_t zeroes :24; // techically, <47:40> are dont-cares
+ uint64_t unaddr: 4; // the hardware ignores <39:36> in Octeon I
+ uint64_t offset :36;
+ } smem; // physical mem address
+
+ struct {
+ uint64_t mem_region :2;
+ uint64_t mbz :13;
+ uint64_t is_io : 1; // 1 in this case
+ uint64_t did : 8; // the hardware ignores this field when is_io==0, else device ID
+ uint64_t unaddr: 4; // the hardware ignores <39:36> in Octeon I
+ uint64_t offset :36;
+ } sio; // physical IO address
+
+ struct {
+ uint64_t ones : 49;
+ octeon_add_win_dec_t csrdec : 2; // CVMX_ADD_WIN_SCR (0) in this case
+ uint64_t addr : 13;
+ } sscr; // scratchpad virtual address - accessed through a window at the end of kseg3
+ // there should only be stores to IOBDMA space, no loads
+ struct {
+ uint64_t ones : 49;
+ octeon_add_win_dec_t csrdec : 2; // CVMX_ADD_WIN_DMA (1) in this case
+ uint64_t unused2: 3;
+ octeon_add_win_dma_dec_t type : 3;
+ uint64_t addr : 7;
+ } sdma; // IOBDMA virtual address - accessed through a window at the end of kseg3
+
+ struct {
+ uint64_t didspace : 24;
+ uint64_t unused : 40;
+ } sfilldidspace;
+
+} cn30xxfpa_addr_t;
+
+#endif
+
+#endif /* _CN30XXFPAREG_H_ */
diff --git a/sys/arch/octeon/dev/cn30xxfpavar.h b/sys/arch/octeon/dev/cn30xxfpavar.h
new file mode 100644
index 00000000000..8040b13496c
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxfpavar.h
@@ -0,0 +1,155 @@
+/* $OpenBSD: cn30xxfpavar.h,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _CN30XXFPAVAR_H_
+#define _CN30XXFPAVAR_H_
+
+struct cn30xxfpa_buf {
+ int fb_poolno; /* pool # */
+
+ size_t fb_size; /* element size */
+ size_t fb_nelems; /* # of elements */
+
+ paddr_t fb_paddr; /* physical address */
+ vaddr_t fb_addr; /* virtual address */
+ size_t fb_len; /* total length */
+
+ bus_dma_tag_t fb_dmat;
+ bus_dmamap_t fb_dmah;
+ bus_dma_segment_t
+ *fb_dma_segs;
+ int fb_dma_nsegs;
+};
+
+uint64_t cn30xxfpa_int_summary(void);
+int cn30xxfpa_buf_init(int, size_t, size_t, struct cn30xxfpa_buf **);
+void *cn30xxfpa_buf_get(struct cn30xxfpa_buf *);
+uint64_t cn30xxfpa_query(int);
+
+#ifdef OCTEON_ETH_DEBUG
+void cn30xxfpa_dump(void);
+#endif
+
+#define CACHE_LINE_SIZE (128)
+
+/* Pool sizes in bytes, must be multiple of a cache line */
+#define FPA_POOL_0_SIZE (16 * CACHE_LINE_SIZE)
+#define FPA_POOL_1_SIZE (1 * CACHE_LINE_SIZE)
+#define FPA_POOL_2_SIZE (8 * CACHE_LINE_SIZE)
+#define FPA_POOL_3_SIZE (4 * CACHE_LINE_SIZE)
+
+#define FPA_POOL_4_SIZE (16 * CACHE_LINE_SIZE)
+#define FPA_POOL_5_SIZE (16 * CACHE_LINE_SIZE)
+#define FPA_POOL_6_SIZE (16 * CACHE_LINE_SIZE)
+#define FPA_POOL_7_SIZE (16 * CACHE_LINE_SIZE)
+
+/* Pools in use */
+#define FPA_RECV_PKT_POOL (0) /* Recieve Packet buffers */
+#define FPA_RECV_PKT_POOL_SIZE FPA_POOL_0_SIZE
+#define FPA_RECV_PKT_POOL_LINE 16
+#define FPA_WQE_POOL (1) /* Work queue entrys */
+#define FPA_WQE_POOL_SIZE FPA_POOL_1_SIZE
+#define FPA_WQE_POOL_LINE 1
+#define FPA_COMMAND_BUFFER_POOL (2) /* PKO queue command buffers */
+#define FPA_COMMAND_BUFFER_POOL_SIZE FPA_POOL_2_SIZE
+#define FPA_COMMAND_BUFFER_POOL_LINE 8
+#define FPA_GATHER_BUFFER_POOL (3) /* PKO gather list buffers */
+#define FPA_GATHER_BUFFER_POOL_SIZE FPA_POOL_3_SIZE
+#define FPA_GATHER_BUFFER_POOL_LINE 4
+
+#ifndef FPA_OUTPUT_BUFFER_POOL
+#define FPA_OUTPUT_BUFFER_POOL FPA_COMMAND_BUFFER_POOL
+#define FPA_OUTPUT_BUFFER_POOL_SIZE FPA_COMMAND_BUFFER_POOL_SIZE
+#endif
+
+/*
+ * operations
+ */
+
+static inline uint64_t
+cn30xxfpa_load(uint64_t fpapool)
+{
+ uint64_t addr;
+
+ addr =
+ (0x1ULL << 48) |
+ (0x5ULL << 43) |
+ (fpapool & 0x07ULL) << 40;
+
+ return octeon_read_csr(addr);
+}
+
+#ifdef notyet
+static inline uint64_t
+cn30xxfpa_iobdma(struct cn30xxfpa_softc *sc, int srcaddr, int len)
+{
+ /* XXX */
+ return 0ULL;
+}
+#endif
+
+static inline void
+cn30xxfpa_store(uint64_t addr, uint64_t fpapool, uint64_t dwbcount)
+{
+ uint64_t ptr;
+
+ ptr =
+ (0x1ULL << 48) |
+ (0x5ULL << 43) |
+ (fpapool & 0x07ULL) << 40 |
+ (addr & 0xffffffffffULL);
+
+ OCTEON_SYNCWS;
+ octeon_write_csr(ptr, (dwbcount & 0x0ffULL));
+}
+
+static inline paddr_t
+cn30xxfpa_buf_get_paddr(struct cn30xxfpa_buf *fb)
+{
+ return cn30xxfpa_load(fb->fb_poolno);
+}
+
+static inline void
+cn30xxfpa_buf_put_paddr(struct cn30xxfpa_buf *fb, paddr_t paddr)
+{
+ KASSERT(paddr >= fb->fb_paddr);
+ KASSERT(paddr < fb->fb_paddr + fb->fb_len);
+ cn30xxfpa_store(paddr, fb->fb_poolno, fb->fb_size / 128);
+}
+
+static inline void
+cn30xxfpa_buf_put(struct cn30xxfpa_buf *fb, void *addr)
+{
+ paddr_t paddr;
+
+ KASSERT((vaddr_t)addr >= fb->fb_addr);
+ KASSERT((vaddr_t)addr < fb->fb_addr + fb->fb_len);
+ paddr = fb->fb_paddr + (paddr_t/* XXX */)((vaddr_t)addr - fb->fb_addr);
+ cn30xxfpa_buf_put_paddr(fb, paddr);
+}
+
+#endif
diff --git a/sys/arch/octeon/dev/cn30xxgmx.c b/sys/arch/octeon/dev/cn30xxgmx.c
new file mode 100644
index 00000000000..14ad35c54b5
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxgmx.c
@@ -0,0 +1,1733 @@
+/* $OpenBSD: cn30xxgmx.c,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * support GMX0 interface only
+ * take no thought for other GMX interface
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/types.h>
+#include <sys/device.h>
+#include <sys/lock.h>
+#include <sys/cdefs.h>
+#include <sys/malloc.h>
+#include <sys/syslog.h>
+
+#include <machine/bus.h>
+#include <machine/octeon_model.h>
+
+#include <octeon/dev/iobusvar.h>
+#include <octeon/dev/cn30xxciureg.h>
+#include <octeon/dev/cn30xxgmxreg.h>
+#include <octeon/dev/cn30xxipdvar.h>
+#include <octeon/dev/cn30xxasxvar.h>
+#include <octeon/dev/cn30xxgmxvar.h>
+
+#define dprintf(...)
+#define OCTEON_ETH_KASSERT KASSERT
+
+#ifndef SET
+#define SET(t, f) ((t) |= (f))
+#define ISSET(t, f) ((t) & (f))
+#define CLR(t, f) ((t) &= ~(f))
+#endif
+
+#define ADDR2UINT64(u, a) \
+ do { \
+ u = \
+ (((uint64_t)a[0] << 40) | ((uint64_t)a[1] << 32) | \
+ ((uint64_t)a[2] << 24) | ((uint64_t)a[3] << 16) | \
+ ((uint64_t)a[4] << 8) | ((uint64_t)a[5] << 0)); \
+ } while (0)
+#define UINT642ADDR(a, u) \
+ do { \
+ a[0] = (uint8_t)((u) >> 40); a[1] = (uint8_t)((u) >> 32); \
+ a[2] = (uint8_t)((u) >> 24); a[3] = (uint8_t)((u) >> 16); \
+ a[4] = (uint8_t)((u) >> 8); a[5] = (uint8_t)((u) >> 0); \
+ } while (0)
+
+#define _GMX_RD8(sc, off) \
+ bus_space_read_8((sc)->sc_port_gmx->sc_regt, (sc)->sc_port_gmx->sc_regh, (off))
+#define _GMX_WR8(sc, off, v) \
+ bus_space_write_8((sc)->sc_port_gmx->sc_regt, (sc)->sc_port_gmx->sc_regh, (off), (v))
+#define _GMX_PORT_RD8(sc, off) \
+ bus_space_read_8((sc)->sc_port_gmx->sc_regt, (sc)->sc_port_regh, (off))
+#define _GMX_PORT_WR8(sc, off, v) \
+ bus_space_write_8((sc)->sc_port_gmx->sc_regt, (sc)->sc_port_regh, (off), (v))
+
+struct cn30xxgmx_port_ops {
+ int (*port_ops_enable)(struct cn30xxgmx_port_softc *, int);
+ int (*port_ops_speed)(struct cn30xxgmx_port_softc *);
+ int (*port_ops_timing)(struct cn30xxgmx_port_softc *);
+ int (*port_ops_set_mac_addr)(struct cn30xxgmx_port_softc *,
+ uint8_t *, uint64_t);
+ int (*port_ops_set_filter)(struct cn30xxgmx_port_softc *);
+};
+
+static int cn30xxgmx_match(struct device *, void *, void *);
+static void cn30xxgmx_attach(struct device *, struct device *, void *);
+static int cn30xxgmx_print(void *, const char *);
+static int cn30xxgmx_submatch(struct device *, void *, void *);
+static int cn30xxgmx_init(struct cn30xxgmx_softc *);
+static int cn30xxgmx_rx_frm_ctl_xable(struct cn30xxgmx_port_softc *,
+ uint64_t, int);
+static int cn30xxgmx_rgmii_enable(struct cn30xxgmx_port_softc *, int);
+static int cn30xxgmx_rgmii_speed(struct cn30xxgmx_port_softc *);
+static int cn30xxgmx_rgmii_speed_newlink(struct cn30xxgmx_port_softc *,
+ uint64_t *);
+static int cn30xxgmx_rgmii_speed_newlink_log(
+ struct cn30xxgmx_port_softc *, uint64_t);
+static int cn30xxgmx_rgmii_speed_speed(struct cn30xxgmx_port_softc *);
+static int cn30xxgmx_rgmii_timing(struct cn30xxgmx_port_softc *);
+static int cn30xxgmx_rgmii_set_mac_addr(struct cn30xxgmx_port_softc *,
+ uint8_t *, uint64_t);
+static int cn30xxgmx_rgmii_set_filter(struct cn30xxgmx_port_softc *);
+
+#ifdef OCTEON_ETH_DEBUG
+void cn30xxgmx_intr_evcnt_attach(struct cn30xxgmx_softc *);
+void cn30xxgmx_dump(void);
+void cn30xxgmx_debug_reset(void);
+int cn30xxgmx_intr_drop(void *);
+#endif
+
+static const int cn30xxgmx_rx_adr_cam_regs[] = {
+ GMX0_RX0_ADR_CAM0, GMX0_RX0_ADR_CAM1, GMX0_RX0_ADR_CAM2,
+ GMX0_RX0_ADR_CAM3, GMX0_RX0_ADR_CAM4, GMX0_RX0_ADR_CAM5
+};
+
+struct cn30xxgmx_port_ops cn30xxgmx_port_ops_mii = {
+ /* XXX not implemented */
+};
+
+struct cn30xxgmx_port_ops cn30xxgmx_port_ops_gmii = {
+ .port_ops_enable = cn30xxgmx_rgmii_enable,
+ .port_ops_speed = cn30xxgmx_rgmii_speed,
+ .port_ops_timing = cn30xxgmx_rgmii_timing,
+ .port_ops_set_mac_addr = cn30xxgmx_rgmii_set_mac_addr,
+ .port_ops_set_filter = cn30xxgmx_rgmii_set_filter
+};
+
+struct cn30xxgmx_port_ops cn30xxgmx_port_ops_rgmii = {
+ .port_ops_enable = cn30xxgmx_rgmii_enable,
+ .port_ops_speed = cn30xxgmx_rgmii_speed,
+ .port_ops_timing = cn30xxgmx_rgmii_timing,
+ .port_ops_set_mac_addr = cn30xxgmx_rgmii_set_mac_addr,
+ .port_ops_set_filter = cn30xxgmx_rgmii_set_filter
+};
+
+struct cn30xxgmx_port_ops cn30xxgmx_port_ops_spi42 = {
+ /* XXX not implemented */
+};
+
+struct cn30xxgmx_port_ops *cn30xxgmx_port_ops[] = {
+ [GMX_MII_PORT] = &cn30xxgmx_port_ops_mii,
+ [GMX_GMII_PORT] = &cn30xxgmx_port_ops_gmii,
+ [GMX_RGMII_PORT] = &cn30xxgmx_port_ops_rgmii,
+ [GMX_SPI42_PORT] = &cn30xxgmx_port_ops_spi42
+};
+
+#ifdef OCTEON_ETH_DEBUG
+static void *cn30xxgmx_intr_drop_ih;
+struct evcnt cn30xxgmx_intr_drop_evcnt =
+ EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "octeon",
+ "gmx drop intr");
+struct evcnt cn30xxgmx_intr_evcnt =
+ EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "octeon",
+ "gmx intr");
+EVCNT_ATTACH_STATIC(cn30xxgmx_intr_drop_evcnt);
+EVCNT_ATTACH_STATIC(cn30xxgmx_intr_evcnt);
+
+struct cn30xxgmx_port_softc *__cn30xxgmx_port_softc[3/* XXX */];
+#endif
+
+struct cfattach cn30xxgmx_ca = {sizeof(struct cn30xxgmx_softc),
+ cn30xxgmx_match, cn30xxgmx_attach, NULL, NULL};
+
+struct cfdriver cn30xxgmx_cd = {NULL, "cn30xxgmx", DV_DULL};
+
+static int
+cn30xxgmx_match(struct device *parent, void *match, void *aux)
+{
+ struct cfdata *cf = (struct cfdata *)match;
+ struct iobus_attach_args *aa = aux;
+
+ if (strcmp(cf->cf_driver->cd_name, aa->aa_name) != 0)
+ return 0;
+ if (cf->cf_unit != aa->aa_unitno)
+ return 0;
+ return 1;
+}
+
+static void
+cn30xxgmx_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct cn30xxgmx_softc *sc = (void *)self;
+ struct iobus_attach_args *aa = aux;
+ struct cn30xxgmx_attach_args gmx_aa;
+ int status;
+ int i;
+ struct cn30xxgmx_port_softc *port_sc;
+
+ printf("\n");
+
+ sc->sc_regt = aa->aa_bust; /* XXX why there are iot? */
+
+ status = bus_space_map(sc->sc_regt, aa->aa_unit->addr,
+ GMX0_BASE_IF_SIZE, 0, &sc->sc_regh);
+ if (status != 0)
+ panic(": can't map register");
+
+ cn30xxgmx_init(sc);
+
+ sc->sc_ports = malloc(sizeof(*sc->sc_ports) * sc->sc_nports, M_DEVBUF,
+ M_NOWAIT | M_ZERO);
+
+ for (i = 0; i < sc->sc_nports; i++) {
+ port_sc = &sc->sc_ports[i];
+ port_sc->sc_port_gmx = sc;
+ port_sc->sc_port_no = i;
+ port_sc->sc_port_type = sc->sc_port_types[i];
+ port_sc->sc_port_ops = cn30xxgmx_port_ops[port_sc->sc_port_type];
+ status = bus_space_map(sc->sc_regt,
+ aa->aa_unit->addr + GMX0_BASE_PORT_SIZE * i,
+ GMX0_BASE_PORT_SIZE, 0, &port_sc->sc_port_regh);
+ if (status != 0)
+ panic(": can't map port register");
+
+ (void)memset(&gmx_aa, 0, sizeof(gmx_aa));
+ gmx_aa.ga_regt = aa->aa_bust;
+ gmx_aa.ga_dmat = aa->aa_dmat;
+ gmx_aa.ga_addr = aa->aa_unit->addr;
+ gmx_aa.ga_name = "cnmac";
+ gmx_aa.ga_portno = i;
+ gmx_aa.ga_port_type = sc->sc_port_types[i];
+ gmx_aa.ga_gmx = sc;
+ gmx_aa.ga_gmx_port = port_sc;
+
+ config_found_sm(self, &gmx_aa,
+ cn30xxgmx_print, cn30xxgmx_submatch);
+
+#ifdef OCTEON_ETH_DEBUG
+ __cn30xxgmx_port_softc[i] = port_sc;
+#endif
+ }
+
+#ifdef OCTEON_ETH_DEBUG
+ cn30xxgmx_intr_evcnt_attach(sc);
+ if (cn30xxgmx_intr_drop_ih == NULL)
+ cn30xxgmx_intr_drop_ih = octeon_intr_establish(
+ ffs64(CIU_INTX_SUM0_GMX_DRP) - 1, 0, IPL_NET,
+ cn30xxgmx_intr_drop, NULL);
+#endif
+}
+
+static int
+cn30xxgmx_print(void *aux, const char *pnp)
+{
+ struct cn30xxgmx_attach_args *ga = aux;
+ static const char *types[] = {
+ [GMX_MII_PORT] = "MII",
+ [GMX_GMII_PORT] = "GMII",
+ [GMX_RGMII_PORT] = "RGMII"
+ };
+
+#if DEBUG
+ if (pnp)
+ printf("%s at %s", ga->ga_name, pnp);
+#endif
+
+ printf(" address=0x%016llx: %s", ga->ga_addr,
+ types[ga->ga_port_type]);
+
+ return UNCONF;
+}
+
+static int
+cn30xxgmx_submatch(struct device *parent, void *vcf, void *aux)
+{
+ struct cfdata *cf = vcf;
+
+ return (*cf->cf_attach->ca_match)(parent, vcf, aux);
+}
+
+static int
+cn30xxgmx_init(struct cn30xxgmx_softc *sc)
+{
+ int result = 0;
+ uint64_t inf_mode;
+ int id;
+
+ inf_mode = bus_space_read_8(sc->sc_regt, sc->sc_regh, GMX0_INF_MODE);
+ if ((inf_mode & INF_MODE_EN) == 0) {
+ printf("port are disable\n");
+ sc->sc_nports = 0;
+ result = 1;
+ return result;
+ }
+
+ id = octeon_get_chipid();
+
+ switch (octeon_model_family(id)) {
+ case OCTEON_MODEL_FAMILY_CN31XX:
+ /*
+ * CN31XX-HM-1.01
+ * 14.1 Packet Interface Introduction
+ * Table 14-1 Packet Interface Configuration
+ * 14.8 GMX Registers, Interface Mode Register, GMX0_INF_MODE
+ */
+ if ((inf_mode & INF_MODE_TYPE) == 0) {
+ /* all three ports configured as RGMII */
+ sc->sc_nports = 3;
+ sc->sc_port_types[0] = GMX_RGMII_PORT;
+ sc->sc_port_types[1] = GMX_RGMII_PORT;
+ sc->sc_port_types[2] = GMX_RGMII_PORT;
+ } else {
+ /* port 0: RGMII, port 1: GMII, port 2: disabled */
+ /* XXX CN31XX-HM-1.01 says "Port 3: disabled"; typo? */
+ sc->sc_nports = 2;
+ sc->sc_port_types[0] = GMX_RGMII_PORT;
+ sc->sc_port_types[1] = GMX_GMII_PORT;
+ }
+ break;
+ case OCTEON_MODEL_FAMILY_CN30XX:
+ case OCTEON_MODEL_FAMILY_CN50XX:
+ /*
+ * CN30XX-HM-1.0
+ * 13.1 Packet Interface Introduction
+ * Table 13-1 Packet Interface Configuration
+ * 13.8 GMX Registers, Interface Mode Register, GMX0_INF_MODE
+ */
+ if ((inf_mode & INF_MODE_P0MII) == 0)
+ sc->sc_port_types[0] = GMX_RGMII_PORT;
+ else
+ sc->sc_port_types[0] = GMX_MII_PORT;
+ if ((inf_mode & INF_MODE_TYPE) == 0) {
+ /* port 1 and 2 are configred as RGMII ports */
+ sc->sc_nports = 3;
+ sc->sc_port_types[1] = GMX_RGMII_PORT;
+ sc->sc_port_types[2] = GMX_RGMII_PORT;
+ } else {
+ /* port 1: GMII/MII, port 2: disabled */
+ /* GMII or MII port is slected by GMX_PRT1_CFG[SPEED] */
+ sc->sc_nports = 2;
+ sc->sc_port_types[1] = GMX_GMII_PORT;
+ }
+ /* port 2 is in CN3010/CN5010 only */
+ if ((octeon_model(id) != OCTEON_MODEL_CN3010) &&
+ (octeon_model(id) != OCTEON_MODEL_CN5010))
+ if (sc->sc_nports == 3)
+ sc->sc_nports = 2;
+ break;
+ case OCTEON_MODEL_FAMILY_CN38XX:
+ case OCTEON_MODEL_FAMILY_CN56XX:
+ case OCTEON_MODEL_FAMILY_CN58XX:
+ default:
+ printf("unsupported octeon model: 0x%x\n", octeon_get_chipid());
+ sc->sc_nports = 0;
+ result = 1;
+ break;
+ }
+
+ return result;
+}
+
+/* XXX RGMII specific */
+int
+cn30xxgmx_link_enable(struct cn30xxgmx_port_softc *sc, int enable)
+{
+ uint64_t prt_cfg;
+
+ cn30xxgmx_tx_int_enable(sc, enable);
+ cn30xxgmx_rx_int_enable(sc, enable);
+
+ prt_cfg = _GMX_PORT_RD8(sc, GMX0_PRT0_CFG);
+ if (enable) {
+ if (cn30xxgmx_link_status(sc)) {
+ SET(prt_cfg, PRTN_CFG_EN);
+ }
+ } else {
+ CLR(prt_cfg, PRTN_CFG_EN);
+ }
+ _GMX_PORT_WR8(sc, GMX0_PRT0_CFG, prt_cfg);
+ /*
+ * According to CN30XX-HM-1.0, 13.4.2 Link Status Changes:
+ * > software should read back to flush the write operation.
+ */
+ (void)_GMX_PORT_RD8(sc, GMX0_PRT0_CFG);
+
+ return 0;
+}
+
+/* XXX RGMII specific */
+int
+cn30xxgmx_stats_init(struct cn30xxgmx_port_softc *sc)
+{
+ _GMX_PORT_WR8(sc, GMX0_RX0_STATS_PKTS, 0x0ULL);
+ _GMX_PORT_WR8(sc, GMX0_RX0_STATS_PKTS_DRP, 0x0ULL);
+ _GMX_PORT_WR8(sc, GMX0_RX0_STATS_PKTS_BAD, 0x0ULL);
+ _GMX_PORT_WR8(sc, GMX0_TX0_STAT0, 0x0ULL);
+ _GMX_PORT_WR8(sc, GMX0_TX0_STAT1, 0x0ULL);
+ _GMX_PORT_WR8(sc, GMX0_TX0_STAT3, 0x0ULL);
+ _GMX_PORT_WR8(sc, GMX0_TX0_STAT9, 0x0ULL);
+ return 0;
+}
+
+int
+cn30xxgmx_tx_stats_rd_clr(struct cn30xxgmx_port_softc *sc, int enable)
+{
+ _GMX_PORT_WR8(sc, GMX0_TX0_STATS_CTL, enable ? 0x1ULL : 0x0ULL);
+ return 0;
+}
+
+int
+cn30xxgmx_rx_stats_rd_clr(struct cn30xxgmx_port_softc *sc, int enable)
+{
+ _GMX_PORT_WR8(sc, GMX0_RX0_STATS_CTL, enable ? 0x1ULL : 0x0ULL);
+ return 0;
+}
+
+void
+cn30xxgmx_rx_stats_dec_bad(struct cn30xxgmx_port_softc *sc)
+{
+ uint64_t tmp;
+
+ tmp = _GMX_PORT_RD8(sc, GMX0_RX0_STATS_PKTS_BAD);
+ _GMX_PORT_WR8(sc, GMX0_RX0_STATS_PKTS_BAD, tmp - 1);
+}
+
+static int
+cn30xxgmx_tx_ovr_bp_enable(struct cn30xxgmx_port_softc *sc, int enable)
+{
+ uint64_t ovr_bp;
+
+ ovr_bp = _GMX_RD8(sc, GMX0_TX_OVR_BP);
+ if (enable) {
+ CLR(ovr_bp, (1 << sc->sc_port_no) << TX_OVR_BP_EN_SHIFT);
+ SET(ovr_bp, (1 << sc->sc_port_no) << TX_OVR_BP_BP_SHIFT);
+ /* XXX really??? */
+ SET(ovr_bp, (1 << sc->sc_port_no) << TX_OVR_BP_IGN_FULL_SHIFT);
+ } else {
+ SET(ovr_bp, (1 << sc->sc_port_no) << TX_OVR_BP_EN_SHIFT);
+ CLR(ovr_bp, (1 << sc->sc_port_no) << TX_OVR_BP_BP_SHIFT);
+ /* XXX really??? */
+ SET(ovr_bp, (1 << sc->sc_port_no) << TX_OVR_BP_IGN_FULL_SHIFT);
+ }
+ _GMX_WR8(sc, GMX0_TX_OVR_BP, ovr_bp);
+ return 0;
+}
+
+static int
+cn30xxgmx_rx_pause_enable(struct cn30xxgmx_port_softc *sc, int enable)
+{
+ if (enable) {
+ cn30xxgmx_rx_frm_ctl_enable(sc, RXN_FRM_CTL_CTL_BCK);
+ } else {
+ cn30xxgmx_rx_frm_ctl_disable(sc, RXN_FRM_CTL_CTL_BCK);
+ }
+
+ return 0;
+}
+
+void
+cn30xxgmx_tx_int_enable(struct cn30xxgmx_port_softc *sc, int enable)
+{
+ uint64_t tx_int_xxx = 0;
+
+ SET(tx_int_xxx,
+ TX_INT_REG_LATE_COL |
+ TX_INT_REG_XSDEF |
+ TX_INT_REG_XSCOL |
+ TX_INT_REG_UNDFLW |
+ TX_INT_REG_PKO_NXA);
+ _GMX_WR8(sc, GMX0_TX_INT_REG, tx_int_xxx);
+ _GMX_WR8(sc, GMX0_TX_INT_EN, enable ? tx_int_xxx : 0);
+}
+
+void
+cn30xxgmx_rx_int_enable(struct cn30xxgmx_port_softc *sc, int enable)
+{
+ uint64_t rx_int_xxx = 0;
+
+ SET(rx_int_xxx, 0 |
+ RXN_INT_REG_PHY_DUPX |
+ RXN_INT_REG_PHY_SPD |
+ RXN_INT_REG_PHY_LINK |
+ RXN_INT_REG_IFGERR |
+ RXN_INT_REG_COLDET |
+ RXN_INT_REG_FALERR |
+ RXN_INT_REG_RSVERR |
+ RXN_INT_REG_PCTERR |
+ RXN_INT_REG_OVRERR |
+ RXN_INT_REG_NIBERR |
+ RXN_INT_REG_SKPERR |
+ RXN_INT_REG_RCVERR |
+ RXN_INT_REG_LENERR |
+ RXN_INT_REG_ALNERR |
+ RXN_INT_REG_FCSERR |
+ RXN_INT_REG_JABBER |
+ RXN_INT_REG_MAXERR |
+ RXN_INT_REG_CAREXT |
+ RXN_INT_REG_MINERR);
+ _GMX_PORT_WR8(sc, GMX0_RX0_INT_REG, rx_int_xxx);
+ _GMX_PORT_WR8(sc, GMX0_RX0_INT_EN, enable ? rx_int_xxx : 0);
+}
+
+int
+cn30xxgmx_rx_frm_ctl_enable(struct cn30xxgmx_port_softc *sc,
+ uint64_t rx_frm_ctl)
+{
+ /*
+ * XXX Jumbo-frame Workarounds
+ * Current implementation of cnmac is required to
+ * configure GMX0_RX0_JABBER[CNT] as follows:
+ * RX0_FRM_MAX(1536) <= GMX0_RX0_JABBER <= 1536(0x600)
+ */
+ _GMX_PORT_WR8(sc, GMX0_RX0_JABBER, GMX_FRM_MAX_SIZ);
+
+ return cn30xxgmx_rx_frm_ctl_xable(sc, rx_frm_ctl, 1);
+}
+
+int
+cn30xxgmx_rx_frm_ctl_disable(struct cn30xxgmx_port_softc *sc,
+ uint64_t rx_frm_ctl)
+{
+ return cn30xxgmx_rx_frm_ctl_xable(sc, rx_frm_ctl, 0);
+}
+
+static int
+cn30xxgmx_rx_frm_ctl_xable(struct cn30xxgmx_port_softc *sc,
+ uint64_t rx_frm_ctl, int enable)
+{
+ uint64_t tmp;
+
+ tmp = _GMX_PORT_RD8(sc, GMX0_RX0_FRM_CTL);
+ if (enable)
+ SET(tmp, rx_frm_ctl);
+ else
+ CLR(tmp, rx_frm_ctl);
+ _GMX_PORT_WR8(sc, GMX0_RX0_FRM_CTL, tmp);
+
+ return 0;
+}
+
+int
+cn30xxgmx_tx_thresh(struct cn30xxgmx_port_softc *sc, int cnt)
+{
+ _GMX_PORT_WR8(sc, GMX0_TX0_THRESH, cnt);
+ return 0;
+}
+
+int
+cn30xxgmx_set_mac_addr(struct cn30xxgmx_port_softc *sc, uint8_t *addr)
+{
+ uint64_t mac = 0;
+
+ ADDR2UINT64(mac, addr);
+ (*sc->sc_port_ops->port_ops_set_mac_addr)(sc, addr, mac);
+ return 0;
+}
+
+int
+cn30xxgmx_set_filter(struct cn30xxgmx_port_softc *sc)
+{
+ (*sc->sc_port_ops->port_ops_set_filter)(sc);
+ return 0;
+}
+
+int
+cn30xxgmx_port_enable(struct cn30xxgmx_port_softc *sc, int enable)
+{
+ (*sc->sc_port_ops->port_ops_enable)(sc, enable);
+ return 0;
+}
+
+int
+cn30xxgmx_reset_speed(struct cn30xxgmx_port_softc *sc)
+{
+ struct ifnet *ifp = &sc->sc_port_ac->ac_if;
+ if (ISSET(sc->sc_port_mii->mii_flags, MIIF_DOINGAUTO)) {
+ log(LOG_WARNING,
+ "%s: autonegotiation has not been completed yet\n",
+ ifp->if_xname);
+ return 1;
+ }
+ (*sc->sc_port_ops->port_ops_speed)(sc);
+ return 0;
+}
+
+int
+cn30xxgmx_reset_timing(struct cn30xxgmx_port_softc *sc)
+{
+ (*sc->sc_port_ops->port_ops_timing)(sc);
+ return 0;
+}
+
+int
+cn30xxgmx_reset_board(struct cn30xxgmx_port_softc *sc)
+{
+
+ return 0;
+}
+
+int
+cn30xxgmx_reset_flowctl(struct cn30xxgmx_port_softc *sc)
+{
+ struct ifmedia_entry *ife = sc->sc_port_mii->mii_media.ifm_cur;
+
+ /*
+ * Get flow control negotiation result.
+ */
+#ifdef GMX_802_3X_DISABLE_AUTONEG
+ /* Tentative support for SEIL-compat.. */
+ if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO) {
+ sc->sc_port_flowflags &= ~IFM_ETH_FMASK;
+ }
+#else
+ /* Default configuration of NetBSD */
+ if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO &&
+ (sc->sc_port_mii->mii_media_active & IFM_ETH_FMASK) !=
+ sc->sc_port_flowflags) {
+ sc->sc_port_flowflags =
+ sc->sc_port_mii->mii_media_active & IFM_ETH_FMASK;
+ sc->sc_port_mii->mii_media_active &= ~IFM_ETH_FMASK;
+ }
+#endif /* GMX_802_3X_DISABLE_AUTONEG */
+
+ /*
+ * 802.3x Flow Control Capabilities
+ */
+ if (sc->sc_port_flowflags & IFM_ETH_TXPAUSE) {
+ cn30xxgmx_tx_ovr_bp_enable(sc, 1);
+ } else {
+ cn30xxgmx_tx_ovr_bp_enable(sc, 0);
+ }
+ if (sc->sc_port_flowflags & IFM_ETH_RXPAUSE) {
+ cn30xxgmx_rx_pause_enable(sc, 1);
+ } else {
+ cn30xxgmx_rx_pause_enable(sc, 0);
+ }
+
+ return 0;
+}
+
+static int
+cn30xxgmx_rgmii_enable(struct cn30xxgmx_port_softc *sc, int enable)
+{
+ uint64_t mode;
+
+ /* XXX */
+ mode = _GMX_RD8(sc, GMX0_INF_MODE);
+ if (ISSET(mode, INF_MODE_EN)) {
+ cn30xxasx_enable(sc->sc_port_asx, 1);
+ }
+
+ return 0;
+}
+
+static int
+cn30xxgmx_rgmii_speed(struct cn30xxgmx_port_softc *sc)
+{
+ struct ifnet *ifp = &sc->sc_port_ac->ac_if;
+ uint64_t newlink;
+ int baudrate;
+
+ /* XXX */
+ cn30xxgmx_link_enable(sc, 1);
+
+ cn30xxgmx_rgmii_speed_newlink(sc, &newlink);
+ if (sc->sc_link == newlink) {
+ return 0;
+ }
+ cn30xxgmx_rgmii_speed_newlink_log(sc, newlink);
+ sc->sc_link = newlink;
+
+ switch (sc->sc_link & RXN_RX_INBND_SPEED) {
+ case RXN_RX_INBND_SPEED_2_5:
+ baudrate = IF_Mbps(10);
+ break;
+ case RXN_RX_INBND_SPEED_25:
+ baudrate = IF_Mbps(100);
+ break;
+ case RXN_RX_INBND_SPEED_125:
+ baudrate = IF_Mbps(1000);
+ break;
+ default:
+ baudrate = 0/* XXX */;
+ break;
+ }
+ ifp->if_baudrate = baudrate;
+
+ cn30xxgmx_link_enable(sc, 0);
+
+ /*
+ * According to CN30XX-HM-1.0, 13.4.2 Link Status Changes:
+ * wait a max_packet_time
+ * max_packet_time(us) = (max_packet_size(bytes) * 8) / link_speed(Mbps)
+ */
+ delay((GMX_FRM_MAX_SIZ * 8) / (baudrate / 1000000));
+
+ cn30xxgmx_rgmii_speed_speed(sc);
+
+ cn30xxgmx_link_enable(sc, 1);
+ cn30xxasx_enable(sc->sc_port_asx, 1);
+
+ return 0;
+}
+
+static int
+cn30xxgmx_rgmii_speed_newlink(struct cn30xxgmx_port_softc *sc,
+ uint64_t *rnewlink)
+{
+ uint64_t newlink = 0;
+
+ switch (sc->sc_quirks &
+ (OCTEON_ETH_QUIRKS_SEILX | OCTEON_ETH_QUIRKS_SEILX2PORT0 |
+ OCTEON_ETH_QUIRKS_L2SWPORT)) {
+ default:
+ /* Inband status does not seem to work */
+ newlink = _GMX_PORT_RD8(sc, GMX0_RX0_RX_INBND);
+ break;
+ case OCTEON_ETH_QUIRKS_SEILX | OCTEON_ETH_QUIRKS_SEILX2PORT0:
+ SET(newlink, RXN_RX_INBND_SPEED_125);
+ SET(newlink, RXN_RX_INBND_DUPLEX);
+ SET(newlink, RXN_RX_INBND_STATUS);
+ break;
+ case OCTEON_ETH_QUIRKS_L2SWPORT:
+ SET(newlink, RXN_RX_INBND_SPEED_125);
+ SET(newlink, RXN_RX_INBND_DUPLEX);
+ SET(newlink, RXN_RX_INBND_STATUS);
+ break;
+ case OCTEON_ETH_QUIRKS_SEILX:
+ newlink = 0;
+ switch (IFM_SUBTYPE(sc->sc_port_mii->mii_media_active)) {
+ default:
+ SET(newlink, RXN_RX_INBND_SPEED_125);
+ break;
+ case IFM_100_TX:
+ SET(newlink, RXN_RX_INBND_SPEED_25);
+ break;
+ case IFM_10_T:
+ /* XXX how can this happen? */
+ SET(newlink, RXN_RX_INBND_SPEED_2_5);
+ break;
+ }
+ SET(newlink,
+ ISSET(sc->sc_port_mii->mii_media_active, IFM_FDX) ?
+ RXN_RX_INBND_DUPLEX : 0);
+ SET(newlink,
+ ISSET(sc->sc_port_mii->mii_media_status, IFM_ACTIVE) ?
+ RXN_RX_INBND_STATUS : 0);
+ break;
+ case OCTEON_ETH_QUIRKS_SEILX2PORT0:
+ /* NOTREACHED */
+ OCTEON_ETH_KASSERT(0);
+ break;
+ }
+
+ *rnewlink = newlink;
+ return 0;
+}
+
+static int
+cn30xxgmx_rgmii_speed_newlink_log(struct cn30xxgmx_port_softc *sc,
+ uint64_t newlink)
+{
+ struct ifnet *ifp = &sc->sc_port_ac->ac_if;
+ const char *status_str;
+ const char *speed_str;
+ const char *duplex_str;
+ int is_status_changed;
+ int is_speed_changed;
+ int is_linked;
+ char status_buf[80/* XXX */];
+ char speed_buf[80/* XXX */];
+
+ is_status_changed = (newlink & RXN_RX_INBND_STATUS) !=
+ (sc->sc_link & RXN_RX_INBND_STATUS);
+ is_speed_changed = (newlink & RXN_RX_INBND_SPEED) !=
+ (sc->sc_link & RXN_RX_INBND_SPEED);
+ is_linked = ISSET(newlink, RXN_RX_INBND_STATUS);
+ if (is_status_changed) {
+ if (is_linked)
+ status_str = "link up";
+ else
+ status_str = "link down";
+ } else {
+ if (is_linked) {
+ /* any other conditions? */
+ if (is_speed_changed)
+ status_str = "link change";
+ else
+ status_str = NULL;
+ } else {
+ status_str = NULL;
+ }
+ }
+
+ if (status_str != NULL) {
+ if ((is_speed_changed && is_linked) || is_linked) {
+ switch (newlink & RXN_RX_INBND_SPEED) {
+ case RXN_RX_INBND_SPEED_2_5:
+ speed_str = "10baseT";
+ break;
+ case RXN_RX_INBND_SPEED_25:
+ speed_str = "100baseTX";
+ break;
+ case RXN_RX_INBND_SPEED_125:
+ speed_str = "1000baseT";
+ break;
+ default:
+ panic("Unknown link speed");
+ break;
+ }
+
+ if (ISSET(newlink, RXN_RX_INBND_DUPLEX))
+ duplex_str = "-FDX";
+ else
+ duplex_str = "";
+
+ (void)snprintf(speed_buf, sizeof(speed_buf), "(%s%s)",
+ speed_str, duplex_str);
+ } else {
+ speed_buf[0] = '\0';
+ }
+ (void)snprintf(status_buf, sizeof(status_buf), "%s: %s%s%s\n",
+ ifp->if_xname, status_str, (is_speed_changed | is_linked) ? " " : "",
+ speed_buf);
+ log(LOG_CRIT, status_buf);
+ }
+
+ return 0;
+}
+
+static int
+cn30xxgmx_rgmii_speed_speed(struct cn30xxgmx_port_softc *sc)
+{
+ uint64_t prt_cfg;
+ uint64_t tx_clk, tx_slot, tx_burst;
+
+ prt_cfg = _GMX_PORT_RD8(sc, GMX0_PRT0_CFG);
+
+ switch (sc->sc_link & RXN_RX_INBND_SPEED) {
+ case RXN_RX_INBND_SPEED_2_5:
+ /* 10Mbps */
+ /*
+ * "GMX Tx Clock Generation Registers", CN30XX-HM-1.0;
+ * > 8ns x 50 = 400ns (2.5MHz TXC clock)
+ */
+ tx_clk = 50;
+ /*
+ * "TX Slottime Counter Registers", CN30XX-HM-1.0;
+ * > 10/100Mbps: set SLOT to 0x40
+ */
+ tx_slot = 0x40;
+ /*
+ * "TX Burst-Counter Registers", CN30XX-HM-1.0;
+ * > 10/100Mbps: set BURST to 0x0
+ */
+ tx_burst = 0;
+ /*
+ * "GMX Tx Port Configuration Registers", CN30XX-HM-1.0;
+ * > Slot time for half-duplex operation
+ * > 0 = 512 bittimes (10/100Mbps operation)
+ */
+ CLR(prt_cfg, PRTN_CFG_SLOTTIME);
+ /*
+ * "GMX Port Configuration Registers", CN30XX-HM-1.0;
+ * > Link speed
+ * > 0 = 10/100Mbps operation
+ * > in RGMII mode: GMX0_TX(0..2)_CLK[CLK_CNT] > 1
+ */
+ CLR(prt_cfg, PRTN_CFG_SPEED);
+ break;
+ case RXN_RX_INBND_SPEED_25:
+ /* 100Mbps */
+ /*
+ * "GMX Tx Clock Generation Registers", CN30XX-HM-1.0;
+ * > 8ns x 5 = 40ns (25.0MHz TXC clock)
+ */
+ tx_clk = 5;
+ /*
+ * "TX Slottime Counter Registers", CN30XX-HM-1.0;
+ * > 10/100Mbps: set SLOT to 0x40
+ */
+ tx_slot = 0x40;
+ /*
+ * "TX Burst-Counter Registers", CN30XX-HM-1.0;
+ * > 10/100Mbps: set BURST to 0x0
+ */
+ tx_burst = 0;
+ /*
+ * "GMX Tx Port Configuration Registers", CN30XX-HM-1.0;
+ * > Slot time for half-duplex operation
+ * > 0 = 512 bittimes (10/100Mbps operation)
+ */
+ CLR(prt_cfg, PRTN_CFG_SLOTTIME);
+ /*
+ * "GMX Port Configuration Registers", CN30XX-HM-1.0;
+ * > Link speed
+ * > 0 = 10/100Mbps operation
+ * > in RGMII mode: GMX0_TX(0..2)_CLK[CLK_CNT] > 1
+ */
+ CLR(prt_cfg, PRTN_CFG_SPEED);
+ break;
+ case RXN_RX_INBND_SPEED_125:
+ /* 1000Mbps */
+ /*
+ * "GMX Tx Clock Generation Registers", CN30XX-HM-1.0;
+ * > 8ns x 1 = 8ns (125.0MHz TXC clock)
+ */
+ tx_clk = 1;
+ /*
+ * "TX Slottime Counter Registers", CN30XX-HM-1.0;
+ * > 1000Mbps: set SLOT to 0x200
+ */
+ tx_slot = 0x200;
+ /*
+ * "TX Burst-Counter Registers", CN30XX-HM-1.0;
+ * > 1000Mbps: set BURST to 0x2000
+ */
+ tx_burst = 0x2000;
+ /*
+ * "GMX Tx Port Configuration Registers", CN30XX-HM-1.0;
+ * > Slot time for half-duplex operation
+ * > 1 = 4096 bittimes (1000Mbps operation)
+ */
+ SET(prt_cfg, PRTN_CFG_SLOTTIME);
+ /*
+ * "GMX Port Configuration Registers", CN30XX-HM-1.0;
+ * > Link speed
+ * > 1 = 1000Mbps operation
+ */
+ SET(prt_cfg, PRTN_CFG_SPEED);
+ break;
+ default:
+ /* NOT REACHED! */
+ /* Following configuration is default value of system.
+ */
+ tx_clk = 1;
+ tx_slot = 0x200;
+ tx_burst = 0x2000;
+ SET(prt_cfg, PRTN_CFG_SLOTTIME);
+ SET(prt_cfg, PRTN_CFG_SPEED);
+ break;
+ }
+
+ /* Setup Duplex mode(negotiated) */
+ /*
+ * "GMX Port Configuration Registers", CN30XX-HM-1.0;
+ * > Duplex mode: 0 = half-duplex mode, 1=full-duplex
+ */
+ if (ISSET(sc->sc_link, RXN_RX_INBND_DUPLEX)) {
+ /* Full-Duplex */
+ SET(prt_cfg, PRTN_CFG_DUPLEX);
+ } else {
+ /* Half-Duplex */
+ CLR(prt_cfg, PRTN_CFG_DUPLEX);
+ }
+
+ _GMX_PORT_WR8(sc, GMX0_TX0_CLK, tx_clk);
+ _GMX_PORT_WR8(sc, GMX0_TX0_SLOT, tx_slot);
+ _GMX_PORT_WR8(sc, GMX0_TX0_BURST, tx_burst);
+ _GMX_PORT_WR8(sc, GMX0_PRT0_CFG, prt_cfg);
+
+ return 0;
+}
+
+static int
+cn30xxgmx_rgmii_timing(struct cn30xxgmx_port_softc *sc)
+{
+ int clk_set_setting;
+ uint64_t rx_frm_ctl;
+
+ /* RGMII TX Threshold Registers, CN30XX-HM-1.0;
+ * > Number of 16-byte ticks to accumulate in the TX FIFO before
+ * > sending on the RGMII interface. This field should be large
+ * > enough to prevent underflow on the RGMII interface and must
+ * > never be set to less than 0x4. This register cannot exceed
+ * > the TX FIFO depth of 0x40 words.
+ */
+ /* Default parameter of CN30XX */
+ cn30xxgmx_tx_thresh(sc, 32);
+
+ rx_frm_ctl = 0 |
+ /* RXN_FRM_CTL_NULL_DIS | (cn5xxx only) */
+ /* RXN_FRM_CTL_PRE_ALIGN | (cn5xxx only) */
+ /* RXN_FRM_CTL_PAD_LEN | (cn3xxx only) */
+ /* RXN_FRM_CTL_VLAN_LEN | (cn3xxx only) */
+ RXN_FRM_CTL_PRE_FREE |
+ RXN_FRM_CTL_CTL_SMAC |
+ RXN_FRM_CTL_CTL_MCST |
+ RXN_FRM_CTL_CTL_DRP |
+ RXN_FRM_CTL_PRE_STRP |
+ RXN_FRM_CTL_PRE_CHK;
+ if (sc->sc_quirks & OCTEON_ETH_QUIRKS_SEILX1_REVB)
+ rx_frm_ctl |= RXN_FRM_CTL_PRE_ALIGN;
+ cn30xxgmx_rx_frm_ctl_enable(sc, rx_frm_ctl);
+
+ /* XXX PHY-dependent parameter */
+ /* RGMII RX Clock-Delay Registers, CN30XX-HM-1.0;
+ * > Delay setting to place n RXC (RGMII receive clock) delay line.
+ * > The intrinsic delay can range from 50ps to 80ps per tap,
+ * > which corresponds to skews of 1.25ns to 2.00ns at 25 taps(CSR+1).
+ * > This is the best match for the RGMII specification which wants
+ * > 1ns - 2.6ns of skew.
+ */
+ /* RGMII TX Clock-Delay Registers, CN30XX-HM-1.0;
+ * > Delay setting to place n TXC (RGMII transmit clock) delay line.
+ * > ...
+ */
+ switch (sc->sc_quirks & OCTEON_ETH_QUIRKS_SEILX) {
+ case OCTEON_ETH_QUIRKS_SEILX:
+ /*
+ * Table.4-6, Summary of ASX Registers, SEIL_HS_v03;
+ */
+ clk_set_setting = 0;
+ break;
+ default:
+ /* Default parameter of CN30XX */
+ clk_set_setting = 24;
+ break;
+ }
+
+ cn30xxasx_clk_set(sc->sc_port_asx, clk_set_setting);
+
+ return 0;
+}
+
+static int
+cn30xxgmx_rgmii_set_mac_addr(struct cn30xxgmx_port_softc *sc, uint8_t *addr,
+ uint64_t mac)
+{
+ int i;
+
+ cn30xxgmx_link_enable(sc, 0);
+
+ sc->sc_mac = mac;
+ _GMX_PORT_WR8(sc, GMX0_SMAC0, mac);
+ for (i = 0; i < 6; i++)
+ _GMX_PORT_WR8(sc, cn30xxgmx_rx_adr_cam_regs[i], addr[i]);
+
+ cn30xxgmx_link_enable(sc, 1);
+
+ return 0;
+}
+
+#define OCTEON_ETH_USE_GMX_CAM
+
+static int
+cn30xxgmx_rgmii_set_filter(struct cn30xxgmx_port_softc *sc)
+{
+ struct ifnet *ifp = &sc->sc_port_ac->ac_if;
+#ifdef OCTEON_ETH_USE_GMX_CAM
+ struct ether_multi *enm;
+ struct ether_multistep step;
+#endif
+ uint64_t ctl = 0;
+ int multi = 0;
+ uint64_t cam_en = 0x01ULL; /* XXX */
+
+ cn30xxgmx_link_enable(sc, 0);
+
+ if (ISSET(ifp->if_flags, IFF_BROADCAST)) {
+ dprintf("accept broadcast\n");
+ SET(ctl, RXN_ADR_CTL_BCST);
+ }
+ if (ISSET(ifp->if_flags, IFF_PROMISC)) {
+ dprintf("promiscas(reject cam)\n");
+ CLR(ctl, RXN_ADR_CTL_CAM_MODE);
+ } else {
+ dprintf("not promiscas(accept cam)\n");
+ SET(ctl, RXN_ADR_CTL_CAM_MODE);
+ }
+
+#ifdef OCTEON_ETH_USE_GMX_CAM
+ /*
+ * Note first entry is self MAC address; other 7 entires are available
+ * for multicast addresses.
+ */
+
+ ETHER_FIRST_MULTI(step, sc->sc_port_ac, enm);
+ while (enm != NULL) {
+ int i;
+
+ dprintf("%d: lo(%02x:%02x:%02x:%02x:%02x:%02x) - "
+ "hi(%02x:%02x:%02x:%02x:%02x:%02x)\n",
+ multi + 1,
+ enm->enm_addrlo[0], enm->enm_addrlo[1],
+ enm->enm_addrlo[2], enm->enm_addrlo[3],
+ enm->enm_addrlo[4], enm->enm_addrlo[5],
+ enm->enm_addrhi[0], enm->enm_addrhi[1],
+ enm->enm_addrhi[2], enm->enm_addrhi[3],
+ enm->enm_addrhi[4], enm->enm_addrhi[5]);
+ if (bcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
+ dprintf("all multicast\n");
+ SET(ifp->if_flags, IFF_ALLMULTI);
+ goto setmulti;
+ }
+ multi++;
+
+ /* XXX */
+ if (multi >= 8) {
+ SET(ifp->if_flags, IFF_ALLMULTI);
+ goto setmulti;
+ }
+
+ SET(cam_en, 1ULL << multi); /* XXX */
+
+ for (i = 0; i < 6; i++) {
+ uint64_t tmp;
+
+ /* XXX */
+ tmp = _GMX_PORT_RD8(sc, cn30xxgmx_rx_adr_cam_regs[i]);
+ CLR(tmp, 0xffULL << (8 * multi));
+ SET(tmp, (uint64_t)enm->enm_addrlo[i] << (8 * multi));
+ _GMX_PORT_WR8(sc, cn30xxgmx_rx_adr_cam_regs[i], tmp);
+
+ }
+ for (i = 0; i < 6; i++)
+ dprintf("cam%d = %016llx\n", i,
+ _GMX_PORT_RD8(sc, cn30xxgmx_rx_adr_cam_regs[i]));
+ ETHER_NEXT_MULTI(step, enm);
+ }
+ CLR(ifp->if_flags, IFF_ALLMULTI);
+
+ OCTEON_ETH_KASSERT(enm == NULL);
+#else
+ /*
+ * XXX
+ * Never use DMAC filter for multicast addresses, but register only
+ * single entry for self address. FreeBSD code do so.
+ */
+ SET(ifp->if_flags, IFF_ALLMULTI);
+ goto setmulti;
+#endif
+
+setmulti:
+ if (ISSET(ifp->if_flags, IFF_ALLMULTI) ||
+ ISSET(ifp->if_flags, IFF_PROMISC)) {
+ /* XXX */
+ dprintf("accept all multicast\n");
+ SET(ctl, RXN_ADR_CTL_MCST_ACCEPT);
+ } else if (multi) {
+ /* XXX */
+ dprintf("use cam\n");
+ SET(ctl, RXN_ADR_CTL_MCST_AFCAM);
+ } else {
+ /* XXX */
+ dprintf("reject all multicast\n");
+ SET(ctl, RXN_ADR_CTL_MCST_REJECT);
+ }
+
+ /* XXX */
+ if (ISSET(ifp->if_flags, IFF_PROMISC)) {
+ cam_en = 0x00ULL;
+ } else if (ISSET(ifp->if_flags, IFF_ALLMULTI)) {
+ cam_en = 0x01ULL;
+ }
+
+ dprintf("ctl = %llx, cam_en = %llx\n", ctl, cam_en);
+ _GMX_PORT_WR8(sc, GMX0_RX0_ADR_CTL, ctl);
+ _GMX_PORT_WR8(sc, GMX0_RX0_ADR_CAM_EN, cam_en);
+
+ cn30xxgmx_link_enable(sc, 1);
+
+ return 0;
+}
+
+void
+cn30xxgmx_stats(struct cn30xxgmx_port_softc *sc)
+{
+ struct ifnet *ifp = &sc->sc_port_ac->ac_if;
+ uint64_t tmp;
+
+ ifp->if_ipackets +=
+ (uint32_t)_GMX_PORT_RD8(sc, GMX0_RX0_STATS_PKTS);
+ ifp->if_ierrors +=
+ (uint32_t)_GMX_PORT_RD8(sc, GMX0_RX0_STATS_PKTS_BAD);
+ ifp->if_iqdrops +=
+ (uint32_t)_GMX_PORT_RD8(sc, GMX0_RX0_STATS_PKTS_DRP);
+ ifp->if_opackets +=
+ (uint32_t)_GMX_PORT_RD8(sc, GMX0_TX0_STAT3);
+ tmp = _GMX_PORT_RD8(sc, GMX0_TX0_STAT0);
+ ifp->if_oerrors +=
+ (uint32_t)tmp + ((uint32_t)(tmp >> 32) * 16);
+ ifp->if_collisions += ((uint32_t)tmp) * 16;
+ tmp = _GMX_PORT_RD8(sc, GMX0_TX0_STAT1);
+ ifp->if_collisions +=
+ ((uint32_t)tmp * 2) + (uint32_t)(tmp >> 32);
+ tmp = _GMX_PORT_RD8(sc, GMX0_TX0_STAT9);
+ ifp->if_oerrors += (uint32_t)(tmp >> 32);
+}
+
+/* ---- DMAC filter */
+
+#ifdef notyet
+/*
+ * DMAC filter configuration
+ * accept all
+ * reject 0 addrs (virtually accept all?)
+ * reject N addrs
+ * accept N addrs
+ * accept 0 addrs (virtually reject all?)
+ * reject all
+ */
+
+/* XXX local namespace */
+#define _POLICY CN30XXGMX_FILTER_POLICY
+#define _POLICY_ACCEPT_ALL CN30XXGMX_FILTER_POLICY_ACCEPT_ALL
+#define _POLICY_ACCEPT CN30XXGMX_FILTER_POLICY_ACCEPT
+#define _POLICY_REJECT CN30XXGMX_FILTER_POLICY_REJECT
+#define _POLICY_REJECT_ALL CN30XXGMX_FILTER_POLICY_REJECT_ALL
+
+static int cn30xxgmx_setfilt_addrs(struct cn30xxgmx_port_softc *,
+ size_t, uint8_t **);
+
+int
+cn30xxgmx_setfilt(struct cn30xxgmx_port_softc *sc, enum _POLICY policy,
+ size_t naddrs, uint8_t **addrs)
+{
+ uint64_t rx_adr_ctl;
+
+ KASSERT(policy >= _POLICY_ACCEPT_ALL);
+ KASSERT(policy <= _POLICY_REJECT_ALL);
+
+ rx_adr_ctl = _GMX_PORT_RD8(sc, GMX0_RX0_ADR_CTL);
+ CLR(rx_adr_ctl, RXN_ADR_CTL_CAM_MODE | RXN_ADR_CTL_MCST);
+
+ switch (policy) {
+ case _POLICY_ACCEPT_ALL:
+ case _POLICY_REJECT_ALL:
+ KASSERT(naddrs == 0);
+ KASSERT(addrs == NULL);
+
+ SET(rx_adr_ctl, (policy == _POLICY_ACCEPT_ALL) ?
+ RXN_ADR_CTL_MCST_ACCEPT : RXN_ADR_CTL_MCST_REJECT);
+ break;
+ case _POLICY_ACCEPT:
+ case _POLICY_REJECT:
+ if (naddrs > CN30XXGMX_FILTER_NADDRS_MAX)
+ return E2BIG;
+ SET(rx_adr_ctl, (policy == _POLICY_ACCEPT) ?
+ RXN_ADR_CTL_CAM_MODE : 0);
+ SET(rx_adr_ctl, RXN_ADR_CTL_MCST_AFCAM);
+ /* set GMX0_RXN_ADR_CAM_EN, GMX0_RXN_ADR_CAM[0-5] */
+ cn30xxgmx_setfilt_addrs(sc, naddrs, addrs);
+ break;
+ }
+
+ /* set GMX0_RXN_ADR_CTL[MCST] */
+ _GMX_PORT_WR8(sc, GMX0_RX0_ADR_CTL, rx_adr_ctl);
+
+ return 0;
+}
+
+static int
+cn30xxgmx_setfilt_addrs(struct cn30xxgmx_port_softc *sc, size_t naddrs,
+ uint8_t **addrs)
+{
+ uint64_t rx_adr_cam_en;
+ uint64_t rx_adr_cam_addrs[CN30XXGMX_FILTER_NADDRS_MAX];
+ int i, j;
+
+ KASSERT(naddrs <= CN30XXGMX_FILTER_NADDRS_MAX);
+
+ rx_adr_cam_en = 0;
+ (void)memset(rx_adr_cam_addrs, 0, sizeof(rx_adr_cam_addrs));
+
+ for (i = 0; i < naddrs; i++) {
+ SET(rx_adr_cam_en, 1ULL << i);
+ for (j = 0; j < 6; j++)
+ SET(rx_adr_cam_addrs[j],
+ (uint64_t)addrs[i][j] << (8 * i));
+ }
+
+ /* set GMX0_RXN_ADR_CAM_EN, GMX0_RXN_ADR_CAM[0-5] */
+ _GMX_PORT_WR8(sc, GMX0_RX0_ADR_CAM_EN, rx_adr_cam_en);
+ for (j = 0; j < 6; j++)
+ _GMX_PORT_WR8(sc, cn30xxgmx_rx_adr_cam_regs[j],
+ rx_adr_cam_addrs[j]);
+
+ return 0;
+}
+#endif
+
+/* ---- interrupt */
+
+#ifdef OCTEON_ETH_DEBUG
+void cn30xxgmx_intr_rml_gmx0(void);
+
+int cn30xxgmx_intr_rml_verbose;
+
+/* tx - per unit (gmx0, gmx1, ...) */
+static const struct octeon_evcnt_entry cn30xxgmx_intr_evcnt_tx_entries[] = {
+#define _ENTRY(name, type, parent, descr) \
+ OCTEON_EVCNT_ENTRY(struct cn30xxgmx_softc, name, type, parent, descr)
+ _ENTRY(latecol, MISC, NULL, "tx late collision"),
+ _ENTRY(xsdef, MISC, NULL, "tx excessive deferral"),
+ _ENTRY(xscol, MISC, NULL, "tx excessive collision"),
+ _ENTRY(undflw, MISC, NULL, "tx underflow"),
+ _ENTRY(pkonxa, MISC, NULL, "tx port addr out-of-range")
+#undef _ENTRY
+};
+
+/* rx - per port (gmx0:0, gmx0:1, ...) */
+static const struct octeon_evcnt_entry cn30xxgmx_intr_evcnt_rx_entries[] = {
+#define _ENTRY(name, type, parent, descr) \
+ OCTEON_EVCNT_ENTRY(struct cn30xxgmx_port_softc, name, type, parent, descr)
+ _ENTRY(minerr, MISC, NULL, "rx min error"),
+ _ENTRY(carext, MISC, NULL, "rx carrier error"),
+ _ENTRY(maxerr, MISC, NULL, "rx max error"),
+ _ENTRY(jabber, MISC, NULL, "rx jabber error"),
+ _ENTRY(fcserr, MISC, NULL, "rx fcs error"),
+ _ENTRY(alnerr, MISC, NULL, "rx align error"),
+ _ENTRY(lenerr, MISC, NULL, "rx length error"),
+ _ENTRY(rcverr, MISC, NULL, "rx receive error"),
+ _ENTRY(skperr, MISC, NULL, "rx skip error"),
+ _ENTRY(niberr, MISC, NULL, "rx nibble error"),
+ _ENTRY(ovrerr, MISC, NULL, "rx overflow error"),
+ _ENTRY(pckterr, MISC, NULL, "rx packet error"),
+ _ENTRY(rsverr, MISC, NULL, "rx reserved opcode error"),
+ _ENTRY(falerr, MISC, NULL, "rx false carrier error"),
+ _ENTRY(coldet, MISC, NULL, "rx collision detect"),
+ _ENTRY(ifgerr, MISC, NULL, "rx ifg error")
+#undef _ENTRY
+};
+
+void
+cn30xxgmx_intr_evcnt_attach(struct cn30xxgmx_softc *sc)
+{
+ struct cn30xxgmx_port_softc *port_sc;
+ int i;
+
+ OCTEON_EVCNT_ATTACH_EVCNTS(sc, cn30xxgmx_intr_evcnt_tx_entries,
+ sc->sc_dev.dv_xname);
+ for (i = 0; i < sc->sc_nports; i++) {
+ port_sc = &sc->sc_ports[i];
+ OCTEON_EVCNT_ATTACH_EVCNTS(port_sc, cn30xxgmx_intr_evcnt_rx_entries,
+ sc->sc_dev.dv_xname);
+ }
+}
+
+void
+cn30xxgmx_intr_rml_gmx0(void)
+{
+ struct cn30xxgmx_port_softc *sc = NULL/* XXX gcc */;
+ int i;
+ uint64_t reg = 0/* XXX gcc */;
+
+ cn30xxgmx_intr_evcnt.ev_count++;
+
+ sc = __cn30xxgmx_port_softc[0];
+ if (sc == NULL)
+ return;
+
+ /* GMX0_RXn_INT_REG or GMX0_TXn_INT_REG */
+ reg = cn30xxgmx_get_tx_int_reg(sc);
+ if (cn30xxgmx_intr_rml_verbose && reg != 0)
+ printf("%s: GMX_TX_INT_REG=0x%016" PRIx64 "\n", __func__, reg);
+ if (reg & TX_INT_REG_LATE_COL)
+ OCTEON_EVCNT_INC(sc->sc_port_gmx, latecol);
+ if (reg & TX_INT_REG_XSDEF)
+ OCTEON_EVCNT_INC(sc->sc_port_gmx, xsdef);
+ if (reg & TX_INT_REG_XSCOL)
+ OCTEON_EVCNT_INC(sc->sc_port_gmx, xscol);
+ if (reg & TX_INT_REG_UNDFLW)
+ OCTEON_EVCNT_INC(sc->sc_port_gmx, undflw);
+ if (reg & TX_INT_REG_PKO_NXA)
+ OCTEON_EVCNT_INC(sc->sc_port_gmx, pkonxa);
+
+ for (i = 0; i < GMX_PORT_NUNITS; i++) {
+ sc = __cn30xxgmx_port_softc[i];
+ if (sc == NULL)
+ continue;
+ reg = cn30xxgmx_get_rx_int_reg(sc);
+ if (cn30xxgmx_intr_rml_verbose)
+ printf("%s: GMX_RX_INT_REG=0x%016" PRIx64 "\n", __func__, reg);
+ if (reg & RXN_INT_REG_MINERR)
+ OCTEON_EVCNT_INC(sc, minerr);
+ if (reg & RXN_INT_REG_CAREXT)
+ OCTEON_EVCNT_INC(sc, carext);
+ if (reg & RXN_INT_REG_JABBER)
+ OCTEON_EVCNT_INC(sc, jabber);
+ if (reg & RXN_INT_REG_FCSERR)
+ OCTEON_EVCNT_INC(sc, fcserr);
+ if (reg & RXN_INT_REG_ALNERR)
+ OCTEON_EVCNT_INC(sc, alnerr);
+ if (reg & RXN_INT_REG_LENERR)
+ OCTEON_EVCNT_INC(sc, lenerr);
+ if (reg & RXN_INT_REG_RCVERR)
+ OCTEON_EVCNT_INC(sc, rcverr);
+ if (reg & RXN_INT_REG_SKPERR)
+ OCTEON_EVCNT_INC(sc, skperr);
+ if (reg & RXN_INT_REG_NIBERR)
+ OCTEON_EVCNT_INC(sc, niberr);
+ if (reg & RXN_INT_REG_OVRERR)
+ OCTEON_EVCNT_INC(sc, ovrerr);
+ if (reg & RXN_INT_REG_PCTERR)
+ OCTEON_EVCNT_INC(sc, pckterr);
+ if (reg & RXN_INT_REG_RSVERR)
+ OCTEON_EVCNT_INC(sc, rsverr);
+ if (reg & RXN_INT_REG_FALERR)
+ OCTEON_EVCNT_INC(sc, falerr);
+ if (reg & RXN_INT_REG_COLDET)
+ OCTEON_EVCNT_INC(sc, coldet);
+ if (reg & RXN_INT_REG_IFGERR)
+ OCTEON_EVCNT_INC(sc, ifgerr);
+ }
+}
+
+#ifdef notyet
+void
+cn30xxgmx_intr_rml_gmx1(void)
+{
+ uint64_t reg = 0/* XXX gcc */;
+
+ /* GMX1_RXn_INT_REG or GMX1_TXn_INT_REG */
+}
+#endif
+
+int
+cn30xxgmx_intr_drop(void *arg)
+{
+ octeon_write_csr(CIU_INT0_SUM0, CIU_INTX_SUM0_GMX_DRP);
+ cn30xxgmx_intr_drop_evcnt.ev_count++;
+ return (1);
+}
+
+uint64_t
+cn30xxgmx_get_rx_int_reg(struct cn30xxgmx_port_softc *sc)
+{
+ uint64_t reg;
+ uint64_t rx_int_reg = 0;
+
+ reg = _GMX_PORT_RD8(sc, GMX0_RX0_INT_REG);
+ /* clear */
+ SET(rx_int_reg, 0 |
+ RXN_INT_REG_PHY_DUPX |
+ RXN_INT_REG_PHY_SPD |
+ RXN_INT_REG_PHY_LINK |
+ RXN_INT_REG_IFGERR |
+ RXN_INT_REG_COLDET |
+ RXN_INT_REG_FALERR |
+ RXN_INT_REG_RSVERR |
+ RXN_INT_REG_PCTERR |
+ RXN_INT_REG_OVRERR |
+ RXN_INT_REG_NIBERR |
+ RXN_INT_REG_SKPERR |
+ RXN_INT_REG_RCVERR |
+ RXN_INT_REG_LENERR |
+ RXN_INT_REG_ALNERR |
+ RXN_INT_REG_FCSERR |
+ RXN_INT_REG_JABBER |
+ RXN_INT_REG_MAXERR |
+ RXN_INT_REG_CAREXT |
+ RXN_INT_REG_MINERR);
+ _GMX_PORT_WR8(sc, GMX0_RX0_INT_REG, rx_int_reg);
+
+ return reg;
+}
+
+uint64_t
+cn30xxgmx_get_tx_int_reg(struct cn30xxgmx_port_softc *sc)
+{
+ uint64_t reg;
+ uint64_t tx_int_reg = 0;
+
+ reg = _GMX_PORT_RD8(sc, GMX0_TX_INT_REG);
+ /* clear */
+ SET(tx_int_reg, 0 |
+ TX_INT_REG_LATE_COL |
+ TX_INT_REG_XSDEF |
+ TX_INT_REG_XSCOL |
+ TX_INT_REG_UNDFLW |
+ TX_INT_REG_PKO_NXA);
+ _GMX_PORT_WR8(sc, GMX0_TX_INT_REG, tx_int_reg);
+
+ return reg;
+}
+#endif /* OCTEON_ETH_DEBUG */
+
+/* ---- debug */
+
+#ifdef OCTEON_ETH_DEBUG
+#define _ENTRY(x) { #x, x##_BITS, x }
+
+struct cn30xxgmx_dump_reg_ {
+ const char *name;
+ const char *format;
+ size_t offset;
+};
+
+static const struct cn30xxgmx_dump_reg_ cn30xxgmx_dump_regs_[] = {
+ _ENTRY(GMX0_SMAC0),
+ _ENTRY(GMX0_BIST0),
+ _ENTRY(GMX0_RX_PRTS),
+ _ENTRY(GMX0_RX_BP_DROP0),
+ _ENTRY(GMX0_RX_BP_DROP1),
+ _ENTRY(GMX0_RX_BP_DROP2),
+ _ENTRY(GMX0_RX_BP_ON0),
+ _ENTRY(GMX0_RX_BP_ON1),
+ _ENTRY(GMX0_RX_BP_ON2),
+ _ENTRY(GMX0_RX_BP_OFF0),
+ _ENTRY(GMX0_RX_BP_OFF1),
+ _ENTRY(GMX0_RX_BP_OFF2),
+ _ENTRY(GMX0_TX_PRTS),
+ _ENTRY(GMX0_TX_IFG),
+ _ENTRY(GMX0_TX_JAM),
+ _ENTRY(GMX0_TX_COL_ATTEMPT),
+ _ENTRY(GMX0_TX_PAUSE_PKT_DMAC),
+ _ENTRY(GMX0_TX_PAUSE_PKT_TYPE),
+ _ENTRY(GMX0_TX_OVR_BP),
+ _ENTRY(GMX0_TX_BP),
+ _ENTRY(GMX0_TX_CORRUPT),
+ _ENTRY(GMX0_RX_PRT_INFO),
+ _ENTRY(GMX0_TX_LFSR),
+ _ENTRY(GMX0_TX_INT_REG),
+ _ENTRY(GMX0_TX_INT_EN),
+ _ENTRY(GMX0_NXA_ADR),
+ _ENTRY(GMX0_BAD_REG),
+ _ENTRY(GMX0_STAT_BP),
+ _ENTRY(GMX0_TX_CLK_MSK0),
+ _ENTRY(GMX0_TX_CLK_MSK1),
+ _ENTRY(GMX0_RX_TX_STATUS),
+ _ENTRY(GMX0_INF_MODE),
+};
+
+static const struct cn30xxgmx_dump_reg_ cn30xxgmx_dump_port_regs_[] = {
+ _ENTRY(GMX0_RX0_INT_REG),
+ _ENTRY(GMX0_RX0_INT_EN),
+ _ENTRY(GMX0_PRT0_CFG),
+ _ENTRY(GMX0_RX0_FRM_CTL),
+ _ENTRY(GMX0_RX0_FRM_CHK),
+ _ENTRY(GMX0_RX0_FRM_MIN),
+ _ENTRY(GMX0_RX0_FRM_MAX),
+ _ENTRY(GMX0_RX0_JABBER),
+ _ENTRY(GMX0_RX0_DECISION),
+ _ENTRY(GMX0_RX0_UDD_SKP),
+ _ENTRY(GMX0_RX0_STATS_CTL),
+ _ENTRY(GMX0_RX0_IFG),
+ _ENTRY(GMX0_RX0_RX_INBND),
+ _ENTRY(GMX0_RX0_ADR_CTL),
+ _ENTRY(GMX0_RX0_ADR_CAM_EN),
+ _ENTRY(GMX0_RX0_ADR_CAM0),
+ _ENTRY(GMX0_RX0_ADR_CAM1),
+ _ENTRY(GMX0_RX0_ADR_CAM2),
+ _ENTRY(GMX0_RX0_ADR_CAM3),
+ _ENTRY(GMX0_RX0_ADR_CAM4),
+ _ENTRY(GMX0_RX0_ADR_CAM5),
+ _ENTRY(GMX0_TX0_CLK),
+ _ENTRY(GMX0_TX0_THRESH),
+ _ENTRY(GMX0_TX0_APPEND),
+ _ENTRY(GMX0_TX0_SLOT),
+ _ENTRY(GMX0_TX0_BURST),
+ _ENTRY(GMX0_TX0_PAUSE_PKT_TIME),
+ _ENTRY(GMX0_TX0_MIN_PKT),
+ _ENTRY(GMX0_TX0_PAUSE_PKT_INTERVAL),
+ _ENTRY(GMX0_TX0_SOFT_PAUSE),
+ _ENTRY(GMX0_TX0_PAUSE_TOGO),
+ _ENTRY(GMX0_TX0_PAUSE_ZERO),
+ _ENTRY(GMX0_TX0_STATS_CTL),
+ _ENTRY(GMX0_TX0_CTL),
+};
+
+static const struct cn30xxgmx_dump_reg_ cn30xxgmx_dump_port_stats_[] = {
+ _ENTRY(GMX0_RX0_STATS_PKTS),
+ _ENTRY(GMX0_RX0_STATS_OCTS),
+ _ENTRY(GMX0_RX0_STATS_PKTS_CTL),
+ _ENTRY(GMX0_RX0_STATS_OCTS_CTL),
+ _ENTRY(GMX0_RX0_STATS_PKTS_DMAC),
+ _ENTRY(GMX0_RX0_STATS_OCTS_DMAC),
+ _ENTRY(GMX0_RX0_STATS_PKTS_DRP),
+ _ENTRY(GMX0_RX0_STATS_OCTS_DRP),
+ _ENTRY(GMX0_RX0_STATS_PKTS_BAD),
+ _ENTRY(GMX0_TX0_STAT0),
+ _ENTRY(GMX0_TX0_STAT1),
+ _ENTRY(GMX0_TX0_STAT2),
+ _ENTRY(GMX0_TX0_STAT3),
+ _ENTRY(GMX0_TX0_STAT4),
+ _ENTRY(GMX0_TX0_STAT5),
+ _ENTRY(GMX0_TX0_STAT6),
+ _ENTRY(GMX0_TX0_STAT7),
+ _ENTRY(GMX0_TX0_STAT8),
+ _ENTRY(GMX0_TX0_STAT9),
+};
+
+void cn30xxgmx_dump_common(void);
+void cn30xxgmx_dump_port0(void);
+void cn30xxgmx_dump_port1(void);
+void cn30xxgmx_dump_port2(void);
+void cn30xxgmx_dump_port0_regs(void);
+void cn30xxgmx_dump_port1_regs(void);
+void cn30xxgmx_dump_port2_regs(void);
+void cn30xxgmx_dump_port0_stats(void);
+void cn30xxgmx_dump_port1_stats(void);
+void cn30xxgmx_dump_port2_stats(void);
+void cn30xxgmx_dump_port_regs(int);
+void cn30xxgmx_dump_port_stats(int);
+void cn30xxgmx_dump_common_x(int, const struct cn30xxgmx_dump_reg_ *, size_t);
+void cn30xxgmx_dump_port_x(int, const struct cn30xxgmx_dump_reg_ *, size_t);
+void cn30xxgmx_dump_x(int, const struct cn30xxgmx_dump_reg_ *, size_t, size_t, int);
+void cn30xxgmx_dump_x_index(char *, size_t, int);
+
+void
+cn30xxgmx_dump(void)
+{
+ cn30xxgmx_dump_common();
+ cn30xxgmx_dump_port0();
+ cn30xxgmx_dump_port1();
+ cn30xxgmx_dump_port2();
+}
+
+void
+cn30xxgmx_dump_common(void)
+{
+ cn30xxgmx_dump_common_x(0, cn30xxgmx_dump_regs_,
+ nitems(cn30xxgmx_dump_regs_));
+}
+
+void
+cn30xxgmx_dump_port0(void)
+{
+ cn30xxgmx_dump_port_regs(0);
+ cn30xxgmx_dump_port_stats(0);
+}
+
+void
+cn30xxgmx_dump_port1(void)
+{
+ cn30xxgmx_dump_port_regs(1);
+ cn30xxgmx_dump_port_stats(1);
+}
+
+void
+cn30xxgmx_dump_port2(void)
+{
+ cn30xxgmx_dump_port_regs(2);
+ cn30xxgmx_dump_port_stats(2);
+}
+
+void
+cn30xxgmx_dump_port_regs(int portno)
+{
+ cn30xxgmx_dump_port_x(portno, cn30xxgmx_dump_port_regs_,
+ nitems(cn30xxgmx_dump_port_regs_));
+}
+
+void
+cn30xxgmx_dump_port_stats(int portno)
+{
+ struct cn30xxgmx_port_softc *sc = __cn30xxgmx_port_softc[0];
+ uint64_t rx_stats_ctl;
+ uint64_t tx_stats_ctl;
+
+ rx_stats_ctl = _GMX_RD8(sc, GMX0_BASE_PORT_SIZE * portno + GMX0_RX0_STATS_CTL);
+ _GMX_WR8(sc, GMX0_BASE_PORT_SIZE * portno + GMX0_RX0_STATS_CTL,
+ rx_stats_ctl & ~RXN_STATS_CTL_RD_CLR);
+ tx_stats_ctl = _GMX_RD8(sc, GMX0_BASE_PORT_SIZE * portno + GMX0_TX0_STATS_CTL);
+ _GMX_WR8(sc, GMX0_BASE_PORT_SIZE * portno + GMX0_TX0_STATS_CTL,
+ tx_stats_ctl & ~TXN_STATS_CTL_RD_CLR);
+ cn30xxgmx_dump_port_x(portno, cn30xxgmx_dump_port_stats_,
+ nitems(cn30xxgmx_dump_port_stats_));
+ _GMX_WR8(sc, GMX0_BASE_PORT_SIZE * portno + GMX0_RX0_STATS_CTL, rx_stats_ctl);
+ _GMX_WR8(sc, GMX0_BASE_PORT_SIZE * portno + GMX0_TX0_STATS_CTL, tx_stats_ctl);
+}
+
+void
+cn30xxgmx_dump_common_x(int portno, const struct cn30xxgmx_dump_reg_ *regs, size_t size)
+{
+ cn30xxgmx_dump_x(portno, regs, size, 0, 0);
+}
+
+void
+cn30xxgmx_dump_port_x(int portno, const struct cn30xxgmx_dump_reg_ *regs, size_t size)
+{
+ cn30xxgmx_dump_x(portno, regs, size, GMX0_BASE_PORT_SIZE * portno, 1);
+}
+
+void
+cn30xxgmx_dump_x(int portno, const struct cn30xxgmx_dump_reg_ *regs, size_t size, size_t base, int index)
+{
+ struct cn30xxgmx_port_softc *sc = __cn30xxgmx_port_softc[0];
+ const struct cn30xxgmx_dump_reg_ *reg;
+ uint64_t tmp;
+ char name[64];
+ char buf[512];
+ int i;
+
+ for (i = 0; i < (int)size; i++) {
+ reg = &regs[i];
+ tmp = _GMX_RD8(sc, base + reg->offset);
+
+ if (reg->format == NULL)
+ snprintf(buf, sizeof(buf), "%016" PRIx64, tmp);
+ else
+ bitmask_snprintf(tmp, reg->format, buf, sizeof(buf));
+
+ snprintf(name, sizeof(name), "%s", reg->name);
+ if (index > 0)
+ cn30xxgmx_dump_x_index(name, sizeof(name), portno);
+
+ printf("\t%-24s: %s\n", name, buf);
+ }
+}
+
+void
+cn30xxgmx_dump_x_index(char *buf, size_t len, int index)
+{
+ static const char *patterns[] = { "_TX0_", "_RX0_", "_PRT0_" };
+ int i;
+
+ for (i = 0; i < (int)nitems(patterns); i++) {
+ char *p;
+
+ p = strstr(buf, patterns[i]);
+ if (p == NULL)
+ continue;
+ p = strchr(p, '0');
+ KASSERT(p != NULL);
+ *p = '0' + index;
+ return;
+ }
+}
+
+void
+cn30xxgmx_debug_reset(void)
+{
+ int i;
+
+ for (i = 0; i < 3; i++)
+ cn30xxgmx_link_enable(__cn30xxgmx_port_softc[i], 0);
+ for (i = 0; i < 3; i++)
+ cn30xxgmx_link_enable(__cn30xxgmx_port_softc[i], 1);
+}
+#endif
diff --git a/sys/arch/octeon/dev/cn30xxgmxreg.h b/sys/arch/octeon/dev/cn30xxgmxreg.h
new file mode 100644
index 00000000000..3b2e3acf39f
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxgmxreg.h
@@ -0,0 +1,1245 @@
+/*
+ * THIS FILE IS AUTOMATICALLY GENERATED
+ * DONT EDIT THIS FILE
+ */
+
+/* $OpenBSD: cn30xxgmxreg.h,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Cavium Networks OCTEON CN30XX Hardware Reference Manual
+ * CN30XX-HM-1.0
+ * 13.8 GMX Registers
+ */
+
+#ifndef _CN30XXGMXREG_H_
+#define _CN30XXGMXREG_H_
+
+#define GMX0_RX0_INT_REG 0x000
+#define GMX0_RX0_INT_EN 0x008
+#define GMX0_PRT0_CFG 0x010
+#define GMX0_RX0_FRM_CTL 0x018
+#define GMX0_RX0_FRM_CHK 0x020
+#define GMX0_RX0_FRM_MIN 0x028
+#define GMX0_RX0_FRM_MAX 0x030
+#define GMX0_RX0_JABBER 0x038
+#define GMX0_RX0_DECISION 0x040
+#define GMX0_RX0_UDD_SKP 0x048
+#define GMX0_RX0_STATS_CTL 0x050
+#define GMX0_RX0_IFG 0x058
+#define GMX0_RX0_RX_INBND 0x060
+#define GMX0_RX0_STATS_PKTS 0x080
+#define GMX0_RX0_STATS_OCTS 0x088
+#define GMX0_RX0_STATS_PKTS_CTL 0x090
+#define GMX0_RX0_STATS_OCTS_CTL 0x098
+#define GMX0_RX0_STATS_PKTS_DMAC 0x0a0
+#define GMX0_RX0_STATS_OCTS_DMAC 0x0a8
+#define GMX0_RX0_STATS_PKTS_DRP 0x0b0
+#define GMX0_RX0_STATS_OCTS_DRP 0x0b8
+#define GMX0_RX0_STATS_PKTS_BAD 0x0c0
+#define GMX0_RX0_ADR_CTL 0x100
+#define GMX0_RX0_ADR_CAM_EN 0x108
+#define GMX0_RX0_ADR_CAM0 0x180
+#define GMX0_RX0_ADR_CAM1 0x188
+#define GMX0_RX0_ADR_CAM2 0x190
+#define GMX0_RX0_ADR_CAM3 0x198
+#define GMX0_RX0_ADR_CAM4 0x1a0
+#define GMX0_RX0_ADR_CAM5 0x1a8
+#define GMX0_TX0_CLK 0x208
+#define GMX0_TX0_THRESH 0x210
+#define GMX0_TX0_APPEND 0x218
+#define GMX0_TX0_SLOT 0x220
+#define GMX0_TX0_BURST 0x228
+#define GMX0_SMAC0 0x230
+#define GMX0_TX0_PAUSE_PKT_TIME 0x238
+#define GMX0_TX0_MIN_PKT 0x240
+#define GMX0_TX0_PAUSE_PKT_INTERVAL 0x248
+#define GMX0_TX0_SOFT_PAUSE 0x250
+#define GMX0_TX0_PAUSE_TOGO 0x258
+#define GMX0_TX0_PAUSE_ZERO 0x260
+#define GMX0_TX0_STATS_CTL 0x268
+#define GMX0_TX0_CTL 0x270
+#define GMX0_TX0_STAT0 0x280
+#define GMX0_TX0_STAT1 0x288
+#define GMX0_TX0_STAT2 0x290
+#define GMX0_TX0_STAT3 0x298
+#define GMX0_TX0_STAT4 0x2a0
+#define GMX0_TX0_STAT5 0x2a8
+#define GMX0_TX0_STAT6 0x2b0
+#define GMX0_TX0_STAT7 0x2b8
+#define GMX0_TX0_STAT8 0x2c0
+#define GMX0_TX0_STAT9 0x2c8
+#define GMX0_BIST0 0x400
+#define GMX0_RX_PRTS 0x410
+#define GMX0_RX_BP_DROP0 0x420
+#define GMX0_RX_BP_DROP1 0x428
+#define GMX0_RX_BP_DROP2 0x430
+#define GMX0_RX_BP_ON0 0x440
+#define GMX0_RX_BP_ON1 0x448
+#define GMX0_RX_BP_ON2 0x450
+#define GMX0_RX_BP_OFF0 0x460
+#define GMX0_RX_BP_OFF1 0x468
+#define GMX0_RX_BP_OFF2 0x470
+#define GMX0_TX_PRTS 0x480
+#define GMX0_TX_IFG 0x488
+#define GMX0_TX_JAM 0x490
+#define GMX0_TX_COL_ATTEMPT 0x498
+#define GMX0_TX_PAUSE_PKT_DMAC 0x4a0
+#define GMX0_TX_PAUSE_PKT_TYPE 0x4a8
+#define GMX0_TX_OVR_BP 0x4c8
+#define GMX0_TX_BP 0x4d0
+#define GMX0_TX_CORRUPT 0x4d8
+#define GMX0_RX_PRT_INFO 0x4e8
+#define GMX0_TX_LFSR 0x4f8
+#define GMX0_TX_INT_REG 0x500
+#define GMX0_TX_INT_EN 0x508
+#define GMX0_NXA_ADR 0x510
+#define GMX0_BAD_REG 0x518
+#define GMX0_STAT_BP 0x520
+#define GMX0_TX_CLK_MSK0 0x780
+#define GMX0_TX_CLK_MSK1 0x788
+#define GMX0_RX_TX_STATUS 0x7e8
+#define GMX0_INF_MODE 0x7f8
+
+/* -------------------------------------------------------------------------- */
+
+/* GMX Interrupt Registers */
+
+#define RXN_INT_REG_XXX_63_19 0xfffffffffff80000ULL
+#define RXN_INT_REG_PHY_DUPX 0x0000000000040000ULL
+#define RXN_INT_REG_PHY_SPD 0x0000000000020000ULL
+#define RXN_INT_REG_PHY_LINK 0x0000000000010000ULL
+#define RXN_INT_REG_IFGERR 0x0000000000008000ULL
+#define RXN_INT_REG_COLDET 0x0000000000004000ULL
+#define RXN_INT_REG_FALERR 0x0000000000002000ULL
+#define RXN_INT_REG_RSVERR 0x0000000000001000ULL
+#define RXN_INT_REG_PCTERR 0x0000000000000800ULL
+#define RXN_INT_REG_OVRERR 0x0000000000000400ULL
+#define RXN_INT_REG_NIBERR 0x0000000000000200ULL
+#define RXN_INT_REG_SKPERR 0x0000000000000100ULL
+#define RXN_INT_REG_RCVERR 0x0000000000000080ULL
+#define RXN_INT_REG_LENERR 0x0000000000000040ULL
+#define RXN_INT_REG_ALNERR 0x0000000000000020ULL
+#define RXN_INT_REG_FCSERR 0x0000000000000010ULL
+#define RXN_INT_REG_JABBER 0x0000000000000008ULL
+#define RXN_INT_REG_MAXERR 0x0000000000000004ULL
+#define RXN_INT_REG_CAREXT 0x0000000000000002ULL
+#define RXN_INT_REG_MINERR 0x0000000000000001ULL
+
+/* GMX Interrupt-Enable Registers */
+
+#define RXN_INT_EN_XXX_63_19 0xfffffffffff80000ULL
+#define RXN_INT_EN_PHY_DUPX 0x0000000000040000ULL
+#define RXN_INT_EN_PHY_SPD 0x0000000000020000ULL
+#define RXN_INT_EN_PHY_LINK 0x0000000000010000ULL
+#define RXN_INT_EN_IFGERR 0x0000000000008000ULL
+#define RXN_INT_EN_COLDET 0x0000000000004000ULL
+#define RXN_INT_EN_FALERR 0x0000000000002000ULL
+#define RXN_INT_EN_RSVERR 0x0000000000001000ULL
+#define RXN_INT_EN_PCTERR 0x0000000000000800ULL
+#define RXN_INT_EN_OVRERR 0x0000000000000400ULL
+#define RXN_INT_EN_NIBERR 0x0000000000000200ULL
+#define RXN_INT_EN_SKPERR 0x0000000000000100ULL
+#define RXN_INT_EN_RCVERR 0x0000000000000080ULL
+#define RXN_INT_EN_LENERR 0x0000000000000040ULL
+#define RXN_INT_EN_ALNERR 0x0000000000000020ULL
+#define RXN_INT_EN_FCSERR 0x0000000000000010ULL
+#define RXN_INT_EN_JABBER 0x0000000000000008ULL
+#define RXN_INT_EN_MAXERR 0x0000000000000004ULL
+#define RXN_INT_EN_CAREXT 0x0000000000000002ULL
+#define RXN_INT_EN_MINERR 0x0000000000000001ULL
+
+/* GMX Port Configuration Registers */
+
+#define PRTN_CFG_XXX_63_4 0xfffffffffffffff0ULL
+#define PRTN_CFG_SLOTTIME 0x0000000000000008ULL
+#define PRTN_CFG_DUPLEX 0x0000000000000004ULL
+#define PRTN_CFG_SPEED 0x0000000000000002ULL
+#define PRTN_CFG_EN 0x0000000000000001ULL
+
+/* Frame Control Registers */
+
+#define RXN_FRM_CTL_XXX_63_11 0xfffffffffffff800ULL
+#define RXN_FRM_CTL_NULL_DIS 0x0000000000000400ULL
+#define RXN_FRM_CTL_PRE_ALIGN 0x0000000000000200ULL
+#define RXN_FRM_CTL_PAD_LEN 0x0000000000000100ULL
+#define RXN_FRM_CTL_VLAN_LEN 0x0000000000000080ULL
+#define RXN_FRM_CTL_PRE_FREE 0x0000000000000040ULL
+#define RXN_FRM_CTL_CTL_SMAC 0x0000000000000020ULL
+#define RXN_FRM_CTL_CTL_MCST 0x0000000000000010ULL
+#define RXN_FRM_CTL_CTL_BCK 0x0000000000000008ULL
+#define RXN_FRM_CTL_CTL_DRP 0x0000000000000004ULL
+#define RXN_FRM_CTL_PRE_STRP 0x0000000000000002ULL
+#define RXN_FRM_CTL_PRE_CHK 0x0000000000000001ULL
+
+/* Frame Check Registers */
+
+#define RXN_FRM_CKK_XXX_63_10 0xfffffffffffffc00ULL
+#define RXN_FRM_CHK_NIBERR 0x0000000000000200ULL
+#define RXN_FRM_CHK_SKPERR 0x0000000000000100ULL
+#define RXN_FRM_CHK_RCVERR 0x0000000000000080ULL
+#define RXN_FRM_CHK_LENERR 0x0000000000000040ULL
+#define RXN_FRM_CHK_ALNERR 0x0000000000000020ULL
+#define RXN_FRM_CHK_FCSERR 0x0000000000000010ULL
+#define RXN_FRM_CHK_JABBER 0x0000000000000008ULL
+#define RXN_FRM_CHK_MAXERR 0x0000000000000004ULL
+#define RXN_FRM_CHK_CAREXT 0x0000000000000002ULL
+#define RXN_FRM_CHK_MINERR 0x0000000000000001ULL
+
+/* Frame Minimum-Length Registers */
+
+#define RXN_RRM_MIN_XXX_63_16 0xffffffffffff0000ULL
+#define RXN_RRM_MIN_LEN 0x000000000000ffffULL
+
+/* Frame Maximun-Length Registers */
+
+#define RXN_RRM_MAX_XXX_63_16 0xffffffffffff0000ULL
+#define RXN_RRM_MAX_LEN 0x000000000000ffffULL
+
+/* GMX Maximun Packet-Size Registers */
+
+#define RXN_JABBER_XXX_63_16 0xffffffffffff0000ULL
+#define RXN_JABBER_CNT 0x000000000000ffffULL
+
+/* GMX Packet Decision Registers */
+
+#define RXN_DECISION_XXX_63_5 0xffffffffffffffe0ULL
+#define RXN_DECISION_CNT 0x000000000000001fULL
+
+/* GMX User-Defined Data Skip Registers */
+
+#define RXN_UDD_SKP_XXX_63_9 0xfffffffffffffe00ULL
+#define RXN_UDD_SKP_FCSSEL 0x0000000000000100ULL
+#define RXN_UDD_SKP_XXX_7 0x0000000000000080ULL
+#define RXN_UDD_SKP_LEN 0x000000000000007fULL
+
+/* GMX RX Statistics Control Registers */
+
+#define RXN_STATS_CTL_XXX_63_1 0xfffffffffffffffeULL
+#define RXN_STATS_CTL_RD_CLR 0x0000000000000001ULL
+
+/* GMX Minimun Interface-Gap Cycles Registers */
+
+#define RXN_IFG_XXX_63_4 0xfffffffffffffff0ULL
+#define RXN_IFG_IFG 0x000000000000000fULL
+
+/* InBand Link Status Registers */
+
+#define RXN_RX_INBND_XXX_63_4 0xfffffffffffffff0ULL
+#define RXN_RX_INBND_DUPLEX 0x0000000000000008ULL
+#define RXN_RX_INBND_DUPLEX_SHIFT 3
+#define RXN_RX_INBND_DUPLEX_HALF (0ULL << RXN_RX_INBND_DUPLEX_SHIFT)
+#define RXN_RX_INBND_DUPLEX_FULL (1ULL << RXN_RX_INBND_DUPLEX_SHIFT)
+#define RXN_RX_INBND_SPEED 0x0000000000000006ULL
+#define RXN_RX_INBND_SPEED_SHIFT 1
+#define RXN_RX_INBND_SPEED_2_5 (0ULL << RXN_RX_INBND_SPEED_SHIFT)
+#define RXN_RX_INBND_SPEED_25 (1ULL << RXN_RX_INBND_SPEED_SHIFT)
+#define RXN_RX_INBND_SPEED_125 (2ULL << RXN_RX_INBND_SPEED_SHIFT)
+#define RXN_RX_INBND_SPEED_XXX_3 (3ULL << RXN_RX_INBND_SPEED_SHIFT)
+#define RXN_RX_INBND_STATUS 0x0000000000000001ULL
+
+/* GMX RX Good Packets Registers */
+
+#define RXN_STATS_PKTS_XXX_63_32 0xffffffff00000000ULL
+#define RXN_STATS_PKTS_CNT 0x00000000ffffffffULL
+
+/* GMX RX Good Packets Octet Registers */
+
+#define RXN_STATS_OCTS_XXX_63_48 0xffff000000000000ULL
+#define RXN_STATS_OCTS_CNT 0x0000ffffffffffffULL
+
+/* GMX RX Pause Packets Registers */
+
+#define RXN_STATS_PKTS_CTL_XXX_63_32 0xffffffff00000000ULL
+#define RXN_STATS_PKTS_CTL_CNT 0x00000000ffffffffULL
+
+/* GMX RX Pause Packets Octet Registers */
+
+#define RXN_STATS_OCTS_CTL_XXX_63_48 0xffff000000000000ULL
+#define RXN_STATS_OCTS_CTL_CNT 0x0000ffffffffffffULL
+
+/* GMX RX DMAC Packets Registers */
+
+#define RXN_STATS_PKTS_DMAC_XXX_63_32 0xffffffff00000000ULL
+#define RXN_STATS_PKTS_DMAC_CNT 0x00000000ffffffffULL
+
+/* GMX RX DMAC Packets Octet Registers */
+
+#define RXN_STATS_OCTS_DMAC_XXX_63_48 0xffff000000000000ULL
+#define RXN_STATS_OCTS_DMAC_CNT 0x0000ffffffffffffULL
+
+/* GMX RX Overflow Packets Registers */
+
+#define RXN_STATS_PKTS_DRP_XXX_63_48 0xffffffff00000000ULL
+#define RXN_STATS_PKTS_DRP_CNT 0x00000000ffffffffULL
+
+/* GMX RX Overflow Packets Octet Registers */
+
+#define RXN_STATS_OCTS_DRP_XXX_63_48 0xffff000000000000ULL
+#define RXN_STATS_OCTS_DRP_CNT 0x0000ffffffffffffULL
+
+/* GMX RX Bad Packets Registers */
+
+#define RXN_STATS_PKTS_BAD_XXX_63_48 0xffffffff00000000ULL
+#define RXN_STATS_PKTS_BAD_CNT 0x00000000ffffffffULL
+
+/* Address-Filtering Control Registers */
+
+#define RXN_ADR_CTL_XXX_63_4 0xfffffffffffffff0ULL
+#define RXN_ADR_CTL_CAM_MODE 0x0000000000000008ULL
+#define RXN_ADR_CTL_CAM_MODE_SHIFT 3
+#define RXN_ADR_CTL_CAM_MODE_REJECT (0ULL << RXN_ADR_CTL_CAM_MODE_SHIFT)
+#define RXN_ADR_CTL_CAM_MODE_ACCEPT (1ULL << RXN_ADR_CTL_CAM_MODE_SHIFT)
+#define RXN_ADR_CTL_MCST 0x0000000000000006ULL
+#define RXN_ADR_CTL_MCST_SHIFT 1
+#define RXN_ADR_CTL_MCST_AFCAM (0ULL << RXN_ADR_CTL_MCST_SHIFT)
+#define RXN_ADR_CTL_MCST_REJECT (1ULL << RXN_ADR_CTL_MCST_SHIFT)
+#define RXN_ADR_CTL_MCST_ACCEPT (2ULL << RXN_ADR_CTL_MCST_SHIFT)
+#define RXN_ADR_CTL_MCST_XXX_3 (3ULL << RXN_ADR_CTL_MCST_SHIFT)
+#define RXN_ADR_CTL_BCST 0x0000000000000001ULL
+
+/* Address-Filtering Control Enable Registers */
+
+#define RXN_ADR_CAM_EN_XXX_63_8 0xffffffffffffff00ULL
+#define RXN_ADR_CAM_EN_EN 0x00000000000000ffULL
+
+/* Address-Filtering CAM Control Registers */
+#define RXN_ADR_CAMN_ADR 0xffffffffffffffffULL
+
+/* GMX TX Clock Generation Registers */
+
+#define TXN_CLK_XXX_63_6 0xffffffffffffffc0ULL
+#define TXN_CLK_CLK_CNT 0x000000000000003fULL
+
+/* TX Threshold Registers */
+
+#define TXN_THRESH_XXX_63_6 0xffffffffffffffc0ULL
+#define TXN_THRESH_CNT 0x000000000000003fULL
+
+/* TX Append Control Registers */
+
+#define TXN_APPEND_XXX_63_4 0xfffffffffffffff0ULL
+#define TXN_APPEND_FORCE_FCS 0x0000000000000008ULL
+#define TXN_APPEND_FCS 0x0000000000000004ULL
+#define TXN_APPEND_PAD 0x0000000000000002ULL
+#define TXN_APPEND_PREAMBLE 0x0000000000000001ULL
+
+/* TX Slottime Counter Registers */
+
+#define TXN_SLOT_XXX_63_10 0xfffffffffffffc00ULL
+#define TXN_SLOT_SLOT 0x00000000000003ffULL
+
+/* TX Burst-Counter Registers */
+
+#define TXN_BURST_XXX_63_16 0xffffffffffff0000ULL
+#define TXN_BURST_BURST 0x000000000000ffffULL
+
+/* RGMII SMAC Registers */
+
+#define SMACN_XXX_63_48 0xffff000000000000ULL
+#define SMACN_SMAC 0x0000ffffffffffffULL
+
+/* TX Pause Packet Pause-Time Registers */
+
+#define TXN_PAUSE_PKT_TIME_XXX_63_16 0xffffffffffff0000ULL
+#define TXN_PAUSE_PKT_TIME_TIME 0x000000000000ffffULL
+
+/* RGMII TX Minimum-Size-Packet Registers */
+
+#define TXN_MIN_PKT_XXX_63_8 0xffffffffffffff00ULL
+#define TXN_MIN_PKT_MIN_SIZE 0x00000000000000ffULL
+
+/* TX Pause-Packet Transmission-Interval Registers */
+
+#define TXN_PAUSE_PKT_INTERVAL_XXX_63_16 0xffffffffffff0000ULL
+#define TXN_PAUSE_PKT_INTERVAL_INTERVAL 0x000000000000ffffULL
+
+/* TX Software-Pause Registers */
+
+#define TXN_SOFT_PAUSE_XXX_63_16 0xffffffffffff0000ULL
+#define TXN_SOFT_PAUSE_TIME 0x000000000000ffffULL
+
+/* TX Time-to-Backpressure Registers */
+
+#define TXN_PAUSE_TOGO_XXX_63_16 0xffffffffffff0000ULL
+#define TXN_PAUSE_TOGO_TIME 0x000000000000ffffULL
+
+/* TX Pause-Zero-Enable Registers */
+
+#define TXN_PAUSE_ZERO_XXX_63_1 0xfffffffffffffffeULL
+#define TXN_PAUSE_ZERO_SEND 0x0000000000000001ULL
+
+/* GMX TX Statistics Control Registers */
+
+#define TXN_STATS_CTL_XXX_63_1 0xfffffffffffffffeULL
+#define TXN_STATS_CTL_RD_CLR 0x0000000000000001ULL
+
+/* GMX TX Transmit Control Registers */
+
+#define TXN_CTL_XXX_63_2 0xfffffffffffffffcULL
+#define TXN_CTL_XSDEF_EN 0x0000000000000002ULL
+#define TXN_CTL_XSCOL_EN 0x0000000000000001ULL
+
+/* Transmit Statistics Registers 0 */
+
+#define TXN_STAT0_XSDEF 0xffffffff00000000ULL
+#define TXN_STAT0_XSCOL 0x00000000ffffffffULL
+
+/* Transmit Statistics Registers 1 */
+
+#define TXN_STAT1_SCOL 0xffffffff00000000ULL
+#define TXN_STAT1_MSCOL 0x00000000ffffffffULL
+
+/* Transmit Statistics Registers 2 */
+
+#define TXN_STAT2_XXX_63_48 0xffff000000000000ULL
+#define TXN_STAT2_OCTS 0x0000ffffffffffffULL
+
+/* Transmit Statistics Registers 3 */
+
+#define TXN_STAT3_XXX_63_48 0xffffffff00000000ULL
+#define TXN_STAT3_PKTS 0x00000000ffffffffULL
+
+/* Transmit Statistics Registers 4 */
+
+#define TXN_STAT4_HIST1 0xffffffff00000000ULL
+#define TXN_STAT4_HIST0 0x00000000ffffffffULL
+
+/* Transmit Statistics Registers 5 */
+
+#define TXN_STAT5_HIST3 0xffffffff00000000ULL
+#define TXN_STAT5_HIST2 0x00000000ffffffffULL
+
+/* Transmit Statistics Registers 6 */
+
+#define TXN_STAT6_HIST5 0xffffffff00000000ULL
+#define TXN_STAT6_HIST4 0x00000000ffffffffULL
+
+/* Transmit Statistics Registers 7 */
+
+#define TXN_STAT7_HIST7 0xffffffff00000000ULL
+#define TXN_STAT7_HIST6 0x00000000ffffffffULL
+
+/* Transmit Statistics Registers 8 */
+
+#define TXN_STAT8_MCST 0xffffffff00000000ULL
+#define TXN_STAT8_BCST 0x00000000ffffffffULL
+
+/* Transmit Statistics Register 9 */
+
+#define TXN_STAT9_UNDFLW 0xffffffff00000000ULL
+#define TXN_STAT9_CTL 0x00000000ffffffffULL
+
+/* BMX BIST Results Register */
+
+#define BIST_XXX_63_10 0xfffffffffffffc00ULL
+#define BIST_STATUS 0x00000000000003ffULL
+
+/* RX Ports Register */
+
+#define RX_PRTS_XXX_63_3 0xfffffffffffffff8ULL
+#define RX_PRTS_PRTS 0x0000000000000007ULL
+
+/* RX FIFO Packet-Drop Registers */
+
+#define RX_BP_DROPN_XXX_63_6 0xffffffffffffffc0ULL
+#define RX_BP_DROPN_MARK 0x000000000000003fULL
+
+/* RX Backpressure On Registers */
+
+#define RX_BP_ONN_XXX_63_9 0xfffffffffffffe00ULL
+#define RX_BP_ONN_MARK 0x00000000000001ffULL
+
+/* RX Backpressure Off Registers */
+
+#define RX_BP_OFFN_XXX_63_6 0xffffffffffffffc0ULL
+#define RX_BP_OFFN_MARK 0x000000000000003fULL
+
+/* TX Ports Register */
+
+#define TX_PRTS_XXX_63_5 0xffffffffffffffe0ULL
+#define TX_PRTS_PRTS 0x000000000000001fULL
+
+/* TX Interframe Gap Register */
+
+#define TX_IFG_XXX_63_8 0xffffffffffffff00ULL
+#define TX_IFG_IFG2 0x00000000000000f0ULL
+#define TX_IFG_IFG1 0x000000000000000fULL
+
+/* TX Jam Pattern Register */
+
+#define TX_JAM_XXX_63_8 0xffffffffffffff00ULL
+#define TX_JAM_JAM 0x00000000000000ffULL
+
+/* TX Collision Attempts Before Dropping Frame Register */
+
+#define TX_COL_ATTEMPT_XXX_63_5 0xffffffffffffffe0ULL
+#define TX_COL_ATTEMPT_LIMIT 0x000000000000001fULL
+
+/* TX Pause-Packet DMAC-Field Register */
+
+#define TX_PAUSE_PKT_DMAC_XXX_63_48 0xffff000000000000ULL
+#define TX_PAUSE_PKT_DMAC_DMAC 0x0000ffffffffffffULL
+
+/* TX Pause Packet Type Field Register */
+
+#define TX_PAUSE_PKT_TYPE_XXX_63_16 0xffffffffffff0000ULL
+#define TX_PAUSE_PKT_TYPE_TYPE 0x000000000000ffffULL
+
+/* TX Override Backpressure Register */
+
+#define TX_OVR_BP_XXX_63_12 0xfffffffffffff000ULL
+#define TX_OVR_BP_XXX_11 0x0000000000000800ULL
+#define TX_OVR_BP_EN 0x0000000000000700ULL
+#define TX_OVR_BP_EN_SHIFT 8
+#define TX_OVR_BP_XXX_7 0x0000000000000080ULL
+#define TX_OVR_BP_BP 0x0000000000000070ULL
+#define TX_OVR_BP_BP_SHIFT 4
+#define TX_OVR_BP_XXX_3 0x0000000000000008ULL
+#define TX_OVR_BP_IGN_FULL 0x0000000000000007ULL
+#define TX_OVR_BP_IGN_FULL_SHIFT 0
+
+/* TX Override Backpressure Register */
+
+#define TX_OVR_BP_XXX_63_12 0xfffffffffffff000ULL
+#define TX_OVR_BP_XXX_11 0x0000000000000800ULL
+#define TX_OVR_BP_EN 0x0000000000000700ULL
+#define TX_OVR_BP_XXX_7 0x0000000000000080ULL
+#define TX_OVR_BP_BP 0x0000000000000070ULL
+#define TX_OVR_BP_XXX_3 0x0000000000000008ULL
+#define TX_OVR_BP_IGN_FULL 0x0000000000000007ULL
+
+/* TX Backpressure Status Register */
+
+#define TX_BP_SR_XXX_63_3 0xfffffffffffffff8ULL
+#define TX_BP_SR_BP 0x0000000000000007ULL
+
+/* TX Corrupt Packets Register */
+
+#define TX_CORRUPT_XXX_63_3 0xfffffffffffffff8ULL
+#define TX_CORRUPT_CORRUPT 0x0000000000000007ULL
+
+/* RX Port State Information Register */
+
+#define RX_PRT_INFO_XXX_63_19 0xfffffffffff80000ULL
+#define RX_PRT_INFO_DROP 0x0000000000070000ULL
+#define RX_PRT_INFO_XXX_15_3 0x000000000000fff8ULL
+#define RX_PRT_INFO_COMMIT 0x0000000000000007ULL
+
+/* TX LFSR Register */
+
+#define TX_LFSR_XXX_63_16 0xffffffffffff0000ULL
+#define TX_LFSR_LFSR 0x000000000000ffffULL
+
+/* TX Interrupt Register */
+
+#define TX_INT_REG_XXX_63_20 0xfffffffffff00000ULL
+#define TX_INT_REG_XXX_19 0x0000000000080000ULL
+#define TX_INT_REG_LATE_COL 0x0000000000070000ULL
+#define TX_INT_REG_XXX_15 0x0000000000008000ULL
+#define TX_INT_REG_XSDEF 0x0000000000007000ULL
+#define TX_INT_REG_XXX_11 0x0000000000000800ULL
+#define TX_INT_REG_XSCOL 0x0000000000000700ULL
+#define TX_INT_REG_XXX_7_5 0x00000000000000e0ULL
+#define TX_INT_REG_UNDFLW 0x000000000000001cULL
+#define TX_INT_REG_XXX_1 0x0000000000000002ULL
+#define TX_INT_REG_PKO_NXA 0x0000000000000001ULL
+
+/* TX Interrupt Register */
+
+#define TX_INT_EN_XXX_63_20 0xfffffffffff00000ULL
+#define TX_INT_EN_XXX_19 0x0000000000080000ULL
+#define TX_INT_EN_LATE_COL 0x0000000000070000ULL
+#define TX_INT_EN_XXX_15 0x0000000000008000ULL
+#define TX_INT_EN_XSDEF 0x0000000000007000ULL
+#define TX_INT_EN_XXX_11 0x0000000000000800ULL
+#define TX_INT_EN_XSCOL 0x0000000000000700ULL
+#define TX_INT_EN_XXX_7_5 0x00000000000000e0ULL
+#define TX_INT_EN_UNDFLW 0x000000000000001cULL
+#define TX_INT_EN_XXX_1 0x0000000000000002ULL
+#define TX_INT_EN_PKO_NXA 0x0000000000000001ULL
+
+/* Address-out-of-Range Error Register */
+
+#define NXA_ADR_XXX_63_6 0xffffffffffffffc0ULL
+#define NXA_ADR_PRT 0x000000000000003fULL
+
+/* GMX Miscellaneous Error Register */
+
+#define BAD_REG_XXX_63_31 0xffffffff80000000ULL
+#define BAD_REG_INB_NXA 0x0000000078000000ULL
+#define BAD_REG_STATOVR 0x0000000004000000ULL
+#define BAD_REG_XXX_25 0x0000000002000000ULL
+#define BAD_REG_LOSTSTAT 0x0000000001c00000ULL
+#define BAD_REG_XXX_21_18 0x00000000003c0000ULL
+#define BAD_REG_XXX_17_5 0x000000000003ffe0ULL
+#define BAD_REG_OUT_OVR 0x000000000000001cULL
+#define BAD_REG_XXX_1_0 0x0000000000000003ULL
+
+/* GMX Backpressure Statistics Register */
+
+#define STAT_BP_XXX_63_17 0xfffffffffffe0000ULL
+#define STAT_BP_BP 0x0000000000010000ULL
+#define STAT_BP_CNT 0x000000000000ffffULL
+
+/* Mode Change Mask Registers */
+
+#define TX_CLK_MSKN_XXX_63_1 0xfffffffffffffffeULL
+#define TX_CLK_MSKN_MSK 0x0000000000000001ULL
+
+/* GMX RX/TX Status Register */
+
+#define RX_TX_STATUS_XXX_63_7 0xffffffffffffff80ULL
+#define RX_TX_STATUS_TX 0x0000000000000070ULL
+#define RX_TX_STATUS_XXX_3 0x0000000000000008ULL
+#define RX_TX_STATUS_RX 0x0000000000000007ULL
+
+/* Interface Mode Register */
+
+#define INF_MODE_XXX_63_3 0xfffffffffffffff8ULL
+#define INF_MODE_P0MII 0x0000000000000004ULL
+#define INF_MODE_EN 0x0000000000000002ULL
+#define INF_MODE_TYPE 0x0000000000000001ULL
+
+/* -------------------------------------------------------------------------- */
+
+/* for bus_space(9) */
+
+#define GMX_IF_NUNITS 1
+#define GMX_PORT_NUNITS 3
+
+#define GMX0_BASE_PORT0 0x0001180008000000ULL
+#define GMX0_BASE_PORT1 0x0001180008000800ULL
+#define GMX0_BASE_PORT2 0x0001180008001000ULL
+#define GMX0_BASE_PORT_SIZE 0x00800
+#define GMX0_BASE_IF0 0x0001180008000000ULL
+#define GMX0_BASE_IF_SIZE (GMX0_BASE_PORT_SIZE * GMX_PORT_NUNITS)
+
+/* for bitmask_snprintf(9) */
+
+#define RXN_INT_REG_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x12" "PHY_DUPX\0" \
+ "b\x11" "PHY_SPD\0" \
+ "b\x10" "PHY_LINK\0" \
+ "b\x0f" "IFGERR\0" \
+ "b\x0e" "COLDET\0" \
+ "b\x0d" "FALERR\0" \
+ "b\x0c" "RSVERR\0" \
+ "b\x0b" "PCTERR\0" \
+ "b\x0a" "OVRERR\0" \
+ "b\x09" "NIBERR\0" \
+ "b\x08" "SKPERR\0" \
+ "b\x07" "RCVERR\0" \
+ "b\x06" "LENERR\0" \
+ "b\x05" "ALNERR\0" \
+ "b\x04" "FCSERR\0" \
+ "b\x03" "JABBER\0" \
+ "b\x02" "MAXERR\0" \
+ "b\x01" "CAREXT\0" \
+ "b\x00" "MINERR\0"
+#define RXN_INT_EN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x12" "PHY_DUPX\0" \
+ "b\x11" "PHY_SPD\0" \
+ "b\x10" "PHY_LINK\0" \
+ "b\x0f" "IFGERR\0" \
+ "b\x0e" "COLDET\0" \
+ "b\x0d" "FALERR\0" \
+ "b\x0c" "RSVERR\0" \
+ "b\x0b" "PCTERR\0" \
+ "b\x0a" "OVRERR\0" \
+ "b\x09" "NIBERR\0" \
+ "b\x08" "SKPERR\0" \
+ "b\x07" "RCVERR\0" \
+ "b\x06" "LENERR\0" \
+ "b\x05" "ALNERR\0" \
+ "b\x04" "FCSERR\0" \
+ "b\x03" "JABBER\0" \
+ "b\x02" "MAXERR\0" \
+ "b\x01" "CAREXT\0" \
+ "b\x00" "MINERR\0"
+#define PRTN_CFG_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x03" "SLOTTIME\0" \
+ "b\x02" "DUPLEX\0" \
+ "b\x01" "SPEED\0" \
+ "b\x00" "EN\0"
+#define RXN_FRM_CTL_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x0a" "NULL_DIS\0" \
+ "b\x09" "PRE_ALIGN\0" \
+ "b\x08" "PAD_LEN\0" \
+ "b\x07" "VLAN_LEN\0" \
+ "b\x06" "PRE_FREE\0" \
+ "b\x05" "CTL_SMAC\0" \
+ "b\x04" "CTL_MCST\0" \
+ "b\x03" "CTL_BCK\0" \
+ "b\x02" "CTL_DRP\0" \
+ "b\x01" "PRE_STRP\0" \
+ "b\x00" "PRE_CHK\0"
+#define RXN_FRM_CHK_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x09" "NIBERR\0" \
+ "b\x08" "SKPERR\0" \
+ "b\x07" "RCVERR\0" \
+ "b\x06" "LENERR\0" \
+ "b\x05" "ALNERR\0" \
+ "b\x04" "FCSERR\0" \
+ "b\x03" "JABBER\0" \
+ "b\x02" "MAXERR\0" \
+ "b\x01" "CAREXT\0" \
+ "b\x00" "MINERR\0"
+/* RXN_FRM_MIN */
+/* RXN_FRM_MAX */
+#define RXN_JABBER_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x10" "CNT\0"
+#define RXN_DECISION_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x05" "CNT\0"
+#define RXN_UDD_SKP_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x08" "FCSSEL\0" \
+ "f\x00\x07" "LEN\0"
+#define RXN_STATS_CTL_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x00" "RD_CLR\0"
+#define RXN_IFG_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x04" "IFG\0"
+#define RXN_RX_INBND_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x03" "DUPLEX\0" \
+ "f\x01\x02" "SPEED\0" \
+ "b\x00" "STATUS\0"
+#define RXN_STATS_PKTS_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x20" "CNT\0"
+#define RXN_STATS_OCTS_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x30" "CNT\0"
+#define RXN_STATS_PKTS_CTL_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x20" "CNT\0"
+#define RXN_STATS_OCTS_CTL_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x30" "CNT\0"
+#define RXN_STATS_PKTS_DMAC_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x20" "CNT\0"
+#define RXN_STATS_OCTS_DMAC_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x30" "CNT\0"
+#define RXN_STATS_PKTS_DRP_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x20" "CNT\0"
+#define RXN_STATS_OCTS_DRP_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x30" "CNT\0"
+#define RXN_STATS_PKTS_BAD_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x20" "CNT\0"
+#define RXN_ADR_CTL_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x03" "CAM_MODE\0" \
+ "f\x01\x02" "MCST\0" \
+ "b\x00" "BCST\0"
+#define RXN_ADR_CAM_EN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x08" "EN\0"
+/* RXN_ADR_CAM0 */
+/* RXN_ADR_CAM1 */
+/* RXN_ADR_CAM2 */
+/* RXN_ADR_CAM3 */
+/* RXN_ADR_CAM4 */
+/* RXN_ADR_CAM5 */
+#define TXN_CLK_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x06" "CLK_CNT\0"
+#define TXN_THRESH_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x06" "CNT\0"
+#define TXN_APPEND_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x03" "FORCE_FCS\0" \
+ "b\x02" "FCS\0" \
+ "b\x01" "PAD\0" \
+ "b\x00" "PREAMBLE\0"
+#define TXN_SLOT_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x0a" "SLOT\0"
+#define TXN_BURST_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x10" "BURST\0"
+/* SMAC0 */
+#define TXN_PAUSE_PKT_TIME_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x10" "TIME\0"
+#define TXN_MIN_PKT_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x08" "MIN_SIZE\0"
+#define TXN_PAUSE_PKT_INTERVAL_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x10" "INTERVAL\0"
+#define TXN_SOFT_PAUSE_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x10" "TIME\0"
+#define TXN_PAUSE_TOGO_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x10" "TIME\0"
+#define TXN_PAUSE_ZERO_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x00" "SEND\0"
+#define TXN_STATS_CTL_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x00" "RD_CLR\0"
+#define TXN_CTL_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x01" "XSDEF_EN\0" \
+ "b\x00" "XSCOL_EN\0"
+#define TXN_STAT0_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x20\x20" "XSDEF\0" \
+ "f\x00\x20" "XSCOL\0"
+#define TXN_STAT1_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x20\x20" "SCOL\0" \
+ "f\x00\x20" "MSCOL\0"
+#define TXN_STAT2_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x30" "OCTS\0"
+#define TXN_STAT3_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x20" "PKTS\0"
+#define TXN_STAT4_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x20\x20" "HIST1\0" \
+ "f\x00\x20" "HIST0\0"
+#define TXN_STAT5_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x20\x20" "HIST3\0" \
+ "f\x00\x20" "HIST2\0"
+#define TXN_STAT6_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x20\x20" "HIST5\0" \
+ "f\x00\x20" "HIST4\0"
+#define TXN_STAT7_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x20\x20" "HIST7\0" \
+ "f\x00\x20" "HIST6\0"
+#define TXN_STAT8_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x20\x20" "MCST\0" \
+ "f\x00\x20" "BCST\0"
+#define TXN_STAT9_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x20\x20" "UNDFLW\0" \
+ "f\x00\x20" "CTL\0"
+/* BIST0 */
+#define RX_PRTS_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x03" "PRTS\0"
+#define RX_BP_DROPN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x06" "MARK\0"
+#define RX_BP_ONN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x09" "MARK\0"
+#define RX_BP_OFFN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x06" "MARK\0"
+#define TX_PRTS_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x05" "PRTS\0"
+#define TX_IFG_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x04\x04" "IFG2\0" \
+ "f\x00\x04" "IFG1\0"
+#define TX_JAM_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x08" "JAM\0"
+#define TX_COL_ATTEMPT_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x05" "LIMIT\0"
+#define TX_PAUSE_PKT_DMAC_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x30" "DMAC\0"
+#define TX_PAUSE_PKT_TYPE_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x10" "TYPE\0"
+#define TX_OVR_BP_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x08\x03" "EN\0" \
+ "f\x04\x03" "BP\0" \
+ "f\x00\x03" "IGN_FULL\0"
+#define TX_BP_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x03" "SR_BP\0"
+#define TX_CORRUPT_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x03" "CORRUPT\0"
+#define RX_PRT_INFO_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x10\x03" "DROP\0" \
+ "f\x00\x03" "COMMIT\0"
+#define TX_LFSR_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x10" "LFSR\0"
+#define TX_INT_REG_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x10\x03" "LATE_COL\0" \
+ "f\x0c\x03" "XSDEF\0" \
+ "f\x08\x03" "XSCOL\0" \
+ "f\x02\x03" "UNDFLW\0" \
+ "b\x00" "PKO_NXA\0"
+#define TX_INT_EN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x10\x03" "LATE_COL\0" \
+ "f\x0c\x03" "XSDEF\0" \
+ "f\x08\x03" "XSCOL\0" \
+ "f\x02\x03" "UNDFLW\0" \
+ "b\x00" "PKO_NXA\0"
+#define NXA_ADR_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x06" "PRT\0"
+#define BAD_REG_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x1b\x04" "INB_NXA\0" \
+ "b\x1a" "STATOVR\0" \
+ "f\x16\x03" "LOSTSTAT\0" \
+ "f\x02\x03" "OUT_OVR\0"
+#define STAT_BP_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x10" "BP\0" \
+ "f\x00\x10" "CNT\0"
+#define TX_CLK_MSKN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x00" "MSK\0"
+#define RX_TX_STATUS_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x04\x03" "TX\0" \
+ "f\x00\x03" "RX\0"
+#define INF_MODE_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x02" "P0MII\0" \
+ "b\x01" "EN\0" \
+ "b\x00" "TYPE\0"
+
+#define GMX0_RX0_INT_REG_BITS RXN_INT_REG_BITS
+#define GMX0_RX0_INT_EN_BITS RXN_INT_EN_BITS
+#define GMX0_PRT0_CFG_BITS PRTN_CFG_BITS
+#define GMX0_RX0_FRM_CTL_BITS RXN_FRM_CTL_BITS
+#define GMX0_RX0_FRM_CHK_BITS RXN_FRM_CHK_BITS
+#define GMX0_RX0_FRM_MIN_BITS NULL//RXN_FRM_MIN_BITS
+#define GMX0_RX0_FRM_MAX_BITS NULL//RXN_FRM_MAX_BITS
+#define GMX0_RX0_JABBER_BITS RXN_JABBER_BITS
+#define GMX0_RX0_DECISION_BITS RXN_DECISION_BITS
+#define GMX0_RX0_UDD_SKP_BITS RXN_UDD_SKP_BITS
+#define GMX0_RX0_STATS_CTL_BITS RXN_STATS_CTL_BITS
+#define GMX0_RX0_IFG_BITS RXN_IFG_BITS
+#define GMX0_RX0_RX_INBND_BITS RXN_RX_INBND_BITS
+#define GMX0_RX0_STATS_PKTS_BITS RXN_STATS_PKTS_BITS
+#define GMX0_RX0_STATS_OCTS_BITS RXN_STATS_OCTS_BITS
+#define GMX0_RX0_STATS_PKTS_CTL_BITS RXN_STATS_PKTS_CTL_BITS
+#define GMX0_RX0_STATS_OCTS_CTL_BITS RXN_STATS_OCTS_CTL_BITS
+#define GMX0_RX0_STATS_PKTS_DMAC_BITS RXN_STATS_PKTS_DMAC_BITS
+#define GMX0_RX0_STATS_OCTS_DMAC_BITS RXN_STATS_OCTS_DMAC_BITS
+#define GMX0_RX0_STATS_PKTS_DRP_BITS RXN_STATS_PKTS_DRP_BITS
+#define GMX0_RX0_STATS_OCTS_DRP_BITS RXN_STATS_OCTS_DRP_BITS
+#define GMX0_RX0_STATS_PKTS_BAD_BITS RXN_STATS_PKTS_BAD_BITS
+#define GMX0_RX0_ADR_CTL_BITS RXN_ADR_CTL_BITS
+#define GMX0_RX0_ADR_CAM_EN_BITS RXN_ADR_CAM_EN_BITS
+#define GMX0_RX0_ADR_CAM0_BITS NULL//RXN_ADR_CAM0_BITS
+#define GMX0_RX0_ADR_CAM1_BITS NULL//RXN_ADR_CAM1_BITS
+#define GMX0_RX0_ADR_CAM2_BITS NULL//RXN_ADR_CAM2_BITS
+#define GMX0_RX0_ADR_CAM3_BITS NULL//RXN_ADR_CAM3_BITS
+#define GMX0_RX0_ADR_CAM4_BITS NULL//RXN_ADR_CAM4_BITS
+#define GMX0_RX0_ADR_CAM5_BITS NULL//RXN_ADR_CAM5_BITS
+#define GMX0_TX0_CLK_BITS TXN_CLK_BITS
+#define GMX0_TX0_THRESH_BITS TXN_THRESH_BITS
+#define GMX0_TX0_APPEND_BITS TXN_APPEND_BITS
+#define GMX0_TX0_SLOT_BITS TXN_SLOT_BITS
+#define GMX0_TX0_BURST_BITS TXN_BURST_BITS
+#define GMX0_SMAC0_BITS NULL//SMAC0_BITS
+#define GMX0_TX0_PAUSE_PKT_TIME_BITS TXN_PAUSE_PKT_TIME_BITS
+#define GMX0_TX0_MIN_PKT_BITS TXN_MIN_PKT_BITS
+#define GMX0_TX0_PAUSE_PKT_INTERVAL_BITS TXN_PAUSE_PKT_INTERVAL_BITS
+#define GMX0_TX0_SOFT_PAUSE_BITS TXN_SOFT_PAUSE_BITS
+#define GMX0_TX0_PAUSE_TOGO_BITS TXN_PAUSE_TOGO_BITS
+#define GMX0_TX0_PAUSE_ZERO_BITS TXN_PAUSE_ZERO_BITS
+#define GMX0_TX0_STATS_CTL_BITS TXN_STATS_CTL_BITS
+#define GMX0_TX0_CTL_BITS TXN_CTL_BITS
+#define GMX0_TX0_STAT0_BITS TXN_STAT0_BITS
+#define GMX0_TX0_STAT1_BITS TXN_STAT1_BITS
+#define GMX0_TX0_STAT2_BITS TXN_STAT2_BITS
+#define GMX0_TX0_STAT3_BITS TXN_STAT3_BITS
+#define GMX0_TX0_STAT4_BITS TXN_STAT4_BITS
+#define GMX0_TX0_STAT5_BITS TXN_STAT5_BITS
+#define GMX0_TX0_STAT6_BITS TXN_STAT6_BITS
+#define GMX0_TX0_STAT7_BITS TXN_STAT7_BITS
+#define GMX0_TX0_STAT8_BITS TXN_STAT8_BITS
+#define GMX0_TX0_STAT9_BITS TXN_STAT9_BITS
+#define GMX0_BIST0_BITS NULL//BIST0_BITS
+#define GMX0_RX_PRTS_BITS RX_PRTS_BITS
+#define GMX0_RX_BP_DROP0_BITS RX_BP_DROPN_BITS
+#define GMX0_RX_BP_ON0_BITS RX_BP_ONN_BITS
+#define GMX0_RX_BP_OFF0_BITS RX_BP_OFFN_BITS
+#define GMX0_RX_BP_DROP1_BITS RX_BP_DROPN_BITS
+#define GMX0_RX_BP_ON1_BITS RX_BP_ONN_BITS
+#define GMX0_RX_BP_OFF1_BITS RX_BP_OFFN_BITS
+#define GMX0_RX_BP_DROP2_BITS RX_BP_DROPN_BITS
+#define GMX0_RX_BP_ON2_BITS RX_BP_ONN_BITS
+#define GMX0_RX_BP_OFF2_BITS RX_BP_OFFN_BITS
+#define GMX0_TX_PRTS_BITS TX_PRTS_BITS
+#define GMX0_TX_IFG_BITS TX_IFG_BITS
+#define GMX0_TX_JAM_BITS TX_JAM_BITS
+#define GMX0_TX_COL_ATTEMPT_BITS TX_COL_ATTEMPT_BITS
+#define GMX0_TX_PAUSE_PKT_DMAC_BITS TX_PAUSE_PKT_DMAC_BITS
+#define GMX0_TX_PAUSE_PKT_TYPE_BITS TX_PAUSE_PKT_TYPE_BITS
+#define GMX0_TX_OVR_BP_BITS TX_OVR_BP_BITS
+#define GMX0_TX_BP_BITS TX_BP_BITS
+#define GMX0_TX_CORRUPT_BITS TX_CORRUPT_BITS
+#define GMX0_RX_PRT_INFO_BITS RX_PRT_INFO_BITS
+#define GMX0_TX_LFSR_BITS TX_LFSR_BITS
+#define GMX0_TX_INT_REG_BITS TX_INT_REG_BITS
+#define GMX0_TX_INT_EN_BITS TX_INT_EN_BITS
+#define GMX0_NXA_ADR_BITS NXA_ADR_BITS
+#define GMX0_BAD_REG_BITS BAD_REG_BITS
+#define GMX0_STAT_BP_BITS STAT_BP_BITS
+#define GMX0_TX_CLK_MSK0_BITS TX_CLK_MSKN_BITS
+#define GMX0_TX_CLK_MSK1_BITS TX_CLK_MSKN_BITS
+#define GMX0_TX_CLK_MSK2_BITS TX_CLK_MSKN_BITS
+#define GMX0_RX_TX_STATUS_BITS RX_TX_STATUS_BITS
+#define GMX0_INF_MODE_BITS INF_MODE_BITS
+
+#endif /* _CN30XXGMXREG_H_ */
diff --git a/sys/arch/octeon/dev/cn30xxgmxvar.h b/sys/arch/octeon/dev/cn30xxgmxvar.h
new file mode 100644
index 00000000000..f21b8c70ccd
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxgmxvar.h
@@ -0,0 +1,187 @@
+/* $OpenBSD: cn30xxgmxvar.h,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _CN30XXGMXVAR_H_
+#define _CN30XXGMXVAR_H_
+
+#include <sys/socket.h>
+#include <net/if.h>
+#include <net/if_media.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+
+#define GMX_MII_PORT 1
+#define GMX_GMII_PORT 2
+#define GMX_RGMII_PORT 3
+#define GMX_SPI42_PORT 4
+
+#define GMX_FRM_MAX_SIZ 0x600
+
+/* Disable 802.3x flow-control when AutoNego is enabled */
+#define GMX_802_3X_DISABLE_AUTONEG
+
+#if 1
+ /* XXX */
+ enum OCTEON_ETH_QUIRKS {
+ OCTEON_ETH_QUIRKS_SEILX = 1 << 1,
+ OCTEON_ETH_QUIRKS_SEILX1 = 1 << 2,
+ OCTEON_ETH_QUIRKS_SEILX2 = 1 << 3,
+ OCTEON_ETH_QUIRKS_SEILX2PORT0 = 1 << 4,
+ OCTEON_ETH_QUIRKS_L2SWPORT = 1 << 5,
+ OCTEON_ETH_QUIRKS_FCS = 1 << 6,
+ OCTEON_ETH_QUIRKS_SEILX1_REVB = 1 << 7,
+ };
+#endif
+
+#if 1
+struct cn30xxgmx_softc;
+struct cn30xxgmx_port_softc;
+
+struct cn30xxgmx_port_softc {
+ struct cn30xxgmx_softc *sc_port_gmx;
+ bus_space_handle_t sc_port_regh;
+ int sc_port_no; /* GMX0:0, GMX0:1, ... */
+ int sc_port_type;
+ uint64_t sc_mac;
+ int sc_quirks;
+ uint64_t sc_link;
+ struct mii_data *sc_port_mii;
+ struct arpcom *sc_port_ac;
+ struct cn30xxgmx_port_ops
+ *sc_port_ops;
+ struct cn30xxasx_softc *sc_port_asx;
+ struct cn30xxipd_softc *sc_ipd;
+ int sc_port_flowflags;
+
+#if defined(OCTEON_DEBUG) || defined(OCTEON_ETH_DEBUG)
+#if 0
+ /* XXX */
+ struct evcnt sc_ev_pausedrp;
+ struct evcnt sc_ev_phydupx;
+ struct evcnt sc_ev_physpd;
+ struct evcnt sc_ev_phylink;
+#endif
+ struct evcnt sc_ev_ifgerr;
+ struct evcnt sc_ev_coldet;
+ struct evcnt sc_ev_falerr;
+ struct evcnt sc_ev_rcverr;
+ struct evcnt sc_ev_rsverr;
+ struct evcnt sc_ev_pckterr;
+ struct evcnt sc_ev_ovrerr;
+ struct evcnt sc_ev_niberr;
+ struct evcnt sc_ev_skperr;
+ struct evcnt sc_ev_lenerr;
+ struct evcnt sc_ev_alnerr;
+ struct evcnt sc_ev_fcserr;
+ struct evcnt sc_ev_jabber;
+ struct evcnt sc_ev_maxerr;
+ struct evcnt sc_ev_carext;
+ struct evcnt sc_ev_minerr;
+#endif
+};
+
+struct cn30xxgmx_softc {
+ struct device sc_dev;
+
+ bus_space_tag_t sc_regt;
+ bus_space_handle_t sc_regh;
+ int sc_unitno; /* GMX0, GMX1, ... */
+ int sc_nports;
+ int sc_port_types[4/* XXX */];
+
+ struct cn30xxgmx_port_softc
+ *sc_ports;
+
+#if defined(OCTEON_DEBUG) || defined(OCTEON_ETH_DEBUG)
+ struct evcnt sc_ev_latecol;
+ struct evcnt sc_ev_xsdef;
+ struct evcnt sc_ev_xscol;
+ struct evcnt sc_ev_undflw;
+ struct evcnt sc_ev_pkonxa;
+#endif
+};
+#endif
+
+struct cn30xxgmx_attach_args {
+ bus_space_tag_t ga_regt;
+ bus_addr_t ga_addr;
+ bus_dma_tag_t ga_dmat;
+ const char *ga_name;
+ int ga_portno;
+ int ga_port_type;
+
+ struct cn30xxgmx_softc *ga_gmx;
+ struct cn30xxgmx_port_softc
+ *ga_gmx_port;
+};
+
+#define CN30XXGMX_FILTER_NADDRS_MAX 8 /* XXX elsewhere */
+
+enum CN30XXGMX_FILTER_POLICY {
+ CN30XXGMX_FILTER_POLICY_ACCEPT_ALL,
+ CN30XXGMX_FILTER_POLICY_ACCEPT,
+ CN30XXGMX_FILTER_POLICY_REJECT,
+ CN30XXGMX_FILTER_POLICY_REJECT_ALL
+};
+
+int cn30xxgmx_link_enable(struct cn30xxgmx_port_softc *, int);
+int cn30xxgmx_tx_stats_rd_clr(struct cn30xxgmx_port_softc *, int);
+int cn30xxgmx_rx_stats_rd_clr(struct cn30xxgmx_port_softc *, int);
+void cn30xxgmx_rx_stats_dec_bad(struct cn30xxgmx_port_softc *);
+int cn30xxgmx_stats_init(struct cn30xxgmx_port_softc *);
+void cn30xxgmx_tx_int_enable(struct cn30xxgmx_port_softc *, int);
+void cn30xxgmx_rx_int_enable(struct cn30xxgmx_port_softc *, int);
+int cn30xxgmx_setfilt(struct cn30xxgmx_port_softc *,
+ enum CN30XXGMX_FILTER_POLICY, size_t, uint8_t **);
+int cn30xxgmx_rx_frm_ctl_enable(struct cn30xxgmx_port_softc *,
+ uint64_t rx_frm_ctl);
+int cn30xxgmx_rx_frm_ctl_disable(struct cn30xxgmx_port_softc *,
+ uint64_t rx_frm_ctl);
+int cn30xxgmx_tx_thresh(struct cn30xxgmx_port_softc *, int);
+int cn30xxgmx_set_mac_addr(struct cn30xxgmx_port_softc *, uint8_t *);
+int cn30xxgmx_set_filter(struct cn30xxgmx_port_softc *);
+int cn30xxgmx_port_enable(struct cn30xxgmx_port_softc *, int);
+int cn30xxgmx_reset_speed(struct cn30xxgmx_port_softc *);
+int cn30xxgmx_reset_flowctl(struct cn30xxgmx_port_softc *);
+int cn30xxgmx_reset_timing(struct cn30xxgmx_port_softc *);
+int cn30xxgmx_reset_board(struct cn30xxgmx_port_softc *);
+void cn30xxgmx_stats(struct cn30xxgmx_port_softc *);
+uint64_t cn30xxgmx_get_rx_int_reg(struct cn30xxgmx_port_softc *sc);
+uint64_t cn30xxgmx_get_tx_int_reg(struct cn30xxgmx_port_softc *sc);
+static inline int cn30xxgmx_link_status(struct cn30xxgmx_port_softc *);
+
+/* XXX RGMII specific */
+static inline int
+cn30xxgmx_link_status(struct cn30xxgmx_port_softc *sc)
+{
+ return (sc->sc_link & RXN_RX_INBND_STATUS) ? 1 : 0;
+}
+
+#endif
diff --git a/sys/arch/octeon/dev/cn30xxipd.c b/sys/arch/octeon/dev/cn30xxipd.c
new file mode 100644
index 00000000000..c3897c29856
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxipd.c
@@ -0,0 +1,400 @@
+/* $OpenBSD: cn30xxipd.c,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+
+#include <machine/octeonvar.h>
+
+#include <octeon/dev/cn30xxciureg.h>
+#include <octeon/dev/cn30xxfpavar.h>
+#include <octeon/dev/cn30xxpipreg.h>
+#include <octeon/dev/cn30xxipdreg.h>
+#include <octeon/dev/cn30xxipdvar.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+
+#define IP_OFFSET(data, word2) \
+ ((caddr_t)(data) + ((word2 & PIP_WQE_WORD2_IP_OFFSET) >> PIP_WQE_WORD2_IP_OFFSET_SHIFT))
+
+#ifdef OCTEON_ETH_DEBUG
+void cn30xxipd_intr_evcnt_attach(struct cn30xxipd_softc *);
+void cn30xxipd_intr_rml(void *);
+int cn30xxipd_intr_drop(void *);
+
+void cn30xxipd_dump(void);
+
+static void *cn30xxipd_intr_drop_ih;
+struct evcnt cn30xxipd_intr_drop_evcnt =
+ EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "octeon",
+ "ipd drop intr");
+EVCNT_ATTACH_STATIC(cn30xxipd_intr_drop_evcnt);
+
+struct cn30xxipd_softc *__cn30xxipd_softc[3/* XXX */];
+#endif
+
+/* XXX */
+void
+cn30xxipd_init(struct cn30xxipd_attach_args *aa,
+ struct cn30xxipd_softc **rsc)
+{
+ struct cn30xxipd_softc *sc;
+ int status;
+
+ sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
+ if (sc == NULL)
+ panic("can't allocate memory: %s", __func__);
+
+ sc->sc_port = aa->aa_port;
+ sc->sc_regt = aa->aa_regt;
+ sc->sc_first_mbuff_skip = aa->aa_first_mbuff_skip;
+ sc->sc_not_first_mbuff_skip = aa->aa_not_first_mbuff_skip;
+
+ status = bus_space_map(sc->sc_regt, IPD_BASE, IPD_SIZE, 0,
+ &sc->sc_regh);
+ if (status != 0)
+ panic("can't map %s space", "ipd register");
+
+ *rsc = sc;
+
+#ifdef OCTEON_ETH_DEBUG
+ cn30xxipd_int_enable(sc, 1);
+ cn30xxipd_intr_evcnt_attach(sc);
+ if (cn30xxipd_intr_drop_ih == NULL)
+ cn30xxipd_intr_drop_ih = octeon_intr_establish(
+ ffs64(CIU_INTX_SUM0_IPD_DRP) - 1, 0, IPL_NET,
+ cn30xxipd_intr_drop, NULL);
+ __cn30xxipd_softc[sc->sc_port] = sc;
+#endif /* OCTEON_ETH_DEBUG */
+}
+
+#define _IPD_RD8(sc, off) \
+ bus_space_read_8((sc)->sc_regt, (sc)->sc_regh, (off))
+#define _IPD_WR8(sc, off, v) \
+ bus_space_write_8((sc)->sc_regt, (sc)->sc_regh, (off), (v))
+
+int
+cn30xxipd_enable(struct cn30xxipd_softc *sc)
+{
+ uint64_t ctl_status;
+
+ ctl_status = _IPD_RD8(sc, IPD_CTL_STATUS_OFFSET);
+ SET(ctl_status, IPD_CTL_STATUS_IPD_EN);
+ _IPD_WR8(sc, IPD_CTL_STATUS_OFFSET, ctl_status);
+
+ return 0;
+}
+
+int
+cn30xxipd_config(struct cn30xxipd_softc *sc)
+{
+ uint64_t first_mbuff_skip;
+ uint64_t not_first_mbuff_skip;
+ uint64_t packet_mbuff_size;
+ uint64_t first_next_ptr_back;
+ uint64_t second_next_ptr_back;
+ uint64_t sqe_fpa_queue;
+ uint64_t ctl_status;
+
+ /* XXX */
+ first_mbuff_skip = 0;
+ SET(first_mbuff_skip, (sc->sc_first_mbuff_skip / 8) & IPD_1ST_MBUFF_SKIP_SZ);
+ _IPD_WR8(sc, IPD_1ST_MBUFF_SKIP_OFFSET, first_mbuff_skip);
+ /* XXX */
+
+ /* XXX */
+ not_first_mbuff_skip = 0;
+ SET(not_first_mbuff_skip, (sc->sc_not_first_mbuff_skip / 8) &
+ IPD_NOT_1ST_MBUFF_SKIP_SZ);
+ _IPD_WR8(sc, IPD_NOT_1ST_MBUFF_SKIP_OFFSET, not_first_mbuff_skip);
+ /* XXX */
+
+ packet_mbuff_size = 0;
+ SET(packet_mbuff_size, (FPA_RECV_PKT_POOL_SIZE / 8) &
+ IPD_PACKET_MBUFF_SIZE_MB_SIZE);
+ _IPD_WR8(sc, IPD_PACKET_MBUFF_SIZE_OFFSET, packet_mbuff_size);
+
+ first_next_ptr_back = 0;
+ SET(first_next_ptr_back, (sc->sc_first_mbuff_skip / 128) & IPD_1ST_NEXT_PTR_BACK_BACK);
+ _IPD_WR8(sc, IPD_1ST_NEXT_PTR_BACK_OFFSET, first_next_ptr_back);
+
+ second_next_ptr_back = 0;
+ SET(second_next_ptr_back, (sc->sc_not_first_mbuff_skip / 128) &
+ IPD_2ND_NEXT_PTR_BACK_BACK);
+ _IPD_WR8(sc, IPD_2ND_NEXT_PTR_BACK_OFFSET, second_next_ptr_back);
+
+ sqe_fpa_queue = 0;
+ SET(sqe_fpa_queue, FPA_WQE_POOL & IPD_WQE_FPA_QUEUE_WQE_QUE);
+ _IPD_WR8(sc, IPD_WQE_FPA_QUEUE_OFFSET, sqe_fpa_queue);
+
+ ctl_status = _IPD_RD8(sc, IPD_CTL_STATUS_OFFSET);
+ CLR(ctl_status, IPD_CTL_STATUS_OPC_MODE);
+ SET(ctl_status, IPD_CTL_STATUS_OPC_MODE_ALL);
+ SET(ctl_status, IPD_CTL_STATUS_PBP_EN);
+
+ _IPD_WR8(sc, IPD_CTL_STATUS_OFFSET, ctl_status);
+
+ return 0;
+}
+
+/*
+ * octeon work queue entry offload
+ * L3 error & L4 error
+ */
+void
+cn30xxipd_offload(uint64_t word2, caddr_t data, uint16_t *rcflags)
+{
+#if 0 /* XXX */
+ int cflags;
+
+ if (ISSET(word2, PIP_WQE_WORD2_IP_NI))
+ return;
+
+ cflags = 0;
+
+ if (!ISSET(word2, PIP_WQE_WORD2_IP_V6))
+ SET(cflags, M_CSUM_IPv4);
+
+ if (ISSET(word2, PIP_WQE_WORD2_IP_TU)) {
+ SET(cflags,
+ !ISSET(word2, PIP_WQE_WORD2_IP_V6) ?
+ (M_CSUM_TCPv4 | M_CSUM_UDPv4) :
+ (M_CSUM_TCPv6 | M_CSUM_UDPv6));
+ }
+
+ /* check L3 (IP) error */
+ if (ISSET(word2, PIP_WQE_WORD2_IP_IE)) {
+ struct ip *ip;
+
+ switch (word2 & PIP_WQE_WORD2_IP_OPECODE) {
+ case IPD_WQE_L3_V4_CSUM_ERR:
+ /* CN31XX_Pass_1.1_Issues_v1.5 2.4.5.1 */
+ ip = (struct ip *)(IP_OFFSET(data, word2));
+ if (ip->ip_hl == 5)
+ SET(cflags, M_CSUM_IPv4_BAD);
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* check L4 (UDP / TCP) error */
+ if (ISSET(word2, PIP_WQE_WORD2_IP_LE)) {
+ switch (word2 & PIP_WQE_WORD2_IP_OPECODE) {
+ case IPD_WQE_L4_CSUM_ERR:
+ SET(cflags, M_CSUM_TCP_UDP_BAD);
+ break;
+ default:
+ break;
+ }
+ }
+
+ *rcflags = cflags;
+#endif
+}
+
+void
+cn30xxipd_sub_port_fcs(struct cn30xxipd_softc *sc, int enable)
+{
+ uint64_t sub_port_fcs;
+
+ sub_port_fcs = _IPD_RD8(sc, IPD_SUB_PORT_FCS_OFFSET);
+ if (enable == 0)
+ CLR(sub_port_fcs, 1 << sc->sc_port);
+ else
+ SET(sub_port_fcs, 1 << sc->sc_port);
+ _IPD_WR8(sc, IPD_SUB_PORT_FCS_OFFSET, sub_port_fcs);
+}
+
+#ifdef OCTEON_ETH_DEBUG
+int cn30xxipd_intr_rml_verbose;
+struct evcnt cn30xxipd_intr_evcnt;
+
+static const struct octeon_evcnt_entry cn30xxipd_intr_evcnt_entries[] = {
+#define _ENTRY(name, type, parent, descr) \
+ OCTEON_EVCNT_ENTRY(struct cn30xxipd_softc, name, type, parent, descr)
+ _ENTRY(ipdbpsub, MISC, NULL, "ipd backpressure subtract"),
+ _ENTRY(ipdprcpar3, MISC, NULL, "ipd parity error 127:96"),
+ _ENTRY(ipdprcpar2, MISC, NULL, "ipd parity error 95:64"),
+ _ENTRY(ipdprcpar1, MISC, NULL, "ipd parity error 63:32"),
+ _ENTRY(ipdprcpar0, MISC, NULL, "ipd parity error 31:0"),
+#undef _ENTRY
+};
+
+void
+cn30xxipd_intr_evcnt_attach(struct cn30xxipd_softc *sc)
+{
+ OCTEON_EVCNT_ATTACH_EVCNTS(sc, cn30xxipd_intr_evcnt_entries, "ipd0");
+}
+
+void
+cn30xxipd_intr_rml(void *arg)
+{
+ int i;
+
+ cn30xxipd_intr_evcnt.ev_count++;
+ for (i = 0; i < 3/* XXX */; i++) {
+ struct cn30xxipd_softc *sc;
+ uint64_t reg;
+
+ sc = __cn30xxipd_softc[i];
+ KASSERT(sc != NULL);
+ reg = cn30xxipd_int_summary(sc);
+ if (cn30xxipd_intr_rml_verbose)
+ printf("%s: IPD_INT_SUM=0x%016" PRIx64 "\n", __func__, reg);
+ if (reg & IPD_INT_SUM_BP_SUB)
+ OCTEON_EVCNT_INC(sc, ipdbpsub);
+ if (reg & IPD_INT_SUM_PRC_PAR3)
+ OCTEON_EVCNT_INC(sc, ipdprcpar3);
+ if (reg & IPD_INT_SUM_PRC_PAR2)
+ OCTEON_EVCNT_INC(sc, ipdprcpar2);
+ if (reg & IPD_INT_SUM_PRC_PAR1)
+ OCTEON_EVCNT_INC(sc, ipdprcpar1);
+ if (reg & IPD_INT_SUM_PRC_PAR0)
+ OCTEON_EVCNT_INC(sc, ipdprcpar0);
+ }
+}
+
+void
+cn30xxipd_int_enable(struct cn30xxipd_softc *sc, int enable)
+{
+ uint64_t ipd_int_xxx = 0;
+
+ SET(ipd_int_xxx,
+ IPD_INT_SUM_BP_SUB |
+ IPD_INT_SUM_PRC_PAR3 |
+ IPD_INT_SUM_PRC_PAR2 |
+ IPD_INT_SUM_PRC_PAR1 |
+ IPD_INT_SUM_PRC_PAR0);
+ _IPD_WR8(sc, IPD_INT_SUM_OFFSET, ipd_int_xxx);
+ _IPD_WR8(sc, IPD_INT_ENB_OFFSET, enable ? ipd_int_xxx : 0);
+}
+
+uint64_t
+cn30xxipd_int_summary(struct cn30xxipd_softc *sc)
+{
+ uint64_t summary;
+
+ summary = _IPD_RD8(sc, IPD_INT_SUM_OFFSET);
+ _IPD_WR8(sc, IPD_INT_SUM_OFFSET, summary);
+ return summary;
+}
+
+int
+cn30xxipd_intr_drop(void *arg)
+{
+ octeon_write_csr(CIU_INT0_SUM0, CIU_INTX_SUM0_IPD_DRP);
+ cn30xxipd_intr_drop_evcnt.ev_count++;
+ return (1);
+}
+
+#define _ENTRY(x) { #x, x##_BITS, x##_OFFSET }
+
+struct cn30xxipd_dump_reg {
+ const char *name;
+ const char *format;
+ size_t offset;
+};
+
+static const struct cn30xxipd_dump_reg cn30xxipd_dump_regs[] = {
+ _ENTRY(IPD_1ST_MBUFF_SKIP),
+ _ENTRY(IPD_NOT_1ST_MBUFF_SKIP),
+ _ENTRY(IPD_PACKET_MBUFF_SIZE),
+ _ENTRY(IPD_CTL_STATUS),
+ _ENTRY(IPD_WQE_FPA_QUEUE),
+ _ENTRY(IPD_PORT0_BP_PAGE_CNT),
+ _ENTRY(IPD_PORT1_BP_PAGE_CNT),
+ _ENTRY(IPD_PORT2_BP_PAGE_CNT),
+ _ENTRY(IPD_PORT32_BP_PAGE_CNT),
+ _ENTRY(IPD_SUB_PORT_BP_PAGE_CNT),
+ _ENTRY(IPD_1ST_NEXT_PTR_BACK),
+ _ENTRY(IPD_2ND_NEXT_PTR_BACK),
+ _ENTRY(IPD_INT_ENB),
+ _ENTRY(IPD_INT_SUM),
+ _ENTRY(IPD_SUB_PORT_FCS),
+ _ENTRY(IPD_QOS0_RED_MARKS),
+ _ENTRY(IPD_QOS1_RED_MARKS),
+ _ENTRY(IPD_QOS2_RED_MARKS),
+ _ENTRY(IPD_QOS3_RED_MARKS),
+ _ENTRY(IPD_QOS4_RED_MARKS),
+ _ENTRY(IPD_QOS5_RED_MARKS),
+ _ENTRY(IPD_QOS6_RED_MARKS),
+ _ENTRY(IPD_QOS7_RED_MARKS),
+ _ENTRY(IPD_PORT_BP_COUNTERS_PAIR0),
+ _ENTRY(IPD_PORT_BP_COUNTERS_PAIR1),
+ _ENTRY(IPD_PORT_BP_COUNTERS_PAIR2),
+ _ENTRY(IPD_PORT_BP_COUNTERS_PAIR32),
+ _ENTRY(IPD_RED_PORT_ENABLE),
+ _ENTRY(IPD_RED_QUE0_PARAM),
+ _ENTRY(IPD_RED_QUE1_PARAM),
+ _ENTRY(IPD_RED_QUE2_PARAM),
+ _ENTRY(IPD_RED_QUE3_PARAM),
+ _ENTRY(IPD_RED_QUE4_PARAM),
+ _ENTRY(IPD_RED_QUE5_PARAM),
+ _ENTRY(IPD_RED_QUE6_PARAM),
+ _ENTRY(IPD_RED_QUE7_PARAM),
+ _ENTRY(IPD_PTR_COUNT),
+ _ENTRY(IPD_BP_PRT_RED_END),
+ _ENTRY(IPD_QUE0_FREE_PAGE_CNT),
+ _ENTRY(IPD_CLK_COUNT),
+ _ENTRY(IPD_PWP_PTR_FIFO_CTL),
+ _ENTRY(IPD_PRC_HOLD_PTR_FIFO_CTL),
+ _ENTRY(IPD_PRC_PORT_PTR_FIFO_CTL),
+ _ENTRY(IPD_PKT_PTR_VALID),
+ _ENTRY(IPD_WQE_PTR_VALID),
+ _ENTRY(IPD_BIST_STATUS),
+};
+
+void
+cn30xxipd_dump(void)
+{
+ struct cn30xxipd_softc *sc;
+ const struct cn30xxipd_dump_reg *reg;
+ uint64_t tmp;
+ char buf[512];
+ int i;
+
+ sc = __cn30xxipd_softc[0];
+ for (i = 0; i < (int)nitems(cn30xxipd_dump_regs); i++) {
+ reg = &cn30xxipd_dump_regs[i];
+ tmp = _IPD_RD8(sc, reg->offset);
+ if (reg->format == NULL) {
+ snprintf(buf, sizeof(buf), "%16" PRIx64, tmp);
+ } else {
+ bitmask_snprintf(tmp, reg->format, buf, sizeof(buf));
+ }
+ printf("%-32s: %s\n", reg->name, buf);
+ }
+}
+#endif /* OCTEON_ETH_DEBUG */
diff --git a/sys/arch/octeon/dev/cn30xxipdreg.h b/sys/arch/octeon/dev/cn30xxipdreg.h
new file mode 100644
index 00000000000..5977d0ffec1
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxipdreg.h
@@ -0,0 +1,787 @@
+/*
+ * THIS FILE IS AUTOMATICALLY GENERATED
+ * DONT EDIT THIS FILE
+ */
+
+/* $OpenBSD: cn30xxipdreg.h,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Cavium Networks OCTEON CN30XX Hardware Reference Manual
+ * CN30XX-HM-1.0
+ * 7.9 IPD Registers
+ */
+
+#ifndef _CN30XXIPDREG_H_
+#define _CN30XXIPDREG_H_
+
+#define IPD_1ST_MBUFF_SKIP 0x00014f0000000000ULL
+#define IPD_NOT_1ST_MBUFF_SKIP 0x00014f0000000008ULL
+#define IPD_PACKET_MBUFF_SIZE 0x00014f0000000010ULL
+#define IPD_CTL_STATUS 0x00014f0000000018ULL
+#define IPD_WQE_FPA_QUEUE 0x00014f0000000020ULL
+#define IPD_PORT0_BP_PAGE_CNT 0x00014f0000000028ULL
+#define IPD_PORT1_BP_PAGE_CNT 0x00014f0000000030ULL
+#define IPD_PORT2_BP_PAGE_CNT 0x00014f0000000038ULL
+#define IPD_PORT32_BP_PAGE_CNT 0x00014f0000000128ULL
+#define IPD_SUB_PORT_BP_PAGE_CNT 0x00014f0000000148ULL
+#define IPD_1ST_NEXT_PTR_BACK 0x00014f0000000150ULL
+#define IPD_2ND_NEXT_PTR_BACK 0x00014f0000000158ULL
+#define IPD_INT_ENB 0x00014f0000000160ULL
+#define IPD_INT_SUM 0x00014f0000000168ULL
+#define IPD_SUB_PORT_FCS 0x00014f0000000170ULL
+#define IPD_QOS0_RED_MARKS 0x00014f0000000178ULL
+#define IPD_QOS1_RED_MARKS 0x00014f0000000180ULL
+#define IPD_QOS2_RED_MARKS 0x00014f0000000188ULL
+#define IPD_QOS3_RED_MARKS 0x00014f0000000190ULL
+#define IPD_QOS4_RED_MARKS 0x00014f0000000198ULL
+#define IPD_QOS5_RED_MARKS 0x00014f00000001a0ULL
+#define IPD_QOS6_RED_MARKS 0x00014f00000001a8ULL
+#define IPD_QOS7_RED_MARKS 0x00014f00000001b0ULL
+#define IPD_PORT_BP_COUNTERS_PAIR0 0x00014f00000001b8ULL
+#define IPD_PORT_BP_COUNTERS_PAIR1 0x00014f00000001c0ULL
+#define IPD_PORT_BP_COUNTERS_PAIR2 0x00014f00000001c8ULL
+#define IPD_PORT_BP_COUNTERS_PAIR32 0x00014f00000002b8ULL
+#define IPD_RED_PORT_ENABLE 0x00014f00000002d8ULL
+#define IPD_RED_QUE0_PARAM 0x00014f00000002e0ULL
+#define IPD_RED_QUE1_PARAM 0x00014f00000002e8ULL
+#define IPD_RED_QUE2_PARAM 0x00014f00000002f0ULL
+#define IPD_RED_QUE3_PARAM 0x00014f00000002f8ULL
+#define IPD_RED_QUE4_PARAM 0x00014f0000000300ULL
+#define IPD_RED_QUE5_PARAM 0x00014f0000000308ULL
+#define IPD_RED_QUE6_PARAM 0x00014f0000000310ULL
+#define IPD_RED_QUE7_PARAM 0x00014f0000000318ULL
+#define IPD_PTR_COUNT 0x00014f0000000320ULL
+#define IPD_BP_PRT_RED_END 0x00014f0000000328ULL
+#define IPD_QUE0_FREE_PAGE_CNT 0x00014f0000000330ULL
+#define IPD_CLK_COUNT 0x00014f0000000338ULL
+#define IPD_PWP_PTR_FIFO_CTL 0x00014f0000000340ULL
+#define IPD_PRC_HOLD_PTR_FIFO_CTL 0x00014f0000000348ULL
+#define IPD_PRC_PORT_PTR_FIFO_CTL 0x00014f0000000350ULL
+#define IPD_PKT_PTR_VALID 0x00014f0000000358ULL
+#define IPD_WQE_PTR_VALID 0x00014f0000000360ULL
+#define IPD_BIST_STATUS 0x00014f00000007f8ULL
+
+#define IPD_BASE 0x00014f0000000000ULL
+#define IPD_SIZE 0x800ULL
+
+#define IPD_1ST_MBUFF_SKIP_OFFSET 0x0ULL
+#define IPD_NOT_1ST_MBUFF_SKIP_OFFSET 0x8ULL
+#define IPD_PACKET_MBUFF_SIZE_OFFSET 0x10ULL
+#define IPD_CTL_STATUS_OFFSET 0x18ULL
+#define IPD_WQE_FPA_QUEUE_OFFSET 0x20ULL
+#define IPD_PORT0_BP_PAGE_CNT_OFFSET 0x28ULL
+#define IPD_PORT1_BP_PAGE_CNT_OFFSET 0x30ULL
+#define IPD_PORT2_BP_PAGE_CNT_OFFSET 0x38ULL
+#define IPD_PORT32_BP_PAGE_CNT_OFFSET 0x128ULL
+#define IPD_SUB_PORT_BP_PAGE_CNT_OFFSET 0x148ULL
+#define IPD_1ST_NEXT_PTR_BACK_OFFSET 0x150ULL
+#define IPD_2ND_NEXT_PTR_BACK_OFFSET 0x158ULL
+#define IPD_INT_ENB_OFFSET 0x160ULL
+#define IPD_INT_SUM_OFFSET 0x168ULL
+#define IPD_SUB_PORT_FCS_OFFSET 0x170ULL
+#define IPD_QOS0_RED_MARKS_OFFSET 0x178ULL
+#define IPD_QOS1_RED_MARKS_OFFSET 0x180ULL
+#define IPD_QOS2_RED_MARKS_OFFSET 0x188ULL
+#define IPD_QOS3_RED_MARKS_OFFSET 0x190ULL
+#define IPD_QOS4_RED_MARKS_OFFSET 0x198ULL
+#define IPD_QOS5_RED_MARKS_OFFSET 0x1a0ULL
+#define IPD_QOS6_RED_MARKS_OFFSET 0x1a8ULL
+#define IPD_QOS7_RED_MARKS_OFFSET 0x1b0ULL
+#define IPD_PORT_BP_COUNTERS_PAIR0_OFFSET 0x1b8ULL
+#define IPD_PORT_BP_COUNTERS_PAIR1_OFFSET 0x1c0ULL
+#define IPD_PORT_BP_COUNTERS_PAIR2_OFFSET 0x1c8ULL
+#define IPD_PORT_BP_COUNTERS_PAIR32_OFFSET 0x2b8ULL
+#define IPD_RED_PORT_ENABLE_OFFSET 0x2d8ULL
+#define IPD_RED_QUE0_PARAM_OFFSET 0x2e0ULL
+#define IPD_RED_QUE1_PARAM_OFFSET 0x2e8ULL
+#define IPD_RED_QUE2_PARAM_OFFSET 0x2f0ULL
+#define IPD_RED_QUE3_PARAM_OFFSET 0x2f8ULL
+#define IPD_RED_QUE4_PARAM_OFFSET 0x300ULL
+#define IPD_RED_QUE5_PARAM_OFFSET 0x308ULL
+#define IPD_RED_QUE6_PARAM_OFFSET 0x310ULL
+#define IPD_RED_QUE7_PARAM_OFFSET 0x318ULL
+#define IPD_PTR_COUNT_OFFSET 0x320ULL
+#define IPD_BP_PRT_RED_END_OFFSET 0x328ULL
+#define IPD_QUE0_FREE_PAGE_CNT_OFFSET 0x330ULL
+#define IPD_CLK_COUNT_OFFSET 0x338ULL
+#define IPD_PWP_PTR_FIFO_CTL_OFFSET 0x340ULL
+#define IPD_PRC_HOLD_PTR_FIFO_CTL_OFFSET 0x348ULL
+#define IPD_PRC_PORT_PTR_FIFO_CTL_OFFSET 0x350ULL
+#define IPD_PKT_PTR_VALID_OFFSET 0x358ULL
+#define IPD_WQE_PTR_VALID_OFFSET 0x360ULL
+#define IPD_BIST_STATUS_OFFSET 0x7f8ULL
+
+/* ----- */
+/*
+ * Work Queue Entry Format (for input packet)
+ * 7.5 Work Queue Entry
+ * Figure 7-8. PIP/IPD Hardware Work-Queue Entry
+ */
+
+/*
+ * word 2
+ * Figure. 7-9 Work-Queue Entry format; Word2 Cases
+ */
+/* RAWFULL */
+#define IPD_WQE_WORD2_RAW_BUFS 0xff00000000000000ULL
+#define IPD_WQE_WORD2_RAW_WORD 0x00ffffffffffffffULL
+
+/* is IP */
+#define IPD_WQE_WORD2_IP_BUFS 0xff00000000000000ULL
+#define IPD_WQE_WORD2_IP_IPOFF 0x00ff000000000000ULL
+#define IPD_WQE_WORD2_IP_VV 0x0000800000000000ULL
+#define IPD_WQE_WORD2_IP_VS 0x0000400000000000ULL
+#define IPD_WQE_WORD2_IP_45 0x0000200000000000ULL
+#define IPD_WQE_WORD2_IP_VC 0x0000100000000000ULL
+#define IPD_WQE_WORD2_IP_VLANID 0x00000fff00000000ULL
+#define IPD_WQE_WORD2_IP_31_20 0x00000000fff00000ULL
+#define IPD_WQE_WORD2_IP_CO 0x0000000000080000ULL
+#define IPD_WQE_WORD2_IP_TU 0x0000000000040000ULL
+#define IPD_WQE_WORD2_IP_SE 0x0000000000020000ULL
+#define IPD_WQE_WORD2_IP_V6 0x0000000000010000ULL
+#define IPD_WQE_WORD2_IP_15 0x0000000000008000ULL
+#define IPD_WQE_WORD2_IP_LE 0x0000000000004000ULL
+#define IPD_WQE_WORD2_IP_FR 0x0000000000002000ULL
+#define IPD_WQE_WORD2_IP_IE 0x0000000000001000ULL
+#define IPD_WQE_WORD2_IP_B 0x0000000000000800ULL
+#define IPD_WQE_WORD2_IP_M 0x0000000000000400ULL
+#define IPD_WQE_WORD2_IP_NI 0x0000000000000200ULL
+#define IPD_WQE_WORD2_IP_RE 0x0000000000000100ULL
+#define IPD_WQE_WORD2_IP_OPCODE 0x00000000000000ffULL
+
+/* All other */
+#define IPD_WQE_WORD2_OTH_BUFS 0xff00000000000000ULL
+#define IPD_WQE_WORD2_OTH_55_48 0x00ff000000000000ULL
+#define IPD_WQE_WORD2_OTH_VV 0x0000800000000000ULL
+#define IPD_WQE_WORD2_OTH_VS 0x0000400000000000ULL
+#define IPD_WQE_WORD2_OTH_45 0x0000200000000000ULL
+#define IPD_WQE_WORD2_OTH_VC 0x0000100000000000ULL
+#define IPD_WQE_WORD2_OTH_VLANID 0x00000fff00000000ULL
+#define IPD_WQE_WORD2_OTH_31_14 0x00000000ffffc000ULL
+#define IPD_WQE_WORD2_OTH_IR 0x0000000000002000ULL
+#define IPD_WQE_WORD2_OTH_IA 0x0000000000001000ULL
+#define IPD_WQE_WORD2_OTH_B 0x0000000000000800ULL
+#define IPD_WQE_WORD2_OTH_M 0x0000000000000400ULL
+#define IPD_WQE_WORD2_OTH_NI 0x0000000000000200ULL
+#define IPD_WQE_WORD2_OTH_RE 0x0000000000000100ULL
+#define IPD_WQE_WORD2_OTH_OPCODE 0x00000000000000ffULL
+
+/*
+ * word 3
+ */
+#define IPD_WQE_WORD3_63 0x8000000000000000ULL
+#define IPD_WQE_WORD3_BACK 0x7800000000000000ULL
+#define IPD_WQE_WORD3_58_56 0x0700000000000000ULL
+#define IPD_WQE_WORD3_SIZE 0x00ffff0000000000ULL
+#define IPD_WQE_WORD3_ADDR 0x000000ffffffffffULL
+
+/*
+ * IPD_1ST_MBUFF_SKIP
+ */
+#define IPD_1ST_MBUFF_SKIP_63_6 0xffffffffffffffc0ULL
+#define IPD_1ST_MBUFF_SKIP_SZ 0x000000000000003fULL
+
+/*
+ * IPD_NOT_1ST_MBUFF_SKIP
+ */
+#define IPD_NOT_1ST_MBUFF_SKIP_63_6 0xffffffffffffffc0ULL
+#define IPD_NOT_1ST_MBUFF_SKIP_SZ 0x000000000000003fULL
+
+/*
+ * IPD_PACKET_MBUFF_SIZE
+ */
+#define IPD_PACKET_MBUFF_SIZE_63_12 0xfffffffffffff000ULL
+#define IPD_PACKET_MBUFF_SIZE_MB_SIZE 0x0000000000000fffULL
+
+/*
+ * IPD_CTL_STATUS
+ */
+#define IPD_CTL_STATUS_63_10 0xfffffffffffffc00ULL
+#define IPD_CTL_STATUS_LEN_M8 0x0000000000000200ULL
+#define IPD_CTL_STATUS_RESET 0x0000000000000100ULL
+#define IPD_CTL_STATUS_ADDPKT 0x0000000000000080ULL
+#define IPD_CTL_STATUS_NADDBUF 0x0000000000000040ULL
+#define IPD_CTL_STATUS_PKT_LEND 0x0000000000000020ULL
+#define IPD_CTL_STATUS_WQE_LEND 0x0000000000000010ULL
+#define IPD_CTL_STATUS_PBP_EN 0x0000000000000008ULL
+#define IPD_CTL_STATUS_OPC_MODE 0x0000000000000006ULL
+#define IPD_CTL_STATUS_OPC_MODE_SHIFT 1
+#define IPD_CTL_STATUS_OPC_MODE_NONE (0ULL << IPD_CTL_STATUS_OPC_MODE_SHIFT)
+#define IPD_CTL_STATUS_OPC_MODE_ALL (1ULL << IPD_CTL_STATUS_OPC_MODE_SHIFT)
+#define IPD_CTL_STATUS_OPC_MODE_ONE (2ULL << IPD_CTL_STATUS_OPC_MODE_SHIFT)
+#define IPD_CTL_STATUS_OPC_MODE_TWO (3ULL << IPD_CTL_STATUS_OPC_MODE_SHIFT)
+#define IPD_CTL_STATUS_IPD_EN 0x0000000000000001ULL
+
+/*
+ * IPD_WQE_FPA_QUEUE
+ */
+#define IPD_WQE_FPA_QUEUE_63_3 0xfffffffffffffff8ULL
+#define IPD_WQE_FPA_QUEUE_WQE_QUE 0x0000000000000007ULL
+
+/*
+ * IPD_PORTN_BP_PAGE_CNT
+ */
+#define IPD_PORTN_BP_PAGE_CNT_63_18 0xfffffffffffc0000ULL
+#define IPD_PORTN_BP_PAGE_CNT_BP_ENB 0x0000000000020000ULL
+#define IPD_PORTN_BP_PAGE_CNT_PAGE_CNT 0x000000000001ffffULL
+
+/*
+ * IPD_SUB_PORT_BP_PAGE_CNT
+ */
+#define IPD_SUB_PORT_BP_PAGE_CNT_63_18 0xffffffff80000000ULL
+#define IPD_SUB_PORT_BP_PAGE_CNT_PORT 0x000000007e000000ULL
+#define IPD_SUB_PORT_BP_PAGE_CNT_PAGE_CNT 0x0000000001ffffffULL
+
+/*
+ * IPD_1ST_NEXT_PTR_BACK
+ */
+#define IPD_1ST_NEXT_PTR_BACK_63_4 0xfffffffffffffff0ULL
+#define IPD_1ST_NEXT_PTR_BACK_BACK 0x000000000000000fULL
+
+/*
+ * IPD_2ND_NEXT_PTR_BACK
+ */
+#define IPD_2ND_NEXT_PTR_BACK_63_4 0xfffffffffffffff0ULL
+#define IPD_2ND_NEXT_PTR_BACK_BACK 0x000000000000000fULL
+
+/*
+ * IPD_INT_ENB
+ */
+#define IPD_INT_ENB_63_4 0xffffffffffffffe0ULL
+#define IPD_INT_ENB_BP_SUB 0x0000000000000010ULL
+#define IPD_INT_ENB_PRC_PAR3 0x0000000000000008ULL
+#define IPD_INT_ENB_PRC_PAR2 0x0000000000000004ULL
+#define IPD_INT_ENB_PRC_PAR1 0x0000000000000002ULL
+#define IPD_INT_ENB_PRC_PAR0 0x0000000000000001ULL
+
+/*
+ * IPD_INT_SUM
+ */
+#define IPD_INT_SUM_63_4 0xffffffffffffffe0ULL
+#define IPD_INT_SUM_BP_SUB 0x0000000000000010ULL
+#define IPD_INT_SUM_PRC_PAR3 0x0000000000000008ULL
+#define IPD_INT_SUM_PRC_PAR2 0x0000000000000004ULL
+#define IPD_INT_SUM_PRC_PAR1 0x0000000000000002ULL
+#define IPD_INT_SUM_PRC_PAR0 0x0000000000000001ULL
+
+/*
+ * IPD_SUB_PORT_FCS
+ */
+#define IPD_SUB_PORT_FCS_63_3 0xfffffffffffffff8ULL
+#define IPD_SUB_PORT_FCS_PORT_BIT 0x0000000000000007ULL
+
+/*
+ * IPD_QOSN_RED_MARKS
+ */
+#define IPD_QOSN_READ_MARKS_DROP 0xffffffff00000000ULL
+#define IPD_QOSN_READ_MARKS_PASS 0x00000000ffffffffULL
+
+/*
+ * IPD_PORT_BP_COUNTERS_PAIRN
+ */
+#define IPD_PORT_BP_COUNTERS_PAIRN_63_25 0xfffffffffe000000ULL
+#define IPD_PORT_BP_COUNTERS_PAIRN_CNT_VAL 0x0000000001ffffffULL
+
+/*
+ * IPD_RED_PORT_ENABLE
+ */
+#define IPD_RED_PORT_ENABLE_PRB_DLY 0xfffc000000000000ULL
+#define IPD_RED_PORT_ENABLE_AVG_DLY 0x0003fff000000000ULL
+#define IPD_RED_PORT_ENABLE_PRT_ENB 0x0000000fffffffffULL
+
+/*
+ * IPD_RED_QUEN_PARAM
+ */
+#define IPD_RED_QUEN_PARAM_63_49 0xfffe000000000000ULL
+#define IPD_RED_QUEN_PARAM_USE_PCNT 0x0001000000000000ULL
+#define IPD_RED_QUEN_PARAM_NEW_CON 0x0000ff0000000000ULL
+#define IPD_RED_QUEN_PARAM_AVG_CON 0x000000ff00000000ULL
+#define IPD_RED_QUEN_PARAM_PRB_CON 0x00000000ffffffffULL
+
+/*
+ * IPD_PTR_COUNT
+ */
+#define IPD_PTR_COUNT_63_19 0xfffffffffff80000ULL
+#define IPD_PTR_COUNT_PKTV_CNT 0x0000000000040000ULL
+#define IPD_PTR_COUNT_WQEV_CNT 0x0000000000020000ULL
+#define IPD_PTR_COUNT_PFIF_CNT 0x000000000001c000ULL
+#define IPD_PTR_COUNT_PKT_PCNT 0x0000000000003f80ULL
+#define IPD_PTR_COUNT_WQE_PCNT 0x000000000000007fULL
+
+/*
+ * IPD_BP_PRT_RED_END
+ */
+#define IPD_BP_PRT_RED_END_63_36 0xfffffff000000000ULL
+#define IPD_BP_PRT_RED_END_PRT_ENB 0x0000000fffffffffULL
+
+/*
+ * IPD_QUE0_FREE_PAGE_CNT
+ */
+#define IPD_QUE0_FREE_PAGE_CNT_63_32 0xffffffff00000000ULL
+#define IPD_QUE0_FREE_PAGE_CNT_Q0_PCNT 0x00000000ffffffffULL
+
+/*
+ * IPD_CLK_COUNT
+ */
+#define IPD_CLK_COUNT_CLK_CNT 0xffffffffffffffffULL
+
+/*
+ * IPD_PWP_PTR_FIFO_CTL
+ */
+#define IPD_PWP_PTR_FIFO_CTL_63_61 0xe000000000000000ULL
+#define IPD_PWP_PTR_FIFO_CTL_MAX_CNTS 0x1fc0000000000000ULL
+#define IPD_PWP_PTR_FIFO_CTL_WRADDR 0x003fc00000000000ULL
+#define IPD_PWP_PTR_FIFO_CTL_PRADDR 0x00003fc000000000ULL
+#define IPD_PWP_PTR_FIFO_CTL_PTR 0x0000003ffffffe00ULL
+#define IPD_PWP_PTR_FIFO_CTL_CENA 0x0000000000000100ULL
+#define IPD_PWP_PTR_FIFO_CTL_RADDR 0x00000000000000ffULL
+
+/*
+ * IPD_PRC_HOLD_PTR_FIFO_CTL
+ */
+#define IPD_PRC_HOLD_PTR_FIFO_CTL_63_39 0xffffff8000000000ULL
+#define IPD_PRC_HOLD_PTR_FIFO_CTL_MAX_PTR 0x0000007000000000ULL
+#define IPD_PRC_HOLD_PTR_FIFO_CTL_PRADDR 0x0000000e00000000ULL
+#define IPD_PRC_HOLD_PTR_FIFO_CTL_PTR 0x00000001fffffff0ULL
+#define IPD_PRC_HOLD_PTR_FIFO_CTL_CENA 0x0000000000000008ULL
+#define IPD_PRC_HOLD_PTR_FIFO_CTL_RADDR 0x0000000000000007ULL
+
+/*
+ * IPD_PRC_PORT_PTR_FIFO_CTL
+ */
+#define IPD_PRC_PORT_PTR_FIFO_CTL_63_44 0xfffff00000000000ULL
+#define IPD_PRC_PORT_PTR_FIFO_CTL_MAX_PTR 0x00000fe000000000ULL
+#define IPD_PRC_PORT_PTR_FIFO_CTL_PTR 0x0000001fffffff00ULL
+#define IPD_PRC_PORT_PTR_FIFO_CTL_CENA 0x0000000000000080ULL
+#define IPD_PRC_PORT_PTR_FIFO_CTL_RADDR 0x000000000000007fULL
+
+/*
+ * IPD_PKT_PTR_VALID
+ */
+#define IPD_PKT_PTR_VALID_63_29 0xffffffffe0000000ULL
+#define IPD_PKT_PTR_VALID_PTR 0x000000001fffffffULL
+
+/*
+ * IPD_WQE_PTR_VALID
+ */
+#define IPD_WQE_PTR_VALID_63_29 0xffffffffe0000000ULL
+#define IPD_WQE_PTR_VALID_PTR 0x000000001fffffffULL
+
+/*
+ * IPD_BIST_STATUS
+ */
+#define IPD_BIST_STATUS_63_29 0xffffffffffff0000ULL
+#define IPD_BIST_STATUS_PWQ_WQED 0x0000000000008000ULL
+#define IPD_BIST_STATUS_PWQ_WP1 0x0000000000004000ULL
+#define IPD_BIST_STATUS_PWQ_POW 0x0000000000002000ULL
+#define IPD_BIST_STATUS_IPQ_PBE1 0x0000000000001000ULL
+#define IPD_BIST_STATUS_IPQ_PBE0 0x0000000000000800ULL
+#define IPD_BIST_STATUS_PBM3 0x0000000000000400ULL
+#define IPD_BIST_STATUS_PBM2 0x0000000000000200ULL
+#define IPD_BIST_STATUS_PBM1 0x0000000000000100ULL
+#define IPD_BIST_STATUS_PBM0 0x0000000000000080ULL
+#define IPD_BIST_STATUS_PBM_WORD 0x0000000000000040ULL
+#define IPD_BIST_STATUS_PWQ1 0x0000000000000020ULL
+#define IPD_BIST_STATUS_PWQ0 0x0000000000000010ULL
+#define IPD_BIST_STATUS_PRC_OFF 0x0000000000000008ULL
+#define IPD_BIST_STATUS_IPD_OLD 0x0000000000000004ULL
+#define IPD_BIST_STATUS_IPD_NEW 0x0000000000000002ULL
+#define IPD_BIST_STATUS_PWP 0x0000000000000001ULL
+
+/*
+ * word2[Opcode]
+ */
+/* L3 (IP) error */
+#define IPD_WQE_L3_NOT_IP 1
+#define IPD_WQE_L3_V4_CSUM_ERR 2
+#define IPD_WQE_L3_HEADER_MALFORMED 3
+#define IPD_WQE_L3_MELFORMED 4
+#define IPD_WQE_L3_TTL_HOP 5
+#define IPD_WQE_L3_IP_OPT 6
+
+/* L4 (UDP/TCP) error */
+#define IPD_WQE_L4_MALFORMED 1
+#define IPD_WQE_L4_CSUM_ERR 2
+#define IPD_WQE_L4_UDP_LEN_ERR 3
+#define IPD_WQE_L4_BAD_PORT 4
+#define IPD_WQE_L4_FIN_ONLY 8
+#define IPD_WQE_L4_NO_FLAGS 9
+#define IPD_WQE_L4_FIN_RST 10
+#define IPD_WQE_L4_SYN_URG 11
+#define IPD_WQE_L4_SYN_RST 12
+#define IPD_WQE_L4_SYN_FIN 13
+
+#define IPD_1ST_MBUFF_SKIP_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x06\x3a" "63_6\0" \
+ "f\x00\x06" "SZ\0"
+#define IPD_NOT_1ST_MBUFF_SKIP_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x06\x3a" "63_6\0" \
+ "f\x00\x06" "SZ\0"
+#define IPD_PACKET_MBUFF_SIZE_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x0c\x34" "63_12\0" \
+ "f\x00\x0c" "MB_SIZE\0"
+#define IPD_CTL_STATUS_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x0a\x36" "63_10\0" \
+ "b\x09" "LEN_M8\0" \
+ "b\x08" "RESET\0" \
+ "b\x07" "ADDPKT\0" \
+ "b\x06" "NADDBUF\0" \
+ "b\x05" "PKT_LEND\0" \
+ "b\x04" "WQE_LEND\0" \
+ "b\x03" "PBP_EN\0" \
+ "f\x01\x02" "OPC_MODE\0" \
+ "b\x00" "IPD_EN\0"
+#define IPD_WQE_FPA_QUEUE_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x03\x3d" "63_3\0" \
+ "f\x00\x03" "WQE_QUE\0"
+#define IPD_PORT0_BP_PAGE_CNT_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define IPD_PORT1_BP_PAGE_CNT_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define IPD_PORT2_BP_PAGE_CNT_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define IPD_PORT32_BP_PAGE_CNT_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define IPD_SUB_PORT_BP_PAGE_CNT_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x1f\x21" "63_18\0" \
+ "f\x19\x06" "PORT\0" \
+ "f\x00\x19" "PAGE_CNT\0"
+#define IPD_1ST_NEXT_PTR_BACK_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x04\x3c" "63_4\0" \
+ "f\x00\x04" "BACK\0"
+#define IPD_2ND_NEXT_PTR_BACK_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x04\x3c" "63_4\0" \
+ "f\x00\x04" "BACK\0"
+#define IPD_INT_ENB_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x05\x3b" "63_4\0" \
+ "b\x04" "BP_SUB\0" \
+ "b\x03" "PRC_PAR3\0" \
+ "b\x02" "PRC_PAR2\0" \
+ "b\x01" "PRC_PAR1\0" \
+ "b\x00" "PRC_PAR0\0"
+#define IPD_INT_SUM_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x05\x3b" "63_4\0" \
+ "b\x04" "BP_SUB\0" \
+ "b\x03" "PRC_PAR3\0" \
+ "b\x02" "PRC_PAR2\0" \
+ "b\x01" "PRC_PAR1\0" \
+ "b\x00" "PRC_PAR0\0"
+#define IPD_SUB_PORT_FCS_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x03\x3d" "63_3\0" \
+ "f\x00\x03" "PORT_BIT\0"
+#define IPD_QOS0_RED_MARKS_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define IPD_QOS1_RED_MARKS_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define IPD_QOS2_RED_MARKS_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define IPD_QOS3_RED_MARKS_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define IPD_QOS4_RED_MARKS_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define IPD_QOS5_RED_MARKS_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define IPD_QOS6_RED_MARKS_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define IPD_QOS7_RED_MARKS_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define IPD_PORT_BP_COUNTERS_PAIR0_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define IPD_PORT_BP_COUNTERS_PAIR1_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define IPD_PORT_BP_COUNTERS_PAIR2_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define IPD_PORT_BP_COUNTERS_PAIR32_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define IPD_RED_PORT_ENABLE_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x32\x0e" "PRB_DLY\0" \
+ "f\x24\x0e" "AVG_DLY\0" \
+ "f\x00\x24" "PRT_ENB\0"
+#define IPD_RED_QUE0_PARAM_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define IPD_RED_QUE1_PARAM_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define IPD_RED_QUE2_PARAM_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define IPD_RED_QUE3_PARAM_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define IPD_RED_QUE4_PARAM_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define IPD_RED_QUE5_PARAM_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define IPD_RED_QUE6_PARAM_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define IPD_RED_QUE7_PARAM_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define IPD_PTR_COUNT_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x13\x2d" "63_19\0" \
+ "b\x12" "PKTV_CNT\0" \
+ "b\x11" "WQEV_CNT\0" \
+ "f\x0e\x03" "PFIF_CNT\0" \
+ "f\x07\x07" "PKT_PCNT\0" \
+ "f\x00\x07" "WQE_PCNT\0"
+#define IPD_BP_PRT_RED_END_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x24\x1c" "63_36\0" \
+ "f\x00\x24" "PRT_ENB\0"
+#define IPD_QUE0_FREE_PAGE_CNT_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x20\x20" "63_32\0" \
+ "f\x00\x20" "Q0_PCNT\0"
+#define IPD_CLK_COUNT_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x40" "CLK_CNT\0"
+#define IPD_PWP_PTR_FIFO_CTL_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x3d\x03" "63_61\0" \
+ "f\x36\x07" "MAX_CNTS\0" \
+ "f\x2e\x08" "WRADDR\0" \
+ "f\x26\x08" "PRADDR\0" \
+ "f\x09\x1d" "PTR\0" \
+ "b\x08" "CENA\0" \
+ "f\x00\x08" "RADDR\0"
+#define IPD_PRC_HOLD_PTR_FIFO_CTL_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x27\x19" "63_39\0" \
+ "f\x24\x03" "MAX_PTR\0" \
+ "f\x21\x03" "PRADDR\0" \
+ "f\x04\x1d" "PTR\0" \
+ "b\x03" "CENA\0" \
+ "f\x00\x03" "RADDR\0"
+#define IPD_PRC_PORT_PTR_FIFO_CTL_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x2c\x14" "63_44\0" \
+ "f\x25\x07" "MAX_PTR\0" \
+ "f\x08\x1d" "PTR\0" \
+ "b\x07" "CENA\0" \
+ "f\x00\x07" "RADDR\0"
+#define IPD_PKT_PTR_VALID_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x1d\x23" "63_29\0" \
+ "f\x00\x1d" "PTR\0"
+#define IPD_WQE_PTR_VALID_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x1d\x23" "63_29\0" \
+ "f\x00\x1d" "PTR\0"
+#define IPD_BIST_STATUS_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x10\x30" "63_29\0" \
+ "b\x0f" "PWQ_WQED\0" \
+ "b\x0e" "PWQ_WP1\0" \
+ "b\x0d" "PWQ_POW\0" \
+ "b\x0c" "IPQ_PBE1\0" \
+ "b\x0b" "IPQ_PBE0\0" \
+ "b\x0a" "PBM3\0" \
+ "b\x09" "PBM2\0" \
+ "b\x08" "PBM1\0" \
+ "b\x07" "PBM0\0" \
+ "b\x06" "PBM_WORD\0" \
+ "b\x05" "PWQ1\0" \
+ "b\x04" "PWQ0\0" \
+ "b\x03" "PRC_OFF\0" \
+ "b\x02" "IPD_OLD\0" \
+ "b\x01" "IPD_NEW\0" \
+ "b\x00" "PWP\0"
+
+#endif /* _CN30XXIPDREG_H_ */
diff --git a/sys/arch/octeon/dev/cn30xxipdvar.h b/sys/arch/octeon/dev/cn30xxipdvar.h
new file mode 100644
index 00000000000..140d9de62c2
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxipdvar.h
@@ -0,0 +1,77 @@
+/* $OpenBSD: cn30xxipdvar.h,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _CN30XXIPDVAR_H_
+#define _CN30XXIPDVAR_H_
+
+#ifndef SET
+#define SET(t, f) ((t) |= (f))
+#define ISSET(t, f) ((t) & (f))
+#define CLR(t, f) ((t) &= ~(f))
+#endif
+
+/* XXX */
+struct cn30xxipd_softc {
+ int sc_port;
+ bus_space_tag_t sc_regt;
+ bus_space_handle_t sc_regh;
+ size_t sc_first_mbuff_skip;
+ size_t sc_not_first_mbuff_skip;
+#ifdef OCTEON_ETH_DEBUG
+ struct evcnt sc_ev_ipdbpsub;
+ struct evcnt sc_ev_ipdprcpar3;
+ struct evcnt sc_ev_ipdprcpar2;
+ struct evcnt sc_ev_ipdprcpar1;
+ struct evcnt sc_ev_ipdprcpar0;
+#endif
+};
+
+/* XXX */
+struct cn30xxipd_attach_args {
+ int aa_port;
+ bus_space_tag_t aa_regt;
+ size_t aa_first_mbuff_skip;
+ size_t aa_not_first_mbuff_skip;
+};
+
+void cn30xxipd_init(struct cn30xxipd_attach_args *,
+ struct cn30xxipd_softc **);
+int cn30xxipd_enable(struct cn30xxipd_softc *);
+int cn30xxipd_config(struct cn30xxipd_softc *);
+void cn30xxipd_sub_port_fcs(struct cn30xxipd_softc *, int);
+void cn30xxipd_offload(uint64_t, caddr_t, uint16_t *);
+
+#ifdef OCTEON_ETH_DEBUG
+void cn30xxipd_int_enable(struct cn30xxipd_softc *, int);
+uint64_t cn30xxipd_int_summary(struct cn30xxipd_softc *);
+#endif /* OCTEON_ETH_DEBUG */
+#ifdef OCTEON_ETH_DEBUG
+void cn30xxipd_int_enable(struct cn30xxipd_softc *, int);
+#endif /* OCTEON_ETH_DEBUG */
+
+#endif
diff --git a/sys/arch/octeon/dev/cn30xxnpireg.h b/sys/arch/octeon/dev/cn30xxnpireg.h
new file mode 100644
index 00000000000..cb1c3659eef
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxnpireg.h
@@ -0,0 +1,441 @@
+/*
+ * THIS FILE IS AUTOMATICALLY GENERATED
+ * DONT EDIT THIS FILE
+ */
+
+/* $OpenBSD: cn30xxnpireg.h,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Cavium Networks OCTEON CN30XX Hardware Reference Manual
+ * CN30XX-HM-1.0
+ * 9.15 NPI Registers
+ */
+
+#ifndef _CN30XXNPIREG_H_
+#define _CN30XXNPIREG_H_
+
+#define MPI_CFG 0x0001070000001000ULL
+
+#define NPI_RSL_INT_BLOCKS 0x00011f0000000000ULL
+#define NPI_DBG_SELECT 0x00011f0000000008ULL
+#define NPI_CTL_STATUS 0x00011f0000000010ULL
+#define NPI_INT_SUM 0x00011f0000000018ULL
+#define NPI_INT_ENB 0x00011f0000000020ULL
+#define NPI_MEM_ACCESS_SUBID3 0x00011f0000000028ULL
+#define NPI_MEM_ACCESS_SUBID4 0x00011f0000000030ULL
+#define NPI_MEM_ACCESS_SUBID5 0x00011f0000000038ULL
+#define NPI_MEM_ACCESS_SUBID6 0x00011f0000000040ULL
+#define NPI_PCI_READ_CMD 0x00011f0000000048ULL
+#define NPI_NUM_DESC_OUTPUT0 0x00011f0000000050ULL
+#define NPI_BASE_ADDR_INPUT0 0x00011f0000000070ULL
+#define NPI_SIZE_INPUT0 0x00011f0000000078ULL
+#define PCI_READ_TIMEOUT 0x00011f00000000b0ULL
+#define NPI_BASE_ADDR_OUTPUT0 0x00011f00000000b8ULL
+#define NPI_PCI_BURST_SIZE 0x00011f00000000d8ULL
+#define NPI_BUFF_SIZE_OUTPUT0 0x00011f00000000e0ULL
+#define NPI_OUTPUT_CONTROL 0x00011f0000000100ULL
+#define NPI_LOWP_IBUFF_SADDR 0x00011f0000000108ULL
+#define NPI_HIGHP_IBUFF_SADDR 0x00011f0000000110ULL
+#define NPI_LOWP_DBELL 0x00011f0000000118ULL
+#define NPI_HIGHP_DBELL 0x00011f0000000120ULL
+#define NPI_DMA_CONTROL 0x00011f0000000128ULL
+#define NPI_PCI_INT_ARB_CFG 0x00011f0000000130ULL
+#define NPI_INPUT_CONTROL 0x00011f0000000138ULL
+#define NPI_DMA_LOWP_COUNTS 0x00011f0000000140ULL
+#define NPI_DMA_HIGHP_COUNTS 0x00011f0000000148ULL
+#define NPI_DMA_LOWP_NADDR 0x00011f0000000150ULL
+#define NPI_DMA_HIGHP_NADDR 0x00011f0000000158ULL
+#define NPI_P0_PAIR_CNTS 0x00011f0000000160ULL
+#define NPI_P0_DBPAIR_ADDR 0x00011f0000000180ULL
+#define NPI_P0_INSTR_CNTS 0x00011f00000001a0ULL
+#define NPI_P0_INSTR_ADDR 0x00011f00000001c0ULL
+#define NPI_WIN_READ_TO 0x00011f00000001e0ULL
+#define DBG_DATA 0x00011f00000001e8ULL
+#define NPI_PORT_BP_CONTROL 0x00011f00000001f0ULL
+#define NPI_PORT32_INSTR_HDR 0x00011f00000001f8ULL
+#define NPI_BIST_STATUS 0x00011f00000003f8ULL
+
+#define NPI_MSI_RCV 0x00011f0000001190ULL
+
+#define NPI_RSL_INT_BLOCKS_XXX_63_31 0xffffffff80000000ULL
+#define NPI_RSL_INT_BLOCKS_IOB 0x0000000040000000ULL
+#define NPI_RSL_INT_BLOCKS_XXX_29_23 0x000000003f800000ULL
+#define NPI_RSL_INT_BLOCKS_ASX0 0x0000000000400000ULL
+#define NPI_RSL_INT_BLOCKS_XXX_21 0x0000000000200000ULL
+#define NPI_RSL_INT_BLOCKS_PIP 0x0000000000100000ULL
+#define NPI_RSL_INT_BLOCKS_XXX_19_18 0x00000000000c0000ULL
+#define NPI_RSL_INT_BLOCKS_LMC 0x0000000000020000ULL
+#define NPI_RSL_INT_BLOCKS_L2C 0x0000000000010000ULL
+#define NPI_RSL_INT_BLOCKS_XXX_15_13 0x000000000000e000ULL
+#define NPI_RSL_INT_BLOCKS_POW 0x0000000000001000ULL
+#define NPI_RSL_INT_BLOCKS_TIM 0x0000000000000800ULL
+#define NPI_RSL_INT_BLOCKS_PKO 0x0000000000000400ULL
+#define NPI_RSL_INT_BLOCKS_IPD 0x0000000000000200ULL
+#define NPI_RSL_INT_BLOCKS_XXX_8_6 0x00000000000001c0ULL
+#define NPI_RSL_INT_BLOCKS_FPA 0x0000000000000020ULL
+#define NPI_RSL_INT_BLOCKS_XXX_4 0x0000000000000010ULL
+#define NPI_RSL_INT_BLOCKS_NPI 0x0000000000000008ULL
+#define NPI_RSL_INT_BLOCKS_GMX1 0x0000000000000004ULL
+#define NPI_RSL_INT_BLOCKS_GMX0 0x0000000000000002ULL
+#define NPI_RSL_INT_BLOCKS_MIO 0x0000000000000001ULL
+
+#define NPI_DBG_SELECT_XXX_63_16 0xffffffffffff0000ULL
+#define NPI_DBG_SELECT_DBG_SEL 0x000000000000ffffULL
+
+#define NPI_CTL_STATUS_XXX_63 0x8000000000000000ULL
+#define NPI_DBG_SELECT_DBG_SEL 0x000000000000ffffULL
+
+#define NPI_CTL_STATUS_XXX_63 0x8000000000000000ULL
+#define NPI_CTL_STATUS_CHIP_REV 0x7f80000000000000ULL
+#define NPI_CTL_STATUS_DIS_PNIW 0x0040000000000000ULL
+#define NPI_CTL_STATUS_SPR5 0x0020000000000000ULL
+#define NPI_CTL_STATUS_SPR4 0x0010000000000000ULL
+#define NPI_CTL_STATUS_SPR8 0x0008000000000000ULL
+#define NPI_CTL_STATUS_OUT0_ENB 0x0004000000000000ULL
+#define NPI_CTL_STATUS_SPR3 0x0002000000000000ULL
+#define NPI_CTL_STATUS_SPR2 0x0001000000000000ULL
+#define NPI_CTL_STATUS_SPR7 0x0000800000000000ULL
+#define NPI_CTL_STATUS_INS0_ENB 0x0000400000000000ULL
+#define NPI_CTL_STATUS_SPR1 0x0000200000000000ULL
+#define NPI_CTL_STATUS_SPR0 0x0000100000000000ULL
+#define NPI_CTL_STATUS_SPR6 0x0000080000000000ULL
+#define NPI_CTL_STATUS_INS0_64B 0x0000040000000000ULL
+#define NPI_CTL_STATUS_PCI_WDIS 0x0000020000000000ULL
+#define NPI_CTL_STATUS_WAIT_COM 0x0000010000000000ULL
+#define NPI_CTL_STATUS_SPARES1 0x000000e000000000ULL
+#define NPI_CTL_STATUS_MAX_WORD 0x0000001f00000000ULL
+#define NPI_CTL_STATUS_SPARES0 0x00000000fffffc00ULL
+#define NPI_CTL_STATUS_TIMER 0x00000000000003ffULL
+
+#define NPI_INT_SUM_XXX_63_62 0xc000000000000000ULL
+#define NPI_INT_SUM_Q1_A_F 0x2000000000000000ULL
+#define NPI_INT_SUM_Q1_S_E 0x1000000000000000ULL
+#define NPI_INT_SUM_PDF_P_F 0x0800000000000000ULL
+#define NPI_INT_SUM_PDF_P_E 0x0400000000000000ULL
+#define NPI_INT_SUM_PCF_P_F 0x0200000000000000ULL
+#define NPI_INT_SUM_PCF_P_E 0x0100000000000000ULL
+#define NPI_INT_SUM_RDX_S_E 0x0080000000000000ULL
+#define NPI_INT_SUM_RWX_S_E 0x0040000000000000ULL
+#define NPI_INT_SUM_PNC_A_F 0x0020000000000000ULL
+#define NPI_INT_SUM_PNC_S_F 0x0010000000000000ULL
+#define NPI_INT_SUM_COM_A_F 0x0008000000000000ULL
+#define NPI_INT_SUM_COM_S_E 0x0004000000000000ULL
+#define NPI_INT_SUM_Q3_A_F 0x0002000000000000ULL
+#define NPI_INT_SUM_Q3_S_E 0x0001000000000000ULL
+#define NPI_INT_SUM_Q2_A_F 0x0000800000000000ULL
+#define NPI_INT_SUM_Q2_S_E 0x0000400000000000ULL
+#define NPI_INT_SUM_PCR_A_F 0x0000200000000000ULL
+#define NPI_INT_SUM_PCR_S_E 0x0000100000000000ULL
+#define NPI_INT_SUM_FCR_A_F 0x0000080000000000ULL
+#define NPI_INT_SUM_FCR_S_E 0x0000040000000000ULL
+#define NPI_INT_SUM_IOBDMA 0x0000020000000000ULL
+#define NPI_INT_SUM_P_DPERR 0x0000010000000000ULL
+#define NPI_INT_SUM_WIN_RTO 0x0000008000000000ULL
+#define NPI_INT_SUM_SPR17 0x0000004000000000ULL
+#define NPI_INT_SUM_SPR16 0x0000002000000000ULL
+#define NPI_INT_SUM_SPR26 0x0000001000000000ULL
+#define NPI_INT_SUM_IO_PPERR 0x0000000800000000ULL
+#define NPI_INT_SUM_SPR15 0x0000000400000000ULL
+#define NPI_INT_SUM_SPR14 0x0000000200000000ULL
+#define NPI_INT_SUM_SPR25 0x0000000100000000ULL
+#define NPI_INT_SUM_P0_PTOUT 0x0000000080000000ULL
+#define NPI_INT_SUM_SPR13 0x0000000040000000ULL
+#define NPI_INT_SUM_SPR12 0x0000000020000000ULL
+#define NPI_INT_SUM_SPR24 0x0000000010000000ULL
+#define NPI_INT_SUM_P0_PPERR 0x0000000008000000ULL
+#define NPI_INT_SUM_SPR11 0x0000000004000000ULL
+#define NPI_INT_SUM_SPR10 0x0000000002000000ULL
+#define NPI_INT_SUM_SPR23 0x0000000001000000ULL
+#define NPI_INT_SUM_G0_RTOUT 0x0000000000800000ULL
+#define NPI_INT_SUM_SPR9 0x0000000000400000ULL
+#define NPI_INT_SUM_SPR8 0x0000000000200000ULL
+#define NPI_INT_SUM_SPR22 0x0000000000100000ULL
+#define NPI_INT_SUM_P0_PERR 0x0000000000080000ULL
+#define NPI_INT_SUM_SPR7 0x0000000000040000ULL
+#define NPI_INT_SUM_SPR6 0x0000000000020000ULL
+#define NPI_INT_SUM_SPR21 0x0000000000010000ULL
+#define NPI_INT_SUM_P0_RTOUT 0x0000000000008000ULL
+#define NPI_INT_SUM_SPR5 0x0000000000004000ULL
+#define NPI_INT_SUM_SPR4 0x0000000000002000ULL
+#define NPI_INT_SUM_SPR20 0x0000000000001000ULL
+#define NPI_INT_SUM_IO_OVERF 0x0000000000000800ULL
+#define NPI_INT_SUM_SPR3 0x0000000000000400ULL
+#define NPI_INT_SUM_SPR2 0x0000000000000200ULL
+#define NPI_INT_SUM_SPR19 0x0000000000000100ULL
+#define NPI_INT_SUM_IO_RTOUT 0x0000000000000080ULL
+#define NPI_INT_SUM_SPR1 0x0000000000000040ULL
+#define NPI_INT_SUM_SPR0 0x0000000000000020ULL
+#define NPI_INT_SUM_SPR18 0x0000000000000010ULL
+#define NPI_INT_SUM_PO0_2SML 0x0000000000000008ULL
+#define NPI_INT_SUM_PCI_RSL 0x0000000000000004ULL
+#define NPI_INT_SUM_RML_TWO 0x0000000000000002ULL
+#define NPI_INT_SUM_RML_RTO 0x0000000000000001ULL
+
+#define NPI_INT_ENB_XXX_63_62 0xc000000000000000ULL
+#define NPI_INT_ENB_Q1_A_F 0x2000000000000000ULL
+#define NPI_INT_ENB_Q1_S_E 0x1000000000000000ULL
+#define NPI_INT_ENB_PDF_P_F 0x0800000000000000ULL
+#define NPI_INT_ENB_PDF_P_E 0x0400000000000000ULL
+#define NPI_INT_ENB_PCF_P_F 0x0200000000000000ULL
+#define NPI_INT_ENB_PCF_P_E 0x0100000000000000ULL
+#define NPI_INT_ENB_RDX_S_E 0x0080000000000000ULL
+#define NPI_INT_ENB_RWX_S_E 0x0040000000000000ULL
+#define NPI_INT_ENB_PNC_A_F 0x0020000000000000ULL
+#define NPI_INT_ENB_PNC_S_F 0x0010000000000000ULL
+#define NPI_INT_ENB_COM_A_F 0x0008000000000000ULL
+#define NPI_INT_ENB_COM_S_E 0x0004000000000000ULL
+#define NPI_INT_ENB_Q3_A_F 0x0002000000000000ULL
+#define NPI_INT_ENB_Q3_S_E 0x0001000000000000ULL
+#define NPI_INT_ENB_Q2_A_F 0x0000800000000000ULL
+#define NPI_INT_ENB_Q2_S_E 0x0000400000000000ULL
+#define NPI_INT_ENB_PCR_A_F 0x0000200000000000ULL
+#define NPI_INT_ENB_PCR_S_E 0x0000100000000000ULL
+#define NPI_INT_ENB_FCR_A_F 0x0000080000000000ULL
+#define NPI_INT_ENB_FCR_S_E 0x0000040000000000ULL
+#define NPI_INT_ENB_IOBDMA 0x0000020000000000ULL
+#define NPI_INT_ENB_P_DPERR 0x0000010000000000ULL
+#define NPI_INT_ENB_WIN_RTO 0x0000008000000000ULL
+#define NPI_INT_ENB_SPR17 0x0000004000000000ULL
+#define NPI_INT_ENB_SPR16 0x0000002000000000ULL
+#define NPI_INT_ENB_SPR26 0x0000001000000000ULL
+#define NPI_INT_ENB_IO_PPERR 0x0000000800000000ULL
+#define NPI_INT_ENB_SPR15 0x0000000400000000ULL
+#define NPI_INT_ENB_SPR14 0x0000000200000000ULL
+#define NPI_INT_ENB_SPR25 0x0000000100000000ULL
+#define NPI_INT_ENB_P0_PTOUT 0x0000000080000000ULL
+#define NPI_INT_ENB_SPR13 0x0000000040000000ULL
+#define NPI_INT_ENB_SPR12 0x0000000020000000ULL
+#define NPI_INT_ENB_SPR24 0x0000000010000000ULL
+#define NPI_INT_ENB_P0_PPERR 0x0000000008000000ULL
+#define NPI_INT_ENB_SPR11 0x0000000004000000ULL
+#define NPI_INT_ENB_SPR10 0x0000000002000000ULL
+#define NPI_INT_ENB_SPR23 0x0000000001000000ULL
+#define NPI_INT_ENB_G0_RTOUT 0x0000000000800000ULL
+#define NPI_INT_ENB_SPR9 0x0000000000400000ULL
+#define NPI_INT_ENB_SPR8 0x0000000000200000ULL
+#define NPI_INT_ENB_SPR22 0x0000000000100000ULL
+#define NPI_INT_ENB_P0_PERR 0x0000000000080000ULL
+#define NPI_INT_ENB_SPR7 0x0000000000040000ULL
+#define NPI_INT_ENB_SPR6 0x0000000000020000ULL
+#define NPI_INT_ENB_SPR21 0x0000000000010000ULL
+#define NPI_INT_ENB_P0_RTOUT 0x0000000000008000ULL
+#define NPI_INT_ENB_SPR5 0x0000000000004000ULL
+#define NPI_INT_ENB_SPR4 0x0000000000002000ULL
+#define NPI_INT_ENB_SPR20 0x0000000000001000ULL
+#define NPI_INT_ENB_IO_OVERF 0x0000000000000800ULL
+#define NPI_INT_ENB_SPR3 0x0000000000000400ULL
+#define NPI_INT_ENB_SPR2 0x0000000000000200ULL
+#define NPI_INT_ENB_SPR19 0x0000000000000100ULL
+#define NPI_INT_ENB_IO_RTOUT 0x0000000000000080ULL
+#define NPI_INT_ENB_SPR1 0x0000000000000040ULL
+#define NPI_INT_ENB_SPR0 0x0000000000000020ULL
+#define NPI_INT_ENB_SPR18 0x0000000000000010ULL
+#define NPI_INT_ENB_PO0_2SML 0x0000000000000008ULL
+#define NPI_INT_ENB_PCI_RSL 0x0000000000000004ULL
+#define NPI_INT_ENB_RML_TWO 0x0000000000000002ULL
+#define NPI_INT_ENB_RML_RTO 0x0000000000000001ULL
+
+#define NPI_MEM_ACCESS_SUBIDX_XXX_63_38 0xffffffc000000000ULL
+#define NPI_MEM_ACCESS_SUBIDX_SHORT 0x0000002000000000ULL
+#define NPI_MEM_ACCESS_SUBIDX_NMERGE 0x0000001000000000ULL
+#define NPI_MEM_ACCESS_SUBIDX_ESR 0x0000000c00000000ULL
+#define NPI_MEM_ACCESS_SUBIDX_ESW 0x0000000300000000ULL
+#define NPI_MEM_ACCESS_SUBIDX_NSR 0x0000000080000000ULL
+#define NPI_MEM_ACCESS_SUBIDX_NSW 0x0000000040000000ULL
+#define NPI_MEM_ACCESS_SUBIDX_ROR 0x0000000020000000ULL
+#define NPI_MEM_ACCESS_SUBIDX_ROW 0x0000000010000000ULL
+#define NPI_MEM_ACCESS_SUBIDX_BA 0x000000000fffffffULL
+
+#define NPI_PCI_READ_CMD_XXX_63_11 0xfffffffffffff800ULL
+#define NPI_PCI_READ_CMD_CMD_SIZE 0x00000000000007ffULL
+
+#define NPI_NUM_DESC_OUTPUT0_XXX_63_32 0xffffffff00000000ULL
+#define NPI_NUM_DESC_OUTPUT0_SIZE 0x00000000ffffffffULL
+
+#define NPI_BASE_ADDR_INPUT0_BADDR 0xfffffffffffffff8ULL
+#define NPI_BASE_ADDR_INPUT0_XXX_2_0 0x0000000000000007ULL
+
+#define NPI_SIZE_INPUT0_XXX_63_32 0xffffffff00000000ULL
+#define NPI_SIZE_INPUT0_SIZE 0x00000000ffffffffULL
+
+#define PCI_READ_TIMEOUT_XXX_63_32 0xffffffff00000000ULL
+#define PCI_READ_TIMEOUT_ENB 0x0000000080000000ULL
+#define PCI_READ_TIMEOUT_CNT 0x000000007fffffffULL
+
+#define NPI_BASE_ADDR_OUTPUT0_BADDR 0xfffffffffffffff8ULL
+#define NPI_BASE_ADDR_OUTPUT0_XXX_2_0 0x0000000000000007ULL
+
+#define NPI_PCI_BURST_SIZE_XXX_63_14 0xffffffffffffc000ULL
+#define NPI_PCI_BURST_SIZE_WR_BRST 0x0000000000003f80ULL
+#define NPI_PCI_BURST_SIZE_RD_BRST 0x000000000000007fULL
+
+#define NPI_BUFF_SIZE_OUTPUT0_XXX_63_23 0xffffffffff800000ULL
+#define NPI_BUFF_SIZE_OUTPUT0_ISIZE 0x00000000007f0000ULL
+#define NPI_BUFF_SIZE_OUTPUT0_BSIZE 0x000000000000ffffULL
+
+#define NPI_OUTPUT_CONTROL_XXX_63_48 0xffff000000000000ULL
+#define NPI_OUTPUT_CONTROL_SPR5 0x0000e00000000000ULL
+#define NPI_OUTPUT_CONTROL_P0_BMODE 0x0000100000000000ULL
+#define NPI_OUTPUT_CONTROL_SPR4 0x00000fff00000000ULL
+#define NPI_OUTPUT_CONTROL_O0_ES 0x00000000c0000000ULL
+#define NPI_OUTPUT_CONTROL_O0_NS 0x0000000020000000ULL
+#define NPI_OUTPUT_CONTROL_O0_RO 0x0000000010000000ULL
+#define NPI_OUTPUT_CONTROL_SPR3 0x000000000e000000ULL
+#define NPI_OUTPUT_CONTROL_O0_CSRM 0x0000000001000000ULL
+#define NPI_OUTPUT_CONTROL_SPR2 0x0000000000f00000ULL
+#define NPI_OUTPUT_CONTROL_SPR1 0x00000000000e0000ULL
+#define NPI_OUTPUT_CONTROL_IPTR_O0 0x0000000000010000ULL
+#define NPI_OUTPUT_CONTROL_SPR0 0x000000000000fff0ULL
+#define NPI_OUTPUT_CONTROL_ESR_SL0 0x000000000000000cULL
+#define NPI_OUTPUT_CONTROL_NSR_SL0 0x0000000000000002ULL
+#define NPI_OUTPUT_CONTROL_ROR_SL0 0x0000000000000001ULL
+
+#define NPI_LOWP_IBUFF_SADDR_XXX_63_36 0xfffffff000000000ULL
+#define NPI_LOWP_IBUFF_SADDR_SADDR 0x0000000fffffffffULL
+
+#define NPI_HIGHP_IBUFF_SADDR_XXX_63_36 0xfffffff000000000ULL
+#define NPI_HIGHP_IBUFF_SADDR_SADDR 0x0000000fffffffffULL
+
+#define NPI_LOWP_DBELL_XXX_63_16 0xffffffffffff0000ULL
+#define NPI_LOWP_DBELL_DBELL 0x000000000000ffffULL
+
+#define NPI_HIGHP_DBELL_XXX_63_16 0xffffffffffff0000ULL
+#define NPI_HIGHP_DBELL_DBELL 0x000000000000ffffULL
+
+#define NPI_DMA_CONTROL_XXX_63_36 0xfffffff000000000ULL
+#define NPI_DMA_CONTROL_B0_LEND 0x0000000800000000ULL
+#define NPI_DMA_CONTROL_DWB_DENB 0x0000000400000000ULL
+#define NPI_DMA_CONTROL_DWB_ICHK 0x00000003fe000000ULL
+#define NPI_DMA_CONTROL_FPA_QUE 0x0000000001c00000ULL
+#define NPI_DMA_CONTROL_O_ADD1 0x0000000000200000ULL
+#define NPI_DMA_CONTROL_O_RO 0x0000000000100000ULL
+#define NPI_DMA_CONTROL_O_NS 0x0000000000080000ULL
+#define NPI_DMA_CONTROL_O_ES 0x0000000000060000ULL
+#define NPI_DMA_CONTROL_O_MODE 0x0000000000010000ULL
+#define NPI_DMA_CONTROL_HP_ENB 0x0000000000008000ULL
+#define NPI_DMA_CONTROL_LP_ENB 0x0000000000004000ULL
+#define NPI_DMA_CONTROL_CSIZE 0x0000000000003fffULL
+
+#define NPI_PCI_INT_ARB_CFG_XXX_63_5 0xffffffffffffffe0ULL
+#define NPI_PCI_INT_ARB_CFG_EN 0x0000000000000010ULL
+#define NPI_PCI_INT_ARB_CFG_PARK_MOD 0x0000000000000008ULL
+#define NPI_PCI_INT_ARB_CFG_PARK_DEV 0x0000000000000007ULL
+
+#define NPI_INPUT_CONTROL_XXX_63_22 0xffffffffffc00000ULL
+#define NPI_INPUT_CONTROL_PBP_DHI 0x00000000003ffe00ULL
+#define NPI_INPUT_CONTROL_D_NSR 0x0000000000000100ULL
+#define NPI_INPUT_CONTROL_D_ESR 0x00000000000000c0ULL
+#define NPI_INPUT_CONTROL_D_ROR 0x0000000000000020ULL
+#define NPI_INPUT_CONTROL_USE_CSR 0x0000000000000010ULL
+#define NPI_INPUT_CONTROL_NSR 0x0000000000000008ULL
+#define NPI_INPUT_CONTROL_ESR 0x0000000000000006ULL
+#define NPI_INPUT_CONTROL_ROR 0x0000000000000001ULL
+
+#define NPI_DMA_LOWP_COUNTS_XXX_63_39 0xffffff8000000000ULL
+#define NPI_DMA_LOWP_COUNTS_FCNT 0x0000007f00000000ULL
+#define NPI_DMA_LOWP_COUNTS_DBELL 0x00000000ffffffffULL
+
+#define NPI_DMA_HIGHP_COUNTS_XXX_63_39 0xffffff8000000000ULL
+#define NPI_DMA_HIGHP_COUNTS_FCNT 0x0000007f00000000ULL
+#define NPI_DMA_HIGHP_COUNTS_DBELL 0x00000000ffffffffULL
+
+#define NPI_DMA_LOWP_NADDR_XXX_63_40 0xffffff0000000000ULL
+#define NPI_DMA_LOWP_NADDR_STATE 0x000000f000000000ULL
+#define NPI_DMA_LOWP_NADDR_ADDR 0x0000000fffffffffULL
+
+#define NPI_DMA_HIGHP_NADDR_XXX_63_40 0xffffff0000000000ULL
+#define NPI_DMA_HIGHP_NADDR_STATE 0x000000f000000000ULL
+#define NPI_DMA_HIGHP_NADDR_ADDR 0x0000000fffffffffULL
+
+#define NPI_P0_PAIR_CNTS_XXX_63_37 0xffffffe000000000ULL
+#define NPI_P0_PAIR_CNTS_FCNT 0xffffffff00000000ULL
+#define NPI_P0_PAIR_CNTS_AVAIL 0x00000000c0000000ULL
+
+#define NPI_P0_DBPAIR_ADDR_XXX_63 0x8000000000000000ULL
+#define NPI_P0_DBPAIR_ADDR_STATE 0x6000000000000000ULL
+#define NPI_P0_DBPAIR_ADDR_NADDR 0x1fffffffffffffffULL
+
+#define NPI_P0_INSTR_CNTS_XXX_63_38 0xffffffc000000000ULL
+#define NPI_P0_INSTR_CNTS_FCNT 0x0000003f00000000ULL
+#define NPI_P0_INSTR_CNTS_AVAIL 0x00000000ffffffffULL
+
+#define NPI_P0_INSTR_ADDR_STATE 0xe000000000000000ULL
+#define NPI_P0_INSTR_ADDR_NADDR 0x1fffffffffffffffULL
+
+#define NPI_WIN_READ_TO_XXX_63_32 0xffffffff00000000ULL
+#define NPI_WIN_READ_TO_TIME 0x00000000ffffffffULL
+
+#define DBG_DATA_XXX_63_31 0xffffffff80000000ULL
+#define DBG_DATA_PLL_MUL 0x0000000070000000ULL
+#define DBG_DATA_XXX_27_23 0x000000000f800000ULL
+#define DBG_DATA_C_MUL 0x00000000007c0000ULL
+#define DBG_DATA_DSEL_EXT 0x0000000000020000ULL
+#define DBG_DATA_DATA 0x000000000001ffffULL
+
+#define NPI_PORT_BP_CONTROL_XXX_63_5 0xffffffffffffffe0ULL
+#define NPI_PORT_BP_CONTROL_BP_ON 0x0000000000000010ULL
+#define NPI_PORT_BP_CONTROL_ENB 0x000000000000000fULL
+
+#define NPI_PORT32_INSTR_HDR_XXX_63_44 0xfffff00000000000ULL
+#define NPI_PORT32_INSTR_HDR_PBP 0x0000080000000000ULL
+#define NPI_PORT32_INSTR_HDR_XXX_42_38 0x000007c000000000ULL
+#define NPI_PORT32_INSTR_HDR_RPARMODE 0x0000003000000000ULL
+#define NPI_PORT32_INSTR_HDR_XXX_35 0x0000000800000000ULL
+#define NPI_PORT32_INSTR_HDR_RSKP_LEN 0x00000007f0000000ULL
+#define NPI_PORT32_INSTR_HDR_XXX_27_22 0x000000000fc00000ULL
+#define NPI_PORT32_INSTR_HDR_USE_IHDR 0x0000000000200000ULL
+#define NPI_PORT32_INSTR_HDR_XXX_20_16 0x00000000001f0000ULL
+#define NPI_PORT32_INSTR_HDR_PAR_MODE 0x000000000000c000ULL
+#define NPI_PORT32_INSTR_HDR_XXX_13 0x0000000000002000ULL
+#define NPI_PORT32_INSTR_HDR_SKP_LEN 0x0000000000001fc0ULL
+#define NPI_PORT32_INSTR_HDR_XXX_5_0 0x000000000000003fULL
+
+#define NPI_BIST_STATUS_XXX_63_20 0xfffffffffff00000ULL
+#define NPI_BIST_STATUS_CSR_BS 0x0000000000080000ULL
+#define NPI_BIST_STATUS_DIF_BS 0x0000000000040000ULL
+#define NPI_BIST_STATUS_RDP_BS 0x0000000000020000ULL
+#define NPI_BIST_STATUS_PCNC_BS 0x0000000000010000ULL
+#define NPI_BIST_STATUS_PCN_BS 0x0000000000008000ULL
+#define NPI_BIST_STATUS_RDN_BS 0x0000000000004000ULL
+#define NPI_BIST_STATUS_PCAC_BS 0x0000000000002000ULL
+#define NPI_BIST_STATUS_PCAD_BS 0x0000000000001000ULL
+#define NPI_BIST_STATUS_RDNL_BS 0x0000000000000800ULL
+#define NPI_BIST_STATUS_PGF_BS 0x0000000000000400ULL
+#define NPI_BIST_STATUS_PIG_BS 0x0000000000000200ULL
+#define NPI_BIST_STATUS_POF0_BS 0x0000000000000100ULL
+#define NPI_BIST_STATUS_POF1_BS 0x0000000000000080ULL
+#define NPI_BIST_STATUS_POF2_BS 0x0000000000000040ULL
+#define NPI_BIST_STATUS_POF3_BS 0x0000000000000020ULL
+#define NPI_BIST_STATUS_POS_BS 0x0000000000000010ULL
+#define NPI_BIST_STATUS_NUS_BS 0x0000000000000008ULL
+#define NPI_BIST_STATUS_DOB_BS 0x0000000000000004ULL
+#define NPI_BIST_STATUS_PDF_BS 0x0000000000000002ULL
+#define NPI_BIST_STATUS_DPI_BS 0x0000000000000001ULL
+
+#endif /* _CN30XXNPIREG_H_ */
diff --git a/sys/arch/octeon/dev/cn30xxpip.c b/sys/arch/octeon/dev/cn30xxpip.c
new file mode 100644
index 00000000000..1749f612e4d
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxpip.c
@@ -0,0 +1,391 @@
+/* $OpenBSD: cn30xxpip.c,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/socket.h>
+#include <sys/syslog.h>
+#include <sys/time.h>
+#include <net/if.h>
+
+#include <machine/octeonvar.h>
+
+#include <octeon/dev/cn30xxpipreg.h>
+#include <octeon/dev/cn30xxpipvar.h>
+
+#ifndef SET
+#define SET(t, f) ((t) |= (f))
+#define ISSET(t, f) ((t) & (f))
+#define CLR(t, f) ((t) &= ~(f))
+#endif
+
+#ifdef OCTEON_ETH_DEBUG
+struct cn30xxpip_softc *__cn30xxpip_softc;
+
+void cn30xxpip_intr_evcnt_attach(struct cn30xxpip_softc *);
+void cn30xxpip_intr_rml(void *);
+
+void cn30xxpip_dump(void);
+void cn30xxpip_int_enable(struct cn30xxpip_softc *, int);
+#endif
+
+/*
+ * register definitions (for debug and statics)
+ */
+#define _ENTRY(x) { #x, x##_BITS, x##_OFFSET }
+#define _ENTRY_0_3(x) \
+ _ENTRY(x## 0), _ENTRY(x## 1), _ENTRY(x## 2), _ENTRY(x## 3)
+#define _ENTRY_0_7(x) \
+ _ENTRY(x## 0), _ENTRY(x## 1), _ENTRY(x## 2), _ENTRY(x## 3), \
+ _ENTRY(x## 4), _ENTRY(x## 5), _ENTRY(x## 6), _ENTRY(x## 7)
+#define _ENTRY_0_1_2_32(x) \
+ _ENTRY(x## 0), _ENTRY(x## 1), _ENTRY(x## 2), _ENTRY(x##32)
+
+struct cn30xxpip_dump_reg_ {
+ const char *name;
+ const char *format;
+ size_t offset;
+};
+
+static const struct cn30xxpip_dump_reg_ cn30xxpip_dump_stats_[] = {
+/* PIP_QOS_DIFF[0-63] */
+ _ENTRY_0_1_2_32 (PIP_STAT0_PRT),
+ _ENTRY_0_1_2_32 (PIP_STAT1_PRT),
+ _ENTRY_0_1_2_32 (PIP_STAT2_PRT),
+ _ENTRY_0_1_2_32 (PIP_STAT3_PRT),
+ _ENTRY_0_1_2_32 (PIP_STAT4_PRT),
+ _ENTRY_0_1_2_32 (PIP_STAT5_PRT),
+ _ENTRY_0_1_2_32 (PIP_STAT6_PRT),
+ _ENTRY_0_1_2_32 (PIP_STAT7_PRT),
+ _ENTRY_0_1_2_32 (PIP_STAT8_PRT),
+ _ENTRY_0_1_2_32 (PIP_STAT9_PRT),
+/* PIP_TAG_INC[0-63] */
+ _ENTRY_0_1_2_32 (PIP_STAT_INB_PKTS),
+ _ENTRY_0_1_2_32 (PIP_STAT_INB_OCTS),
+ _ENTRY_0_1_2_32 (PIP_STAT_INB_ERRS),
+};
+
+static const struct cn30xxpip_dump_reg_ cn30xxpip_dump_regs_[] = {
+ _ENTRY (PIP_BIST_STATUS),
+ _ENTRY (PIP_INT_REG),
+ _ENTRY (PIP_INT_EN),
+ _ENTRY (PIP_STAT_CTL),
+ _ENTRY (PIP_GBL_CTL),
+ _ENTRY (PIP_GBL_CFG),
+ _ENTRY (PIP_SOFT_RST),
+ _ENTRY (PIP_IP_OFFSET),
+ _ENTRY (PIP_TAG_SECRET),
+ _ENTRY (PIP_TAG_MASK),
+ _ENTRY_0_3 (PIP_DEC_IPSEC),
+ _ENTRY (PIP_RAW_WORD),
+ _ENTRY_0_7 (PIP_QOS_VLAN),
+ _ENTRY_0_3 (PIP_QOS_WATCH),
+ _ENTRY_0_1_2_32 (PIP_PRT_CFG),
+ _ENTRY_0_1_2_32 (PIP_PRT_TAG),
+};
+#undef _ENTRY
+#undef _ENTRY_0_3
+#undef _ENTRY_0_7
+#undef _ENTRY_0_1_2_32
+
+/* XXX */
+void
+cn30xxpip_init(struct cn30xxpip_attach_args *aa,
+ struct cn30xxpip_softc **rsc)
+{
+ struct cn30xxpip_softc *sc;
+ int status;
+
+ sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
+ if (sc == NULL)
+ panic("can't allocate memory: %s", __func__);
+
+ sc->sc_port = aa->aa_port;
+ sc->sc_regt = aa->aa_regt;
+ sc->sc_tag_type = aa->aa_tag_type;
+ sc->sc_receive_group = aa->aa_receive_group;
+ sc->sc_ip_offset = aa->aa_ip_offset;
+
+ status = bus_space_map(sc->sc_regt, PIP_BASE, PIP_SIZE, 0,
+ &sc->sc_regh);
+ if (status != 0)
+ panic("can't map %s space", "pip register");
+
+ *rsc = sc;
+
+#ifdef OCTEON_ETH_DEBUG
+ cn30xxpip_int_enable(sc, 1);
+ cn30xxpip_intr_evcnt_attach(sc);
+ __cn30xxpip_softc = sc;
+ printf("PIP Code initialized.\n");
+#endif
+}
+
+#define _PIP_RD8(sc, off) \
+ bus_space_read_8((sc)->sc_regt, (sc)->sc_regh, (off))
+#define _PIP_WR8(sc, off, v) \
+ bus_space_write_8((sc)->sc_regt, (sc)->sc_regh, (off), (v))
+
+int
+cn30xxpip_port_config(struct cn30xxpip_softc *sc)
+{
+ uint64_t prt_cfg;
+ uint64_t prt_tag;
+ uint64_t ip_offset;
+
+ /*
+ * Process the headers and place the IP header in the work queue
+ */
+ prt_cfg = 0;
+ /* RAWDRP=0; don't allow raw packet drop */
+ /* TAGINC=0 */
+ SET(prt_cfg, PIP_PRT_CFGN_DYN_RS);
+ /* INST_HDR=0 */
+ /* GRP_WAT=0 */
+ SET(prt_cfg, (sc->sc_port << 24) & PIP_PRT_CFGN_QOS);
+ /* QOS_WAT=0 */
+ /* SPARE=0 */
+ /* QOS_DIFF=0 */
+ /* QOS_VLAN=0 */
+ SET(prt_cfg, PIP_PRT_CFGN_CRC_EN);
+ SET(prt_cfg, (PIP_PORT_CFG_MODE_L2) & PIP_PRT_CFGN_MODE);
+ /* SKIP=0 */
+
+ prt_tag = 0;
+ SET(prt_tag, PIP_PRT_TAGN_INC_PRT);
+ CLR(prt_tag, PIP_PRT_TAGN_IP6_DPRT);
+ CLR(prt_tag, PIP_PRT_TAGN_IP4_DPRT);
+ CLR(prt_tag, PIP_PRT_TAGN_IP6_SPRT);
+ CLR(prt_tag, PIP_PRT_TAGN_IP4_SPRT);
+ CLR(prt_tag, PIP_PRT_TAGN_IP6_NXTH);
+ CLR(prt_tag, PIP_PRT_TAGN_IP4_PCTL);
+ CLR(prt_tag, PIP_PRT_TAGN_IP6_DST);
+ CLR(prt_tag, PIP_PRT_TAGN_IP4_SRC);
+ CLR(prt_tag, PIP_PRT_TAGN_IP6_SRC);
+ CLR(prt_tag, PIP_PRT_TAGN_IP4_DST);
+ SET(prt_tag, PIP_PRT_TAGN_TCP6_TAG_ORDERED);
+ SET(prt_tag, PIP_PRT_TAGN_TCP4_TAG_ORDERED);
+ SET(prt_tag, PIP_PRT_TAGN_IP6_TAG_ORDERED);
+ SET(prt_tag, PIP_PRT_TAGN_IP4_TAG_ORDERED);
+ SET(prt_tag, PIP_PRT_TAGN_NON_TAG_ORDERED);
+ SET(prt_tag, sc->sc_receive_group & PIP_PRT_TAGN_GRP);
+
+ ip_offset = 0;
+ SET(ip_offset, (sc->sc_ip_offset / 8) & PIP_IP_OFFSET_MASK_OFFSET);
+
+ _PIP_WR8(sc, PIP_PRT_CFG0_OFFSET + (8 * sc->sc_port), prt_cfg);
+ _PIP_WR8(sc, PIP_PRT_TAG0_OFFSET + (8 * sc->sc_port), prt_tag);
+ _PIP_WR8(sc, PIP_IP_OFFSET_OFFSET, ip_offset);
+
+ return 0;
+}
+
+void
+cn30xxpip_prt_cfg_enable(struct cn30xxpip_softc *sc, uint64_t prt_cfg,
+ int enable)
+{
+ uint64_t tmp;
+
+ tmp = _PIP_RD8(sc, PIP_PRT_CFG0_OFFSET + (8 * sc->sc_port));
+ if (enable)
+ tmp |= prt_cfg;
+ else
+ tmp &= ~prt_cfg;
+ _PIP_WR8(sc, PIP_PRT_CFG0_OFFSET + (8 * sc->sc_port), tmp);
+}
+
+void
+cn30xxpip_stats(struct cn30xxpip_softc *sc, struct ifnet *ifp, int gmx_port)
+{
+ const struct cn30xxpip_dump_reg_ *reg;
+ uint64_t tmp, pkts, octs;
+ uint64_t pip_stat_ctl;
+
+ if (sc == NULL || ifp == NULL)
+ panic("%s: invalid argument. sc=%p, ifp=%p\n", __func__,
+ sc, ifp);
+
+ if (gmx_port < 0 || gmx_port > 2) {
+ printf("%s: invalid gmx_port %d\n", __func__, gmx_port);
+ return;
+ }
+
+ pip_stat_ctl = _PIP_RD8(sc, PIP_STAT_CTL_OFFSET);
+ _PIP_WR8(sc, PIP_STAT_CTL_OFFSET, pip_stat_ctl | PIP_STAT_CTL_RDCLR);
+ reg = &cn30xxpip_dump_stats_[gmx_port];
+ tmp = _PIP_RD8(sc, reg->offset);
+ octs = (tmp & 0x00000000ffffffffULL); /* XXX: no counter in ifp?? */
+ pkts = (tmp & 0xffffffff00000000ULL) >> 32;
+ ifp->if_iqdrops += pkts;
+
+ _PIP_WR8(sc, PIP_STAT_CTL_OFFSET, pip_stat_ctl);
+}
+
+
+#ifdef OCTEON_ETH_DEBUG
+int cn30xxpip_intr_rml_verbose;
+struct evcnt cn30xxpip_intr_evcnt;
+
+static const struct octeon_evcnt_entry cn30xxpip_intr_evcnt_entries[] = {
+#define _ENTRY(name, type, parent, descr) \
+ OCTEON_EVCNT_ENTRY(struct cn30xxpip_softc, name, type, parent, descr)
+ _ENTRY(pipbeperr, MISC, NULL, "pip parity error backend"),
+ _ENTRY(pipfeperr, MISC, NULL, "pip parity error frontend"),
+ _ENTRY(pipskprunt, MISC, NULL, "pip skiper"),
+ _ENTRY(pipbadtag, MISC, NULL, "pip bad tag"),
+ _ENTRY(pipprtnxa, MISC, NULL, "pip nonexistent port"),
+ _ENTRY(pippktdrp, MISC, NULL, "pip qos drop"),
+#undef _ENTRY
+};
+
+void
+cn30xxpip_intr_evcnt_attach(struct cn30xxpip_softc *sc)
+{
+ OCTEON_EVCNT_ATTACH_EVCNTS(sc, cn30xxpip_intr_evcnt_entries, "pip0");
+}
+
+void
+cn30xxpip_intr_rml(void *arg)
+{
+ struct cn30xxpip_softc *sc;
+ uint64_t reg;
+
+ cn30xxpip_intr_evcnt.ev_count++;
+ sc = __cn30xxpip_softc;
+ KASSERT(sc != NULL);
+ reg = cn30xxpip_int_summary(sc);
+ if (cn30xxpip_intr_rml_verbose)
+ printf("%s: PIP_INT_REG=0x%016llx\n", __func__, reg);
+ if (reg & PIP_INT_REG_BEPERR)
+ OCTEON_EVCNT_INC(sc, pipbeperr);
+ if (reg & PIP_INT_REG_FEPERR)
+ OCTEON_EVCNT_INC(sc, pipfeperr);
+ if (reg & PIP_INT_REG_SKPRUNT)
+ OCTEON_EVCNT_INC(sc, pipskprunt);
+ if (reg & PIP_INT_REG_BADTAG)
+ OCTEON_EVCNT_INC(sc, pipbadtag);
+ if (reg & PIP_INT_REG_PRTNXA)
+ OCTEON_EVCNT_INC(sc, pipprtnxa);
+ if (reg & PIP_INT_REG_PKTDRP)
+ OCTEON_EVCNT_INC(sc, pippktdrp);
+}
+
+void cn30xxpip_dump_regs(void);
+void cn30xxpip_dump_stats(void);
+
+void
+cn30xxpip_dump(void)
+{
+ cn30xxpip_dump_regs();
+ cn30xxpip_dump_stats();
+}
+
+void
+cn30xxpip_dump_regs(void)
+{
+ struct cn30xxpip_softc *sc = __cn30xxpip_softc;
+ const struct cn30xxpip_dump_reg_ *reg;
+ uint64_t tmp;
+ char buf[512];
+ int i;
+
+ for (i = 0; i < (int)nitems(cn30xxpip_dump_regs_); i++) {
+ reg = &cn30xxpip_dump_regs_[i];
+ tmp = _PIP_RD8(sc, reg->offset);
+ snprintf(buf, sizeof(buf), "%16llx", tmp);
+ printf("\t%-24s: %s\n", reg->name, buf);
+ }
+}
+
+void
+cn30xxpip_dump_stats(void)
+{
+ struct cn30xxpip_softc *sc = __cn30xxpip_softc;
+ const struct cn30xxpip_dump_reg_ *reg;
+ uint64_t tmp;
+ char buf[512];
+ int i;
+ uint64_t pip_stat_ctl;
+
+ pip_stat_ctl = _PIP_RD8(sc, PIP_STAT_CTL_OFFSET);
+ _PIP_WR8(sc, PIP_STAT_CTL_OFFSET, pip_stat_ctl & ~PIP_STAT_CTL_RDCLR);
+ for (i = 0; i < (int)nitems(cn30xxpip_dump_stats_); i++) {
+ reg = &cn30xxpip_dump_stats_[i];
+ tmp = _PIP_RD8(sc, reg->offset);
+ if (reg->format == NULL) {
+ snprintf(buf, sizeof(buf), "%16llx", tmp);
+ }
+ printf("\t%-24s: %s\n", reg->name, buf);
+ }
+ printf("\t%-24s:\n", "PIP_QOS_DIFF[0-63]");
+ for (i = 0; i < 64; i++) {
+ tmp = _PIP_RD8(sc, PIP_QOS_DIFF0_OFFSET + sizeof(uint64_t) * i);
+ snprintf(buf, sizeof(buf), "%16" PRIx64, tmp);
+ printf("%s\t%s%s",
+ ((i % 4) == 0) ? "\t" : "",
+ buf,
+ ((i % 4) == 3) ? "\n" : "");
+ }
+ printf("\t%-24s:\n", "PIP_TAG_INC[0-63]");
+ for (i = 0; i < 64; i++) {
+ tmp = _PIP_RD8(sc, PIP_TAG_INC0_OFFSET + sizeof(uint64_t) * i);
+ snprintf(buf, sizeof(buf), "%16" PRIx64, tmp);
+ printf("%s\t%s%s",
+ ((i % 4) == 0) ? "\t" : "",
+ buf,
+ ((i % 4) == 3) ? "\n" : "");
+ }
+ _PIP_WR8(sc, PIP_STAT_CTL_OFFSET, pip_stat_ctl);
+}
+
+void
+cn30xxpip_int_enable(struct cn30xxpip_softc *sc, int enable)
+{
+ uint64_t pip_int_xxx = 0;
+
+ SET(pip_int_xxx,
+ PIP_INT_EN_BEPERR |
+ PIP_INT_EN_FEPERR |
+ PIP_INT_EN_SKPRUNT |
+ PIP_INT_EN_BADTAG |
+ PIP_INT_EN_PRTNXA |
+ PIP_INT_EN_PKTDRP);
+ _PIP_WR8(sc, PIP_INT_REG_OFFSET, pip_int_xxx);
+ _PIP_WR8(sc, PIP_INT_EN_OFFSET, enable ? pip_int_xxx : 0);
+}
+uint64_t
+cn30xxpip_int_summary(struct cn30xxpip_softc *sc)
+{
+ uint64_t summary;
+
+ summary = _PIP_RD8(sc, PIP_INT_REG_OFFSET);
+ _PIP_WR8(sc, PIP_INT_REG_OFFSET, summary);
+ return summary;
+}
+#endif /* OCTEON_ETH_DEBUG */
diff --git a/sys/arch/octeon/dev/cn30xxpipreg.h b/sys/arch/octeon/dev/cn30xxpipreg.h
new file mode 100644
index 00000000000..9b6964c5998
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxpipreg.h
@@ -0,0 +1,987 @@
+/*
+ * THIS FILE IS AUTOMATICALLY GENERATED
+ * DONT EDIT THIS FILE
+ */
+
+/* $OpenBSD: cn30xxpipreg.h,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Cavium Networks OCTEON CN30XX Hardware Reference Manual
+ * CN30XX-HM-1.0
+ * 7.8 PIP Registers
+ */
+
+#ifndef _CN30XXPIPREG_H_
+#define _CN30XXPIPREG_H_
+
+#define PIP_BIST_STATUS 0x00011800a0000000ULL
+#define PIP_INT_REG 0x00011800a0000008ULL
+#define PIP_INT_EN 0x00011800a0000010ULL
+#define PIP_STAT_CTL 0x00011800a0000018ULL
+#define PIP_GBL_CTL 0x00011800a0000020ULL
+#define PIP_GBL_CFG 0x00011800a0000028ULL
+#define PIP_SOFT_RST 0x00011800a0000030ULL
+#define PIP_IP_OFFSET 0x00011800a0000060ULL
+#define PIP_TAG_SECRET 0x00011800a0000068ULL
+#define PIP_TAG_MASK 0x00011800a0000070ULL
+#define PIP_DEC_IPSEC0 0x00011800a0000080ULL
+#define PIP_DEC_IPSEC1 0x00011800a0000088ULL
+#define PIP_DEC_IPSEC2 0x00011800a0000090ULL
+#define PIP_DEC_IPSEC3 0x00011800a0000098ULL
+#define PIP_RAW_WORD 0x00011800a00000b0ULL
+#define PIP_QOS_VLAN0 0x00011800a00000c0ULL
+#define PIP_QOS_VLAN1 0x00011800a00000c8ULL
+#define PIP_QOS_VLAN2 0x00011800a00000d0ULL
+#define PIP_QOS_VLAN3 0x00011800a00000d8ULL
+#define PIP_QOS_VLAN4 0x00011800a00000e0ULL
+#define PIP_QOS_VLAN5 0x00011800a00000e8ULL
+#define PIP_QOS_VLAN6 0x00011800a00000f0ULL
+#define PIP_QOS_VLAN7 0x00011800a00000f8ULL
+#define PIP_QOS_WATCH0 0x00011800a0000100ULL
+#define PIP_QOS_WATCH1 0x00011800a0000108ULL
+#define PIP_QOS_WATCH2 0x00011800a0000110ULL
+#define PIP_QOS_WATCH3 0x00011800a0000118ULL
+#define PIP_PRT_CFG0 0x00011800a0000200ULL
+#define PIP_PRT_CFG1 0x00011800a0000208ULL
+#define PIP_PRT_CFG2 0x00011800a0000210ULL
+#define PIP_PRT_CFG32 0x00011800a0000300ULL
+#define PIP_PRT_TAG0 0x00011800a0000400ULL
+#define PIP_PRT_TAG1 0x00011800a0000408ULL
+#define PIP_PRT_TAG2 0x00011800a0000410ULL
+#define PIP_PRT_TAG32 0x00011800a0000500ULL
+#define PIP_QOS_DIFF0 0x00011800a0000600ULL
+/* PIP_QOS_DIFF[1-63] */
+/* PIP_STAT[0-9]_PRT{0,1,2,32} */
+#define PIP_STAT0_PRT0 0x00011800a0000800ULL
+#define PIP_STAT0_PRT1 0x00011800a0000850ULL
+#define PIP_STAT0_PRT2 0x00011800a00008a0ULL
+#define PIP_STAT0_PRT32 0x00011800a0001200ULL
+#define PIP_TAG_INC0 0x00011800a0001800ULL
+/* PIP_TAG_INC[1-63] */
+#define PIP_STAT_INB_PKTS0 0x00011800a0001a00ULL
+#define PIP_STAT_INB_PKTS1 0x00011800a0001a20ULL
+#define PIP_STAT_INB_PKTS2 0x00011800a0001a40ULL
+#define PIP_STAT_INB_PKTS32 0x00011800a0001e00ULL
+#define PIP_STAT_INB_OCTS0 0x00011800a0001a08ULL
+#define PIP_STAT_INB_OCTS1 0x00011800a0001a28ULL
+#define PIP_STAT_INB_OCTS2 0x00011800a0001a48ULL
+#define PIP_STAT_INB_OCTS32 0x00011800a0001e08ULL
+#define PIP_STAT_INB_ERRS0 0x00011800a0001a10ULL
+#define PIP_STAT_INB_ERRS1 0x00011800a0001a30ULL
+#define PIP_STAT_INB_ERRS2 0x00011800a0001a50ULL
+#define PIP_STAT_INB_ERRS32 0x00011800a0001e10ULL
+
+#define PIP_BASE 0x00011800a0000000ULL
+#define PIP_SIZE 0x1e50ULL
+
+#define PIP_BIST_STATUS_OFFSET 0x0ULL
+#define PIP_INT_REG_OFFSET 0x8ULL
+#define PIP_INT_EN_OFFSET 0x10ULL
+#define PIP_STAT_CTL_OFFSET 0x18ULL
+#define PIP_GBL_CTL_OFFSET 0x20ULL
+#define PIP_GBL_CFG_OFFSET 0x28ULL
+#define PIP_SOFT_RST_OFFSET 0x30ULL
+#define PIP_IP_OFFSET_OFFSET 0x60ULL
+#define PIP_TAG_SECRET_OFFSET 0x68ULL
+#define PIP_TAG_MASK_OFFSET 0x70ULL
+#define PIP_DEC_IPSEC0_OFFSET 0x80ULL
+#define PIP_DEC_IPSEC1_OFFSET 0x88ULL
+#define PIP_DEC_IPSEC2_OFFSET 0x90ULL
+#define PIP_DEC_IPSEC3_OFFSET 0x98ULL
+#define PIP_RAW_WORD_OFFSET 0xb0ULL
+#define PIP_QOS_VLAN0_OFFSET 0xc0ULL
+#define PIP_QOS_VLAN1_OFFSET 0xc8ULL
+#define PIP_QOS_VLAN2_OFFSET 0xd0ULL
+#define PIP_QOS_VLAN3_OFFSET 0xd8ULL
+#define PIP_QOS_VLAN4_OFFSET 0xe0ULL
+#define PIP_QOS_VLAN5_OFFSET 0xe8ULL
+#define PIP_QOS_VLAN6_OFFSET 0xf0ULL
+#define PIP_QOS_VLAN7_OFFSET 0xf8ULL
+#define PIP_QOS_WATCH0_OFFSET 0x100ULL
+#define PIP_QOS_WATCH1_OFFSET 0x108ULL
+#define PIP_QOS_WATCH2_OFFSET 0x110ULL
+#define PIP_QOS_WATCH3_OFFSET 0x118ULL
+#define PIP_PRT_CFG0_OFFSET 0x200ULL
+#define PIP_PRT_CFG1_OFFSET 0x208ULL
+#define PIP_PRT_CFG2_OFFSET 0x210ULL
+#define PIP_PRT_CFG32_OFFSET 0x300ULL
+#define PIP_PRT_TAG0_OFFSET 0x400ULL
+#define PIP_PRT_TAG1_OFFSET 0x408ULL
+#define PIP_PRT_TAG2_OFFSET 0x410ULL
+#define PIP_PRT_TAG32_OFFSET 0x500ULL
+#define PIP_QOS_DIFF0_OFFSET 0x600ULL
+/* PIP_QOS_DIFF[1-63] */
+#define PIP_STAT0_PRT0_OFFSET 0x800ULL
+#define PIP_STAT0_PRT1_OFFSET 0x850ULL
+#define PIP_STAT0_PRT2_OFFSET 0x8a0ULL
+#define PIP_STAT0_PRT32_OFFSET 0x1200ULL
+#define PIP_STAT0_PRT33_OFFSET 0x1250ULL
+#define PIP_STAT1_PRT0_OFFSET 0x800ULL
+#define PIP_STAT1_PRT1_OFFSET 0x850ULL
+#define PIP_STAT1_PRT2_OFFSET 0x8a0ULL
+#define PIP_STAT1_PRT32_OFFSET 0x1200ULL
+#define PIP_STAT1_PRT33_OFFSET 0x1250ULL
+#define PIP_STAT2_PRT0_OFFSET 0x810ULL
+#define PIP_STAT2_PRT1_OFFSET 0x860ULL
+#define PIP_STAT2_PRT2_OFFSET 0x8b0ULL
+#define PIP_STAT2_PRT32_OFFSET 0x1210ULL
+#define PIP_STAT2_PRT33_OFFSET 0x1260ULL
+#define PIP_STAT3_PRT0_OFFSET 0x818ULL
+#define PIP_STAT3_PRT1_OFFSET 0x868ULL
+#define PIP_STAT3_PRT2_OFFSET 0x8b8ULL
+#define PIP_STAT3_PRT32_OFFSET 0x1218ULL
+#define PIP_STAT3_PRT33_OFFSET 0x1268ULL
+#define PIP_STAT4_PRT0_OFFSET 0x820ULL
+#define PIP_STAT4_PRT1_OFFSET 0x870ULL
+#define PIP_STAT4_PRT2_OFFSET 0x8c0ULL
+#define PIP_STAT4_PRT32_OFFSET 0x1220ULL
+#define PIP_STAT4_PRT33_OFFSET 0x1270ULL
+#define PIP_STAT5_PRT0_OFFSET 0x828ULL
+#define PIP_STAT5_PRT1_OFFSET 0x878ULL
+#define PIP_STAT5_PRT2_OFFSET 0x8c8ULL
+#define PIP_STAT5_PRT32_OFFSET 0x1228ULL
+#define PIP_STAT5_PRT33_OFFSET 0x1278ULL
+#define PIP_STAT6_PRT0_OFFSET 0x830ULL
+#define PIP_STAT6_PRT1_OFFSET 0x880ULL
+#define PIP_STAT6_PRT2_OFFSET 0x8d0ULL
+#define PIP_STAT6_PRT32_OFFSET 0x1238ULL
+#define PIP_STAT6_PRT33_OFFSET 0x1288ULL
+#define PIP_STAT7_PRT0_OFFSET 0x838ULL
+#define PIP_STAT7_PRT1_OFFSET 0x888ULL
+#define PIP_STAT7_PRT2_OFFSET 0x8d8ULL
+#define PIP_STAT7_PRT32_OFFSET 0x1238ULL
+#define PIP_STAT7_PRT33_OFFSET 0x1288ULL
+#define PIP_STAT8_PRT0_OFFSET 0x840ULL
+#define PIP_STAT8_PRT1_OFFSET 0x890ULL
+#define PIP_STAT8_PRT2_OFFSET 0x8e0ULL
+#define PIP_STAT8_PRT32_OFFSET 0x1240ULL
+#define PIP_STAT8_PRT33_OFFSET 0x1290ULL
+#define PIP_STAT9_PRT0_OFFSET 0x848ULL
+#define PIP_STAT9_PRT1_OFFSET 0x898ULL
+#define PIP_STAT9_PRT2_OFFSET 0x8e8ULL
+#define PIP_STAT9_PRT32_OFFSET 0x1248ULL
+#define PIP_STAT9_PRT33_OFFSET 0x1298ULL
+#define PIP_TAG_INC0_OFFSET 0x1800ULL
+/* PIP_TAG_INC[1-63] */
+#define PIP_STAT_INB_PKTS0_OFFSET 0x1a00ULL
+#define PIP_STAT_INB_PKTS1_OFFSET 0x1a20ULL
+#define PIP_STAT_INB_PKTS2_OFFSET 0x1a40ULL
+#define PIP_STAT_INB_PKTS32_OFFSET 0x1e00ULL
+#define PIP_STAT_INB_OCTS0_OFFSET 0x1a08ULL
+#define PIP_STAT_INB_OCTS1_OFFSET 0x1a28ULL
+#define PIP_STAT_INB_OCTS2_OFFSET 0x1a48ULL
+#define PIP_STAT_INB_OCTS32_OFFSET 0x1e08ULL
+#define PIP_STAT_INB_ERRS0_OFFSET 0x1a10ULL
+#define PIP_STAT_INB_ERRS1_OFFSET 0x1a30ULL
+#define PIP_STAT_INB_ERRS2_OFFSET 0x1a50ULL
+#define PIP_STAT_INB_ERRS32_OFFSET 0x1e10ULL
+#define PIP_STAT_INB_ERRS33_OFFSET 0x1e30ULL
+
+/*
+ * PIP_BIST_STATUS
+ */
+#define PIP_BIST_STATUS_63_13 0xfffffffffffc0000ULL
+#define PIP_BIST_STATUS_BIST 0x000000000003ffffULL
+
+/*
+ * PIP_INT_REG
+ */
+#define PIP_INT_REG_63_9 0xfffffffffffffe00ULL
+#define PIP_INT_REG_BEPERR 0x0000000000000100ULL
+#define PIP_INT_REG_FEPERR 0x0000000000000080ULL
+#define PIP_INT_REG_6 0x0000000000000040ULL
+#define PIP_INT_REG_SKPRUNT 0x0000000000000020ULL
+#define PIP_INT_REG_BADTAG 0x0000000000000010ULL
+#define PIP_INT_REG_PRTNXA 0x0000000000000008ULL
+#define PIP_INT_REG_2_1 0x00000006
+#define PIP_INT_REG_PKTDRP 0x00000001
+
+/*
+ * PIP_INT_EN
+ */
+#define PIP_INT_EN_63_9 0xfffffffffffffe00ULL
+#define PIP_INT_EN_BEPERR 0x0000000000000100ULL
+#define PIP_INT_EN_FEPERR 0x0000000000000080ULL
+#define PIP_INT_EN_6 0x0000000000000040ULL
+#define PIP_INT_EN_SKPRUNT 0x0000000000000020ULL
+#define PIP_INT_EN_BADTAG 0x0000000000000010ULL
+#define PIP_INT_EN_PRTNXA 0x0000000000000008ULL
+#define PIP_INT_EN_2_1 0x00000006
+#define PIP_INT_EN_PKTDRP 0x00000001
+
+/*
+ * PIP_STAT_CTL
+ */
+#define PIP_STAT_CTL_63_1 0xfffffffffffffffeULL
+#define PIP_STAT_CTL_RDCLR 0x0000000000000001ULL
+
+/*
+ * PIP_GBL_CTL
+ */
+#define PIP_GBL_CTL_63_17 0xfffffffffffe0000ULL
+#define PIP_GBL_CTL_IGNRS 0x0000000000010000ULL
+#define PIP_GBL_CTL_VS_WQE 0x0000000000008000ULL
+#define PIP_GBL_CTL_VS_QOS 0x0000000000004000ULL
+#define PIP_GBL_CTL_L2MAL 0x0000000000002000ULL
+#define PIP_GBL_CTL_TCP_FLAG 0x0000000000001000ULL
+#define PIP_GBL_CTL_L4_LEN 0x0000000000000800ULL
+#define PIP_GBL_CTL_L4_CHK 0x0000000000000400ULL
+#define PIP_GBL_CTL_L4_PRT 0x0000000000000200ULL
+#define PIP_GBL_CTL_L4_MAL 0x0000000000000100ULL
+#define PIP_GBL_CTL_7_6 0x00000000000000c0ULL
+#define PIP_GBL_CTL_IP6_EEXT 0x0000000000000030ULL
+#define PIP_GBL_CTL_IP4_OPTS 0x0000000000000008ULL
+#define PIP_GBL_CTL_IP_HOP 0x0000000000000004ULL
+#define PIP_GBL_CTL_IP_MAL 0x0000000000000002ULL
+#define PIP_GBL_CTL_IP_CHK 0x0000000000000001ULL
+
+/*
+ * PIP_GBL_CFG
+ */
+/* XXX CN30XX-HM-1.0 says 63_17 is reserved */
+#define PIP_GBL_CFG_63_19 0xfffffffffff80000ULL
+#define PIP_GBL_CFG_TAG_SYN 0x0000000000040000ULL
+#define PIP_GBL_CFG_IP6_UDP 0x0000000000020000ULL
+#define PIP_GBL_CFG_MAX_L2 0x0000000000010000ULL
+#define PIP_GBL_CFG_15_11 0x000000000000f800ULL
+#define PIP_GBL_CFG_RAW_SHF 0x0000000000000700ULL
+#define PIP_GBL_CFG_7_3 0x00000000000000f8ULL
+#define PIP_GBL_CFG_NIP_SHF 0x0000000000000007ULL
+
+/*
+ * PIP_SFT_RST
+ */
+#define PIP_SFT_RST_63_17 0xfffffffffffffffeULL
+#define PIP_SFT_RST_RST 0x0000000000000001ULL
+
+/*
+ * PIP_IP_OFFSET
+ */
+#define PIP_IP_OFFSET_63_3 0xfffffffffffffff8ULL
+/* PIP_IP_OFFSET_OFFSET is defined above - conflict! */
+#define PIP_IP_OFFSET_MASK_OFFSET 0x0000000000000007ULL
+
+/*
+ * PIP_TAG_SECRET
+ */
+#define PIP_TAG_SECRET_63_3 0xffffffff00000000ULL
+#define PIP_TAG_SECRET_DST 0x00000000ffff0000ULL
+#define PIP_TAG_SECRET_SRC 0x000000000000ffffULL
+
+/*
+ * PIP_TAG_MASK
+ */
+#define PIP_TAG_MASK_63_16 0xffffffffffff0000ULL
+#define PIP_TAG_MASK_MASK 0x000000000000ffffULL
+
+/*
+ * PIP_DEC_IPSECN
+ */
+#define PIP_DEC_IPSECN_63_18 0xfffffffffffc0000ULL
+#define PIP_DEC_IPSECN_TCP 0x0000000000020000ULL
+#define PIP_DEC_IPSECN_UDP 0x0000000000010000ULL
+#define PIP_DEC_IPSECN_DPRT 0x000000000000ffffULL
+
+/*
+ * PIP_RAW_WORD
+ */
+#define PIP_RAW_WORD_63_56 0xff00000000000000ULL
+#define PIP_RAW_WORD_WORD 0x00ffffffffffffffULL
+
+/*
+ * PIP_QOS_VLAN
+ */
+#define PIP_QOS_VLAN_63_3 0xfffffffffffffff8ULL
+#define PIP_QOS_VLAN_QOS 0x0000000000000007ULL
+
+/*
+ * PIP_QOS_WATCHN
+ */
+#define PIP_QOS_WATCHN_63_48 0xffff000000000000ULL
+#define PIP_QOS_WATCHN_MASK 0x0000ffff00000000ULL
+#define PIP_QOS_WATCHN_31_28 0x00000000f0000000ULL
+#define PIP_QOS_WATCHN_GRP 0x000000000f000000ULL
+#define PIP_QOS_WATCHN_23 0x0000000000800000ULL
+#define PIP_QOS_WATCHN_WATCHER 0x0000000000700000ULL
+#define PIP_QOS_WATCHN_19_18 0x00000000000c0000ULL
+#define PIP_QOS_WATCHN_TYPE 0x0000000000030000ULL
+#define PIP_QOS_WATCHN_15_0 0x000000000000ffffULL
+
+/*
+ * PIP_PRT_CFGN
+ */
+#define PIP_PRT_CFGN_63_37 0xffffffe000000000ULL
+#define PIP_PRT_CFGN_RAWDRP 0x0000001000000000ULL
+#define PIP_PRT_CFGN_TAG_INC 0x0000000c00000000ULL
+#define PIP_PRT_CFGN_DYN_RS 0x0000000200000000ULL
+#define PIP_PRT_CFGN_INST_HDR 0x0000000100000000ULL
+#define PIP_PRT_CFGN_GRP_WAT 0x00000000f0000000ULL
+#define PIP_PRT_CFGN_27 0x0000000008000000ULL
+#define PIP_PRT_CFGN_QOS 0x0000000007000000ULL
+#define PIP_PRT_CFGN_QOS_WAT 0x0000000000f00000ULL
+#define PIP_PRT_CFGN_19 0x0000000000080000ULL
+#define PIP_PRT_CFGN_SPARE 0x0000000000040000ULL
+#define PIP_PRT_CFGN_QOS_DIFF 0x0000000000020000ULL
+#define PIP_PRT_CFGN_QOS_VLAN 0x0000000000010000ULL
+#define PIP_PRT_CFGN_15_13 0x000000000000e000ULL
+#define PIP_PRT_CFGN_CRC_EN 0x0000000000001000ULL
+#define PIP_PRT_CFGN_11_10 0x0000000000000c00ULL
+#define PIP_PRT_CFGN_MODE 0x0000000000000300ULL
+#define PIP_PRT_CFGN_MODE_SHIFT 8
+#define PIP_PORT_CFG_MODE_NONE (0ULL << PIP_PRT_CFGN_MODE_SHIFT)
+#define PIP_PORT_CFG_MODE_L2 (1ULL << PIP_PRT_CFGN_MODE_SHIFT)
+#define PIP_PORT_CFG_MODE_IP (2ULL << PIP_PRT_CFGN_MODE_SHIFT)
+#define PIP_PORT_CFG_MODE_PCI (3ULL << PIP_PRT_CFGN_MODE_SHIFT)
+#define PIP_PRT_CFGN_7 0x0000000000000080ULL
+#define PIP_PRT_CFGN_SKIP 0x000000000000007fULL
+
+/*
+ * PIP_PRT_TAGN
+ */
+#define PIP_PRT_TAGN_63_40 0xffffff0000000000ULL
+#define PIP_PRT_TAGN_GRPTAGBASE 0x000000f000000000ULL
+#define PIP_PRT_TAGN_GRPTAGMASK 0x0000000f00000000ULL
+#define PIP_PRT_TAGN_GRPTAG 0x0000000080000000ULL
+#define PIP_PRT_TAGN_SPARE 0x0000000040000000ULL
+#define PIP_PRT_TAGN_TAG_MODE 0x0000000030000000ULL
+#define PIP_PRT_TAGN_INC_VS 0x000000000c000000ULL
+#define PIP_PRT_TAGN_INC_VLAN 0x0000000002000000ULL
+#define PIP_PRT_TAGN_INC_PRT 0x0000000001000000ULL
+#define PIP_PRT_TAGN_IP6_DPRT 0x0000000000800000ULL
+#define PIP_PRT_TAGN_IP4_DPRT 0x0000000000400000ULL
+#define PIP_PRT_TAGN_IP6_SPRT 0x0000000000200000ULL
+#define PIP_PRT_TAGN_IP4_SPRT 0x0000000000100000ULL
+#define PIP_PRT_TAGN_IP6_NXTH 0x0000000000080000ULL
+#define PIP_PRT_TAGN_IP4_PCTL 0x0000000000040000ULL
+#define PIP_PRT_TAGN_IP6_DST 0x0000000000020000ULL
+#define PIP_PRT_TAGN_IP4_SRC 0x0000000000010000ULL
+#define PIP_PRT_TAGN_IP6_SRC 0x0000000000008000ULL
+#define PIP_PRT_TAGN_IP4_DST 0x0000000000004000ULL
+#define PIP_PRT_TAGN_TCP6_TAG 0x0000000000003000ULL
+#define PIP_PRT_TAGN_TCP6_TAG 0x0000000000003000ULL
+#define PIP_PRT_TAGN_TCP6_TAG_SHIFT 12
+#define PIP_PRT_TAGN_TCP6_TAG_ORDERED (0ULL << PIP_PRT_TAGN_TCP6_TAG_SHIFT)
+#define PIP_PRT_TAGN_TCP6_TAG_ATOMIC (1ULL << PIP_PRT_TAGN_TCP6_TAG_SHIFT)
+#define PIP_PRT_TAGN_TCP6_TAG_NULL (2ULL << PIP_PRT_TAGN_TCP6_TAG_SHIFT)
+#define PIP_PRT_TAGN_TCP6_TAG_XXX_3 (3ULL << PIP_PRT_TAGN_TCP6_TAG_SHIFT)
+#define PIP_PRT_TAGN_TCP4_TAG 0x0000000000000c00ULL
+#define PIP_PRT_TAGN_TCP4_TAG_SHIFT 10
+#define PIP_PRT_TAGN_TCP4_TAG_ORDERED (0ULL << PIP_PRT_TAGN_TCP4_TAG_SHIFT)
+#define PIP_PRT_TAGN_TCP4_TAG_ATOMIC (1ULL << PIP_PRT_TAGN_TCP4_TAG_SHIFT)
+#define PIP_PRT_TAGN_TCP4_TAG_NULL (2ULL << PIP_PRT_TAGN_TCP4_TAG_SHIFT)
+#define PIP_PRT_TAGN_TCP4_TAG_XXX_3 (3ULL << PIP_PRT_TAGN_TCP4_TAG_SHIFT)
+#define PIP_PRT_TAGN_IP6_TAG 0x0000000000000300ULL
+#define PIP_PRT_TAGN_IP6_TAG_SHIFT 8
+#define PIP_PRT_TAGN_IP6_TAG_ORDERED (0ULL << PIP_PRT_TAGN_IP6_TAG_SHIFT)
+#define PIP_PRT_TAGN_IP6_TAG_ATOMIC (1ULL << PIP_PRT_TAGN_IP6_TAG_SHIFT)
+#define PIP_PRT_TAGN_IP6_TAG_NULL (2ULL << PIP_PRT_TAGN_IP6_TAG_SHIFT)
+#define PIP_PRT_TAGN_IP6_TAG_XXX_3 (3ULL << PIP_PRT_TAGN_IP6_TAG_SHIFT)
+#define PIP_PRT_TAGN_IP4_TAG 0x00000000000000c0ULL
+#define PIP_PRT_TAGN_IP4_TAG_SHIFT 6
+#define PIP_PRT_TAGN_IP4_TAG_ORDERED (0ULL << PIP_PRT_TAGN_IP4_TAG_SHIFT)
+#define PIP_PRT_TAGN_IP4_TAG_ATOMIC (1ULL << PIP_PRT_TAGN_IP4_TAG_SHIFT)
+#define PIP_PRT_TAGN_IP4_TAG_NULL (2ULL << PIP_PRT_TAGN_IP4_TAG_SHIFT)
+#define PIP_PRT_TAGN_IP4_TAG_XXX_3 (3ULL << PIP_PRT_TAGN_IP4_TAG_SHIFT)
+#define PIP_PRT_TAGN_NON_TAG 0x0000000000000030ULL
+#define PIP_PRT_TAGN_NON_TAG_SHIFT 4
+#define PIP_PRT_TAGN_NON_TAG_ORDERED (0ULL << PIP_PRT_TAGN_NON_TAG_SHIFT)
+#define PIP_PRT_TAGN_NON_TAG_ATOMIC (1ULL << PIP_PRT_TAGN_NON_TAG_SHIFT)
+#define PIP_PRT_TAGN_NON_TAG_NULL (2ULL << PIP_PRT_TAGN_NON_TAG_SHIFT)
+#define PIP_PRT_TAGN_NON_TAG_XXX_3 (3ULL << PIP_PRT_TAGN_NON_TAG_SHIFT)
+#define PIP_PRT_TAGN_GRP 0x000000000000000fULL
+
+/*
+ * PIP_QOS_DIFFN
+ */
+#define PIP_QOS_DIFF_63_3 0xfffffffffffffff8ULL
+#define PIP_QOS_DIFF_QOS 0x0000000000000007ULL
+
+/*
+ * PIP_TAG_INCN
+ */
+#define PIP_TAG_INCN_63_8 0xffffffffffffff00ULL
+#define PIP_TAG_INCN_EN 0x00000000000000ffULL
+
+/*
+ * PIP_STAT0_PRTN
+ */
+#define PIP_STAT0_PRTN_DRP_PKTS 0xffffffff00000000ULL
+#define PIP_STAT0_PRTN_DRP_OCTS 0x00000000ffffffffULL
+
+/*
+ * PIP_STAT1_PRTN
+ */
+#define PIP_STAT1_PRTN_63_48 0xffff000000000000ULL
+#define PIP_STAT1_PRTN_OCTS 0x0000ffffffffffffULL
+
+/*
+ * PIP_STAT2_PRTN
+ */
+#define PIP_STAT2_PRTN_PKTS 0xffffffff00000000ULL
+#define PIP_STAT2_PRTN_RAW 0x00000000ffffffffULL
+
+/*
+ * PIP_STAT3_PRTN
+ */
+#define PIP_STAT3_PRTN_BCST 0xffffffff00000000ULL
+#define PIP_STAT3_PRTN_MCST 0x00000000ffffffffULL
+
+/*
+ * PIP_STAT4_PRTN
+ */
+#define PIP_STAT4_PRTN_H65TO127 0xffffffff00000000ULL
+#define PIP_STAT4_PRTN_H64 0x00000000ffffffffULL
+
+/*
+ * PIP_STAT5_PRTN
+ */
+#define PIP_STAT5_PRTN_H256TO511 0xffffffff00000000ULL
+#define PIP_STAT5_PRTN_H128TO255 0x00000000ffffffffULL
+
+/*
+ * PIP_STAT6_PRTN
+ */
+#define PIP_STAT6_PRTN_H1024TO1518 0xffffffff00000000ULL
+#define PIP_STAT6_PRTN_H512TO1023 0x00000000ffffffffULL
+
+/*
+ * PIP_STAT7_PRTN
+ */
+#define PIP_STAT7_PRTN_FCS 0xffffffff00000000ULL
+#define PIP_STAT7_PRTN_H1519 0x00000000ffffffffULL
+
+/*
+ * PIP_STAT8_PRTN
+ */
+#define PIP_STAT8_PRTN_FRAG 0xffffffff00000000ULL
+#define PIP_STAT8_PRTN_UNDERSZ 0x00000000ffffffffULL
+
+/*
+ * PIP_STAT9_PRTN
+ */
+#define PIP_STAT9_PRTN_JABBER 0xffffffff00000000ULL
+#define PIP_STAT9_PRTN_OVERSZ 0x00000000ffffffffULL
+
+/*
+ * PIP_STAT_INB_PKTN
+ */
+#define PIP_STAT_INB_PKTSN 0xffffffff00000000ULL
+#define PIP_STAT_INB_PKTSN_PKTS 0x00000000ffffffffULL
+
+/*
+ * PIP_STAT_INB_OCTSN
+ */
+#define PIP_STAT_INB_OCTSN 0xffff000000000000ULL
+#define PIP_STAT_INB_OCTSN_OCTS 0x0000ffffffffffffULL
+
+/*
+ * PIP_STAT_INB_ERRS
+ */
+#define PIP_STAT_INB_ERRSN 0xffffffffffff0000ULL
+#define PIP_STAT_INB_ERRSN_OCTS 0x000000000000ffffULL
+
+/*
+ * Work-Queue Entry Format
+ */
+/* WORD0 */
+#define PIP_WQE_WORD0_HW_CSUM 0xffff000000000000ULL
+#define PIP_WQE_WORD0_47_40 0x0000ff0000000000ULL
+#define PIP_WQE_WORD0_POW_NEXT_PTR 0x000000ffffffffffULL
+
+/* WORD 1 */
+#define PIP_WQE_WORD1_LEN 0xffff000000000000ULL
+#define PIP_WQE_WORD1_IPRT 0x0000fc0000000000ULL
+#define PIP_WQE_WORD1_QOS 0x0000038000000000ULL
+#define PIP_WQE_WORD1_GRP 0x0000007800000000ULL
+#define PIP_WQE_WORD1_TT 0x0000000700000000ULL
+#define PIP_WQE_WORD1_TAG 0x00000000ffffffffULL
+
+/* WORD 2 */
+#define PIP_WQE_WORD2_RAWFULL_BUFS 0xff00000000000000ULL
+#define PIP_WQE_WORD2_RAWFULL_PIP_RAW_WORD 0x00ffffffffffffffULL
+
+#define PIP_WQE_WORD2_IP_BUFS 0xff00000000000000ULL
+#define PIP_WQE_WORD2_IP_OFFSET 0x00ff000000000000ULL
+#define PIP_WQE_WORD2_IP_OFFSET_SHIFT 48
+#define PIP_WQE_WORD2_IP_VV 0x0000800000000000ULL
+#define PIP_WQE_WORD2_IP_VS 0x0000400000000000ULL
+#define PIP_WQE_WORD2_IP_45 0x0000200000000000ULL
+#define PIP_WQE_WORD2_IP_VC 0x0000100000000000ULL
+#define PIP_WQE_WORD2_IP_VLAN_ID 0x00000fff00000000ULL
+#define PIP_WQE_WORD2_IP_31_20 0x00000000fff00000ULL
+#define PIP_WQE_WORD2_IP_CO 0x0000000000080000ULL
+#define PIP_WQE_WORD2_IP_TU 0x0000000000040000ULL
+#define PIP_WQE_WORD2_IP_SE 0x0000000000020000ULL
+#define PIP_WQE_WORD2_IP_V6 0x0000000000010000ULL
+#define PIP_WQE_WORD2_IP_15 0x0000000000008000ULL
+#define PIP_WQE_WORD2_IP_LE 0x0000000000004000ULL
+#define PIP_WQE_WORD2_IP_FR 0x0000000000002000ULL
+#define PIP_WQE_WORD2_IP_IE 0x0000000000001000ULL
+#define PIP_WQE_WORD2_IP_B 0x0000000000000800ULL
+#define PIP_WQE_WORD2_IP_M 0x0000000000000400ULL
+#define PIP_WQE_WORD2_IP_NI 0x0000000000000200ULL
+#define PIP_WQE_WORD2_IP_RE 0x0000000000000100ULL
+#define PIP_WQE_WORD2_IP_OPECODE 0x00000000000000ffULL
+
+#define PIP_WQE_WORD2_NOIP_BUFS 0xff00000000000000ULL
+#define PIP_WQE_WORD2_NOIP_55_48 0x00ff000000000000ULL
+#define PIP_WQE_WORD2_NOIP_VV 0x0000800000000000ULL
+#define PIP_WQE_WORD2_NOIP_VS 0x0000400000000000ULL
+#define PIP_WQE_WORD2_NOIP_45 0x0000200000000000ULL
+#define PIP_WQE_WORD2_NOIP_VC 0x0000100000000000ULL
+#define PIP_WQE_WORD2_NOIP_VLAN_ID 0x00000fff00000000ULL
+#define PIP_WQE_WORD2_NOIP_31_14 0x00000000ffffc000ULL
+#define PIP_WQE_WORD2_NOIP_IR 0x0000000000002000ULL
+#define PIP_WQE_WORD2_NOIP_IA 0x0000000000001000ULL
+#define PIP_WQE_WORD2_NOIP_B 0x0000000000000800ULL
+#define PIP_WQE_WORD2_NOIP_M 0x0000000000000400ULL
+#define PIP_WQE_WORD2_NOIP_NI 0x0000000000000200ULL
+#define PIP_WQE_WORD2_NOIP_RE 0x0000000000000100ULL
+#define PIP_WQE_WORD2_NOIP_OPECODE 0x00000000000000ffULL
+
+/* WORD 3 */
+#define PIP_WQE_WORD3_63 0x8000000000000000ULL
+#define PIP_WQE_WORD3_BACK 0x7800000000000000ULL
+#define PIP_WQE_WORD3_58_56 0x0700000000000000ULL
+#define PIP_WQE_WORD3_SIZE 0x00ffff0000000000ULL
+#define PIP_WQE_WORD3_ADDR 0x000000ffffffffffULL
+
+/* opcode for WORD2[LE] */
+#define PIP_WQE_WORD2_LE_OPCODE_MAL 1ULL
+#define PIP_WQE_WORD2_LE_OPCODE_CSUM 2ULL
+#define PIP_WQE_WORD2_LE_OPCODE_UDPLEN 3ULL
+#define PIP_WQE_WORD2_LE_OPCODE_PORT 4ULL
+#define PIP_WQE_WORD2_LE_OPCODE_XXX_5 5ULL
+#define PIP_WQE_WORD2_LE_OPCODE_XXX_6 6ULL
+#define PIP_WQE_WORD2_LE_OPCODE_XXX_7 7ULL
+#define PIP_WQE_WORD2_LE_OPCODE_FINO 8ULL
+#define PIP_WQE_WORD2_LE_OPCODE_NOFL 9ULL
+#define PIP_WQE_WORD2_LE_OPCODE_FINRST 10ULL
+#define PIP_WQE_WORD2_LE_OPCODE_SYNURG 11ULL
+#define PIP_WQE_WORD2_LE_OPCODE_SYNRST 12ULL
+#define PIP_WQE_WORD2_LE_OPCODE_SYNFIN 13ULL
+
+/* opcode for WORD2[IE] */
+#define PIP_WQE_WORD2_IE_OPCODE_NOTIP 1ULL
+#define PIP_WQE_WORD2_IE_OPCODE_CSUM 2ULL
+#define PIP_WQE_WORD2_IE_OPCODE_MALHDR 3ULL
+#define PIP_WQE_WORD2_IE_OPCODE_MAL 4ULL
+#define PIP_WQE_WORD2_IE_OPCODE_TTL 5ULL
+#define PIP_WQE_WORD2_IE_OPCODE_OPT 6ULL
+
+/* opcode for WORD2[RE] */
+#define PIP_WQE_WORD2_RE_OPCODE_PARTIAL 1ULL
+#define PIP_WQE_WORD2_RE_OPCODE_JABBER 2ULL
+#define PIP_WQE_WORD2_RE_OPCODE_OVRRUN 3ULL
+#define PIP_WQE_WORD2_RE_OPCODE_OVRSZ 4ULL
+#define PIP_WQE_WORD2_RE_OPCODE_ALIGN 5ULL
+#define PIP_WQE_WORD2_RE_OPCODE_FRAG 6ULL
+#define PIP_WQE_WORD2_RE_OPCODE_GMXFCS 7ULL
+#define PIP_WQE_WORD2_RE_OPCODE_UDRSZ 8ULL
+#define PIP_WQE_WORD2_RE_OPCODE_EXTEND 9ULL
+#define PIP_WQE_WORD2_RE_OPCODE_LENGTH 10ULL
+#define PIP_WQE_WORD2_RE_OPCODE_MIIRX 11ULL
+#define PIP_WQE_WORD2_RE_OPCODE_MIISKIP 12ULL
+#define PIP_WQE_WORD2_RE_OPCODE_MIINBL 13ULL
+#define PIP_WQE_WORD2_RE_OPCODE_XXX_14 14ULL
+#define PIP_WQE_WORD2_RE_OPCODE_XXX_15 15ULL
+#define PIP_WQE_WORD2_RE_OPCODE_XXX_16 16ULL
+#define PIP_WQE_WORD2_RE_OPCODE_SKIP 17ULL
+#define PIP_WQE_WORD2_RE_OPCODE_L2MAL 18ULL
+
+/* XXX backward compatibility */
+#define PIP_OVER_ERR PIP_WQE_WORD2_RE_OPCODE_OVRRUN
+#define PIP_GMX_FCS_ERR PIP_WQE_WORD2_RE_OPCODE_GMXFCS
+#define PIP_ALIGN_ERR PIP_WQE_WORD2_RE_OPCODE_ALIGN
+
+#define PIP_BIST_STATUS_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x12\x2e" "63_13\0" \
+ "f\x00\x12" "BIST\0"
+#define PIP_INT_REG_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x09\x37" "63_9\0" \
+ "b\x08" "BEPERR\0" \
+ "b\x07" "FEPERR\0" \
+ "b\x06" "6\0" \
+ "b\x05" "SKPRUNT\0" \
+ "b\x04" "BADTAG\0" \
+ "b\x03" "PRTNXA\0" \
+ "f\x01\x02" "2_1\0" \
+ "b\x00" "PKTDRP\0"
+#define PIP_INT_EN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x09\x37" "63_9\0" \
+ "b\x08" "BEPERR\0" \
+ "b\x07" "FEPERR\0" \
+ "b\x06" "6\0" \
+ "b\x05" "SKPRUNT\0" \
+ "b\x04" "BADTAG\0" \
+ "b\x03" "PRTNXA\0" \
+ "f\x01\x02" "2_1\0" \
+ "b\x00" "PKTDRP\0"
+#define PIP_STAT_CTL_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x01\x3f" "63_1\0" \
+ "b\x00" "RDCLR\0"
+#define PIP_GBL_CTL_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x11\x2f" "63_17\0" \
+ "b\x10" "IGNRS\0" \
+ "b\x0f" "VS_WQE\0" \
+ "b\x0e" "VS_QOS\0" \
+ "b\x0d" "L2MAL\0" \
+ "b\x0c" "TCP_FLAG\0" \
+ "b\x0b" "L4_LEN\0" \
+ "b\x0a" "L4_CHK\0" \
+ "b\x09" "L4_PRT\0" \
+ "b\x08" "L4_MAL\0" \
+ "f\x06\x02" "7_6\0" \
+ "f\x04\x02" "IP6_EEXT\0" \
+ "b\x03" "IP4_OPTS\0" \
+ "b\x02" "IP_HOP\0" \
+ "b\x01" "IP_MAL\0" \
+ "b\x00" "IP_CHK\0"
+#define PIP_GBL_CFG_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x13\x2d" "63_19\0" \
+ "b\x12" "TAG_SYN\0" \
+ "b\x11" "IP6_UDP\0" \
+ "b\x10" "MAX_L2\0" \
+ "f\x0b\x05" "15_11\0" \
+ "f\x08\x03" "RAW_SHF\0" \
+ "f\x03\x05" "7_3\0" \
+ "f\x00\x03" "NIP_SHF\0"
+#define PIP_SOFT_RST_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define PIP_IP_OFFSET_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x03\x3d" "63_3\0" \
+ "f\x00\x03" "MASK_OFFSET\0"
+#define PIP_TAG_SECRET_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x20\x20" "63_3\0" \
+ "f\x10\x10" "DST\0" \
+ "f\x00\x10" "SRC\0"
+#define PIP_TAG_MASK_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x10\x30" "63_16\0" \
+ "f\x00\x10" "MASK\0"
+#define PIP_DEC_IPSECN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x12\x2e" "63_18\0" \
+ "b\x11" "TCP\0" \
+ "b\x10" "UDP\0" \
+ "f\x00\x10" "DPRT\0"
+#define PIP_DEC_IPSEC0_BITS PIP_DEC_IPSECN_BITS
+#define PIP_DEC_IPSEC1_BITS PIP_DEC_IPSECN_BITS
+#define PIP_DEC_IPSEC2_BITS PIP_DEC_IPSECN_BITS
+#define PIP_DEC_IPSEC3_BITS PIP_DEC_IPSECN_BITS
+#define PIP_RAW_WORD_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x38\x08" "63_56\0" \
+ "f\x00\x38" "WORD\0"
+#define PIP_QOS_VLANN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define PIP_QOS_VLAN0_BITS PIP_QOS_VLANN_BITS
+#define PIP_QOS_VLAN1_BITS PIP_QOS_VLANN_BITS
+#define PIP_QOS_VLAN2_BITS PIP_QOS_VLANN_BITS
+#define PIP_QOS_VLAN3_BITS PIP_QOS_VLANN_BITS
+#define PIP_QOS_VLAN4_BITS PIP_QOS_VLANN_BITS
+#define PIP_QOS_VLAN5_BITS PIP_QOS_VLANN_BITS
+#define PIP_QOS_VLAN6_BITS PIP_QOS_VLANN_BITS
+#define PIP_QOS_VLAN7_BITS PIP_QOS_VLANN_BITS
+#define PIP_QOS_WATCHN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x30\x10" "63_48\0" \
+ "f\x20\x10" "MASK\0" \
+ "f\x1c\x04" "31_28\0" \
+ "f\x18\x04" "GRP\0" \
+ "b\x17" "23\0" \
+ "f\x14\x03" "WATCHER\0" \
+ "f\x12\x02" "19_18\0" \
+ "f\x10\x02" "TYPE\0" \
+ "f\x00\x10" "15_0\0"
+#define PIP_QOS_WATCH0_BITS PIP_QOS_WATCHN_BITS
+#define PIP_QOS_WATCH1_BITS PIP_QOS_WATCHN_BITS
+#define PIP_QOS_WATCH2_BITS PIP_QOS_WATCHN_BITS
+#define PIP_QOS_WATCH3_BITS PIP_QOS_WATCHN_BITS
+#define PIP_PRT_CFGN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x25\x1b" "63_37\0" \
+ "b\x24" "RAWDRP\0" \
+ "f\x22\x02" "TAG_INC\0" \
+ "b\x21" "DYN_RS\0" \
+ "b\x20" "INST_HDR\0" \
+ "f\x1c\x04" "GRP_WAT\0" \
+ "b\x1b" "27\0" \
+ "f\x18\x03" "QOS\0" \
+ "f\x14\x04" "QOS_WAT\0" \
+ "b\x13" "19\0" \
+ "b\x12" "SPARE\0" \
+ "b\x11" "QOS_DIFF\0" \
+ "b\x10" "QOS_VLAN\0" \
+ "f\x0d\x03" "15_13\0" \
+ "b\x0c" "CRC_EN\0" \
+ "f\x0a\x02" "11_10\0" \
+ "f\x08\x02" "MODE\0" \
+ "b\x07" "7\0" \
+ "f\x00\x07" "SKIP\0"
+#define PIP_PRT_CFG0_BITS PIP_PRT_CFGN_BITS
+#define PIP_PRT_CFG1_BITS PIP_PRT_CFGN_BITS
+#define PIP_PRT_CFG2_BITS PIP_PRT_CFGN_BITS
+#define PIP_PRT_CFG32_BITS PIP_PRT_CFGN_BITS
+#define PIP_PRT_TAGN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x28\x18" "63_40\0" \
+ "f\x24\x04" "GRPTAGBASE\0" \
+ "f\x20\x04" "GRPTAGMASK\0" \
+ "b\x1f" "GRPTAG\0" \
+ "b\x1e" "SPARE\0" \
+ "f\x1c\x02" "TAG_MODE\0" \
+ "f\x1a\x02" "INC_VS\0" \
+ "b\x19" "INC_VLAN\0" \
+ "b\x18" "INC_PRT\0" \
+ "b\x17" "IP6_DPRT\0" \
+ "b\x16" "IP4_DPRT\0" \
+ "b\x15" "IP6_SPRT\0" \
+ "b\x14" "IP4_SPRT\0" \
+ "b\x13" "IP6_NXTH\0" \
+ "b\x12" "IP4_PCTL\0" \
+ "b\x11" "IP6_DST\0" \
+ "b\x10" "IP4_SRC\0" \
+ "b\x0f" "IP6_SRC\0" \
+ "b\x0e" "IP4_DST\0" \
+ "f\x0c\x02" "TCP6_TAG\0" \
+ "f\x0a\x02" "TCP4_TAG\0" \
+ "f\x08\x02" "IP6_TAG\0" \
+ "f\x06\x02" "IP4_TAG\0" \
+ "f\x04\x02" "NON_TAG\0" \
+ "f\x00\x04" "GRP\0"
+#define PIP_PRT_TAG0_BITS PIP_PRT_TAGN_BITS
+#define PIP_PRT_TAG1_BITS PIP_PRT_TAGN_BITS
+#define PIP_PRT_TAG2_BITS PIP_PRT_TAGN_BITS
+#define PIP_PRT_TAG32_BITS PIP_PRT_TAGN_BITS
+/* PIP_QOS_DIFF[0-63] */
+#define PIP_STAT0_PRTN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x20\x20" "DRP_PKTS\0" \
+ "f\x00\x20" "DRP_OCTS\0"
+#define PIP_STAT0_PRT0_BITS PIP_STAT0_PRTN_BITS
+#define PIP_STAT0_PRT1_BITS PIP_STAT0_PRTN_BITS
+#define PIP_STAT0_PRT2_BITS PIP_STAT0_PRTN_BITS
+#define PIP_STAT0_PRT32_BITS PIP_STAT0_PRTN_BITS
+#define PIP_STAT1_PRTN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x30\x10" "63_48\0" \
+ "f\x00\x30" "OCTS\0"
+#define PIP_STAT1_PRT0_BITS PIP_STAT1_PRTN_BITS
+#define PIP_STAT1_PRT1_BITS PIP_STAT1_PRTN_BITS
+#define PIP_STAT1_PRT2_BITS PIP_STAT1_PRTN_BITS
+#define PIP_STAT1_PRT32_BITS PIP_STAT1_PRTN_BITS
+#define PIP_STAT2_PRTN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x20\x20" "PKTS\0" \
+ "f\x00\x20" "RAW\0"
+#define PIP_STAT2_PRT0_BITS PIP_STAT2_PRTN_BITS
+#define PIP_STAT2_PRT1_BITS PIP_STAT2_PRTN_BITS
+#define PIP_STAT2_PRT2_BITS PIP_STAT2_PRTN_BITS
+#define PIP_STAT2_PRT32_BITS PIP_STAT2_PRTN_BITS
+#define PIP_STAT3_PRTN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x20\x20" "BCST\0" \
+ "f\x00\x20" "MCST\0"
+#define PIP_STAT3_PRT0_BITS PIP_STAT3_PRTN_BITS
+#define PIP_STAT3_PRT1_BITS PIP_STAT3_PRTN_BITS
+#define PIP_STAT3_PRT2_BITS PIP_STAT3_PRTN_BITS
+#define PIP_STAT3_PRT32_BITS PIP_STAT3_PRTN_BITS
+#define PIP_STAT4_PRTN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x20\x20" "H65TO127\0" \
+ "f\x00\x20" "H64\0"
+#define PIP_STAT4_PRT0_BITS PIP_STAT4_PRTN_BITS
+#define PIP_STAT4_PRT1_BITS PIP_STAT4_PRTN_BITS
+#define PIP_STAT4_PRT2_BITS PIP_STAT4_PRTN_BITS
+#define PIP_STAT4_PRT32_BITS PIP_STAT4_PRTN_BITS
+#define PIP_STAT5_PRTN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x20\x20" "H256TO511\0" \
+ "f\x00\x20" "H128TO255\0"
+#define PIP_STAT5_PRT0_BITS PIP_STAT5_PRTN_BITS
+#define PIP_STAT5_PRT1_BITS PIP_STAT5_PRTN_BITS
+#define PIP_STAT5_PRT2_BITS PIP_STAT5_PRTN_BITS
+#define PIP_STAT5_PRT32_BITS PIP_STAT5_PRTN_BITS
+#define PIP_STAT6_PRTN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x20\x20" "H1024TO1518\0" \
+ "f\x00\x20" "H512TO1023\0"
+#define PIP_STAT6_PRT0_BITS PIP_STAT6_PRTN_BITS
+#define PIP_STAT6_PRT1_BITS PIP_STAT6_PRTN_BITS
+#define PIP_STAT6_PRT2_BITS PIP_STAT6_PRTN_BITS
+#define PIP_STAT6_PRT32_BITS PIP_STAT6_PRTN_BITS
+#define PIP_STAT7_PRTN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x20\x20" "FCS\0" \
+ "f\x00\x20" "H1519\0"
+#define PIP_STAT7_PRT0_BITS PIP_STAT7_PRTN_BITS
+#define PIP_STAT7_PRT1_BITS PIP_STAT7_PRTN_BITS
+#define PIP_STAT7_PRT2_BITS PIP_STAT7_PRTN_BITS
+#define PIP_STAT7_PRT32_BITS PIP_STAT7_PRTN_BITS
+#define PIP_STAT8_PRTN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x20\x20" "FRAG\0" \
+ "f\x00\x20" "UNDERSZ\0"
+#define PIP_STAT8_PRT0_BITS PIP_STAT8_PRTN_BITS
+#define PIP_STAT8_PRT1_BITS PIP_STAT8_PRTN_BITS
+#define PIP_STAT8_PRT2_BITS PIP_STAT8_PRTN_BITS
+#define PIP_STAT8_PRT32_BITS PIP_STAT8_PRTN_BITS
+#define PIP_STAT9_PRTN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x20\x20" "JABBER\0" \
+ "f\x00\x20" "OVERSZ\0"
+#define PIP_STAT9_PRT0_BITS PIP_STAT9_PRTN_BITS
+#define PIP_STAT9_PRT1_BITS PIP_STAT9_PRTN_BITS
+#define PIP_STAT9_PRT2_BITS PIP_STAT9_PRTN_BITS
+#define PIP_STAT9_PRT32_BITS PIP_STAT9_PRTN_BITS
+/* PIP_TAG_INC[0-63] */
+#define PIP_STAT_INB_PKTSN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x20\x20" "PIP_STAT_INB_PKTSN\0" \
+ "f\x00\x20" "PKTS\0"
+#define PIP_STAT_INB_PKTS0_BITS PIP_STAT_INB_PKTSN_BITS
+#define PIP_STAT_INB_PKTS1_BITS PIP_STAT_INB_PKTSN_BITS
+#define PIP_STAT_INB_PKTS2_BITS PIP_STAT_INB_PKTSN_BITS
+#define PIP_STAT_INB_PKTS32_BITS PIP_STAT_INB_PKTSN_BITS
+#define PIP_STAT_INB_OCTSN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x30\x10" "PIP_STAT_INB_OCTSN\0" \
+ "f\x00\x30" "OCTS\0"
+#define PIP_STAT_INB_OCTS0_BITS PIP_STAT_INB_OCTSN_BITS
+#define PIP_STAT_INB_OCTS1_BITS PIP_STAT_INB_OCTSN_BITS
+#define PIP_STAT_INB_OCTS2_BITS PIP_STAT_INB_OCTSN_BITS
+#define PIP_STAT_INB_OCTS32_BITS PIP_STAT_INB_OCTSN_BITS
+#define PIP_STAT_INB_ERRSN_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x10\x30" "PIP_STAT_INB_ERRSN\0" \
+ "f\x00\x10" "OCTS\0"
+#define PIP_STAT_INB_ERRS0_BITS PIP_STAT_INB_ERRSN_BITS
+#define PIP_STAT_INB_ERRS1_BITS PIP_STAT_INB_ERRSN_BITS
+#define PIP_STAT_INB_ERRS2_BITS PIP_STAT_INB_ERRSN_BITS
+#define PIP_STAT_INB_ERRS32_BITS PIP_STAT_INB_ERRSN_BITS
+
+#endif /* _CN30XXPIPREG_H_ */
diff --git a/sys/arch/octeon/dev/cn30xxpipvar.h b/sys/arch/octeon/dev/cn30xxpipvar.h
new file mode 100644
index 00000000000..6d2205fc53d
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxpipvar.h
@@ -0,0 +1,80 @@
+/* $OpenBSD: cn30xxpipvar.h,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _CN30XXPIPVAR_H_
+#define _CN30XXPIPVAR_H_
+
+/* XXX */
+struct cn30xxpip_softc {
+ int sc_port;
+ bus_space_tag_t sc_regt;
+ bus_space_handle_t sc_regh;
+ int sc_tag_type;
+ int sc_receive_group;
+ size_t sc_ip_offset;
+#ifdef OCTEON_ETH_DEBUG
+ struct evcnt sc_ev_pipbeperr;
+ struct evcnt sc_ev_pipfeperr;
+ struct evcnt sc_ev_pipskprunt;
+ struct evcnt sc_ev_pipbadtag;
+ struct evcnt sc_ev_pipprtnxa;
+ struct evcnt sc_ev_pippktdrp;
+#endif
+};
+
+/* XXX */
+struct cn30xxpip_attach_args {
+ int aa_port;
+ bus_space_tag_t aa_regt;
+ int aa_tag_type;
+ int aa_receive_group;
+ size_t aa_ip_offset;
+};
+
+void cn30xxpip_init(struct cn30xxpip_attach_args *,
+ struct cn30xxpip_softc **);
+void cn30xxpip_gbl_ctl_debug(struct cn30xxpip_softc *);
+int cn30xxpip_port_config(struct cn30xxpip_softc *);
+void cn30xxpip_prt_cfg_enable(struct cn30xxpip_softc *,
+ uint64_t, int);
+void cn30xxpip_stats(struct cn30xxpip_softc *,
+ struct ifnet *, int);
+#ifdef OCTEON_ETH_DEBUG
+void cn30xxpip_int_enable(struct cn30xxpip_softc *, int);
+void cn30xxpip_dump(void);
+void cn30xxpip_dump_regs(void);
+void cn30xxpip_dump_stats(void);
+#endif /* OCTEON_ETH_DEBUG */
+
+#ifdef OCTEON_ETH_DEBUG
+void cn30xxpip_int_enable(struct cn30xxpip_softc *, int);
+uint64_t cn30xxpip_int_summary(struct cn30xxpip_softc *);
+#endif /* OCTEON_ETH_DEBUG */
+
+
+#endif
diff --git a/sys/arch/octeon/dev/cn30xxpko.c b/sys/arch/octeon/dev/cn30xxpko.c
new file mode 100644
index 00000000000..0afdd9200fb
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxpko.c
@@ -0,0 +1,251 @@
+/* $OpenBSD: cn30xxpko.c,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+
+#include <machine/octeonvar.h>
+
+#include <octeon/dev/cn30xxfaureg.h>
+#include <octeon/dev/cn30xxfpavar.h>
+#include <octeon/dev/cn30xxpkoreg.h>
+#include <octeon/dev/cn30xxpkovar.h>
+
+static inline void cn30xxpko_op_store(uint64_t, uint64_t);
+
+#ifdef OCTEON_ETH_DEBUG
+void cn30xxpko_intr_evcnt_attach(struct cn30xxpko_softc *);
+void cn30xxpko_intr_rml(void *);
+#endif
+
+#define _PKO_RD8(sc, off) \
+ bus_space_read_8((sc)->sc_regt, (sc)->sc_regh, (off))
+#define _PKO_WR8(sc, off, v) \
+ bus_space_write_8((sc)->sc_regt, (sc)->sc_regh, (off), (v))
+
+#ifdef OCTEON_ETH_DEBUG
+struct cn30xxpko_softc *__cn30xxpko_softc;
+#endif
+
+/* ----- gloal functions */
+
+/* XXX */
+void
+cn30xxpko_init(struct cn30xxpko_attach_args *aa,
+ struct cn30xxpko_softc **rsc)
+{
+ struct cn30xxpko_softc *sc;
+ int status;
+
+ sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
+ if (sc == NULL)
+ panic("can't allocate memory: %s", __func__);
+
+ sc->sc_port = aa->aa_port;
+ sc->sc_regt = aa->aa_regt;
+ sc->sc_cmdptr = aa->aa_cmdptr;
+ sc->sc_cmd_buf_pool = aa->aa_cmd_buf_pool;
+ sc->sc_cmd_buf_size = aa->aa_cmd_buf_size;
+
+ status = bus_space_map(sc->sc_regt, PKO_BASE, PKO_SIZE, 0,
+ &sc->sc_regh);
+ if (status != 0)
+ panic("can't map %s space", "pko register");
+
+ *rsc = sc;
+
+#ifdef OCTEON_ETH_DEBUG
+ cn30xxpko_intr_evcnt_attach(sc);
+ __cn30xxpko_softc = sc;
+#endif
+}
+
+int
+cn30xxpko_enable(struct cn30xxpko_softc *sc)
+{
+ uint64_t reg_flags;
+
+ reg_flags = _PKO_RD8(sc, PKO_REG_FLAGS_OFFSET);
+ /* PKO_REG_FLAGS_RESET=0 */
+ /* PKO_REG_FLAGS_STORE_BE=0 */
+ SET(reg_flags, PKO_REG_FLAGS_ENA_DWB);
+ SET(reg_flags, PKO_REG_FLAGS_ENA_PKO);
+ /* XXX */
+ OCTEON_SYNCW;
+ _PKO_WR8(sc, PKO_REG_FLAGS_OFFSET, reg_flags);
+
+ return 0;
+}
+
+#if 0
+void
+cn30xxpko_reset(cn30xxpko_softc *sc)
+{
+ uint64_t reg_flags;
+
+ reg_flags = _PKO_RD8(sc, PKO_REG_FLAGS_OFFSET);
+ SET(reg_flags, PKO_REG_FLAGS_RESET);
+ _PKO_WR8(sc, PKO_REG_FLAGS_OFFSET, reg_flags);
+}
+#endif
+
+void
+cn30xxpko_config(struct cn30xxpko_softc *sc)
+{
+ uint64_t reg_cmd_buf = 0;
+
+ SET(reg_cmd_buf, (sc->sc_cmd_buf_pool << 20) & PKO_REG_CMD_BUF_POOL);
+ SET(reg_cmd_buf, sc->sc_cmd_buf_size & PKO_REG_CMD_BUF_SIZE);
+ _PKO_WR8(sc, PKO_REG_CMD_BUF_OFFSET, reg_cmd_buf);
+
+#ifdef OCTEON_ETH_DEBUG
+ cn30xxpko_int_enable(sc, 1);
+#endif
+}
+
+int
+cn30xxpko_port_enable(struct cn30xxpko_softc *sc, int enable)
+{
+ uint64_t reg_read_idx;
+ uint64_t mem_queue_qos;
+
+ reg_read_idx = 0;
+ SET(reg_read_idx, sc->sc_port & PKO_REG_READ_IDX_IDX);
+
+ /* XXX assume one queue maped one port */
+ /* Enable packet output by enabling all queues for this port */
+ mem_queue_qos = 0;
+ SET(mem_queue_qos, ((uint64_t)sc->sc_port << 7) & PKO_MEM_QUEUE_QOS_PID);
+ SET(mem_queue_qos, sc->sc_port & PKO_MEM_QUEUE_QOS_QID);
+ SET(mem_queue_qos, ((enable ? 0xffULL : 0x00ULL) << 53) &
+ PKO_MEM_QUEUE_QOS_QOS_MASK);
+
+ _PKO_WR8(sc, PKO_REG_READ_IDX_OFFSET, reg_read_idx);
+ _PKO_WR8(sc, PKO_MEM_QUEUE_QOS_OFFSET, mem_queue_qos);
+
+ return 0;
+}
+
+static int pko_queue_map_init[32];
+
+int
+cn30xxpko_port_config(struct cn30xxpko_softc *sc)
+{
+ paddr_t buf_ptr = 0;
+ uint64_t mem_queue_ptrs;
+
+ KASSERT(sc->sc_port < 32);
+
+ buf_ptr = cn30xxfpa_load(FPA_COMMAND_BUFFER_POOL);
+ if (buf_ptr == 0)
+ return 1;
+
+ KASSERT(buf_ptr != 0);
+
+ /* assume one queue maped one port */
+ mem_queue_ptrs = 0;
+ SET(mem_queue_ptrs, PKO_MEM_QUEUE_PTRS_TAIL);
+ SET(mem_queue_ptrs, ((uint64_t)0 << 13) & PKO_MEM_QUEUE_PTRS_IDX);
+ SET(mem_queue_ptrs, ((uint64_t)sc->sc_port << 7) & PKO_MEM_QUEUE_PTRS_PID);
+ SET(mem_queue_ptrs, sc->sc_port & PKO_MEM_QUEUE_PTRS_QID);
+ SET(mem_queue_ptrs, ((uint64_t)0xff << 53) & PKO_MEM_QUEUE_PTRS_QOS_MASK);
+ SET(mem_queue_ptrs, ((uint64_t)buf_ptr << 17) & PKO_MEM_QUEUE_PTRS_BUF_PTR);
+ OCTEON_SYNCW;
+ _PKO_WR8(sc, PKO_MEM_QUEUE_PTRS_OFFSET, mem_queue_ptrs);
+
+ /*
+ * Set initial command buffer address and index
+ * for queue.
+ */
+ sc->sc_cmdptr->cmdptr = (uint64_t)buf_ptr;
+ sc->sc_cmdptr->cmdptr_idx = 0;
+
+ pko_queue_map_init[sc->sc_port] = 1;
+
+ return 0;
+}
+
+#ifdef OCTEON_ETH_DEBUG
+int cn30xxpko_intr_rml_verbose;
+struct evcnt cn30xxpko_intr_evcnt;
+
+static const struct octeon_evcnt_entry cn30xxpko_intr_evcnt_entries[] = {
+#define _ENTRY(name, type, parent, descr) \
+ OCTEON_EVCNT_ENTRY(struct cn30xxpko_softc, name, type, parent, descr)
+ _ENTRY(pkoerrdbell, MISC, NULL, "pko doorbell overflow"),
+ _ENTRY(pkoerrparity, MISC, NULL, "pko parity error")
+#undef _ENTRY
+};
+
+void
+cn30xxpko_intr_evcnt_attach(struct cn30xxpko_softc *sc)
+{
+ OCTEON_EVCNT_ATTACH_EVCNTS(sc, cn30xxpko_intr_evcnt_entries, "pko0");
+}
+
+void
+cn30xxpko_intr_rml(void *arg)
+{
+ struct cn30xxpko_softc *sc;
+ uint64_t reg;
+
+ cn30xxpko_intr_evcnt.ev_count++;
+ sc = __cn30xxpko_softc;
+ KASSERT(sc != NULL);
+ reg = cn30xxpko_int_summary(sc);
+ if (cn30xxpko_intr_rml_verbose)
+ printf("%s: PKO_REG_ERROR=0x%016" PRIx64 "\n", __func__, reg);
+ if (reg & PKO_REG_ERROR_DOORBELL)
+ OCTEON_EVCNT_INC(sc, pkoerrdbell);
+ if (reg & PKO_REG_ERROR_PARITY)
+ OCTEON_EVCNT_INC(sc, pkoerrparity);
+}
+
+void
+cn30xxpko_int_enable(struct cn30xxpko_softc *sc, int enable)
+{
+ uint64_t pko_int_xxx = 0;
+
+ pko_int_xxx = PKO_REG_ERROR_DOORBELL | PKO_REG_ERROR_PARITY;
+ _PKO_WR8(sc, PKO_REG_ERROR_OFFSET, pko_int_xxx);
+ _PKO_WR8(sc, PKO_REG_INT_MASK_OFFSET, enable ? pko_int_xxx : 0);
+}
+
+uint64_t
+cn30xxpko_int_summary(struct cn30xxpko_softc *sc)
+{
+ uint64_t summary;
+
+ summary = _PKO_RD8(sc, PKO_REG_ERROR_OFFSET);
+ _PKO_WR8(sc, PKO_REG_ERROR_OFFSET, summary);
+ return summary;
+}
+#endif
diff --git a/sys/arch/octeon/dev/cn30xxpkoreg.h b/sys/arch/octeon/dev/cn30xxpkoreg.h
new file mode 100644
index 00000000000..9f8436364cc
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxpkoreg.h
@@ -0,0 +1,404 @@
+/*
+ * THIS FILE IS AUTOMATICALLY GENERATED
+ * DONT EDIT THIS FILE
+ */
+
+/* $OpenBSD: cn30xxpkoreg.h,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Cavium Networks OCTEON CN30XX Hardware Reference Manual
+ * CN30XX-HM-1.0
+ * 8.9 PKO Registers
+ */
+
+#ifndef _CN30XXPKOREG_H_
+#define _CN30XXPKOREG_H_
+
+#define PKO_REG_FLAGS 0x0001180050000000ULL
+#define PKO_REG_READ_IDX 0x0001180050000008ULL
+#define PKO_REG_CMD_BUF 0x0001180050000010ULL
+#define PKO_REG_GMX_PORT_MODE 0x0001180050000018ULL
+#define PKO_REG_QUEUE_MODE 0x0001180050000048ULL
+#define PKO_REG_BIST_RESULT 0x0001180050000050ULL
+#define PKO_REG_ERROR 0x0001180050000058ULL
+#define PKO_REG_INT_MASK 0x0001180050000090ULL
+#define PKO_REG_DEBUG0 0x0001180050000098ULL
+#define PKO_MEM_QUEUE_PTRS 0x0001180050001000ULL
+#define PKO_MEM_QUEUE_QOS 0x0001180050001008ULL
+#define PKO_MEM_COUNT0 0x0001180050001080ULL
+#define PKO_MEM_COUNT1 0x0001180050001088ULL
+#define PKO_DEBUG0 0x0001180050001100ULL
+#define PKO_DEBUG1 0x0001180050001108ULL
+#define PKO_DEBUG2 0x0001180050001110ULL
+#define PKO_DEBUG3 0x0001180050001118ULL
+#define PKO_DEBUG4 0x0001180050001120ULL
+#define PKO_DEBUG5 0x0001180050001128ULL
+#define PKO_DEBUG6 0x0001180050001130ULL
+#define PKO_DEBUG7 0x0001180050001138ULL
+#define PKO_DEBUG8 0x0001180050001140ULL
+#define PKO_DEBUG9 0x0001180050001148ULL
+#define PKO_DEBUG10 0x0001180050001150ULL
+#define PKO_DEBUG11 0x0001180050001158ULL
+#define PKO_DEBUG12 0x0001180050001160ULL
+#define PKO_DEBUG13 0x0001180050001168ULL
+#define PKO_DEBUG14 0x0001180050001170ULL
+
+#define PKO_BASE 0x0001180050000000ULL
+#define PKO_SIZE 0x01178ULL
+
+#define PKO_REG_FLAGS_OFFSET 0x00000ULL
+#define PKO_REG_READ_IDX_OFFSET 0x00008ULL
+#define PKO_REG_CMD_BUF_OFFSET 0x00010ULL
+#define PKO_REG_GMX_PORT_MODE_OFFSET 0x00018ULL
+#define PKO_REG_QUEUE_MODE_OFFSET 0x00048ULL
+#define PKO_REG_BIST_RESULT_OFFSET 0x00080ULL
+#define PKO_REG_ERROR_OFFSET 0x00088ULL
+#define PKO_REG_INT_MASK_OFFSET 0x00090ULL
+#define PKO_REG_DEBUG0_OFFSET 0x00098ULL
+#define PKO_MEM_QUEUE_PTRS_OFFSET 0x01000ULL
+#define PKO_MEM_QUEUE_QOS_OFFSET 0x01008ULL
+#define PKO_MEM_COUNT0_OFFSET 0x01080ULL
+#define PKO_MEM_COUNT1_OFFSET 0x01088ULL
+#define PKO_MEM_DEBUG0_OFFSET 0x01100ULL
+#define PKO_MEM_DEBUG1_OFFSET 0x01108ULL
+#define PKO_MEM_DEBUG2_OFFSET 0x01110ULL
+#define PKO_MEM_DEBUG3_OFFSET 0x01118ULL
+#define PKO_MEM_DEBUG4_OFFSET 0x01120ULL
+#define PKO_MEM_DEBUG5_OFFSET 0x01128ULL
+#define PKO_MEM_DEBUG6_OFFSET 0x01130ULL
+#define PKO_MEM_DEBUG7_OFFSET 0x01138ULL
+#define PKO_MEM_DEBUG8_OFFSET 0x01140ULL
+#define PKO_MEM_DEBUG9_OFFSET 0x01148ULL
+#define PKO_MEM_DEBUG10_OFFSET 0x01150ULL
+#define PKO_MEM_DEBUG11_OFFSET 0x01158ULL
+#define PKO_MEM_DEBUG12_OFFSET 0x01160ULL
+#define PKO_MEM_DEBUG13_OFFSET 0x01168ULL
+#define PKO_MEM_DEBUG14_OFFSET 0x01170ULL
+
+/*
+ * PKO_REG_FLAGS
+ */
+#define PKO_REG_FLAGS_63_7 0xfffffffffffffff0ULL
+#define PKO_REG_FLAGS_RESET 0x0000000000000008ULL
+#define PKO_REG_FLAGS_STORE_BE 0x0000000000000004ULL
+#define PKO_REG_FLAGS_ENA_DWB 0x0000000000000002ULL
+#define PKO_REG_FLAGS_ENA_PKO 0x0000000000000001ULL
+
+/*
+ * PKO_REG_READ_IDX
+ */
+#define PKO_REG_READ_IDX_63_16 0xffffffffffff0000ULL
+#define PKO_REG_READ_IDX_INC 0x000000000000ff00ULL
+#define PKO_REG_READ_IDX_IDX 0x00000000000000ffULL
+
+/*
+ * PKO_REG_CMD_BUF
+ */
+#define PKO_REG_CMD_BUF_63_23 0xffffffffff800000ULL
+#define PKO_REG_CMD_BUF_POOL 0x0000000000700000ULL
+#define PKO_REG_CMD_BUF_19_13 0x00000000000fe000ULL
+#define PKO_REG_CMD_BUF_SIZE 0x0000000000001fffULL
+
+/*
+ * PKO_REG_GMX_PORT_MODE
+ */
+#define PKO_REG_GMX_PORT_MODE_63_6 0xffffffffffffffc0ULL
+#define PKO_REG_GMX_PORT_MODE_MODE1 0x0000000000000038ULL
+#define PKO_REG_GMX_PORT_MODE_MODE0 0x0000000000000007ULL
+
+/*
+ * PKO_REG_QUEUE_MODE
+ */
+#define PKO_REG_QUEUE_MODE_63_6 0xfffffffffffffffcULL
+#define PKO_REG_QUEUE_MODE_MODE 0x000000000000000eULL
+
+/*
+ * PKO_REG_BIST_RESULT
+ */
+#define PKO_REG_BIST_RESULT_63_27 0xfffffffff8000000ULL
+#define PKO_REG_BIST_RESULT_PSB2 0x0000000007c00000ULL
+#define PKO_REG_BIST_RESULT_COUNT 0x0000000000200000ULL
+#define PKO_REG_BIST_RESULT_RIF 0x0000000000100000ULL
+#define PKO_REG_BIST_RESULT_WIF 0x0000000000080000ULL
+#define PKO_REG_BIST_RESULT_NCB 0x0000000000040000ULL
+#define PKO_REG_BIST_RESULT_OUT 0x0000000000020000ULL
+#define PKO_REG_BIST_RESULT_CRC 0x0000000000010000ULL
+#define PKO_REG_BIST_RESULT_CHK 0x0000000000008000ULL
+#define PKO_REG_BIST_RESULT_QSB 0x0000000000006000ULL
+#define PKO_REG_BIST_RESULT_QCB 0x0000000000001800ULL
+#define PKO_REG_BIST_RESULT_PDB 0x0000000000000780ULL
+#define PKO_REG_BIST_RESULT_PSB 0x000000000000007fULL
+
+/*
+ * PKO_REG_ERROR
+ */
+#define PKO_REG_ERROR_63_2 0xfffffffffffffffcULL
+#define PKO_REG_ERROR_DOORBELL 0x0000000000000002ULL
+#define PKO_REG_ERROR_PARITY 0x0000000000000001ULL
+
+/*
+ * PKO_REG_INT_MASK
+ */
+#define PKO_REG_INT_MASK_63_2 0xfffffffffffffffcULL
+#define PKO_REG_INT_MASK_DOORBELL 0x0000000000000002ULL
+#define PKO_REG_INT_MASK_PARITY 0x0000000000000001ULL
+
+/*
+ * PKO_REG_DEBUG0
+ */
+#define PKO_REG_DEBUG0_63_17 0xfffffffffffe0000ULL
+#define PKO_REG_DEBUG0_ASSERTS 0x000000000001ffffULL
+
+/*
+ * PKO_MEM_QUEUE_PTRS
+ */
+#define PKO_MEM_QUEUE_PTRS_S_TAIL 0x8000000000000000ULL
+#define PKO_MEM_QUEUE_PTRS_STATIC_P 0x4000000000000000ULL
+#define PKO_MEM_QUEUE_PTRS_STATIC_Q 0x2000000000000000ULL
+#define PKO_MEM_QUEUE_PTRS_QOS_MASK 0x1fe0000000000000ULL
+#define PKO_MEM_QUEUE_PTRS_BUF_PTR 0x001ffffffffe0000ULL
+#define PKO_MEM_QUEUE_PTRS_TAIL 0x0000000000010000ULL
+#define PKO_MEM_QUEUE_PTRS_IDX 0x000000000000e000ULL
+#define PKO_MEM_QUEUE_PTRS_PID 0x0000000000001f80ULL
+#define PKO_MEM_QUEUE_PTRS_QID 0x000000000000007fULL
+
+/*
+ * PKO_MEM_QUEUE_QOS
+ */
+#define PKO_MEM_QUEUE_QOS_63_61 0xe000000000000000ULL
+#define PKO_MEM_QUEUE_QOS_QOS_MASK 0x1fe0000000000000ULL
+#define PKO_MEM_QUEUE_QOS_52_13 0x001fffffffffe000ULL
+#define PKO_MEM_QUEUE_QOS_PID 0x0000000000001f80ULL
+#define PKO_MEM_QUEUE_QOS_QID 0x000000000000007fULL
+
+/*
+ * PKO_MEM_COUNT0
+ */
+#define PKO_MEM_COUNT0_63_32 0xffffffff00000000ULL
+#define PKO_MEM_COUNT0_COUNT 0x00000000ffffffffULL
+
+/*
+ * PKO_MEM_COUNT1
+ */
+#define PKO_MEM_COUNT1_63_48 0xffff000000000000ULL
+#define PKO_MEM_COUNT1_COUNT 0x0000ffffffffffffULL
+
+/*
+ * PKO_MEM_DEBUG0
+ */
+#define PKO_MEM_DEBUG0_FAU 0xfffffff000000000ULL
+#define PKO_MEM_DEBUG0_CMD 0x0000000fffc00000ULL
+#define PKO_MEM_DEBUG0_SEGS 0x00000000003f0000ULL
+#define PKO_MEM_DEBUG0_SIZE 0x000000000000ffffULL
+
+/*
+ * PKO_MEM_DEBUG1
+ */
+#define PKO_MEM_DEBUG1_I 0x8000000000000000ULL
+#define PKO_MEM_DEBUG1_BACK 0x7800000000000000ULL
+#define PKO_MEM_DEBUG1_POOL 0x0700000000000000ULL
+#define PKO_MEM_DEBUG1_SIZE 0x00ffff0000000000ULL
+#define PKO_MEM_DEBUG1_PTR 0x000000ffffffffffULL
+
+/*
+ * PKO_MEM_DEBUG2
+ */
+#define PKO_MEM_DEBUG2_I 0x8000000000000000ULL
+#define PKO_MEM_DEBUG2_BACK 0x7800000000000000ULL
+#define PKO_MEM_DEBUG2_POOL 0x0700000000000000ULL
+#define PKO_MEM_DEBUG2_SIZE 0x00ffff0000000000ULL
+#define PKO_MEM_DEBUG2_PTR 0x000000ffffffffffULL
+
+/*
+ * PKO_MEM_DEBUG3
+ */
+#define PKO_MEM_DEBUG3_I 0x8000000000000000ULL
+#define PKO_MEM_DEBUG3_BACK 0x7800000000000000ULL
+#define PKO_MEM_DEBUG3_POOL 0x0700000000000000ULL
+#define PKO_MEM_DEBUG3_SIZE 0x00ffff0000000000ULL
+#define PKO_MEM_DEBUG3_PTR 0x000000ffffffffffULL
+
+/*
+ * PKO_MEM_DEBUG4
+ */
+#define PKO_MEM_DEBUG4_DATA 0xffffffffffffffffULL
+
+/*
+ * PKO_MEM_DEBUG5
+ */
+#define PKO_MEM_DEBUG5_DWRI_MOD 0x8000000000000000ULL
+#define PKO_MEM_DEBUG5_DWRI_SOP 0x4000000000000000ULL
+#define PKO_MEM_DEBUG5_DWRI_LEN 0x2000000000000000ULL
+#define PKO_MEM_DEBUG5_DWRI_CNT 0x1fff000000000000ULL
+#define PKO_MEM_DEBUG5_CMND_SIZ 0x0000ffff00000000ULL
+#define PKO_MEM_DEBUG5_UID 0x0000000080000000ULL
+#define PKO_MEM_DEBUG5_XFER_WOR 0x0000000040000000ULL
+#define PKO_MEM_DEBUG5_XFER_DWR 0x0000000020000000ULL
+#define PKO_MEM_DEBUG5_CBUF_FRE 0x0000000010000000ULL
+#define PKO_MEM_DEBUG5_27 0x0000000008000000ULL
+#define PKO_MEM_DEBUG5_CHK_MODE 0x0000000004000000ULL
+#define PKO_MEM_DEBUG5_ACTIVE 0x0000000002000000ULL
+#define PKO_MEM_DEBUG5_QOS 0x0000000001c00000ULL
+#define PKO_MEM_DEBUG5_QCB_RIDX 0x00000000003e0000ULL
+#define PKO_MEM_DEBUG5_QID_OFF 0x000000000001c000ULL
+#define PKO_MEM_DEBUG5_QID_BASE 0x0000000000003f80ULL
+#define PKO_MEM_DEBUG5_WAIT 0x0000000000000040ULL
+#define PKO_MEM_DEBUG5_MINOR 0x0000000000000030ULL
+#define PKO_MEM_DEBUG5_MAJOR 0x000000000000000fULL
+
+/*
+ * PKO_MEM_DEBUG6
+ */
+#define PKO_MEM_DEBUG6_63_11 0xfffffffffffff800ULL
+#define PKO_MEM_DEBUG6_QID_OFFM 0x0000000000000700ULL
+#define PKO_MEM_DEBUG6_STATIC_P 0x0000000000000080ULL
+#define PKO_MEM_DEBUG6_WORK_MIN 0x0000000000000070ULL
+#define PKO_MEM_DEBUG6_DWRI_CHK 0x0000000000000008ULL
+#define PKO_MEM_DEBUG6_DWRI_UID 0x0000000000000004ULL
+#define PKO_MEM_DEBUG6_DWRI_MOD 0x0000000000000003ULL
+
+/*
+ * PKO_MEM_DEBUG7
+ */
+#define PKO_MEM_DEBUG7_63_58 0xfc00000000000000ULL
+#define PKO_MEM_DEBUG7_DWB 0x03fe000000000000ULL
+#define PKO_MEM_DEBUG7_START 0x0001ffffffff0000ULL
+#define PKO_MEM_DEBUG7_SIZE 0x000000000000ffffULL
+
+/*
+ * PKO_MEM_DEBUG8
+ */
+#define PKO_MEM_DEBUG8_QOS 0xf800000000000000ULL
+#define PKO_MEM_DEBUG8_TAIL 0x0400000000000000ULL
+#define PKO_MEM_DEBUG8_BUF_SIZ 0x03ffe00000000000ULL
+#define PKO_MEM_DEBUG8_BUF_PTR 0x00001ffffffff000ULL
+#define PKO_MEM_DEBUG8_QCB_WIDX 0x0000000000000fc0ULL
+#define PKO_MEM_DEBUG8_QCB_RIDX 0x000000000000003fULL
+
+/*
+ * PKO_MEM_DEBUG9
+ */
+#define PKO_MEM_DEBUG9_63_28 0xfffffffff0000000ULL
+#define PKO_MEM_DEBUG9_DOORBELL 0x000000000fffff00ULL
+#define PKO_MEM_DEBUG9_7_5 0x00000000000000e0ULL
+#define PKO_MEM_DEBUG9_S_TAIL 0x0000000000000010ULL
+#define PKO_MEM_DEBUG9_STATIC_Q 0x0000000000000008ULL
+#define PKO_MEM_DEBUG9_QOOS 0x0000000000000007ULL
+
+/*
+ * PKO_MEM_DEBUG10
+ */
+#define PKO_MEM_DEBUG10_FAU 0xfffffff000000000ULL
+#define PKO_MEM_DEBUG10_CMD 0x0000000fffc00000ULL
+#define PKO_MEM_DEBUG10_SEGS 0x00000000003f0000ULL
+#define PKO_MEM_DEBUG10_SIZE 0x000000000000ffffULL
+
+/*
+ * PKO_MEM_DEBUG11
+ */
+#define PKO_MEM_DEBUG11_I 0x8000000000000000ULL
+#define PKO_MEM_DEBUG11_BACK 0x7800000000000000ULL
+#define PKO_MEM_DEBUG11_POOL 0x0700000000000000ULL
+#define PKO_MEM_DEBUG11_SIZE 0x00ffff0000000000ULL
+#define PKO_MEM_DEBUG11_PTR 0x000000ffffffffffULL
+
+/*
+ * PKO_MEM_DEBUG12
+ */
+#define PKO_MEM_DEBUG12_DATA 0xffffffffffffffffULL
+
+/*
+ * PKO_MEM_DEBUG13
+ */
+#define PKO_MEM_DEBUG13_63_51 0xfff8000000000000ULL
+#define PKO_MEM_DEBUG13_WIDX 0x0007fffc00000000ULL
+#define PKO_MEM_DEBUG13_RIDX2 0x00000003fffe0000ULL
+#define PKO_MEM_DEBUG13_WIDX2 0x000000000001ffffULL
+
+/*
+ * PKO_MEM_DEBUG14
+ */
+#define PKO_MEM_DEBUG13_63_17 0xfffffffffffe0000ULL
+#define PKO_MEM_DEBUG13_RIDX 0x000000000001ffffULL
+
+/*
+ * PKO_CMD_WORD0
+ */
+#define PKO_CMD_WORD0_SZ1 0xc000000000000000ULL
+#define PKO_CMD_WORD0_SZ0 0x3000000000000000ULL
+#define PKO_CMD_WORD0_S1 0x0800000000000000ULL
+#define PKO_CMD_WORD0_REG1 0x07ff000000000000ULL
+#define PKO_CMD_WORD0_S0 0x0000800000000000ULL
+#define PKO_CMD_WORD0_REG0 0x00007ff000000000ULL
+#define PKO_CMD_WORD0_LE 0x0000000800000000ULL
+#define PKO_CMD_WORD0_N2 0x0000000400000000ULL
+#define PKO_CMD_WORD0_Q 0x0000000200000000ULL
+#define PKO_CMD_WORD0_R 0x0000000100000000ULL
+#define PKO_CMD_WORD0_G 0x0000000080000000ULL
+#define PKO_CMD_WORD0_IPOFFP1 0x000000007f000000ULL
+#define PKO_CMD_WORD0_II 0x0000000000800000ULL
+#define PKO_CMD_WORD0_DF 0x0000000000400000ULL
+#define PKO_CMD_WORD0_SEGS 0x00000000003f0000ULL
+#define PKO_CMD_WORD0_TOTALBYTES 0x000000000000ffffULL
+
+/*
+ * PKO_CMD_WORD1
+ */
+#define PKO_CMD_WORD1_I 0x8000000000000000ULL
+#define PKO_CMD_WORD1_BACK 0x7800000000000000ULL
+#define PKO_CMD_WORD1_POOL 0x0700000000000000ULL
+#define PKO_CMD_WORD1_SIZE 0x00ffff0000000000ULL
+#define PKO_CMD_WORD1_ADDR 0x000000ffffffffffULL
+
+/*
+ * PKO_CMD_WORD2
+ */
+#define PKO_CMD_WORD2_63_36 0xfffffff000000000ULL
+#define PKO_CMD_WORD2_PTR 0x0000000fffffffffULL
+
+/*
+ * DOORBELL_WRITE
+ */
+#define PKO_DOORBELL_WRITE_IO_BIT 0x0001000000000000ULL
+#define PKO_DOORBELL_WRITE_MAJOR_DID 0x0000f80000000000ULL
+#define PKO_DOORBELL_WRITE_SUB_DID 0x0000070000000000ULL
+#define PKO_DOORBELL_WRITE_39_16 0x000000ffffff0000ULL
+#define PKO_DOORBELL_WRITE_PID 0x000000000003f000ULL
+#define PKO_DOORBELL_WRITE_QID 0x0000000000000ff8ULL
+#define PKO_DOORBELL_WRITE_2_0 0x0000000000000007ULL
+
+#define PKO_DOORBELL_WRITE_WDC 0x00000000000fffffULL
+
+/* ---- operations */
+
+#define CN30XXPKO_MAJORDID 0x0a
+#define CN30XXPKO_SUBDID 0x02
+
+#endif /* _CN30XXPKOREG_H_ */
+
diff --git a/sys/arch/octeon/dev/cn30xxpkovar.h b/sys/arch/octeon/dev/cn30xxpkovar.h
new file mode 100644
index 00000000000..d752634d4f8
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxpkovar.h
@@ -0,0 +1,173 @@
+/* $OpenBSD: cn30xxpkovar.h,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Cavium Networks OCTEON CN30XX Hardware Reference Manual
+ * CN30XX-HM-1.0
+ * 8.9 PKO Registers
+ */
+
+#ifndef _CN30XXPKOVAR_H_
+#define _CN30XXPKOVAR_H_
+
+#include <octeon/dev/cn30xxfauvar.h>
+#include <octeon/dev/cn30xxpkoreg.h>
+
+#ifndef SET
+#define SET(t, f) ((t) |= (f))
+#define ISSET(t, f) ((t) & (f))
+#define CLR(t, f) ((t) &= ~(f))
+#endif
+
+#define FAU_OP_SIZE_8 0
+#define FAU_OP_SIZE_16 1
+#define FAU_OP_SIZE_32 2
+#define FAU_OP_SIZE_64 3
+
+#define PKO_OUTPUT_PORTS_NUM 5
+#define PKO_OUTPUT_PORTS_PKTIF_NUM 3
+#define PKO_OUTPUT_PORTS_PCIIF_NUM 2
+#define PKO_MEM_QUEUE_PTRS_ILLEGAL_PID 63
+
+/* XXX */
+struct cn30xxpko_cmdptr_desc {
+ uint64_t cmdptr;
+ uint64_t cmdptr_idx;
+};
+
+/* XXX */
+struct cn30xxpko_softc {
+ int sc_port;
+ bus_space_tag_t sc_regt;
+ bus_space_handle_t sc_regh;
+ struct cn30xxpko_cmdptr_desc
+ *sc_cmdptr;
+ int sc_cmd_buf_pool;
+ size_t sc_cmd_buf_size;
+
+#ifdef OCTEON_ETH_DEBUG
+ struct evcnt sc_ev_pkoerrdbell;
+ struct evcnt sc_ev_pkoerrparity;
+#endif
+};
+
+/* XXX */
+struct cn30xxpko_attach_args {
+ int aa_port;
+ bus_space_tag_t aa_regt;
+ struct cn30xxpko_cmdptr_desc *aa_cmdptr;
+ int aa_cmd_buf_pool;
+ size_t aa_cmd_buf_size;
+};
+
+/* XXX */
+void cn30xxpko_init(struct cn30xxpko_attach_args *,
+ struct cn30xxpko_softc **);
+int cn30xxpko_enable(struct cn30xxpko_softc *);
+int cn30xxpko_reset(struct cn30xxpko_softc *);
+void cn30xxpko_config(struct cn30xxpko_softc *);
+int cn30xxpko_port_enable(struct cn30xxpko_softc *, int);
+int cn30xxpko_port_config(struct cn30xxpko_softc *);
+void cn30xxpko_int_enable(struct cn30xxpko_softc *, int);
+uint64_t cn30xxpko_int_summary(struct cn30xxpko_softc *);
+static inline uint64_t cn30xxpko_cmd_word0(int, int, int, int, int, int,
+ int, int, int, int, int, int, int, int, int, int);
+static inline uint64_t cn30xxpko_cmd_word1(int, int, int, int, paddr_t);
+
+
+static inline uint64_t
+cn30xxpko_cmd_word0(int sz1, int sz0, int s1, int reg1, int s0, int reg0,
+ int le, int n2, int q, int r, int g, int ipoffp1, int ii, int df, int segs,
+ int totalbytes)
+{
+ uint64_t cmd = 0;
+
+ SET(cmd, (((uint64_t)sz1 << 62) & PKO_CMD_WORD0_SZ1)
+ | (((uint64_t)sz0 << 60) & PKO_CMD_WORD0_SZ0)
+ | (((uint64_t)s1 << 59) & PKO_CMD_WORD0_S1)
+ | (((uint64_t)reg1 << 48) & PKO_CMD_WORD0_REG1)
+ | (((uint64_t)s0 << 47) & PKO_CMD_WORD0_S0)
+ | (((uint64_t)reg0 << 36) & PKO_CMD_WORD0_REG0)
+ | (((uint64_t)le << 35) & PKO_CMD_WORD0_LE)
+ | (((uint64_t)n2 << 34) & PKO_CMD_WORD0_N2)
+ | (((uint64_t)q << 33) & PKO_CMD_WORD0_Q)
+ | (((uint64_t)r << 32) & PKO_CMD_WORD0_R)
+ | (((uint64_t)g << 31) & PKO_CMD_WORD0_G)
+ | (((uint64_t)ipoffp1 << 24) & PKO_CMD_WORD0_IPOFFP1)
+ | (((uint64_t)ii << 23) & PKO_CMD_WORD0_II)
+ | (((uint64_t)df << 22) & PKO_CMD_WORD0_DF)
+ | (((uint64_t)segs << 16) & PKO_CMD_WORD0_SEGS)
+ | (((uint64_t)totalbytes << 0) & PKO_CMD_WORD0_TOTALBYTES));
+ return cmd;
+}
+
+static inline uint64_t
+cn30xxpko_cmd_word1(int i, int back, int pool, int size, paddr_t addr)
+{
+ uint64_t cmd = 0;
+
+ SET(cmd, (((uint64_t)i << 63) & PKO_CMD_WORD1_I)
+ | (((uint64_t)back << 59) & PKO_CMD_WORD1_BACK)
+ | (((uint64_t)pool << 56) & PKO_CMD_WORD1_POOL)
+ | (((uint64_t)size << 40) & PKO_CMD_WORD1_SIZE)
+ | (((uint64_t)addr << 0) & PKO_CMD_WORD1_ADDR));
+ return cmd;
+}
+
+/* ---- operation primitives */
+
+/* 8.8.1 Store Operations */
+
+static inline void
+cn30xxpko_op_store(uint64_t args, uint64_t value)
+{
+ paddr_t addr;
+
+ addr =
+ ((uint64_t)1 << 48) |
+ ((uint64_t)(CN30XXPKO_MAJORDID & 0x1f) << 43) |
+ ((uint64_t)(CN30XXPKO_SUBDID & 0x7) << 40) |
+ ((uint64_t)args);
+ /* XXX */
+ OCTEON_SYNCW;
+ octeon_write_csr(addr, value);
+}
+
+static inline void
+cn30xxpko_op_doorbell_write(int pid, int qid, int wdc)
+{
+ uint64_t args, value;
+
+ args =
+ ((uint64_t)(pid & 0x3f) << 12) |
+ ((uint64_t)(qid & 0x1ff) << 3);
+ value = wdc & 0xfffff;
+ cn30xxpko_op_store(args, value);
+}
+
+#endif
diff --git a/sys/arch/octeon/dev/cn30xxpow.c b/sys/arch/octeon/dev/cn30xxpow.c
new file mode 100644
index 00000000000..e28f2753362
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxpow.c
@@ -0,0 +1,1079 @@
+/* $OpenBSD: cn30xxpow.c,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/types.h>
+#include <sys/kernel.h> /* hz */
+#include <sys/malloc.h>
+#include <sys/device.h> /* evcnt */
+#include <sys/syslog.h> /* evcnt */
+
+#include <machine/bus.h>
+#include <machine/octeonvar.h>
+
+#include <octeon/dev/iobusvar.h>
+#include <octeon/dev/cn30xxciureg.h> /* XXX */
+#include <octeon/dev/cn30xxpowreg.h>
+#include <octeon/dev/cn30xxpowvar.h>
+
+/* XXX ensure assertion */
+#if !defined(DIAGNOSTIC)
+#define DIAGNOSTIC
+#endif
+
+extern int ipflow_fastforward_disable_flags;
+
+struct cn30xxpow_intr_handle {
+ void *pi_ih;
+ struct cn30xxpow_softc *pi_sc;
+ int pi_group;
+ void (*pi_cb)(void *, uint64_t *);
+ void *pi_data;
+
+#ifdef OCTEON_ETH_DEBUG
+#define _EV_PER_N 32 /* XXX */
+#define _EV_IVAL_N 32 /* XXX */
+ int pi_first;
+ struct timeval pi_last;
+ struct evcnt pi_ev_per[_EV_PER_N];
+ struct evcnt pi_ev_ival[_EV_IVAL_N];
+ struct evcnt pi_ev_stray_tc;
+ struct evcnt pi_ev_stray_ds;
+ struct evcnt pi_ev_stray_iq;
+#endif
+};
+
+void cn30xxpow_bootstrap(struct octeon_config *);
+
+#ifdef OCTEON_ETH_DEBUG
+void cn30xxpow_intr_evcnt_attach(struct cn30xxpow_softc *);
+void cn30xxpow_intr_rml(void *);
+
+static void cn30xxpow_intr_debug_init(
+ struct cn30xxpow_intr_handle *, int);
+static void cn30xxpow_intr_work_debug_ival(struct cn30xxpow_softc *,
+ struct cn30xxpow_intr_handle *);
+static void cn30xxpow_intr_work_debug_per(struct cn30xxpow_softc *,
+ struct cn30xxpow_intr_handle *, int);
+#endif
+static void cn30xxpow_init(struct cn30xxpow_softc *);
+static void cn30xxpow_init_regs(struct cn30xxpow_softc *);
+static int cn30xxpow_tag_sw_poll(void);
+static void cn30xxpow_tag_sw_wait(void);
+static void cn30xxpow_config_int_pc(struct cn30xxpow_softc *, int);
+static void cn30xxpow_config_int(struct cn30xxpow_softc *, int,
+ uint64_t, uint64_t, uint64_t);
+static void cn30xxpow_intr_work(struct cn30xxpow_softc *,
+ struct cn30xxpow_intr_handle *, int);
+static int cn30xxpow_intr(void *);
+
+#ifdef OCTEON_ETH_DEBUG
+void cn30xxpow_dump(void);
+#endif
+
+/* XXX */
+struct cn30xxpow_softc cn30xxpow_softc;
+
+#ifdef OCTEON_ETH_DEBUG
+struct cn30xxpow_softc *__cn30xxpow_softc;
+#endif
+
+/*
+ * XXX: parameter tuning is needed: see files.octeon
+ */
+#ifndef OCTEON_ETH_RING_MAX
+#define OCTEON_ETH_RING_MAX 512
+#endif
+#ifndef OCTEON_ETH_RING_MIN
+#define OCTEON_ETH_RING_MIN 1
+#endif
+
+#ifdef OCTEON_ETH_INTR_FEEDBACK_RING
+int max_recv_cnt = OCTEON_ETH_RING_MAX;
+int min_recv_cnt = OCTEON_ETH_RING_MIN;
+int recv_cnt = OCTEON_ETH_RING_MIN;
+int int_rate = 1;
+#else
+/* infinity */
+int max_recv_cnt = 0;
+int min_recv_cnt = 0;
+int recv_cnt = 0;
+#endif
+
+/* -------------------------------------------------------------------------- */
+
+/* ---- operation primitive functions */
+
+/* 5.11.1 Load Operations */
+
+/* 5.11.2 IOBDMA Operations */
+
+/* 5.11.3 Store Operations */
+
+/* -------------------------------------------------------------------------- */
+
+/* ---- utility functions */
+
+void
+cn30xxpow_work_request_async(uint64_t scraddr, uint64_t wait)
+{
+ cn30xxpow_ops_get_work_iobdma(scraddr, wait);
+}
+
+uint64_t *
+cn30xxpow_work_response_async(uint64_t scraddr)
+{
+ uint64_t result;
+
+ OCTEON_SYNCIOBDMA;
+ result = octeon_cvmseg_read_8(scraddr);
+
+ return (result & POW_IOBDMA_GET_WORK_RESULT_NO_WORK) ?
+ NULL :
+ (uint64_t *)PHYS_TO_CKSEG0(
+ result & POW_IOBDMA_GET_WORK_RESULT_ADDR);
+}
+
+/* ---- status by coreid */
+
+static inline uint64_t
+cn30xxpow_status_by_coreid_pend_tag(int coreid)
+{
+ return cn30xxpow_ops_pow_status(coreid, 0, 0, 0);
+}
+
+static inline uint64_t
+cn30xxpow_status_by_coreid_pend_wqp(int coreid)
+{
+ return cn30xxpow_ops_pow_status(coreid, 0, 0, 1);
+}
+
+static inline uint64_t
+cn30xxpow_status_by_coreid_cur_tag_next(int coreid)
+{
+ return cn30xxpow_ops_pow_status(coreid, 0, 1, 0);
+}
+
+static inline uint64_t
+cn30xxpow_status_by_coreid_cur_tag_prev(int coreid)
+{
+ return cn30xxpow_ops_pow_status(coreid, 1, 1, 0);
+}
+
+static inline uint64_t
+cn30xxpow_status_by_coreid_cur_wqp_next(int coreid)
+{
+ return cn30xxpow_ops_pow_status(coreid, 0, 1, 1);
+}
+
+static inline uint64_t
+cn30xxpow_status_by_coreid_cur_wqp_prev(int coreid)
+{
+ return cn30xxpow_ops_pow_status(coreid, 1, 1, 1);
+}
+
+/* ---- status by index */
+
+static inline uint64_t
+cn30xxpow_status_by_index_tag(int index)
+{
+ return cn30xxpow_ops_pow_memory(index, 0, 0);
+}
+
+static inline uint64_t
+cn30xxpow_status_by_index_wqp(int index)
+{
+ return cn30xxpow_ops_pow_memory(index, 0, 1);
+}
+
+static inline uint64_t
+cn30xxpow_status_by_index_desched(int index)
+{
+ return cn30xxpow_ops_pow_memory(index, 1, 0);
+}
+
+/* ---- status by qos level */
+
+static inline uint64_t
+cn30xxpow_status_by_qos_free_loc(int qos)
+{
+ return cn30xxpow_ops_pow_idxptr(qos, 0, 0);
+}
+
+/* ---- status by desched group */
+
+static inline uint64_t
+cn30xxpow_status_by_grp_nosched_des(int grp)
+{
+ return cn30xxpow_ops_pow_idxptr(grp, 0, 1);
+}
+
+/* ---- status by memory input queue */
+
+static inline uint64_t
+cn30xxpow_status_by_queue_remote_head(int queue)
+{
+ return cn30xxpow_ops_pow_idxptr(queue, 1, 0);
+}
+
+static inline uint64_t
+cn30xxpow_status_by_queue_remote_tail(int queue)
+{
+ return cn30xxpow_ops_pow_idxptr(queue, 1, 0);
+}
+
+/* ---- tag switch */
+
+/*
+ * "RDHWR rt, $30" returns:
+ * 0 => pending bit is set
+ * 1 => pending bit is clear
+ */
+
+/* return 1 if pending bit is clear (ready) */
+static int
+cn30xxpow_tag_sw_poll(void)
+{
+ uint64_t result;
+
+ __asm __volatile (
+ " .set push \n"
+ " .set noreorder \n"
+ " .set arch=mips64r2 \n"
+ " rdhwr %[result], $30 \n"
+ " .set pop \n"
+ : [result]"=r"(result)
+ );
+ return (int)result;
+}
+
+static void
+cn30xxpow_tag_sw_wait(void)
+{
+
+ while (cn30xxpow_tag_sw_poll() == 0)
+ continue;
+}
+
+/* -------------------------------------------------------------------------- */
+
+/* ---- initialization and configuration */
+
+void
+cn30xxpow_bootstrap(struct octeon_config *mcp)
+{
+ struct cn30xxpow_softc *sc = &cn30xxpow_softc;
+
+ sc->sc_regt = mcp->mc_iobus_bust;
+ /* XXX */
+
+ cn30xxpow_init(sc);
+
+#ifdef OCTEON_ETH_DEBUG
+ __cn30xxpow_softc = sc;
+#endif
+
+}
+
+static void
+cn30xxpow_config_int(struct cn30xxpow_softc *sc, int group,
+ uint64_t tc_thr, uint64_t ds_thr, uint64_t iq_thr)
+{
+ uint64_t wq_int_thr;
+
+ wq_int_thr =
+ POW_WQ_INT_THRX_TC_EN |
+ (tc_thr << POW_WQ_INT_THRX_TC_THR_SHIFT) |
+ (ds_thr << POW_WQ_INT_THRX_DS_THR_SHIFT) |
+ (iq_thr << POW_WQ_INT_THRX_IQ_THR_SHIFT);
+ _POW_WR8(sc, POW_WQ_INT_THR0_OFFSET + (group * 8), wq_int_thr);
+}
+
+/*
+ * interrupt threshold configuration
+ *
+ * => DS / IQ
+ * => ...
+ * => time counter threshold
+ * => unit is 1msec
+ * => each group can set timeout
+ * => temporary disable bit
+ * => use CIU generic timer
+ */
+
+void
+cn30xxpow_config(struct cn30xxpow_softc *sc, int group)
+{
+
+ cn30xxpow_config_int(sc, group,
+ 0x0f, /* TC */
+ 0x00, /* DS */
+ 0x00); /* IQ */
+}
+
+void *
+cn30xxpow_intr_establish(int group, int level,
+ void (*cb)(void *, uint64_t *), void (*fcb)(int*, int *, uint64_t, void *),
+ void *data, char *what)
+{
+ struct cn30xxpow_intr_handle *pow_ih;
+
+ KASSERT(group >= 0);
+ KASSERT(group < 16);
+
+ pow_ih = malloc(sizeof(*pow_ih), M_DEVBUF, M_NOWAIT);
+ KASSERT(pow_ih != NULL);
+
+ pow_ih->pi_ih = octeon_intr_establish(
+ ffs64(CIU_INTX_SUM0_WORKQ_0) - 1 + group,
+ level,
+ cn30xxpow_intr, pow_ih, what);
+ KASSERT(pow_ih->pi_ih != NULL);
+
+ pow_ih->pi_sc = &cn30xxpow_softc; /* XXX */
+ pow_ih->pi_group = group;
+ pow_ih->pi_cb = cb;
+ pow_ih->pi_data = data;
+
+#ifdef OCTEON_ETH_DEBUG
+ cn30xxpow_intr_debug_init(pow_ih, group);
+#endif
+ return pow_ih;
+}
+
+#ifdef OCTEON_ETH_DEBUG
+#define _NAMELEN 8
+#define _DESCRLEN 40
+
+static void
+cn30xxpow_intr_debug_init(struct cn30xxpow_intr_handle *pow_ih, int group)
+{
+ pow_ih->pi_first = 1;
+ char *name, *descr;
+ int i;
+
+ name = malloc(_NAMELEN +
+ _DESCRLEN * nitems(pow_ih->pi_ev_per) +
+ _DESCRLEN * nitems(pow_ih->pi_ev_ival),
+ M_DEVBUF, M_NOWAIT);
+ descr = name + _NAMELEN;
+ snprintf(name, _NAMELEN, "pow%d", group);
+ for (i = 0; i < (int)nitems(pow_ih->pi_ev_per); i++) {
+ int n = 1 << (i - 1);
+
+ (void)snprintf(descr, _DESCRLEN,
+ "# of works per intr (%d-%d)",
+ (i == 0) ? 0 : n,
+ (i == 0) ? 0 : ((n << 1) - 1));
+ evcnt_attach_dynamic(&pow_ih->pi_ev_per[i],
+ EVCNT_TYPE_MISC, NULL, name, descr);
+ descr += _DESCRLEN;
+ }
+ for (i = 0; i < (int)nitems(pow_ih->pi_ev_ival); i++) {
+ int n = 1 << (i - 1);
+ int p, q;
+ char unit;
+
+ p = n;
+ q = (n << 1) - 1;
+ unit = 'u';
+ /*
+ * 0 is exceptional
+ */
+ if (i == 0)
+ p = q = 0;
+ /*
+ * count 1024usec as 1msec
+ *
+ * XXX this is not exact
+ */
+ if ((i - 1) >= 10) {
+ p /= 1000;
+ q /= 1000;
+ unit = 'm';
+ }
+ (void)snprintf(descr, _DESCRLEN, "intr interval (%d-%d%csec)",
+ p, q, unit);
+ evcnt_attach_dynamic(&pow_ih->pi_ev_ival[i],
+ EVCNT_TYPE_MISC, NULL, name, descr);
+ descr += _DESCRLEN;
+ }
+ evcnt_attach_dynamic(&pow_ih->pi_ev_stray_tc,
+ EVCNT_TYPE_MISC, NULL, name, "stray intr (TC)");
+ evcnt_attach_dynamic(&pow_ih->pi_ev_stray_ds,
+ EVCNT_TYPE_MISC, NULL, name, "stray intr (DS)");
+ evcnt_attach_dynamic(&pow_ih->pi_ev_stray_iq,
+ EVCNT_TYPE_MISC, NULL, name, "stray intr (IQ)");
+}
+#endif
+
+void
+cn30xxpow_init(struct cn30xxpow_softc *sc)
+{
+ cn30xxpow_init_regs(sc);
+
+ sc->sc_int_pc_base = 10000;
+ cn30xxpow_config_int_pc(sc, sc->sc_int_pc_base);
+
+#ifdef OCTEON_ETH_DEBUG
+ cn30xxpow_error_int_enable(sc, 1);
+#endif
+}
+
+void
+cn30xxpow_init_regs(struct cn30xxpow_softc *sc)
+{
+ int status;
+
+ status = bus_space_map(sc->sc_regt, POW_BASE, POW_SIZE, 0,
+ &sc->sc_regh);
+ if (status != 0)
+ panic("can't map %s space", "pow register");
+
+#ifdef OCTEON_ETH_DEBUG
+ _POW_WR8(sc, POW_ECC_ERR_OFFSET,
+ POW_ECC_ERR_IOP_IE | POW_ECC_ERR_RPE_IE |
+ POW_ECC_ERR_DBE_IE | POW_ECC_ERR_SBE_IE);
+#endif
+}
+
+/* -------------------------------------------------------------------------- */
+
+/* ---- interrupt handling */
+
+#ifdef OCTEON_ETH_DEBUG
+static void
+cn30xxpow_intr_work_debug_ival(struct cn30xxpow_softc *sc,
+ struct cn30xxpow_intr_handle *pow_ih)
+{
+ struct timeval now;
+ struct timeval ival;
+ int n;
+
+ microtime(&now);
+ if (__predict_false(pow_ih->pi_first == 1)) {
+ pow_ih->pi_first = 0;
+ goto stat_done;
+ }
+ timersub(&now, &pow_ih->pi_last, &ival);
+ if (ival.tv_sec != 0)
+ goto stat_done; /* XXX */
+ n = ffs64((uint64_t)ival.tv_usec);
+ if (n > (int)nitems(pow_ih->pi_ev_ival) - 1)
+ n = (int)nitems(pow_ih->pi_ev_ival) - 1;
+ pow_ih->pi_ev_ival[n].ev_count++;
+
+stat_done:
+ pow_ih->pi_last = now; /* struct copy */
+}
+
+static void
+cn30xxpow_intr_work_debug_per(struct cn30xxpow_softc *sc,
+ struct cn30xxpow_intr_handle *pow_ih, int count)
+{
+ int n;
+
+ n = ffs64(count);
+ if (n > (int)nitems(pow_ih->pi_ev_per) - 1)
+ n = (int)nitems(pow_ih->pi_ev_per) - 1;
+ pow_ih->pi_ev_per[n].ev_count++;
+#if 1
+ if (count == 0) {
+ uint64_t wq_int_cnt;
+
+ wq_int_cnt = _POW_GROUP_RD8(sc, pow_ih, POW_WQ_INT_CNT0_OFFSET);
+ if (wq_int_cnt & POW_WQ_INT_CNTX_TC_CNT)
+ pow_ih->pi_ev_stray_tc.ev_count++;
+ if (wq_int_cnt & POW_WQ_INT_CNTX_DS_CNT)
+ pow_ih->pi_ev_stray_ds.ev_count++;
+ if (wq_int_cnt & POW_WQ_INT_CNTX_IQ_CNT)
+ pow_ih->pi_ev_stray_iq.ev_count++;
+ }
+#endif
+}
+#endif
+
+#ifdef OCTEON_ETH_DEBUG
+#define _POW_INTR_WORK_DEBUG_IVAL(sc, ih) \
+ cn30xxpow_intr_work_debug_ival((sc), (ih))
+#define _POW_INTR_WORK_DEBUG_PER(sc, ih, count) \
+ cn30xxpow_intr_work_debug_per((sc), (ih), (count))
+#else
+#define _POW_INTR_WORK_DEBUG_IVAL(sc, ih) \
+ do {} while (0)
+#define _POW_INTR_WORK_DEBUG_PER(sc, ih, count) \
+ do {} while (0)
+#endif
+
+/*
+ * Interrupt handling by fixed count.
+ *
+ * XXX the fixed count (MAX_RX_CNT) could be changed dynamically?
+ *
+ * XXX this does not utilize "tag switch" very well
+ */
+/*
+ * usually all packet recieve
+ */
+#define MAX_RX_CNT 0x7fffffff
+
+static void
+cn30xxpow_intr_work(struct cn30xxpow_softc *sc,
+ struct cn30xxpow_intr_handle *pow_ih, int max_recv_cnt)
+{
+ uint64_t *work;
+ uint64_t count = 0;
+ int recv_cnt = MAX_RX_CNT;
+
+ /* s = splhigh(); */
+ _POW_WR8(sc, POW_PP_GRP_MSK0_OFFSET, 1ULL << pow_ih->pi_group);
+
+ if (max_recv_cnt > 0)
+ recv_cnt = max_recv_cnt - 1;
+
+ _POW_INTR_WORK_DEBUG_IVAL(sc, pow_ih);
+
+ cn30xxpow_tag_sw_wait();
+ cn30xxpow_work_request_async(OCTEON_CVMSEG_OFFSET(csm_pow_intr),
+ POW_NO_WAIT);
+
+ for (count = 0; count < recv_cnt; count++) {
+ work = (uint64_t *)cn30xxpow_work_response_async(
+ OCTEON_CVMSEG_OFFSET(csm_pow_intr));
+ if (work == NULL)
+ goto done;
+ cn30xxpow_tag_sw_wait();
+ cn30xxpow_work_request_async(
+ OCTEON_CVMSEG_OFFSET(csm_pow_intr), POW_NO_WAIT);
+ (*pow_ih->pi_cb)(pow_ih->pi_data, work);
+ }
+
+ work = (uint64_t *)cn30xxpow_work_response_async(
+ OCTEON_CVMSEG_OFFSET(csm_pow_intr));
+ if (work == NULL)
+ goto done;
+
+ (*pow_ih->pi_cb)(pow_ih->pi_data, work);
+ count++;
+
+done:
+ _POW_INTR_WORK_DEBUG_PER(sc, pow_ih, count);
+
+ /* KASSERT(work == NULL); */
+ /* KASSERT(count > 0); */
+
+ /* _POW_WR8(sc, POW_PP_GRP, 0)ULL; */
+ /* splx(s); */
+}
+
+static int
+cn30xxpow_intr(void *data)
+{
+ struct cn30xxpow_intr_handle *pow_ih = data;
+ struct cn30xxpow_softc *sc = pow_ih->pi_sc;
+ uint64_t wq_int_mask = 0x1ULL << pow_ih->pi_group;
+
+#if 0
+ if (ipflow_fastforward_disable_flags == 0)
+ cn30xxpow_intr_work(sc, pow_ih, -1);
+ else
+ cn30xxpow_intr_work(sc, pow_ih, recv_cnt);
+#else
+ cn30xxpow_intr_work(sc, pow_ih, recv_cnt);
+#endif
+
+ _POW_WR8(sc, POW_WQ_INT_OFFSET, wq_int_mask << POW_WQ_INT_WQ_INT_SHIFT);
+ return 1;
+}
+
+/* -------------------------------------------------------------------------- */
+
+/* ---- debug configuration */
+
+#ifdef OCTEON_ETH_DEBUG
+
+void
+cn30xxpow_error_int_enable(void *data, int enable)
+{
+ struct cn30xxpow_softc *sc = data;
+ uint64_t pow_error_int_xxx;
+
+ pow_error_int_xxx =
+ POW_ECC_ERR_IOP | POW_ECC_ERR_RPE |
+ POW_ECC_ERR_DBE | POW_ECC_ERR_SBE;
+ _POW_WR8(sc, POW_ECC_ERR_OFFSET, pow_error_int_xxx);
+ _POW_WR8(sc, POW_ECC_ERR_OFFSET, enable ? pow_error_int_xxx : 0);
+}
+
+uint64_t
+cn30xxpow_error_int_summary(void *data)
+{
+ struct cn30xxpow_softc *sc = data;
+ uint64_t summary;
+
+ summary = _POW_RD8(sc, POW_ECC_ERR_OFFSET);
+ _POW_WR8(sc, POW_ECC_ERR_OFFSET, summary);
+ return summary;
+}
+
+#endif
+
+/* -------------------------------------------------------------------------- */
+
+/* ---- debug counter */
+
+#ifdef OCTEON_ETH_DEBUG
+int cn30xxpow_intr_rml_verbose;
+struct evcnt cn30xxpow_intr_evcnt;
+
+static const struct octeon_evcnt_entry cn30xxpow_intr_evcnt_entries[] = {
+#define _ENTRY(name, type, parent, descr) \
+ OCTEON_EVCNT_ENTRY(struct cn30xxpow_softc, name, type, parent, descr)
+ _ENTRY(powecciopcsrpend, MISC, NULL, "pow csr load"),
+ _ENTRY(powecciopdbgpend, MISC, NULL, "pow dbg load"),
+ _ENTRY(powecciopaddwork, MISC, NULL, "pow addwork"),
+ _ENTRY(powecciopillop, MISC, NULL, "pow ill op"),
+ _ENTRY(poweccioppend24, MISC, NULL, "pow pend24"),
+ _ENTRY(poweccioppend23, MISC, NULL, "pow pend23"),
+ _ENTRY(poweccioppend22, MISC, NULL, "pow pend22"),
+ _ENTRY(poweccioppend21, MISC, NULL, "pow pend21"),
+ _ENTRY(poweccioptagnull, MISC, NULL, "pow tag null"),
+ _ENTRY(poweccioptagnullnull, MISC, NULL, "pow tag nullnull"),
+ _ENTRY(powecciopordatom, MISC, NULL, "pow ordered atomic"),
+ _ENTRY(powecciopnull, MISC, NULL, "pow core null"),
+ _ENTRY(powecciopnullnull, MISC, NULL, "pow core nullnull"),
+ _ENTRY(poweccrpe, MISC, NULL, "pow remote-pointer error"),
+ _ENTRY(poweccsyn, MISC, NULL, "pow syndrome value"),
+ _ENTRY(poweccdbe, MISC, NULL, "pow double bit"),
+ _ENTRY(poweccsbe, MISC, NULL, "pow single bit"),
+#undef _ENTRY
+};
+
+void
+cn30xxpow_intr_evcnt_attach(struct cn30xxpow_softc *sc)
+{
+ OCTEON_EVCNT_ATTACH_EVCNTS(sc, cn30xxpow_intr_evcnt_entries, "pow0");
+}
+
+void
+cn30xxpow_intr_rml(void *arg)
+{
+ struct cn30xxpow_softc *sc;
+ uint64_t reg;
+
+ cn30xxpow_intr_evcnt.ev_count++;
+ sc = __cn30xxpow_softc;
+ KASSERT(sc != NULL);
+ reg = cn30xxpow_error_int_summary(sc);
+ if (cn30xxpow_intr_rml_verbose)
+ printf("%s: POW_ECC_ERR=0x%016" PRIx64 "\n", __func__, reg);
+ switch (reg & POW_ECC_ERR_IOP) {
+ case POW_ECC_ERR_IOP_CSRPEND:
+ OCTEON_EVCNT_INC(sc, powecciopcsrpend);
+ break;
+ case POW_ECC_ERR_IOP_DBGPEND:
+ OCTEON_EVCNT_INC(sc, powecciopdbgpend);
+ break;
+ case POW_ECC_ERR_IOP_ADDWORK:
+ OCTEON_EVCNT_INC(sc, powecciopaddwork);
+ break;
+ case POW_ECC_ERR_IOP_ILLOP:
+ OCTEON_EVCNT_INC(sc, powecciopillop);
+ break;
+ case POW_ECC_ERR_IOP_PEND24:
+ OCTEON_EVCNT_INC(sc, poweccioppend24);
+ break;
+ case POW_ECC_ERR_IOP_PEND23:
+ OCTEON_EVCNT_INC(sc, poweccioppend23);
+ break;
+ case POW_ECC_ERR_IOP_PEND22:
+ OCTEON_EVCNT_INC(sc, poweccioppend22);
+ break;
+ case POW_ECC_ERR_IOP_PEND21:
+ OCTEON_EVCNT_INC(sc, poweccioppend21);
+ break;
+ case POW_ECC_ERR_IOP_TAGNULL:
+ OCTEON_EVCNT_INC(sc, poweccioptagnull);
+ break;
+ case POW_ECC_ERR_IOP_TAGNULLNULL:
+ OCTEON_EVCNT_INC(sc, poweccioptagnullnull);
+ break;
+ case POW_ECC_ERR_IOP_ORDATOM:
+ OCTEON_EVCNT_INC(sc, powecciopordatom);
+ break;
+ case POW_ECC_ERR_IOP_NULL:
+ OCTEON_EVCNT_INC(sc, powecciopnull);
+ break;
+ case POW_ECC_ERR_IOP_NULLNULL:
+ OCTEON_EVCNT_INC(sc, powecciopnullnull);
+ break;
+ default:
+ break;
+ }
+ if (reg & POW_ECC_ERR_RPE)
+ OCTEON_EVCNT_INC(sc, poweccrpe);
+ if (reg & POW_ECC_ERR_SYN)
+ OCTEON_EVCNT_INC(sc, poweccsyn);
+ if (reg & POW_ECC_ERR_DBE)
+ OCTEON_EVCNT_INC(sc, poweccdbe);
+ if (reg & POW_ECC_ERR_SBE)
+ OCTEON_EVCNT_INC(sc, poweccsbe);
+}
+#endif
+
+/* -------------------------------------------------------------------------- */
+
+/* ---- debug dump */
+
+#ifdef OCTEON_ETH_DEBUG
+
+void cn30xxpow_dump_reg(void);
+void cn30xxpow_dump_ops(void);
+
+void
+cn30xxpow_dump(void)
+{
+ cn30xxpow_dump_reg();
+ cn30xxpow_dump_ops();
+}
+
+/* ---- register dump */
+
+struct cn30xxpow_dump_reg_entry {
+ const char *name;
+ const char *format;
+ size_t offset;
+};
+
+#define _ENTRY(x) { #x, x##_BITS, x##_OFFSET }
+#define _ENTRY_0_7(x) \
+ _ENTRY(x## 0), _ENTRY(x## 1), _ENTRY(x## 2), _ENTRY(x## 3), \
+ _ENTRY(x## 4), _ENTRY(x## 5), _ENTRY(x## 6), _ENTRY(x## 7)
+#define _ENTRY_0_15(x) \
+ _ENTRY(x## 0), _ENTRY(x## 1), _ENTRY(x## 2), _ENTRY(x## 3), \
+ _ENTRY(x## 4), _ENTRY(x## 5), _ENTRY(x## 6), _ENTRY(x## 7), \
+ _ENTRY(x## 8), _ENTRY(x## 9), _ENTRY(x##10), _ENTRY(x##11), \
+ _ENTRY(x##12), _ENTRY(x##13), _ENTRY(x##14), _ENTRY(x##15)
+
+static const struct cn30xxpow_dump_reg_entry cn30xxpow_dump_reg_entries[] = {
+ _ENTRY (POW_PP_GRP_MSK0),
+ _ENTRY (POW_PP_GRP_MSK1),
+ _ENTRY_0_15 (POW_WQ_INT_THR),
+ _ENTRY_0_15 (POW_WQ_INT_CNT),
+ _ENTRY_0_7 (POW_QOS_THR),
+ _ENTRY_0_7 (POW_QOS_RND),
+ _ENTRY (POW_WQ_INT),
+ _ENTRY (POW_WQ_INT_PC),
+ _ENTRY (POW_NW_TIM),
+ _ENTRY (POW_ECC_ERR),
+ _ENTRY (POW_NOS_CNT),
+ _ENTRY_0_15 (POW_WS_PC),
+ _ENTRY_0_7 (POW_WA_PC),
+ _ENTRY_0_7 (POW_IQ_CNT),
+ _ENTRY (POW_WA_COM_PC),
+ _ENTRY (POW_IQ_COM_CNT),
+ _ENTRY (POW_TS_PC),
+ _ENTRY (POW_DS_PC),
+ _ENTRY (POW_BIST_STAT)
+};
+
+#undef _ENTRY
+
+void
+cn30xxpow_dump_reg(void)
+{
+ struct cn30xxpow_softc *sc = __cn30xxpow_softc;
+ const struct cn30xxpow_dump_reg_entry *entry;
+ uint64_t tmp;
+ char buf[512];
+ int i;
+
+ for (i = 0; i < (int)nitems(cn30xxpow_dump_reg_entries); i++) {
+ entry = &cn30xxpow_dump_reg_entries[i];
+ tmp = _POW_RD8(sc, entry->offset);
+ if (entry->format == NULL)
+ snprintf(buf, sizeof(buf), "%16" PRIx64, tmp);
+ else
+ bitmask_snprintf(tmp, entry->format, buf, sizeof(buf));
+ printf("\t%-24s: %s\n", entry->name, buf);
+ }
+}
+
+/* ---- operations dump */
+
+struct cn30xxpow_dump_ops_entry {
+ const char *name;
+ const char *format;
+ uint64_t (*func)(int);
+};
+
+void cn30xxpow_dump_ops_coreid(int);
+void cn30xxpow_dump_ops_index(int);
+void cn30xxpow_dump_ops_qos(int);
+void cn30xxpow_dump_ops_grp(int);
+void cn30xxpow_dump_ops_queue(int);
+void cn30xxpow_dump_ops_common(const struct
+ cn30xxpow_dump_ops_entry *, size_t, const char *,
+ int);
+
+#define _ENTRY_COMMON(name, prefix, x, y) \
+ { #name "_" #x, prefix##_##y##_BITS, cn30xxpow_status_by_##name##_##x }
+
+const struct cn30xxpow_dump_ops_entry cn30xxpow_dump_ops_coreid_entries[] = {
+#define _ENTRY(x, y) _ENTRY_COMMON(coreid, POW_STATUS_LOAD_RESULT, x, y)
+ _ENTRY(pend_tag, PEND_TAG),
+ _ENTRY(pend_wqp, PEND_WQP),
+ _ENTRY(cur_tag_next, CUR_TAG_NEXT),
+ _ENTRY(cur_tag_prev, CUR_TAG_PREV),
+ _ENTRY(cur_wqp_next, CUR_WQP_NEXT),
+ _ENTRY(cur_wqp_prev, CUR_WQP_PREV)
+#undef _ENTRY
+};
+
+const struct cn30xxpow_dump_ops_entry cn30xxpow_dump_ops_index_entries[] = {
+#define _ENTRY(x, y) _ENTRY_COMMON(index, POW_MEMORY_LOAD_RESULT, x, y)
+ _ENTRY(tag, TAG),
+ _ENTRY(wqp, WQP),
+ _ENTRY(desched, DESCHED)
+#undef _ENTRY
+};
+
+const struct cn30xxpow_dump_ops_entry cn30xxpow_dump_ops_qos_entries[] = {
+#define _ENTRY(x, y) _ENTRY_COMMON(qos, POW_IDXPTR_LOAD_RESULT_QOS, x, y)
+ _ENTRY(free_loc, FREE_LOC)
+#undef _ENTRY
+};
+
+const struct cn30xxpow_dump_ops_entry cn30xxpow_dump_ops_grp_entries[] = {
+#define _ENTRY(x, y) _ENTRY_COMMON(grp, POW_IDXPTR_LOAD_RESULT_GRP, x, y)
+ _ENTRY(nosched_des, NOSCHED_DES)
+#undef _ENTRY
+};
+
+const struct cn30xxpow_dump_ops_entry cn30xxpow_dump_ops_queue_entries[] = {
+#define _ENTRY(x, y) _ENTRY_COMMON(queue, POW_IDXPTR_LOAD_RESULT_QUEUE, x, y)
+ _ENTRY(remote_head, REMOTE_HEAD),
+ _ENTRY(remote_tail, REMOTE_TAIL)
+#undef _ENTRY
+};
+
+void
+cn30xxpow_dump_ops(void)
+{
+ int i;
+
+ /* XXX */
+ for (i = 0; i < 2/* XXX */; i++)
+ cn30xxpow_dump_ops_coreid(i);
+
+ /* XXX */
+ cn30xxpow_dump_ops_index(0);
+
+ for (i = 0; i < 8; i++)
+ cn30xxpow_dump_ops_qos(i);
+
+ for (i = 0; i < 16; i++)
+ cn30xxpow_dump_ops_grp(i);
+
+ for (i = 0; i < 16; i++)
+ cn30xxpow_dump_ops_queue(i);
+}
+
+void
+cn30xxpow_dump_ops_coreid(int coreid)
+{
+ cn30xxpow_dump_ops_common(cn30xxpow_dump_ops_coreid_entries,
+ nitems(cn30xxpow_dump_ops_coreid_entries), "coreid", coreid);
+}
+
+void
+cn30xxpow_dump_ops_index(int index)
+{
+ cn30xxpow_dump_ops_common(cn30xxpow_dump_ops_index_entries,
+ nitems(cn30xxpow_dump_ops_index_entries), "index", index);
+}
+
+void
+cn30xxpow_dump_ops_qos(int qos)
+{
+ cn30xxpow_dump_ops_common(cn30xxpow_dump_ops_qos_entries,
+ nitems(cn30xxpow_dump_ops_qos_entries), "qos", qos);
+}
+
+void
+cn30xxpow_dump_ops_grp(int grp)
+{
+ cn30xxpow_dump_ops_common(cn30xxpow_dump_ops_grp_entries,
+ nitems(cn30xxpow_dump_ops_grp_entries), "grp", grp);
+}
+
+void
+cn30xxpow_dump_ops_queue(int queue)
+{
+ cn30xxpow_dump_ops_common(cn30xxpow_dump_ops_queue_entries,
+ nitems(cn30xxpow_dump_ops_queue_entries), "queue", queue);
+}
+
+void
+cn30xxpow_dump_ops_common(const struct cn30xxpow_dump_ops_entry *entries,
+ size_t nentries, const char *by_what, int arg)
+{
+ const struct cn30xxpow_dump_ops_entry *entry;
+ uint64_t tmp;
+ char buf[512];
+ int i;
+
+ printf("%s=%d\n", by_what, arg);
+ for (i = 0; i < (int)nentries; i++) {
+ entry = &entries[i];
+ tmp = (*entry->func)(arg);
+ if (entry->format == NULL)
+ snprintf(buf, sizeof(buf), "%16" PRIx64, tmp);
+ else
+ bitmask_snprintf(tmp, entry->format, buf, sizeof(buf));
+ printf("\t%-24s: %s\n", entry->name, buf);
+ }
+}
+
+#endif
+
+/* -------------------------------------------------------------------------- */
+
+/* ---- test */
+
+#ifdef OCTEON_POW_TEST
+/*
+ * Standalone test entries; meant to be called from ddb.
+ */
+
+void cn30xxpow_test(void);
+void cn30xxpow_test_dump_wqe(paddr_t);
+
+static void cn30xxpow_test_1(void);
+
+struct test_wqe {
+ uint64_t word0;
+ uint64_t word1;
+ uint64_t word2;
+ uint64_t word3;
+} __packed;
+struct test_wqe test_wqe;
+
+void
+cn30xxpow_test(void)
+{
+ cn30xxpow_test_1();
+}
+
+static void
+cn30xxpow_test_1(void)
+{
+ struct test_wqe *wqe = &test_wqe;
+ int qos, grp, queue, tt;
+ uint32_t tag;
+ paddr_t ptr;
+
+ qos = 7; /* XXX */
+ grp = queue = 15; /* XXX */
+ tt = POW_TAG_TYPE_ORDERED; /* XXX */
+ tag = UINT32_C(0x01234567); /* XXX */
+
+ /* => make sure that the queue is empty */
+
+ cn30xxpow_dump_ops_qos(qos);
+ cn30xxpow_dump_ops_grp(grp);
+ printf("\n");
+
+ /*
+ * Initialize WQE.
+ *
+ * word0:next is used by hardware.
+ *
+ * word1:qos, word1:grp, word1:tt, word1:tag must match with arguments
+ * of the following ADDWQ transaction.
+ */
+
+ (void)memset(wqe, 0, sizeof(*wqe));
+ wqe->word0 =
+ __BITS64_SET(POW_WQE_WORD0_NEXT, 0);
+ wqe->word1 =
+ __BITS64_SET(POW_WQE_WORD1_QOS, qos) |
+ __BITS64_SET(POW_WQE_WORD1_GRP, grp) |
+ __BITS64_SET(POW_WQE_WORD1_TT, tt) |
+ __BITS64_SET(POW_WQE_WORD1_TAG, tag);
+
+ printf("calling ADDWQ\n");
+ cn30xxpow_ops_addwq(MIPS_KSEG0_TO_PHYS(wqe), qos, grp, tt, tag);
+
+ cn30xxpow_dump_ops_qos(qos);
+ cn30xxpow_dump_ops_grp(grp);
+ printf("\n");
+
+ /* => make sure that a WQE is added to the queue */
+
+ printf("calling GET_WORK_LOAD\n");
+ ptr = cn30xxpow_ops_get_work_load(0);
+
+ cn30xxpow_dump_ops_qos(qos);
+ cn30xxpow_dump_ops_grp(grp);
+ printf("\n");
+
+ cn30xxpow_test_dump_wqe(ptr);
+
+ /* => make sure that the WQE is in-flight (and scheduled) */
+
+ printf("calling SWTAG(NULL)\n");
+ cn30xxpow_ops_swtag(POW_TAG_TYPE_NULL, tag);
+
+ cn30xxpow_dump_ops_qos(qos);
+ cn30xxpow_dump_ops_grp(grp);
+ printf("\n");
+
+ /* => make sure that the WQE is un-scheduled (completed) */
+}
+
+void
+cn30xxpow_test_dump_wqe(paddr_t ptr)
+{
+ uint64_t word0, word1;
+ char buf[128];
+
+ printf("wqe\n");
+
+ word0 = *(uint64_t *)PHYS_TO_CKSEG0(ptr);
+ bitmask_snprintf(word0, POW_WQE_WORD0_BITS, buf, sizeof(buf));
+ printf("\t%-24s: %s\n", "word0", buf);
+
+ word1 = *(uint64_t *)PHYS_TO_CKSEG0(ptr + 8);
+ bitmask_snprintf(word1, POW_WQE_WORD1_BITS, buf, sizeof(buf));
+ printf("\t%-24s: %s\n", "word1", buf);
+}
+#endif
diff --git a/sys/arch/octeon/dev/cn30xxpowreg.h b/sys/arch/octeon/dev/cn30xxpowreg.h
new file mode 100644
index 00000000000..e8f7cf70715
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxpowreg.h
@@ -0,0 +1,1045 @@
+/*
+ * THIS FILE IS AUTOMATICALLY GENERATED
+ * DONT EDIT THIS FILE
+ */
+
+/* $OpenBSD: cn30xxpowreg.h,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Cavium Networks OCTEON CN30XX Hardware Reference Manual
+ * CN30XX-HM-1.0
+ * 5.12 POW Registers
+ */
+
+#ifndef _CN30XXPOWREG_H_
+#define _CN30XXPOWREG_H_
+
+/* ---- register addresses */
+
+#define POW_PP_GRP_MSK0 0x0001670000000000ULL
+#define POW_PP_GRP_MSK1 0x0001670000000008ULL
+#define POW_WQ_INT_THR0 0x0001670000000080ULL
+#define POW_WQ_INT_THR1 0x0001670000000088ULL
+#define POW_WQ_INT_THR2 0x0001670000000090ULL
+#define POW_WQ_INT_THR3 0x0001670000000098ULL
+#define POW_WQ_INT_THR4 0x00016700000000a0ULL
+#define POW_WQ_INT_THR5 0x00016700000000a8ULL
+#define POW_WQ_INT_THR6 0x00016700000000b0ULL
+#define POW_WQ_INT_THR7 0x00016700000000b8ULL
+#define POW_WQ_INT_THR8 0x00016700000000c0ULL
+#define POW_WQ_INT_THR9 0x00016700000000c8ULL
+#define POW_WQ_INT_THR10 0x00016700000000d0ULL
+#define POW_WQ_INT_THR11 0x00016700000000d8ULL
+#define POW_WQ_INT_THR12 0x00016700000000e0ULL
+#define POW_WQ_INT_THR13 0x00016700000000e8ULL
+#define POW_WQ_INT_THR14 0x00016700000000f0ULL
+#define POW_WQ_INT_THR15 0x00016700000000f8ULL
+#define POW_WQ_INT_CNT0 0x0001670000000100ULL
+#define POW_WQ_INT_CNT1 0x0001670000000108ULL
+#define POW_WQ_INT_CNT2 0x0001670000000110ULL
+#define POW_WQ_INT_CNT3 0x0001670000000118ULL
+#define POW_WQ_INT_CNT4 0x0001670000000120ULL
+#define POW_WQ_INT_CNT5 0x0001670000000128ULL
+#define POW_WQ_INT_CNT6 0x0001670000000130ULL
+#define POW_WQ_INT_CNT7 0x0001670000000138ULL
+#define POW_WQ_INT_CNT8 0x0001670000000140ULL
+#define POW_WQ_INT_CNT9 0x0001670000000148ULL
+#define POW_WQ_INT_CNT10 0x0001670000000150ULL
+#define POW_WQ_INT_CNT11 0x0001670000000158ULL
+#define POW_WQ_INT_CNT12 0x0001670000000160ULL
+#define POW_WQ_INT_CNT13 0x0001670000000168ULL
+#define POW_WQ_INT_CNT14 0x0001670000000170ULL
+#define POW_WQ_INT_CNT15 0x0001670000000178ULL
+#define POW_QOS_THR0 0x0001670000000180ULL
+#define POW_QOS_THR1 0x0001670000000188ULL
+#define POW_QOS_THR2 0x0001670000000190ULL
+#define POW_QOS_THR3 0x0001670000000198ULL
+#define POW_QOS_THR4 0x00016700000001a0ULL
+#define POW_QOS_THR5 0x00016700000001a8ULL
+#define POW_QOS_THR6 0x00016700000001b0ULL
+#define POW_QOS_THR7 0x00016700000001b8ULL
+#define POW_QOS_RND0 0x00016700000001c0ULL
+#define POW_QOS_RND1 0x00016700000001c8ULL
+#define POW_QOS_RND2 0x00016700000001d0ULL
+#define POW_QOS_RND3 0x00016700000001d8ULL
+#define POW_QOS_RND4 0x00016700000001e0ULL
+#define POW_QOS_RND5 0x00016700000001e8ULL
+#define POW_QOS_RND6 0x00016700000001f0ULL
+#define POW_QOS_RND7 0x00016700000001f8ULL
+#define POW_WQ_INT 0x0001670000000200ULL
+#define POW_WQ_INT_PC 0x0001670000000208ULL
+#define POW_NW_TIM 0x0001670000000210ULL
+#define POW_ECC_ERR 0x0001670000000218ULL
+#define POW_NOS_CNT 0x0001670000000220ULL
+#define POW_WS_PC0 0x0001670000000280ULL
+#define POW_WS_PC1 0x0001670000000288ULL
+#define POW_WS_PC2 0x0001670000000290ULL
+#define POW_WS_PC3 0x0001670000000298ULL
+#define POW_WS_PC4 0x00016700000002a0ULL
+#define POW_WS_PC5 0x00016700000002a8ULL
+#define POW_WS_PC6 0x00016700000002b0ULL
+#define POW_WS_PC7 0x00016700000002b8ULL
+#define POW_WS_PC8 0x00016700000002c0ULL
+#define POW_WS_PC9 0x00016700000002c8ULL
+#define POW_WS_PC10 0x00016700000002d0ULL
+#define POW_WS_PC11 0x00016700000002d8ULL
+#define POW_WS_PC12 0x00016700000002e0ULL
+#define POW_WS_PC13 0x00016700000002e8ULL
+#define POW_WS_PC14 0x00016700000002f0ULL
+#define POW_WS_PC15 0x00016700000002f8ULL
+#define POW_WA_PC0 0x0001670000000300ULL
+#define POW_WA_PC1 0x0001670000000308ULL
+#define POW_WA_PC2 0x0001670000000310ULL
+#define POW_WA_PC3 0x0001670000000318ULL
+#define POW_WA_PC4 0x0001670000000320ULL
+#define POW_WA_PC5 0x0001670000000328ULL
+#define POW_WA_PC6 0x0001670000000330ULL
+#define POW_WA_PC7 0x0001670000000338ULL
+#define POW_IQ_CNT0 0x0001670000000340ULL
+#define POW_IQ_CNT1 0x0001670000000348ULL
+#define POW_IQ_CNT2 0x0001670000000350ULL
+#define POW_IQ_CNT3 0x0001670000000358ULL
+#define POW_IQ_CNT4 0x0001670000000360ULL
+#define POW_IQ_CNT5 0x0001670000000368ULL
+#define POW_IQ_CNT6 0x0001670000000370ULL
+#define POW_IQ_CNT7 0x0001670000000378ULL
+#define POW_WA_COM_PC 0x0001670000000380ULL
+#define POW_IQ_COM_CNT 0x0001670000000388ULL
+#define POW_TS_PC 0x0001670000000390ULL
+#define POW_DS_PC 0x0001670000000398ULL
+#define POW_BIST_STAT 0x00016700000003f8ULL
+
+#define POW_BASE 0x0001670000000000ULL
+#define POW_SIZE 0x400ULL
+
+#define POW_PP_GRP_MSK0_OFFSET 0x0ULL
+#define POW_PP_GRP_MSK1_OFFSET 0x8ULL
+#define POW_WQ_INT_THR0_OFFSET 0x80ULL
+#define POW_WQ_INT_THR1_OFFSET 0x88ULL
+#define POW_WQ_INT_THR2_OFFSET 0x90ULL
+#define POW_WQ_INT_THR3_OFFSET 0x98ULL
+#define POW_WQ_INT_THR4_OFFSET 0xa0ULL
+#define POW_WQ_INT_THR5_OFFSET 0xa8ULL
+#define POW_WQ_INT_THR6_OFFSET 0xb0ULL
+#define POW_WQ_INT_THR7_OFFSET 0xb8ULL
+#define POW_WQ_INT_THR8_OFFSET 0xc0ULL
+#define POW_WQ_INT_THR9_OFFSET 0xc8ULL
+#define POW_WQ_INT_THR10_OFFSET 0xd0ULL
+#define POW_WQ_INT_THR11_OFFSET 0xd8ULL
+#define POW_WQ_INT_THR12_OFFSET 0xe0ULL
+#define POW_WQ_INT_THR13_OFFSET 0xe8ULL
+#define POW_WQ_INT_THR14_OFFSET 0xf0ULL
+#define POW_WQ_INT_THR15_OFFSET 0xf8ULL
+#define POW_WQ_INT_CNT0_OFFSET 0x100ULL
+#define POW_WQ_INT_CNT1_OFFSET 0x108ULL
+#define POW_WQ_INT_CNT2_OFFSET 0x110ULL
+#define POW_WQ_INT_CNT3_OFFSET 0x118ULL
+#define POW_WQ_INT_CNT4_OFFSET 0x120ULL
+#define POW_WQ_INT_CNT5_OFFSET 0x128ULL
+#define POW_WQ_INT_CNT6_OFFSET 0x130ULL
+#define POW_WQ_INT_CNT7_OFFSET 0x138ULL
+#define POW_WQ_INT_CNT8_OFFSET 0x140ULL
+#define POW_WQ_INT_CNT9_OFFSET 0x148ULL
+#define POW_WQ_INT_CNT10_OFFSET 0x150ULL
+#define POW_WQ_INT_CNT11_OFFSET 0x158ULL
+#define POW_WQ_INT_CNT12_OFFSET 0x160ULL
+#define POW_WQ_INT_CNT13_OFFSET 0x168ULL
+#define POW_WQ_INT_CNT14_OFFSET 0x170ULL
+#define POW_WQ_INT_CNT15_OFFSET 0x178ULL
+#define POW_QOS_THR0_OFFSET 0x180ULL
+#define POW_QOS_THR1_OFFSET 0x188ULL
+#define POW_QOS_THR2_OFFSET 0x190ULL
+#define POW_QOS_THR3_OFFSET 0x198ULL
+#define POW_QOS_THR4_OFFSET 0x1a0ULL
+#define POW_QOS_THR5_OFFSET 0x1a8ULL
+#define POW_QOS_THR6_OFFSET 0x1b0ULL
+#define POW_QOS_THR7_OFFSET 0x1b8ULL
+#define POW_QOS_RND0_OFFSET 0x1c0ULL
+#define POW_QOS_RND1_OFFSET 0x1c8ULL
+#define POW_QOS_RND2_OFFSET 0x1d0ULL
+#define POW_QOS_RND3_OFFSET 0x1d8ULL
+#define POW_QOS_RND4_OFFSET 0x1e0ULL
+#define POW_QOS_RND5_OFFSET 0x1e8ULL
+#define POW_QOS_RND6_OFFSET 0x1f0ULL
+#define POW_QOS_RND7_OFFSET 0x1f8ULL
+#define POW_WQ_INT_OFFSET 0x200ULL
+#define POW_WQ_INT_PC_OFFSET 0x208ULL
+#define POW_NW_TIM_OFFSET 0x210ULL
+#define POW_ECC_ERR_OFFSET 0x218ULL
+#define POW_NOS_CNT_OFFSET 0x220ULL
+#define POW_WS_PC0_OFFSET 0x280ULL
+#define POW_WS_PC1_OFFSET 0x288ULL
+#define POW_WS_PC2_OFFSET 0x290ULL
+#define POW_WS_PC3_OFFSET 0x298ULL
+#define POW_WS_PC4_OFFSET 0x2a0ULL
+#define POW_WS_PC5_OFFSET 0x2a8ULL
+#define POW_WS_PC6_OFFSET 0x2b0ULL
+#define POW_WS_PC7_OFFSET 0x2b8ULL
+#define POW_WS_PC8_OFFSET 0x2c0ULL
+#define POW_WS_PC9_OFFSET 0x2c8ULL
+#define POW_WS_PC10_OFFSET 0x2d0ULL
+#define POW_WS_PC11_OFFSET 0x2d8ULL
+#define POW_WS_PC12_OFFSET 0x2e0ULL
+#define POW_WS_PC13_OFFSET 0x2e8ULL
+#define POW_WS_PC14_OFFSET 0x2f0ULL
+#define POW_WS_PC15_OFFSET 0x2f8ULL
+#define POW_WA_PC0_OFFSET 0x300ULL
+#define POW_WA_PC1_OFFSET 0x308ULL
+#define POW_WA_PC2_OFFSET 0x310ULL
+#define POW_WA_PC3_OFFSET 0x318ULL
+#define POW_WA_PC4_OFFSET 0x320ULL
+#define POW_WA_PC5_OFFSET 0x328ULL
+#define POW_WA_PC6_OFFSET 0x330ULL
+#define POW_WA_PC7_OFFSET 0x338ULL
+#define POW_IQ_CNT0_OFFSET 0x340ULL
+#define POW_IQ_CNT1_OFFSET 0x348ULL
+#define POW_IQ_CNT2_OFFSET 0x350ULL
+#define POW_IQ_CNT3_OFFSET 0x358ULL
+#define POW_IQ_CNT4_OFFSET 0x360ULL
+#define POW_IQ_CNT5_OFFSET 0x368ULL
+#define POW_IQ_CNT6_OFFSET 0x370ULL
+#define POW_IQ_CNT7_OFFSET 0x378ULL
+#define POW_WA_COM_PC_OFFSET 0x380ULL
+#define POW_IQ_COM_CNT_OFFSET 0x388ULL
+#define POW_TS_PC_OFFSET 0x390ULL
+#define POW_DS_PC_OFFSET 0x398ULL
+#define POW_BIST_STAT_OFFSET 0x3f8ULL
+
+/* ---- register bits */
+
+#define POW_PP_GRP_MSKX_XXX_63_16 0xffffffffffff0000ULL
+#define POW_PP_GRP_MSKX_GRP_MSK 0x000000000000ffffULL
+#define POW_PP_GRP_MSKX_GRP_MSK_SHIFT 0
+
+#define POW_WQ_INT_THRX_XXX_63_29 0xffffffffe0000000ULL
+#define POW_WQ_INT_THRX_TC_EN 0x0000000010000000ULL
+#define POW_WQ_INT_THRX_TC_THR 0x000000000f000000ULL
+#define POW_WQ_INT_THRX_TC_THR_SHIFT 24
+#define POW_WQ_INT_THRX_XXX_23_18 0x0000000000fc0000ULL
+#define POW_WQ_INT_THRX_DS_THR 0x000000000003f000ULL
+#define POW_WQ_INT_THRX_DS_THR_SHIFT 12
+#define POW_WQ_INT_THRX_XXX_11_6 0x0000000000000fc0ULL
+#define POW_WQ_INT_THRX_IQ_THR 0x000000000000003fULL
+#define POW_WQ_INT_THRX_IQ_THR_SHIFT 0
+
+#define POW_WQ_INT_CNTX_XXX_63_28 0xfffffffff0000000ULL
+#define POW_WQ_INT_CNTX_TC_CNT 0x000000000f000000ULL
+#define POW_WQ_INT_CNTX_TC_CNT_SHIFT 24
+#define POW_WQ_INT_CNTX_XXX_23_18 0x0000000000fc0000ULL
+#define POW_WQ_INT_CNTX_DS_CNT 0x000000000003f000ULL
+#define POW_WQ_INT_CNTX_DS_CNT_SHIFT 12
+#define POW_WQ_INT_CNTX_XXX_11_6 0x0000000000000fc0ULL
+#define POW_WQ_INT_CNTX_IQ_CNT 0x000000000000003fULL
+#define POW_WQ_INT_CNTX_IQ_CNT_SHIFT 0
+
+#define POW_QOS_THRX_XXX_63_55 0xff80000000000000ULL
+#define POW_QOS_THRX_DES_CNT 0x007f000000000000ULL
+#define POW_QOS_THRX_DES_CNT_SHIFT 48
+#define POW_QOS_THRX_XXX_47_43 0x0000f80000000000ULL
+#define POW_QOS_THRX_BUF_CNT 0x000007f000000000ULL
+#define POW_QOS_THRX_BUF_CNT_SHIFT 36
+#define POW_QOS_THRX_XXX_35_31 0x0000000f80000000ULL
+#define POW_QOS_THRX_FREE_CNT 0x000000007f000000ULL
+#define POW_QOS_THRX_FREE_CNT_SHIFT 24
+#define POW_QOS_THRX_XXX_23_18 0x0000000000fc0000ULL
+#define POW_QOS_THRX_MAX_THR 0x000000000003f000ULL
+#define POW_QOS_THRX_MAX_THR_SHIFT 12
+#define POW_QOS_THRX_XXX_11_6 0x0000000000000fc0ULL
+#define POW_QOS_THRX_MIN_THR 0x000000000000003fULL
+#define POW_QOS_THRX_MIN_THR_SHIFT 0
+
+#define POW_QOS_RNDX_XXX_63_32 0xffffffff00000000ULL
+#define POW_QOS_RNDX_RND_P3 0x00000000ff000000ULL
+#define POW_QOS_RNDX_RND_P3_SHIFT 24
+#define POW_QOS_RNDX_RND_P2 0x0000000000ff0000ULL
+#define POW_QOS_RNDX_RND_P2_SHIFT 16
+#define POW_QOS_RNDX_RND_P1 0x000000000000ff00ULL
+#define POW_QOS_RNDX_RND_P1_SHIFT 8
+#define POW_QOS_RNDX_RND 0x00000000000000ffULL
+#define POW_QOS_RNDX_RND_SHIFT 0
+
+#define POW_WQ_INT_XXX_63_32 0xffffffff00000000ULL
+#define POW_WQ_INT_IQ_DIS 0x00000000ffff0000ULL
+#define POW_WQ_INT_IQ_DIS_SHIFT 16
+#define POW_WQ_INT_WQ_INT 0x000000000000ffffULL
+#define POW_WQ_INT_WQ_INT_SHIFT 0
+
+#define POW_WQ_INT_PC_XXX_63_60 0xf000000000000000ULL
+#define POW_WQ_INT_PC_PC 0x0fffffff00000000ULL
+#define POW_WQ_INT_PC_PC_SHIFT 32
+#define POW_WQ_INT_PC_XXX_31_28 0x00000000f0000000ULL
+#define POW_WQ_INT_PC_PC_THR 0x000000000fffff00ULL
+#define POW_WQ_INT_PC_PC_THR_SHIFT 8
+#define POW_WQ_INT_PC_XXX_7_0 0x00000000000000ffULL
+
+#define POW_NW_TIM_XXX_63_10 0xfffffffffffffc00ULL
+#define POW_NW_TIM_NW_TIM 0x00000000000003ffULL
+#define POW_NW_TIM_NW_TIM_SHIFT 0
+
+#define POW_ECC_ERR_XXX_63_45 0xffffe00000000000ULL
+#define POW_ECC_ERR_IOP_IE 0x00001fff00000000ULL
+#define POW_ECC_ERR_IOP_IE_SHIFT 32
+#define POW_ECC_ERR_XXX_31_29 0x00000000e0000000ULL
+#define POW_ECC_ERR_IOP 0x000000001fff0000ULL
+#define POW_ECC_ERR_IOP_SHIFT 16
+#define POW_ECC_ERR_IOP_CSRPEND (28) << POW_ECC_ERR_IOP_SHIFTULL
+#define POW_ECC_ERR_IOP_DBGPEND (27) << POW_ECC_ERR_IOP_SHIFTULL
+#define POW_ECC_ERR_IOP_ADDWORK (26) << POW_ECC_ERR_IOP_SHIFTULL
+#define POW_ECC_ERR_IOP_ILLOP (25) << POW_ECC_ERR_IOP_SHIFTULL
+#define POW_ECC_ERR_IOP_PEND24 (24) << POW_ECC_ERR_IOP_SHIFTULL
+#define POW_ECC_ERR_IOP_PEND23 (23) << POW_ECC_ERR_IOP_SHIFTULL
+#define POW_ECC_ERR_IOP_PEND22 (22) << POW_ECC_ERR_IOP_SHIFTULL
+#define POW_ECC_ERR_IOP_PEND21 (21) << POW_ECC_ERR_IOP_SHIFTULL
+#define POW_ECC_ERR_IOP_TAGNULL (20) << POW_ECC_ERR_IOP_SHIFTULL
+#define POW_ECC_ERR_IOP_TAGNULLNULL (19) << POW_ECC_ERR_IOP_SHIFTULL
+#define POW_ECC_ERR_IOP_ORDATOM (18) << POW_ECC_ERR_IOP_SHIFTULL
+#define POW_ECC_ERR_IOP_NULL (17) << POW_ECC_ERR_IOP_SHIFTULL
+#define POW_ECC_ERR_IOP_NULLNULL (16) << POW_ECC_ERR_IOP_SHIFTULL
+#define POW_ECC_ERR_XXX_15_14 0x000000000000c000ULL
+#define POW_ECC_ERR_RPE_IE 0x0000000000002000ULL
+#define POW_ECC_ERR_RPE 0x0000000000001000ULL
+#define POW_ECC_ERR_XXX_11_9 0x0000000000000e00ULL
+#define POW_ECC_ERR_SYN 0x00000000000001f0ULL
+#define POW_ECC_ERR_SYN_SHIFT 4
+#define POW_ECC_ERR_DBE_IE 0x0000000000000008ULL
+#define POW_ECC_ERR_SBE_IE 0x0000000000000004ULL
+#define POW_ECC_ERR_DBE 0x0000000000000002ULL
+#define POW_ECC_ERR_SBE 0x0000000000000001ULL
+
+#define POW_NOS_CNT_XXX_63_7 0xffffffffffffff80ULL
+#define POW_NOS_CNT_NOS_CNT 0x000000000000007fULL
+#define POW_NOS_CNT_NOS_CNT_SHIFT 0
+
+#define POW_WS_PC0_XXX_63_32 0xffffffff00000000ULL
+#define POW_WS_PC0_WS_PC 0x00000000ffffffffULL
+#define POW_WS_PC0_WS_PC_SHIFT 0
+
+#define POW_WA_PC0_XXX_63_32 0xffffffff00000000ULL
+#define POW_WA_PC0_WA_PC 0x00000000ffffffffULL
+#define POW_WA_PC0_WA_PC_SHIFT 0
+
+#define POW_IQ_CNT0_XXX_63_32 0xffffffff00000000ULL
+#define POW_IQ_CNT0_IQ_CNT 0x00000000ffffffffULL
+#define POW_IQ_CNT0_IQ_CNT_SHIFT 0
+
+#define POW_WA_COM_PC_XXX_63_32 0xffffffff00000000ULL
+#define POW_WA_COM_PC_WA_PC 0x00000000ffffffffULL
+#define POW_WA_COM_PC_WA_PC_SHIFT 0
+
+#define POW_WQ_COM_CNT_XXX_63_32 0xffffffff00000000ULL
+#define POW_WQ_COM_CNT_IQ_CNT 0x00000000ffffffffULL
+#define POW_WQ_COM_CNT_IQ_CNT_SHIFT 0
+
+#define POW_TS_PC_XXX_63_32 0xffffffff00000000ULL
+#define POW_TS_PC_TS_PC 0x00000000ffffffffULL
+#define POW_TS_PC_TS_PC_SHIFT 0
+
+#define POW_DS_PC_XXX_63_32 0xffffffff00000000ULL
+#define POW_DS_PC_DS_PC 0x00000000ffffffffULL
+#define POW_DS_PC_DS_PC_SHIFT 0
+
+#define POW_BIST_STAT_XXX_63_7 0xfffffffffffe0000ULL
+#define POW_BIST_STAT_PP 0x0000000000010000ULL
+#define POW_BIST_STAT_XXX_15_9 0x000000000000fe00ULL
+#define POW_BIST_STAT_CAM 0x0000000000000100ULL
+#define POW_BIST_STAT_NBT1 0x0000000000000080ULL
+#define POW_BIST_STAT_NBT0 0x0000000000000040ULL
+#define POW_BIST_STAT_IDX 0x0000000000000020ULL
+#define POW_BIST_STAT_FIDX 0x0000000000000010ULL
+#define POW_BIST_STAT_NBR1 0x0000000000000008ULL
+#define POW_BIST_STAT_NBR0 0x0000000000000004ULL
+#define POW_BIST_STAT_PEND 0x0000000000000002ULL
+#define POW_BIST_STAT_ADR 0x0000000000000001ULL
+
+/* ---- pow operations */
+
+/* pow operations base */
+#define POW_OPERATION_BASE_IO_BIT 0x0001000000000000ULL
+#define POW_OPERATION_BASE_MAJOR_DID 0x0000f80000000000ULL
+#define POW_OPERATION_BASE_SUB_DID 0x0000070000000000ULL
+#define POW_OPERATION_BASE_IO_BIT_SHIFT 48
+#define POW_OPERATION_BASE_MAJOR_DID_SHIFT 43
+#define POW_OPERATION_BASE_SUB_DID_SHIFT 40
+
+/* get work load (subid = 0) */
+#define POW_GET_WORK_LOAD_WAIT 0x0000000000000008ULL
+#define POW_GET_WORK_LOAD_2_0 0x0000000000000007ULL
+#define POW_GET_WORK_LOAD_WAIT_SHIFT 3
+#define POW_GET_WORK_LOAD_2_0_SHIFT 0
+
+#define POW_GET_WORK_LOAD_RESULT_NO_WORK 0x8000000000000000ULL
+#define POW_GET_WORK_LOAD_RESULT_62_40 0x7fffff0000000000ULL
+#define POW_GET_WORK_LOAD_RESULT_ADDR 0x000000ffffffffffULL
+
+/* pow status load (subid = 1) */
+#define POW_STATUS_LOAD_COREID 0x00000000000003c0ULL
+#define POW_STATUS_LOAD_GET_REV 0x0000000000000020ULL
+#define POW_STATUS_LOAD_GET_CUR 0x0000000000000010ULL
+#define POW_STATUS_LOAD_GET_WQP 0x0000000000000008ULL
+#define POW_STATUS_LOAD_GET_2_0 0x0000000000000007ULL
+#define POW_STATUS_LOAD_COREID_SHIFT 6
+#define POW_STATUS_LOAD_GET_REV_SHIFT 5
+#define POW_STATUS_LOAD_GET_CUR_SHIFT 4
+#define POW_STATUS_LOAD_GET_WQP_SHIFT 3
+#define POW_STATUS_LOAD_GET_2_0_SHIFT 0
+
+/* get_cur = 0 and get_wqp = 0 ("pend_tag") */
+#define POW_STATUS_LOAD_RESULT_PEND_TAG_XXX_63_62 0xc000000000000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_SWITCH 0x2000000000000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_SWITCH_FULL 0x1000000000000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_SWITCH_NULL 0x0800000000000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_DESCHED 0x0400000000000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_DESCHED_SWITCH 0x0200000000000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_NOSCHED 0x0100000000000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_NEW_WORK 0x0080000000000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_NEW_WORK_WAIT 0x0040000000000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_NULL_RD 0x0020000000000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_NOSCHED_CLR 0x0010000000000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_XXX_51 0x0008000000000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_INDEX 0x0007ff0000000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_GRP 0x000000f000000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_XXX_35_34 0x0000000c00000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_TYPE 0x0000000300000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_TAG 0x00000000ffffffffULL
+#define POW_STATUS_LOAD_RESULT_PEND_TAG_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x3d" "PEND_SWITCH\0" \
+ "b\x3c" "PEND_SWITCH_FULL\0" \
+ "b\x3b" "PEND_SWITCH_NULL\0" \
+ "b\x3a" "PEND_DESCHED\0" \
+ "b\x39" "PEND_DESCHED_SWITCH\0" \
+ "b\x38" "PEND_NOSCHED\0" \
+ "b\x37" "PEND_NEW_WORK\0" \
+ "b\x36" "PEND_NEW_WORK_WAIT\0" \
+ "b\x35" "PEND_NULL_RD\0" \
+ "b\x34" "PEND_NOSCHED_CLR\0" \
+ "f\x28\x0b" "PEND_INDEX\0" \
+ "f\x24\x04" "PEND_GRP\0" \
+ "f\x20\x02" "PEND_TYPE\0" \
+ "f\x00\x20" "PEND_TAG\0"
+
+/* get_cur = 0 and get_wqp = 1 ("pend_wqp") */
+#define POW_STATUS_LOAD_RESULT_PEND_WQP_XXX_63_62 0xc000000000000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_WQP_PEND_SWITCH 0x2000000000000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_WQP_PEND_SWITCH_FULL 0x1000000000000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_WQP_PEND_SWITCH_NULL 0x0800000000000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_WQP_PEND_DESCHED 0x0400000000000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_WQP_PEND_DESCHED_SWITCH 0x0200000000000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_WQP_PEND_NOSCHED 0x0100000000000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_WQP_PEND_NEW_WORK 0x0080000000000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_WQP_PEND_NEW_WORK_WAIT 0x0040000000000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_WQP_PEND_NULL_RD 0x0020000000000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_WQP_PEND_NOSCHED_CLR 0x0010000000000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_WQP_PEND_XXX_51 0x0008000000000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_WQP_PEND_INDEX 0x0007ff0000000000ULL
+#define POW_STATUS_LOAD_RESULT_PEND_WQP_PEND_WQP 0x0000000fffffffffULL
+#define POW_STATUS_LOAD_RESULT_PEND_WQP_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x3d" "PEND_SWITCH\0" \
+ "b\x3c" "PEND_SWITCH_FULL\0" \
+ "b\x3b" "PEND_SWITCH_NULL\0" \
+ "b\x3a" "PEND_DESCHED\0" \
+ "b\x39" "PEND_DESCHED_SWITCH\0" \
+ "b\x38" "PEND_NOSCHED\0" \
+ "b\x37" "PEND_NEW_WORK\0" \
+ "b\x36" "PEND_NEW_WORK_WAIT\0" \
+ "b\x35" "PEND_NULL_RD\0" \
+ "b\x34" "PEND_NOSCHED_CLR\0" \
+ "f\x28\x0b" "PEND_INDEX\0" \
+ "f\x00\x24" "PEND_WQP\0"
+
+/* get_cur = 1 and get_wqp = 0 and get_rev = 0 ("cur_tag_next") */
+#define POW_STATUS_LOAD_RESULT_CUR_TAG_NEXT_XXX_63_62 0xc000000000000000ULL
+#define POW_STATUS_LOAD_RESULT_CUR_TAG_NEXT_LINK_INDEX 0x3ff8000000000000ULL
+#define POW_STATUS_LOAD_RESULT_CUR_TAG_NEXT_INDEX 0x0007ff0000000000ULL
+#define POW_STATUS_LOAD_RESULT_CUR_TAG_NEXT_GRP 0x000000f000000000ULL
+#define POW_STATUS_LOAD_RESULT_CUR_TAG_NEXT_HEAD 0x0000000800000000ULL
+#define POW_STATUS_LOAD_RESULT_CUR_TAG_NEXT_TAIL 0x0000000400000000ULL
+#define POW_STATUS_LOAD_RESULT_CUR_TAG_NEXT_TAG_TYPE 0x0000000300000000ULL
+#define POW_STATUS_LOAD_RESULT_CUR_TAG_NEXT_TAG 0x00000000ffffffffULL
+#define POW_STATUS_LOAD_RESULT_CUR_TAG_NEXT_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x33\x0b" "LINK_INDEX\0" \
+ "f\x28\x0b" "INDEX\0" \
+ "f\x24\x04" "GRP\0" \
+ "b\x23" "HEAD\0" \
+ "b\x22" "TAIL\0" \
+ "f\x20\x02" "TAG_TYPE\0" \
+ "f\x00\x20" "TAG\0"
+
+/* get_cur = 1 and get_wqp = 0 and get_rev = 1 ("cur_tag_prev") */
+#define POW_STATUS_LOAD_RESULT_CUR_TAG_PREV_XXX_63_62 0xc000000000000000ULL
+#define POW_STATUS_LOAD_RESULT_CUR_TAG_PREV_REVLINK_INDEX 0x3ff8000000000000ULL
+#define POW_STATUS_LOAD_RESULT_CUR_TAG_PREV_INDEX 0x0007ff0000000000ULL
+#define POW_STATUS_LOAD_RESULT_CUR_TAG_PREV_GRP 0x000000f000000000ULL
+#define POW_STATUS_LOAD_RESULT_CUR_TAG_PREV_HEAD 0x0000000800000000ULL
+#define POW_STATUS_LOAD_RESULT_CUR_TAG_PREV_TAIL 0x0000000400000000ULL
+#define POW_STATUS_LOAD_RESULT_CUR_TAG_PREV_TAG_TYPE 0x0000000300000000ULL
+#define POW_STATUS_LOAD_RESULT_CUR_TAG_PREV_TAG 0x00000000ffffffffULL
+#define POW_STATUS_LOAD_RESULT_CUR_TAG_PREV_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x33\x0b" "REVLINK_INDEX\0" \
+ "f\x28\x0b" "INDEX\0" \
+ "f\x24\x04" "GRP\0" \
+ "b\x23" "HEAD\0" \
+ "b\x22" "TAIL\0" \
+ "f\x20\x02" "TAG_TYPE\0" \
+ "f\x00\x20" "TAG\0"
+
+/* get_cur = 1 and get_wqp = 1 and get_rev = 0 ("cur_wqp_next") */
+#define POW_STATUS_LOAD_RESULT_CUR_WQP_NEXT_XXX_63_62 0xc000000000000000ULL
+#define POW_STATUS_LOAD_RESULT_CUR_WQP_NEXT_LINK_INDEX 0x3ff8000000000000ULL
+#define POW_STATUS_LOAD_RESULT_CUR_WQP_NEXT_INDEX 0x0007ff0000000000ULL
+#define POW_STATUS_LOAD_RESULT_CUR_WQP_NEXT_GRP 0x000000f000000000ULL
+#define POW_STATUS_LOAD_RESULT_CUR_WQP_NEXT_WQP 0x0000000fffffffffULL
+#define POW_STATUS_LOAD_RESULT_CUR_WQP_NEXT_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x33\x0b" "LINK_INDEX\0" \
+ "f\x28\x0b" "INDEX\0" \
+ "f\x24\x04" "GRP\0" \
+ "f\x00\x24" "WQP\0"
+
+/* get_cur = 1 and get_wqp = 1 and get_rev = 1 ("cur_wqp_prev") */
+#define POW_STATUS_LOAD_RESULT_CUR_WQP_PREV_XXX_63_62 0xc000000000000000ULL
+#define POW_STATUS_LOAD_RESULT_CUR_WQP_PREV_REVLINK_INDEX 0x3ff8000000000000ULL
+#define POW_STATUS_LOAD_RESULT_CUR_WQP_PREV_INDEX 0x0007ff0000000000ULL
+#define POW_STATUS_LOAD_RESULT_CUR_WQP_PREV_GRP 0x000000f000000000ULL
+#define POW_STATUS_LOAD_RESULT_CUR_WQP_PREV_WQP 0x0000000fffffffffULL
+#define POW_STATUS_LOAD_RESULT_CUR_WQP_PREV_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x33\x0b" "REVLINK_INDEX\0" \
+ "f\x28\x0b" "INDEX\0" \
+ "f\x24\x04" "GRP\0" \
+ "f\x00\x24" "WQP\0"
+
+/* pow memory load (subid = 2) */
+#define POW_MEMORY_LOAD_INDEX 0x000000000000ffe0ULL
+#define POW_MEMORY_LOAD_GET_DES 0x0000000000000010ULL
+#define POW_MEMORY_LOAD_GET_WQP 0x0000000000000008ULL
+#define POW_MEMORY_LOAD_2_0 0x0000000000000007ULL
+#define POW_MEMORY_LOAD_GET_DES_SHIFT 4
+#define POW_MEMORY_LOAD_INDEX_SHIFT 5
+#define POW_MEMORY_LOAD_2_0_SHIFT 0
+#define POW_MEMORY_LOAD_GET_WQP_SHIFT 3
+
+/* get_des = 0 and get_wqp = 0 ("tag") */
+#define POW_MEMORY_LOAD_RESULT_TAG_XXX_63_51 0xfff8000000000000ULL
+#define POW_MEMORY_LOAD_RESULT_TAG_NEXT_INDEX 0x0007ff0000000000ULL
+#define POW_MEMORY_LOAD_RESULT_TAG_GRP 0x000000f000000000ULL
+#define POW_MEMORY_LOAD_RESULT_TAG_XXX_35 0x0000000800000000ULL
+#define POW_MEMORY_LOAD_RESULT_TAG_TAIL 0x0000000400000000ULL
+#define POW_MEMORY_LOAD_RESULT_TAG_TAG_TYPE 0x0000000300000000ULL
+#define POW_MEMORY_LOAD_RESULT_TAG_TAG 0x00000000ffffffffULL
+#define POW_MEMORY_LOAD_RESULT_TAG_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x28\x0b" "NEXT_INDEX\0" \
+ "f\x24\x04" "GRP\0" \
+ "b\x22" "TAIL\0" \
+ "f\x20\x02" "TAG_TYPE\0" \
+ "f\x00\x20" "TAG\0"
+
+/* get_des = 0 and get_wqp = 1 ("wqp") */
+#define POW_MEMORY_LOAD_RESULT_WQP_XXX_63_51 0xfff8000000000000ULL
+#define POW_MEMORY_LOAD_RESULT_WQP_NEXT_INDEX 0x0007ff0000000000ULL
+#define POW_MEMORY_LOAD_RESULT_WQP_GRP 0x000000f000000000ULL
+#define POW_MEMORY_LOAD_RESULT_WQP_WQP 0x0000000fffffffffULL
+#define POW_MEMORY_LOAD_RESULT_WQP_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x28\x0b" "NEXT_INDEX\0" \
+ "f\x24\x04" "GRP\0" \
+ "f\x00\x24" "WQP\0"
+
+/* get_des = 1 ("desched") */
+#define POW_MEMORY_LOAD_RESULT_DESCHED_XXX_63_51 0xfff8000000000000ULL
+#define POW_MEMORY_LOAD_RESULT_DESCHED_FWD_INDEX 0x0007ff0000000000ULL
+#define POW_MEMORY_LOAD_RESULT_DESCHED_GRP 0x000000f000000000ULL
+#define POW_MEMORY_LOAD_RESULT_DESCHED_NOSCHED 0x0000000800000000ULL
+#define POW_MEMORY_LOAD_RESULT_DESCHED_PEND_SWITCH 0x0000000400000000ULL
+#define POW_MEMORY_LOAD_RESULT_DESCHED_PEND_TYPE 0x0000000300000000ULL
+#define POW_MEMORY_LOAD_RESULT_DESCHED_PEND_TAG 0x00000000ffffffffULL
+#define POW_MEMORY_LOAD_RESULT_DESCHED_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x28\x0b" "FWD_INDEX\0" \
+ "f\x24\x04" "GRP\0" \
+ "b\x23" "NOSCHED\0" \
+ "b\x22" "PEND_SWITCH\0" \
+ "f\x20\x02" "PEND_TYPE\0" \
+ "f\x00\x20" "PEND_TAG\0"
+
+/* pow index/pointer load (subid = 3) */
+#define POW_IDXPTR_LOAD_QOSGRP 0x00000000000001e0ULL
+#define POW_IDXPTR_LOAD_GET_DES_GET_TAIL 0x0000000000000010ULL
+#define POW_IDXPTR_LOAD_GET_RMT 0x0000000000000008ULL
+#define POW_IDXPTR_LOAD_2_0 0x0000000000000007ULL
+#define POW_IDXPTR_LOAD_GET_DES_GET_TAIL_SHIFT 4
+#define POW_IDXPTR_LOAD_QOSGRP_SHIFT 5
+#define POW_IDXPTR_LOAD_2_0_SHIFT 0
+#define POW_IDXPTR_LOAD_GET_RMT_SHIFT 3
+
+/* get_rmt = 0 and get_des_get_tail = 0 ("qos") */
+#define POW_IDXPTR_LOAD_RESULT_QOS_FREE_LOC_XXX_63_52 0xfff0000000000000ULL
+#define POW_IDXPTR_LOAD_RESULT_QOS_FREE_LOC_FREE_VAL 0x0008000000000000ULL
+#define POW_IDXPTR_LOAD_RESULT_QOS_FREE_LOC_FREE_ONE 0x0004000000000000ULL
+#define POW_IDXPTR_LOAD_RESULT_QOS_FREE_LOC_XXX_49 0x0002000000000000ULL
+#define POW_IDXPTR_LOAD_RESULT_QOS_FREE_LOC_FREE_HEAD 0x0001ffc000000000ULL
+#define POW_IDXPTR_LOAD_RESULT_QOS_FREE_LOC_XXX_37 0x0000002000000000ULL
+#define POW_IDXPTR_LOAD_RESULT_QOS_FREE_LOC_FREE_TAIL 0x0000001ffc000000ULL
+#define POW_IDXPTR_LOAD_RESULT_QOS_FREE_LOC_LOC_VAL 0x0000000002000000ULL
+#define POW_IDXPTR_LOAD_RESULT_QOS_FREE_LOC_LOC_ONE 0x0000000001000000ULL
+#define POW_IDXPTR_LOAD_RESULT_QOS_FREE_LOC_XXX_23 0x0000000000800000ULL
+#define POW_IDXPTR_LOAD_RESULT_QOS_FREE_LOC_LOC_HEAD 0x00000000007ff000ULL
+#define POW_IDXPTR_LOAD_RESULT_QOS_FREE_LOC_XXX_11 0x0000000000000800ULL
+#define POW_IDXPTR_LOAD_RESULT_QOS_FREE_LOC_LOC_TAIL 0x00000000000007ffULL
+#define POW_IDXPTR_LOAD_RESULT_QOS_FREE_LOC_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x33" "FREE_VAL\0" \
+ "b\x32" "FREE_ONE\0" \
+ "f\x26\x0b" "FREE_HEAD\0" \
+ "f\x1a\x0b" "FREE_TAIL\0" \
+ "b\x19" "LOC_VAL\0" \
+ "b\x18" "LOC_ONE\0" \
+ "f\x0c\x0b" "LOC_HEAD\0" \
+ "f\x00\x0b" "LOC_TAIL\0"
+
+/* get_rmt = 0 and get_des_get_tail = 1 ("desched") */
+#define POW_IDXPTR_LOAD_RESULT_GRP_NOSCHED_DES_XXX_63_52 0xfff0000000000000ULL
+#define POW_IDXPTR_LOAD_RESULT_GRP_NOSCHED_DES_NOSCHED_VAL 0x0008000000000000ULL
+#define POW_IDXPTR_LOAD_RESULT_GRP_NOSCHED_DES_NOSCHED_ONE 0x0004000000000000ULL
+#define POW_IDXPTR_LOAD_RESULT_GRP_NOSCHED_DES_XXX_49 0x0002000000000000ULL
+#define POW_IDXPTR_LOAD_RESULT_GRP_NOSCHED_DES_NOSCHED_HEAD 0x0001ffc000000000ULL
+#define POW_IDXPTR_LOAD_RESULT_GRP_NOSCHED_DES_XXX_37 0x0000002000000000ULL
+#define POW_IDXPTR_LOAD_RESULT_GRP_NOSCHED_DES_NOSCHED_TAIL 0x0000001ffc000000ULL
+#define POW_IDXPTR_LOAD_RESULT_GRP_NOSCHED_DES_DES_VAL 0x0000000002000000ULL
+#define POW_IDXPTR_LOAD_RESULT_GRP_NOSCHED_DES_DES_ONE 0x0000000001000000ULL
+#define POW_IDXPTR_LOAD_RESULT_GRP_NOSCHED_DES_XXX_23 0x0000000000800000ULL
+#define POW_IDXPTR_LOAD_RESULT_GRP_NOSCHED_DES_DES_HEAD 0x00000000007ff000ULL
+#define POW_IDXPTR_LOAD_RESULT_GRP_NOSCHED_DES_XXX_11 0x0000000000000800ULL
+#define POW_IDXPTR_LOAD_RESULT_GRP_NOSCHED_DES_DES_TAIL 0x00000000000007ffULL
+#define POW_IDXPTR_LOAD_RESULT_GRP_NOSCHED_DES_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x33" "NOSCHED_VAL\0" \
+ "b\x32" "NOSCHED_ONE\0" \
+ "f\x26\x0b" "NOSCHED_HEAD\0" \
+ "f\x1a\x0b" "NOSCHED_TAIL\0" \
+ "b\x19" "DES_VAL\0" \
+ "b\x18" "DES_ONE\0" \
+ "f\x0c\x0b" "DES_HEAD\0" \
+ "f\x00\x0b" "DES_TAIL\0"
+
+/* get_rmt = 1 and get_des_get_tail = 0 ("remote_head") */
+#define POW_IDXPTR_LOAD_RESULT_QUEUE_REMOTE_HEAD_XXX_63_39 0xffffff8000000000ULL
+#define POW_IDXPTR_LOAD_RESULT_QUEUE_REMOTE_HEAD_RMT_IS_HEAD 0x0000004000000000ULL
+#define POW_IDXPTR_LOAD_RESULT_QUEUE_REMOTE_HEAD_RMT_VAL 0x0000002000000000ULL
+#define POW_IDXPTR_LOAD_RESULT_QUEUE_REMOTE_HEAD_RMT_ONE 0x0000001000000000ULL
+#define POW_IDXPTR_LOAD_RESULT_QUEUE_REMOTE_HEAD_RMT_HEAD 0x0000000fffffffffULL
+#define POW_IDXPTR_LOAD_RESULT_QUEUE_REMOTE_HEAD_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x26" "RMT_IS_HEAD\0" \
+ "b\x25" "RMT_VAL\0" \
+ "b\x24" "RMT_ONE\0" \
+ "f\x00\x24" "RMT_HEAD\0"
+
+/* get_rmt = 1 and get_des_get_tail = 1 ("remote_tail") */
+#define POW_IDXPTR_LOAD_RESULT_QUEUE_REMOTE_TAIL_XXX_63_39 0xffffff8000000000ULL
+#define POW_IDXPTR_LOAD_RESULT_QUEUE_REMOTE_TAIL_RMT_IS_HEAD 0x0000004000000000ULL
+#define POW_IDXPTR_LOAD_RESULT_QUEUE_REMOTE_TAIL_RMT_VAL 0x0000002000000000ULL
+#define POW_IDXPTR_LOAD_RESULT_QUEUE_REMOTE_TAIL_RMT_ONE 0x0000001000000000ULL
+#define POW_IDXPTR_LOAD_RESULT_QUEUE_REMOTE_TAIL_RMT_TAIL 0x0000000fffffffffULL
+#define POW_IDXPTR_LOAD_RESULT_QUEUE_REMOTE_TAIL_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x26" "RMT_IS_HEAD\0" \
+ "b\x25" "RMT_VAL\0" \
+ "b\x24" "RMT_ONE\0" \
+ "f\x00\x24" "RMT_TAIL\0"
+
+/* pow index/pointer load (subid = 2) */
+#define POW_NULL_RD_LOAD_39_3 0x000000fffffffff8ULL
+#define POW_NULL_RD_LOAD_2_0 0x0000000000000007ULL
+#define POW_NULL_RD_LOAD_2_0_SHIFT 0
+#define POW_NULL_RD_LOAD_39_3_SHIFT 3
+
+#define POW_NULL_RD_LOAD_RESULT_63_2 0xfffffffffffffffcULL
+#define POW_NULL_RD_LOAD_RESULT_STATUS 0x0000000000000003ULL
+
+/* pow store operations */
+
+#define POW_PHY_ADDR_STORE_ADDR 0x0000000fffffffffULL
+#define POW_PHY_ADDR_STORE_ADDR_SHIFT 0
+
+#define POW_STORE_DATA_NO_SCHED 0x8000000000000000ULL
+#define POW_STORE_DATA_62_61 0x6000000000000000ULL
+#define POW_STORE_DATA_INDEX 0x1fff000000000000ULL
+#define POW_STORE_DATA_OP 0x0000f00000000000ULL
+#define POW_STORE_DATA_43_42 0x00000c0000000000ULL
+#define POW_STORE_DATA_QOS 0x0000038000000000ULL
+#define POW_STORE_DATA_GRP 0x0000007800000000ULL
+#define POW_STORE_DATA_TYPE 0x0000000700000000ULL
+#define POW_STORE_DATA_TAG 0x00000000ffffffffULL
+#define POW_STORE_DATA_NO_SCHED_SHIFT 63
+#define POW_STORE_DATA_62_61_SHIFT 61
+#define POW_STORE_DATA_INDEX_SHIFT 48
+#define POW_STORE_DATA_OP_SHIFT 44
+#define POW_STORE_DATA_43_42_SHIFT 42
+#define POW_STORE_DATA_QOS_SHIFT 39
+#define POW_STORE_DATA_GRP_SHIFT 35
+#define POW_STORE_DATA_TYPE_SHIFT 32
+#define POW_STORE_DATA_TAG_SHIFT 0
+
+/* pow iobdma operations */
+
+/* pow iobdma operations base*/
+#define POW_IOBDMA_BASE_SCRADDR 0xff00000000000000ULL
+#define POW_IOBDMA_BASE_LEN 0x00ff000000000000ULL
+#define POW_IOBDMA_BASE_MAJOR_DID 0x0000f80000000000ULL
+#define POW_IOBDMA_BASE_SUB_DID 0x0000070000000000ULL
+#define POW_IOBDMA_BASE_39_0 0x000000ffffffffffULL
+#define POW_IOBDMA_BASE_SCRADDR_SHIFT 56
+#define POW_IOBDMA_BASE_SUB_DID_SHIFT 40
+#define POW_IOBDMA_BASE_39_0_SHIFT 0
+#define POW_IOBDMA_BASE_LEN_SHIFT 48
+#define POW_IOBDMA_BASE_MAJOR_DID_SHIFT 43
+
+/* pow iobdma get work (subid = 0) */
+#define POW_IOBDMA_GET_WORK_39_4 0x000000ffffffffffULL
+#define POW_IOBDMA_GET_WORK_WAIT 0x0000000000000008ULL
+#define POW_IOBDMA_GET_WORK_2_0 0x0000000000000007ULL
+#define POW_IOBDMA_GET_WORK_39_4_SHIFT 0
+#define POW_IOBDMA_GET_WORK_2_0_SHIFT 0
+#define POW_IOBDMA_GET_WORK_WAIT_SHIFT 3
+
+#define POW_IOBDMA_GET_WORK_RESULT_NO_WORK 0x8000000000000000ULL
+#define POW_IOBDMA_GET_WORK_RESULT_62_40 0x7fffff0000000000ULL
+#define POW_IOBDMA_GET_WORK_RESULT_ADDR 0x000000ffffffffffULL
+
+/* pow iobdma null rd (subid = 4) */
+#define POW_IOBDMA_NULL_RD_39_0 0x000000ffffffffffULL
+#define POW_IOBDMA_NULL_RD_39_0_SHIFT 0
+
+#define POW_IOBDMA_NULL_RD_RESULT_63_2 0xfffffffffffffffcULL
+#define POW_IOBDMA_NULL_RD_RESULT_STATUS 0x0000000000000003ULL
+
+/* ------------------------------------------------------------------------- */
+
+/* Work Queue Entry */
+
+#define POW_WQE_WORD0_XXX_63_40 0xffffff0000000000ULL
+#define POW_WQE_WORD0_NEXT 0x000000ffffffffffULL
+#define POW_WQE_WORD0_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x28" "NEXT\0"
+#define POW_WQE_WORD0_NEXT_SHIFT 0
+
+#define POW_WQE_WORD1_XXX_63_42 0xfffffc0000000000ULL
+#define POW_WQE_WORD1_QOS 0x0000038000000000ULL
+#define POW_WQE_WORD1_GRP 0x0000007800000000ULL
+#define POW_WQE_WORD1_TT 0x0000000700000000ULL
+#define POW_WQE_WORD1_TAG 0x00000000ffffffffULL
+#define POW_WQE_WORD1_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x27\x03" "QOS\0" \
+ "f\x23\x04" "GRP\0" \
+ "f\x20\x03" "TT\0" \
+ "f\x00\x20" "TAG\0"
+#define POW_WQE_WORD1_GRP_SHIFT 35
+#define POW_WQE_WORD1_QOS_SHIFT 39
+#define POW_WQE_WORD1_TT_SHIFT 32
+#define POW_WQE_WORD1_TAG_SHIFT 0
+
+/* ------------------------------------------------------------------------- */
+
+/* for bitmask_snprintf(9) */
+
+#define POW_PP_GRP_MSKX_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x10" "GRP_MSK\0"
+#define POW_PP_GRP_MSK0_BITS POW_PP_GRP_MSKX_BITS
+#define POW_PP_GRP_MSK1_BITS POW_PP_GRP_MSKX_BITS
+#define POW_WQ_INT_THRX_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x1c" "TC_EN\0" \
+ "f\x18\x04" "TC_THR\0" \
+ "f\x0c\x06" "DS_THR\0" \
+ "f\x00\x06" "IQ_THR\0"
+#define POW_WQ_INT_THR0_BITS POW_WQ_INT_THRX_BITS
+#define POW_WQ_INT_THR1_BITS POW_WQ_INT_THRX_BITS
+#define POW_WQ_INT_THR2_BITS POW_WQ_INT_THRX_BITS
+#define POW_WQ_INT_THR3_BITS POW_WQ_INT_THRX_BITS
+#define POW_WQ_INT_THR4_BITS POW_WQ_INT_THRX_BITS
+#define POW_WQ_INT_THR5_BITS POW_WQ_INT_THRX_BITS
+#define POW_WQ_INT_THR6_BITS POW_WQ_INT_THRX_BITS
+#define POW_WQ_INT_THR7_BITS POW_WQ_INT_THRX_BITS
+#define POW_WQ_INT_THR8_BITS POW_WQ_INT_THRX_BITS
+#define POW_WQ_INT_THR9_BITS POW_WQ_INT_THRX_BITS
+#define POW_WQ_INT_THR10_BITS POW_WQ_INT_THRX_BITS
+#define POW_WQ_INT_THR11_BITS POW_WQ_INT_THRX_BITS
+#define POW_WQ_INT_THR12_BITS POW_WQ_INT_THRX_BITS
+#define POW_WQ_INT_THR13_BITS POW_WQ_INT_THRX_BITS
+#define POW_WQ_INT_THR14_BITS POW_WQ_INT_THRX_BITS
+#define POW_WQ_INT_THR15_BITS POW_WQ_INT_THRX_BITS
+#define POW_WQ_INT_CNTX_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x18\x04" "TC_CNT\0" \
+ "f\x0c\x06" "DS_CNT\0" \
+ "f\x00\x06" "IQ_CNT\0"
+#define POW_WQ_INT_CNT0_BITS POW_WQ_INT_CNTX_BITS
+#define POW_WQ_INT_CNT1_BITS POW_WQ_INT_CNTX_BITS
+#define POW_WQ_INT_CNT2_BITS POW_WQ_INT_CNTX_BITS
+#define POW_WQ_INT_CNT3_BITS POW_WQ_INT_CNTX_BITS
+#define POW_WQ_INT_CNT4_BITS POW_WQ_INT_CNTX_BITS
+#define POW_WQ_INT_CNT5_BITS POW_WQ_INT_CNTX_BITS
+#define POW_WQ_INT_CNT6_BITS POW_WQ_INT_CNTX_BITS
+#define POW_WQ_INT_CNT7_BITS POW_WQ_INT_CNTX_BITS
+#define POW_WQ_INT_CNT8_BITS POW_WQ_INT_CNTX_BITS
+#define POW_WQ_INT_CNT9_BITS POW_WQ_INT_CNTX_BITS
+#define POW_WQ_INT_CNT10_BITS POW_WQ_INT_CNTX_BITS
+#define POW_WQ_INT_CNT11_BITS POW_WQ_INT_CNTX_BITS
+#define POW_WQ_INT_CNT12_BITS POW_WQ_INT_CNTX_BITS
+#define POW_WQ_INT_CNT13_BITS POW_WQ_INT_CNTX_BITS
+#define POW_WQ_INT_CNT14_BITS POW_WQ_INT_CNTX_BITS
+#define POW_WQ_INT_CNT15_BITS POW_WQ_INT_CNTX_BITS
+#define POW_QOS_THRX_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x30\x07" "DES_CNT\0" \
+ "f\x24\x07" "BUF_CNT\0" \
+ "f\x18\x07" "FREE_CNT\0" \
+ "f\x0c\x06" "MAX_THR\0" \
+ "f\x00\x06" "MIN_THR\0"
+#define POW_QOS_THR0_BITS POW_QOS_THRX_BITS
+#define POW_QOS_THR1_BITS POW_QOS_THRX_BITS
+#define POW_QOS_THR2_BITS POW_QOS_THRX_BITS
+#define POW_QOS_THR3_BITS POW_QOS_THRX_BITS
+#define POW_QOS_THR4_BITS POW_QOS_THRX_BITS
+#define POW_QOS_THR5_BITS POW_QOS_THRX_BITS
+#define POW_QOS_THR6_BITS POW_QOS_THRX_BITS
+#define POW_QOS_THR7_BITS POW_QOS_THRX_BITS
+#define POW_QOS_RNDX_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x18\x08" "RND_P3\0" \
+ "f\x10\x08" "RND_P2\0" \
+ "f\x08\x08" "RND_P1\0" \
+ "f\x00\x08" "RND\0"
+#define POW_QOS_RND0_BITS POW_QOS_RNDX_BITS
+#define POW_QOS_RND1_BITS POW_QOS_RNDX_BITS
+#define POW_QOS_RND2_BITS POW_QOS_RNDX_BITS
+#define POW_QOS_RND3_BITS POW_QOS_RNDX_BITS
+#define POW_QOS_RND4_BITS POW_QOS_RNDX_BITS
+#define POW_QOS_RND5_BITS POW_QOS_RNDX_BITS
+#define POW_QOS_RND6_BITS POW_QOS_RNDX_BITS
+#define POW_QOS_RND7_BITS POW_QOS_RNDX_BITS
+#define POW_WQ_INT_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x10\x10" "IQ_DIS\0" \
+ "f\x00\x10" "WQ_INT\0"
+#define POW_WQ_INT_PC_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x20\x1c" "PC\0" \
+ "f\x08\x14" "PC_THR\0"
+#define POW_NW_TIM_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x0a" "NW_TIM\0"
+#define POW_ECC_ERR_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x20\x0d" "IOP_IE\0" \
+ "f\x10\x0d" "IOP\0" \
+ "b\x0d" "RPE_IE\0" \
+ "b\x0c" "RPE\0" \
+ "f\x04\x05" "SYN\0" \
+ "b\x03" "DBE_IE\0" \
+ "b\x02" "SBE_IE\0" \
+ "b\x01" "DBE\0" \
+ "b\x00" "SBE\0"
+#define POW_NOS_CNT_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x07" "NOS_CNT\0"
+#define POW_WS_PCX_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define POW_WS_PC0_BITS POW_WS_PCX_BITS
+#define POW_WS_PC1_BITS POW_WS_PCX_BITS
+#define POW_WS_PC2_BITS POW_WS_PCX_BITS
+#define POW_WS_PC3_BITS POW_WS_PCX_BITS
+#define POW_WS_PC4_BITS POW_WS_PCX_BITS
+#define POW_WS_PC5_BITS POW_WS_PCX_BITS
+#define POW_WS_PC6_BITS POW_WS_PCX_BITS
+#define POW_WS_PC7_BITS POW_WS_PCX_BITS
+#define POW_WS_PC8_BITS POW_WS_PCX_BITS
+#define POW_WS_PC9_BITS POW_WS_PCX_BITS
+#define POW_WS_PC10_BITS POW_WS_PCX_BITS
+#define POW_WS_PC11_BITS POW_WS_PCX_BITS
+#define POW_WS_PC12_BITS POW_WS_PCX_BITS
+#define POW_WS_PC13_BITS POW_WS_PCX_BITS
+#define POW_WS_PC14_BITS POW_WS_PCX_BITS
+#define POW_WS_PC15_BITS POW_WS_PCX_BITS
+#define POW_WA_PCX_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define POW_WA_PC0_BITS POW_WA_PCX_BITS
+#define POW_WA_PC1_BITS POW_WA_PCX_BITS
+#define POW_WA_PC2_BITS POW_WA_PCX_BITS
+#define POW_WA_PC3_BITS POW_WA_PCX_BITS
+#define POW_WA_PC4_BITS POW_WA_PCX_BITS
+#define POW_WA_PC5_BITS POW_WA_PCX_BITS
+#define POW_WA_PC6_BITS POW_WA_PCX_BITS
+#define POW_WA_PC7_BITS POW_WA_PCX_BITS
+#define POW_IQ_CNTX_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define POW_IQ_CNT0_BITS POW_IQ_CNTX_BITS
+#define POW_IQ_CNT1_BITS POW_IQ_CNTX_BITS
+#define POW_IQ_CNT2_BITS POW_IQ_CNTX_BITS
+#define POW_IQ_CNT3_BITS POW_IQ_CNTX_BITS
+#define POW_IQ_CNT4_BITS POW_IQ_CNTX_BITS
+#define POW_IQ_CNT5_BITS POW_IQ_CNTX_BITS
+#define POW_IQ_CNT6_BITS POW_IQ_CNTX_BITS
+#define POW_IQ_CNT7_BITS POW_IQ_CNTX_BITS
+#define POW_WA_COM_PC_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x20" "WA_PC\0"
+#define POW_IQ_COM_CNT_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+
+#define POW_TS_PC_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x20" "TS_PC\0"
+#define POW_DS_PC_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "f\x00\x20" "DS_PC\0"
+#define POW_BIST_STAT_BITS \
+ "\177" /* new format */ \
+ "\177" /* seil ext */ \
+ "\020" /* hex display */ \
+ "\020" /* %016x format */ \
+ "b\x10" "PP\0" \
+ "b\x08" "CAM\0" \
+ "b\x07" "NBT1\0" \
+ "b\x06" "NBT0\0" \
+ "b\x05" "IDX\0" \
+ "b\x04" "FIDX\0" \
+ "b\x03" "NBR1\0" \
+ "b\x02" "NBR0\0" \
+ "b\x01" "PEND\0" \
+ "b\x00" "ADR\0"
+
+#endif /* _CN30XXPOWREG_H_ */
diff --git a/sys/arch/octeon/dev/cn30xxpowvar.h b/sys/arch/octeon/dev/cn30xxpowvar.h
new file mode 100644
index 00000000000..ba339cadb12
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxpowvar.h
@@ -0,0 +1,508 @@
+/* $OpenBSD: cn30xxpowvar.h,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _CN30XXPOWVAR_H_
+#define _CN30XXPOWVAR_H_
+
+#define POW_TAG_TYPE_ORDERED 0
+#define POW_TAG_TYPE_ATOMIC 1
+#define POW_TAG_TYPE_NULL 2
+#define POW_TAG_TYPE_NULL_NULL 3
+
+#define POW_TAG_OP_SWTAG 0
+#define POW_TAG_OP_SWTAG_FULL 1
+#define POW_TAG_OP_SWTAG_DESCHED 2
+#define POW_TAG_OP_DESCHED 3
+#define POW_TAG_OP_ADDWQ 4
+#define POW_TAG_OP_UPD_WQP_GRP 5
+#define POW_TAG_OP_CLR_NSCHED 7
+#define POW_TAG_OP_NOP 15
+
+#define POW_WAIT 1
+#define POW_NO_WAIT 0
+
+/* XXX */
+struct cn30xxpow_softc {
+ struct device sc_dev;
+ bus_space_tag_t sc_regt;
+ bus_space_handle_t sc_regh;
+ int sc_port;
+ int sc_int_pc_base;
+#ifdef OCTEON_ETH_DEBUG
+ struct evcnt sc_ev_powecciopcsrpend;
+ struct evcnt sc_ev_powecciopdbgpend;
+ struct evcnt sc_ev_powecciopaddwork;
+ struct evcnt sc_ev_powecciopillop;
+ struct evcnt sc_ev_poweccioppend24;
+ struct evcnt sc_ev_poweccioppend23;
+ struct evcnt sc_ev_poweccioppend22;
+ struct evcnt sc_ev_poweccioppend21;
+ struct evcnt sc_ev_poweccioptagnull;
+ struct evcnt sc_ev_poweccioptagnullnull;
+ struct evcnt sc_ev_powecciopordatom;
+ struct evcnt sc_ev_powecciopnull;
+ struct evcnt sc_ev_powecciopnullnull;
+ struct evcnt sc_ev_poweccrpe;
+ struct evcnt sc_ev_poweccsyn;
+ struct evcnt sc_ev_poweccdbe;
+ struct evcnt sc_ev_poweccsbe;
+#endif
+};
+
+/* XXX */
+struct cn30xxpow_attach_args {
+ int aa_port;
+ bus_space_tag_t aa_regt;
+};
+
+void cn30xxpow_config(struct cn30xxpow_softc *, int);
+void *cn30xxpow_intr_establish(int, int,
+ void (*)(void *, uint64_t *),
+ void (*)(int *, int *, uint64_t, void *),
+ void *, char *);
+void cn30xxpow_error_int_enable(void *, int);
+uint64_t cn30xxpow_error_int_summary(void *);
+int cn30xxpow_ring_reduce(void *);
+int cn30xxpow_ring_grow(void *);
+int cn30xxpow_ring_size(void);
+int cn30xxpow_ring_intr(void);
+
+#define _POW_RD8(sc, off) \
+ bus_space_read_8((sc)->sc_regt, (sc)->sc_regh, (off))
+#define _POW_WR8(sc, off, v) \
+ bus_space_write_8((sc)->sc_regt, (sc)->sc_regh, (off), (v))
+#define _POW_GROUP_RD8(sc, pi, off) \
+ bus_space_read_8((sc)->sc_regt, (sc)->sc_regh, \
+ (off) + sizeof(uint64_t) * (pi)->pi_group)
+#define _POW_GROUP_WR8(sc, pi, off, v) \
+ bus_space_write_8((sc)->sc_regt, (sc)->sc_regh, \
+ (off) + sizeof(uint64_t) * (pi)->pi_group, (v))
+
+extern struct cn30xxpow_softc cn30xxpow_softc;
+
+/* -------------------------------------------------------------------------- */
+
+/* 5.11.1 Load Operations */
+
+/* GET_WORK Loads */
+
+static inline uint64_t
+cn30xxpow_ops_get_work_load(
+ int wait) /* 0-1 */
+{
+ uint64_t ptr =
+ POW_OPERATION_BASE_IO_BIT |
+ __BITS64_SET(POW_OPERATION_BASE_MAJOR_DID, 0x0c) |
+ __BITS64_SET(POW_OPERATION_BASE_SUB_DID, 0x00) |
+ __BITS64_SET(POW_GET_WORK_LOAD_WAIT, wait);
+
+ return octeon_xkphys_read_8(ptr);
+}
+
+/* POW Status Loads */
+
+/*
+ * a) get_cur == 0, get_wqp == 0 (pend_tag)
+ * b) get_cur == 0, get_wqp == 1 (pend_wqp)
+ * c) get_cur == 1, get_wqp == 0, get_rev == 0 (cur_tag_next)
+ * d) get_cur == 1, get_wqp == 0, get_rev == 1 (cur_tag_prev)
+ * e) get_cur == 1, get_wqp == 1, get_rev == 0 (cur_wqp_next)
+ * f) get_cur == 1, get_wqp == 1, get_rev == 1 (cur_wqp_prev)
+ */
+
+static inline uint64_t
+cn30xxpow_ops_pow_status(
+ int coreid, /* 0-15 */
+ int get_rev, /* 0-1 */
+ int get_cur, /* 0-1 */
+ int get_wqp) /* 0-1 */
+{
+ uint64_t ptr =
+ POW_OPERATION_BASE_IO_BIT |
+ __BITS64_SET(POW_OPERATION_BASE_MAJOR_DID, 0x0c) |
+ __BITS64_SET(POW_OPERATION_BASE_SUB_DID, 0x01) |
+ __BITS64_SET(POW_STATUS_LOAD_COREID, coreid) |
+ __BITS64_SET(POW_STATUS_LOAD_GET_REV, get_rev) |
+ __BITS64_SET(POW_STATUS_LOAD_GET_CUR, get_cur) |
+ __BITS64_SET(POW_STATUS_LOAD_GET_WQP, get_wqp);
+
+ return octeon_xkphys_read_8(ptr);
+}
+
+/* POW Memory Loads */
+
+/*
+ * a) get_des == 0, get_wqp == 0 (tag)
+ * b) get_des == 0, get_wqp == 1 (wqe)
+ * c) get_des == 1 (desched)
+ */
+
+static inline uint64_t
+cn30xxpow_ops_pow_memory(
+ int index, /* 0-2047 */
+ int get_des, /* 0-1 */
+ int get_wqp) /* 0-1 */
+{
+ uint64_t ptr =
+ POW_OPERATION_BASE_IO_BIT |
+ __BITS64_SET(POW_OPERATION_BASE_MAJOR_DID, 0x0c) |
+ __BITS64_SET(POW_OPERATION_BASE_SUB_DID, 0x02) |
+ __BITS64_SET(POW_MEMORY_LOAD_INDEX, index) |
+ __BITS64_SET(POW_MEMORY_LOAD_GET_DES, get_des) |
+ __BITS64_SET(POW_MEMORY_LOAD_GET_WQP, get_wqp);
+
+ return octeon_xkphys_read_8(ptr);
+}
+
+/* POW Index/Pointer Loads */
+
+/*
+ * a) get_rmt == 0, get_des_get_tail == 0
+ * b) get_rmt == 0, get_des_get_tail == 1
+ * c) get_rmt == 1, get_des_get_tail == 0
+ * d) get_rmt == 1, get_des_get_tail == 1
+ */
+
+static inline uint64_t
+cn30xxpow_ops_pow_idxptr(
+ int qosgrp, /* 0-7 */
+ int get_des_get_tail, /* 0-1 */
+ int get_rmt) /* 0-1 */
+{
+ uint64_t ptr =
+ POW_OPERATION_BASE_IO_BIT |
+ __BITS64_SET(POW_OPERATION_BASE_MAJOR_DID, 0x0c) |
+ __BITS64_SET(POW_OPERATION_BASE_SUB_DID, 0x03) |
+ __BITS64_SET(POW_IDXPTR_LOAD_QOSGRP, qosgrp) |
+ __BITS64_SET(POW_IDXPTR_LOAD_GET_DES_GET_TAIL, get_des_get_tail) |
+ __BITS64_SET(POW_IDXPTR_LOAD_GET_RMT, get_rmt);
+
+ return octeon_xkphys_read_8(ptr);
+}
+
+/* NULL_RD Loads */
+
+static inline uint64_t
+cn30xxpow_ops_null_rd_load(void)
+{
+ uint64_t ptr =
+ POW_OPERATION_BASE_IO_BIT |
+ __BITS64_SET(POW_OPERATION_BASE_MAJOR_DID, 0x0c) |
+ __BITS64_SET(POW_OPERATION_BASE_SUB_DID, 0x04);
+
+ return octeon_xkphys_read_8(ptr);
+}
+
+/* 5.11.2 IOBDMA Operations */
+
+/*
+ * XXXSEIL
+ * ``subdid'' values are inverted between ``get_work_addr'' and ``null_read_id''
+ * in CN30XX-HM-1.0 and CN31XX-HM-1.01. (Corrected in CN50XX-HM-0.99A.)
+ *
+ * XXXSEIL
+ * The ``scraddr'' part is index in 8 byte words, not address. This is not
+ * documented...
+ */
+
+/* GET_WORK IOBDMAs */
+
+static inline void
+cn30xxpow_ops_get_work_iobdma(
+ int scraddr, /* 0-2047 */
+ int wait) /* 0-1 */
+{
+ /* ``scraddr'' part is index in 64-bit words, not address */
+ const int scrindex = scraddr / sizeof(uint64_t);
+
+ uint64_t args =
+ __BITS64_SET(POW_IOBDMA_GET_WORK_WAIT, wait);
+ uint64_t value =
+ __BITS64_SET(POW_IOBDMA_BASE_SCRADDR, scrindex) |
+ __BITS64_SET(POW_IOBDMA_BASE_LEN, 0x01) |
+ __BITS64_SET(POW_IOBDMA_BASE_MAJOR_DID, 0x0c) |
+ __BITS64_SET(POW_IOBDMA_BASE_SUB_DID, 0x00) |
+ __BITS64_SET(POW_IOBDMA_BASE_39_0, args);
+
+ octeon_iobdma_write_8(value);
+}
+
+/* NULL_RD IOBDMAs */
+
+static inline void
+cn30xxpow_ops_null_rd_iobdma(
+ int scraddr) /* 0-2047 */
+{
+ /* ``scraddr'' part is index in 64-bit words, not address */
+ const int scrindex = scraddr / sizeof(uint64_t);
+
+ uint64_t value =
+ __BITS64_SET(POW_IOBDMA_BASE_SCRADDR, scrindex) |
+ __BITS64_SET(POW_IOBDMA_BASE_LEN, 0x01) |
+ __BITS64_SET(POW_IOBDMA_BASE_MAJOR_DID, 0x0c) |
+ __BITS64_SET(POW_IOBDMA_BASE_SUB_DID, 0x04) |
+ __BITS64_SET(POW_IOBDMA_BASE_39_0, 0);
+
+ octeon_iobdma_write_8(value);
+}
+
+/* 5.11.3 Store Operations */
+
+static inline void
+cn30xxpow_store(
+ int subdid, /* 0, 1, 3 */
+ uint64_t addr, /* 0-0x0000.000f.ffff.ffff */
+ int no_sched, /* 0, 1 */
+ int index, /* 0-8191 */
+ int op, /* 0-15 */
+ int qos, /* 0-7 */
+ int grp, /* 0-7 */
+ int type, /* 0-7 */
+ uint32_t tag) /* 0-0xffff.ffff */
+{
+ /* Physical Address to Store to POW */
+ uint64_t ptr =
+ POW_OPERATION_BASE_IO_BIT |
+ __BITS64_SET(POW_OPERATION_BASE_MAJOR_DID, 0x0c) |
+ __BITS64_SET(POW_OPERATION_BASE_SUB_DID, subdid) |
+ __BITS64_SET(POW_PHY_ADDR_STORE_ADDR, addr);
+
+ /* Store Data on Store to POW */
+ uint64_t args =
+ __BITS64_SET(POW_STORE_DATA_NO_SCHED, no_sched) |
+ __BITS64_SET(POW_STORE_DATA_INDEX, index) |
+ __BITS64_SET(POW_STORE_DATA_OP, op) |
+ __BITS64_SET(POW_STORE_DATA_QOS, qos) |
+ __BITS64_SET(POW_STORE_DATA_GRP, grp) |
+ __BITS64_SET(POW_STORE_DATA_TYPE, type) |
+ __BITS64_SET(POW_STORE_DATA_TAG, tag);
+
+ octeon_xkphys_write_8(ptr, args);
+}
+
+/* SWTAG */
+
+static inline void
+cn30xxpow_ops_swtag(int type, uint32_t tag)
+{
+ cn30xxpow_store(
+ 1, /* subdid == 1 */
+ 0, /* addr (not used for SWTAG) */
+ 0, /* no_sched (not used for SWTAG) */
+ 0, /* index (not used for SWTAG) */
+ POW_TAG_OP_SWTAG, /* op == SWTAG */
+ 0, /* qos (not used for SWTAG) */
+ 0, /* grp (not used for SWTAG) */
+ type,
+ tag);
+ /* switch to NULL completes immediately */
+}
+
+/* SWTAG_FULL */
+
+static inline void
+cn30xxpow_ops_swtag_full(paddr_t addr, int grp, int type, uint32_t tag)
+{
+ cn30xxpow_store(
+ 0, /* subdid == 0 */
+ addr,
+ 0, /* no_sched (not used for SWTAG_FULL) */
+ 0, /* index (not used for SWTAG_FULL) */
+ POW_TAG_OP_SWTAG_FULL, /* op == SWTAG_FULL */
+ 0, /* qos (not used for SWTAG_FULL) */
+ grp,
+ type,
+ tag);
+}
+
+/* SWTAG_DESCHED */
+
+static inline void
+cn30xxpow_ops_swtag_desched(int no_sched, int grp, int type, uint32_t tag)
+{
+ cn30xxpow_store(
+ 3, /* subdid == 3 */
+ 0, /* addr (not used for SWTAG_DESCHED) */
+ no_sched,
+ 0, /* index (not used for SWTAG_DESCHED) */
+ POW_TAG_OP_SWTAG_DESCHED, /* op == SWTAG_DESCHED */
+ 0, /* qos (not used for SWTAG_DESCHED) */
+ grp,
+ type,
+ tag);
+}
+
+/* DESCHED */
+
+static inline void
+cn30xxpow_ops_desched(int no_sched)
+{
+ cn30xxpow_store(
+ 3, /* subdid == 3 */
+ 0, /* addr (not used for DESCHED) */
+ no_sched,
+ 0, /* index (not used for DESCHED) */
+ POW_TAG_OP_DESCHED, /* op == DESCHED */
+ 0, /* qos (not used for DESCHED) */
+ 0, /* grp (not used for DESCHED) */
+ 0, /* type (not used for DESCHED) */
+ 0); /* tag (not used for DESCHED) */
+}
+
+/* ADDWQ */
+
+static inline void
+cn30xxpow_ops_addwq(paddr_t addr, int qos, int grp, int type, uint32_t tag)
+{
+ cn30xxpow_store(
+ 1, /* subdid == 1 */
+ addr,
+ 0, /* no_sched (not used for ADDWQ) */
+ 0, /* index (not used for ADDWQ) */
+ POW_TAG_OP_ADDWQ, /* op == ADDWQ */
+ qos,
+ grp,
+ type,
+ tag);
+}
+
+/* UPD_WQP_GRP */
+
+static inline void
+cn30xxpow_ops_upd_wqp_grp(paddr_t addr, int grp)
+{
+ cn30xxpow_store(
+ 1, /* subdid == 1 */
+ addr,
+ 0, /* no_sched (not used for UPD_WQP_GRP) */
+ 0, /* index (not used for UPD_WQP_GRP) */
+ POW_TAG_OP_UPD_WQP_GRP, /* op == UPD_WQP_GRP */
+ 0, /* qos (not used for UPD_WQP_GRP) */
+ grp,
+ 0, /* type (not used for UPD_WQP_GRP) */
+ 0); /* tag (not used for UPD_WQP_GRP) */
+}
+
+/* CLR_NSCHED */
+
+static inline void
+cn30xxpow_ops_clr_nsched(paddr_t addr, int index)
+{
+ cn30xxpow_store(
+ 1, /* subdid == 1 */
+ addr,
+ 0, /* no_sched (not used for CLR_NSCHED) */
+ index,
+ POW_TAG_OP_CLR_NSCHED, /* op == CLR_NSCHED */
+ 0, /* qos (not used for CLR_NSCHED) */
+ 0, /* grp (not used for CLR_NSCHED) */
+ 0, /* type (not used for CLR_NSCHED) */
+ 0); /* tag (not used for CLR_NSCHED) */
+}
+
+/* NOP */
+
+static inline void
+cn30xxpow_ops_nop(void)
+{
+ cn30xxpow_store(
+ 1, /* subdid == 1 */
+ 0, /* addr (not used for NOP) */
+ 0, /* no_sched (not used for NOP) */
+ 0, /* index (not used for NOP) */
+ POW_TAG_OP_NOP, /* op == NOP */
+ 0, /* qos (not used for NOP) */
+ 0, /* grp (not used for NOP) */
+ 0, /* type (not used for NOP) */
+ 0); /* tag (not used for NOP) */
+}
+
+/* -------------------------------------------------------------------------- */
+
+/*
+ * global functions
+ */
+void cn30xxpow_work_request_async(uint64_t, uint64_t);
+uint64_t *cn30xxpow_work_response_async(uint64_t);
+void cn30xxpow_ops_swtag(int, uint32_t);
+void cn30xxpow_intr_set_freedback_queue(int, void *);
+
+static inline void
+cn30xxpow_config_int_pc(struct cn30xxpow_softc *sc, int unit)
+{
+ uint64_t wq_int_pc;
+ uint64_t pc_thr;
+ static uint64_t cpu_clock_hz;
+
+ if (cpu_clock_hz == 0)
+ cpu_clock_hz = curcpu()->ci_hw.clock;
+
+#if 0
+ /* from Documents */
+ /*
+ * => counter value is POW_WQ_INT_PC[PC_THR] * 256 + 255
+ * => counter is decremented every CPU clock
+ * => counter is reset when interrupt occurs
+ *
+ * cpu_clock_per_sec
+ * = cpu_clock_mhz * 1000000
+ * cpu_clock_per_msec
+ * = cpu_clock_mhz * 1000
+ * cpu_clock_per_usec
+ * = cpu_clock_mhz
+ *
+ * pc_thr_for_1sec * 256 + 255
+ * = cpu_clock_mhz * 1000000
+ * pc_thr_for_1sec
+ * = ((cpu_clock_mhz * 1000000) - 255) / 256
+ *
+ * pc_thr_for_1msec * 256 + 255
+ * = cpu_clock_mhz * 1000
+ * pc_thr_for_1msec
+ * = ((cpu_clock_mhz * 1000) - 255) / 256
+ *
+ * pc_thr_for_1usec * 256 + 255
+ * = cpu_clock_mhz
+ * pc_thr_for_1usec
+ * = (cpu_clock_mhz - 255) / 256
+ */
+ pc_thr = (((cpu_clock_hz / 1000000) * (unit)) - 255) / 256;
+#else
+ pc_thr = (cpu_clock_hz) / (unit * 16 * 256);
+#endif
+ wq_int_pc = pc_thr << POW_WQ_INT_PC_PC_THR_SHIFT;
+ _POW_WR8(sc, POW_WQ_INT_PC_OFFSET, wq_int_pc);
+}
+
+static inline void
+cn30xxpow_config_int_pc_rate(struct cn30xxpow_softc *sc, int rate)
+{
+ cn30xxpow_config_int_pc(sc, sc->sc_int_pc_base / rate);
+}
+
+#endif /* _CN30XXPOWVAR_H_ */
diff --git a/sys/arch/octeon/dev/cn30xxsmi.c b/sys/arch/octeon/dev/cn30xxsmi.c
new file mode 100644
index 00000000000..f5807a9326a
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxsmi.c
@@ -0,0 +1,139 @@
+/* $OpenBSD: cn30xxsmi.c,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+
+#include <machine/octeonvar.h>
+
+#include <octeon/dev/cn30xxfpavar.h>
+#include <octeon/dev/cn30xxpipreg.h>
+#include <octeon/dev/cn30xxsmireg.h>
+#include <octeon/dev/cn30xxsmivar.h>
+
+static void cn30xxsmi_enable(struct cn30xxsmi_softc *);
+
+/* XXX */
+void
+cn30xxsmi_init(struct cn30xxsmi_attach_args *aa,
+ struct cn30xxsmi_softc **rsc)
+{
+ struct cn30xxsmi_softc *sc;
+ int status;
+
+ sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
+ if (sc == NULL)
+ panic("can't allocate memory: %s", __func__);
+
+ sc->sc_port = aa->aa_port;
+ sc->sc_regt = aa->aa_regt;
+
+ status = bus_space_map(sc->sc_regt, SMI_BASE, SMI_SIZE, 0,
+ &sc->sc_regh);
+ if (status != 0)
+ panic("can't map %s space", "smi register");
+
+ cn30xxsmi_enable(sc);
+
+ *rsc = sc;
+}
+
+#define _SMI_RD8(sc, off) \
+ bus_space_read_8((sc)->sc_regt, (sc)->sc_regh, (off))
+#define _SMI_WR8(sc, off, v) \
+ bus_space_write_8((sc)->sc_regt, (sc)->sc_regh, (off), (v))
+
+int
+cn30xxsmi_read(struct cn30xxsmi_softc *sc, int phy_addr, int reg)
+{
+ uint64_t smi_rd;
+ int timo;
+
+ _SMI_WR8(sc, SMI_CMD_OFFSET, SMI_CMD_PHY_OP |
+ (phy_addr << SMI_CMD_PHY_ADR_SHIFT) |
+ (reg << SMI_CMD_REG_ADR_SHIFT));
+
+ timo = 10000;
+ smi_rd = _SMI_RD8(sc, SMI_RD_DAT_OFFSET);
+ while (ISSET(smi_rd, SMI_RD_DAT_PENDING)) {
+ if (timo-- == 0)
+ break;
+ delay(10);
+ smi_rd = _SMI_RD8(sc, SMI_RD_DAT_OFFSET);
+ }
+ if (ISSET(smi_rd, SMI_RD_DAT_PENDING)) {
+ return -1;
+ }
+
+ return ISSET(smi_rd, SMI_RD_DAT_VAL) ? (smi_rd & SMI_RD_DAT_DAT) : 0;
+}
+
+void
+cn30xxsmi_write(struct cn30xxsmi_softc *sc, int phy_addr, int reg, int value)
+{
+ uint64_t smi_wr;
+ int timo;
+
+ smi_wr = 0;
+ SET(smi_wr, value);
+ _SMI_WR8(sc, SMI_WR_DAT_OFFSET, smi_wr);
+
+ _SMI_WR8(sc, SMI_CMD_OFFSET, (phy_addr << SMI_CMD_PHY_ADR_SHIFT) |
+ (reg << SMI_CMD_REG_ADR_SHIFT));
+
+ timo = 10000;
+ smi_wr = _SMI_RD8(sc, SMI_WR_DAT_OFFSET);
+ while (ISSET(smi_wr, SMI_WR_DAT_PENDING)) {
+ if (timo-- == 0)
+ break;
+ delay(10);
+ smi_wr = _SMI_RD8(sc, SMI_WR_DAT_OFFSET);
+ }
+ if (ISSET(smi_wr, SMI_WR_DAT_PENDING)) {
+ /* XXX log */
+ printf("ERROR: cnmac_mii_writereg(0x%x, 0x%x, 0x%x) timed out.\n",
+ phy_addr, reg, value);
+ }
+}
+
+static void
+cn30xxsmi_enable(struct cn30xxsmi_softc *sc)
+{
+ _SMI_WR8(sc, SMI_EN_OFFSET, SMI_EN_EN);
+}
+
+void
+cn30xxsmi_set_clock(struct cn30xxsmi_softc *sc, uint64_t clock)
+{
+ _SMI_WR8(sc, SMI_CLK_OFFSET, clock);
+}
+
diff --git a/sys/arch/octeon/dev/cn30xxsmireg.h b/sys/arch/octeon/dev/cn30xxsmireg.h
new file mode 100644
index 00000000000..a7b488d9a22
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxsmireg.h
@@ -0,0 +1,95 @@
+/*
+ * THIS FILE IS AUTOMATICALLY GENERATED
+ * DONT EDIT THIS FILE
+ */
+
+/* $OpenBSD: cn30xxsmireg.h,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Cavium Networks OCTEON CN30XX Hardware Reference Manual
+ * CN30XX-HM-1.0
+ * 18.3 SMI Registers
+ */
+
+#ifndef _CN30XXSMIREG_H_
+#define _CN30XXSMIREG_H_
+
+#define SMI_CMD 0x0001180000001800ULL
+#define SMI_WR_DAT 0x0001180000001808ULL
+#define SMI_RD_DAT 0x0001180000001810ULL
+#define SMI_CLK 0x0001180000001818ULL
+#define SMI_EN 0x0001180000001820ULL
+
+#define SMI_CMD_OFFSET 0x00ULL
+#define SMI_WR_DAT_OFFSET 0x08ULL
+#define SMI_RD_DAT_OFFSET 0x10ULL
+#define SMI_CLK_OFFSET 0x18ULL
+#define SMI_EN_OFFSET 0x20ULL
+
+#define SMI_BASE 0x0001180000001800ULL
+#define SMI_SIZE 0x028ULL
+
+/* SMI CMD */
+#define SMI_CMD_63_17 0xfffffffffffe0000ULL
+#define SMI_CMD_PHY_OP 0x0000000000010000ULL
+#define SMI_CMD_15_13 0x000000000000e000ULL
+#define SMI_CMD_PHY_ADR 0x0000000000001f00ULL
+#define SMI_CMD_PHY_ADR_SHIFT 8
+#define SMI_CMD_7_5 0x00000000000000e0ULL
+#define SMI_CMD_REG_ADR 0x000000000000001fULL
+#define SMI_CMD_REG_ADR_SHIFT 0
+
+/* SMI_WR_DAT */
+#define SMI_WR_DAT_63_18 0xfffffffffffc0000ULL
+#define SMI_WR_DAT_PENDING 0x0000000000020000ULL
+#define SMI_WR_DAT_VAL 0x0000000000010000ULL
+#define SMI_WR_DAT_DAT 0x000000000000ffffULL
+
+/* SMI_RD_DAT */
+#define SMI_RD_DAT_63_18 0xfffffffffffc0000ULL
+#define SMI_RD_DAT_PENDING 0x0000000000020000ULL
+#define SMI_RD_DAT_VAL 0x0000000000010000ULL
+#define SMI_RD_DAT_DAT 0x000000000000ffffULL
+
+/* SMI_CLK */
+#define SMI_CLK_63_21 0xffffffffffe00000ULL
+#define SMI_CLK_SAMPLE_HI 0x00000000001f0000ULL
+#define SMI_CLK_15_14 0x000000000000c000ULL
+#define SMI_CLK_CLK_IDLE 0x0000000000002000ULL
+#define SMI_CLK_PREAMBLE 0x0000000000001000ULL
+#define SMI_CLK_SAMPLE 0x0000000000000f00ULL
+#define SMI_CLK_PHASE 0x00000000000000ffULL
+
+/* SMI_EN */
+#define SMI_EN_63_1 0xfffffffffffffffeULL
+#define SMI_EN_EN 0x0000000000000001ULL
+
+/* XXX */
+
+#endif /* _CN30XXSMIREG_H_ */
diff --git a/sys/arch/octeon/dev/cn30xxsmivar.h b/sys/arch/octeon/dev/cn30xxsmivar.h
new file mode 100644
index 00000000000..966e5a0a522
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxsmivar.h
@@ -0,0 +1,57 @@
+/* $OpenBSD: cn30xxsmivar.h,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _CN30XXSMIVAR_H_
+#define _CN30XXSMIVAR_H_
+
+#ifndef SET
+#define SET(t, f) ((t) |= (f))
+#define ISSET(t, f) ((t) & (f))
+#define CLR(t, f) ((t) &= ~(f))
+#endif
+
+/* XXX */
+struct cn30xxsmi_softc {
+ int sc_port;
+ bus_space_tag_t sc_regt;
+ bus_space_handle_t sc_regh;
+};
+
+/* XXX */
+struct cn30xxsmi_attach_args {
+ int aa_port;
+ bus_space_tag_t aa_regt;
+};
+
+void cn30xxsmi_init(struct cn30xxsmi_attach_args *,
+ struct cn30xxsmi_softc **);
+int cn30xxsmi_read(struct cn30xxsmi_softc *, int, int);
+void cn30xxsmi_write(struct cn30xxsmi_softc *, int, int, int);
+void cn30xxsmi_set_clock(struct cn30xxsmi_softc *, uint64_t);
+
+#endif
diff --git a/sys/arch/octeon/dev/cn30xxuartreg.h b/sys/arch/octeon/dev/cn30xxuartreg.h
new file mode 100644
index 00000000000..676978a85f9
--- /dev/null
+++ b/sys/arch/octeon/dev/cn30xxuartreg.h
@@ -0,0 +1,131 @@
+/*
+ * THIS FILE IS AUTOMATICALLY GENERATED
+ * DONT EDIT THIS FILE
+ */
+
+/* $OpenBSD: cn30xxuartreg.h,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007 Internet Initiative Japan, Inc.
+ * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Cavium Networks OCTEON CN30XX Hardware Reference Manual
+ * CN30XX-HM-1.0
+ * 16.4 UART Registers
+ */
+
+#ifndef _CN30XXUARTREG_H_
+#define _CN30XXUARTREG_H_
+
+/* ---- register addresses */
+
+#define MIO_UART0_RBR 0x0001180000000800ULL
+#define MIO_UART0_IER 0x0001180000000808ULL
+#define MIO_UART0_IIR 0x0001180000000810ULL
+#define MIO_UART0_LCR 0x0001180000000818ULL
+#define MIO_UART0_MCR 0x0001180000000820ULL
+#define MIO_UART0_LSR 0x0001180000000828ULL
+#define MIO_UART0_MSR 0x0001180000000830ULL
+#define MIO_UART0_SCR 0x0001180000000838ULL
+#define MIO_UART0_THR 0x0001180000000840ULL
+#define MIO_UART0_FCR 0x0001180000000850ULL
+#define MIO_UART0_DLL 0x0001180000000880ULL
+#define MIO_UART0_DLH 0x0001180000000888ULL
+#define MIO_UART0_FAR 0x0001180000000920ULL
+#define MIO_UART0_TFR 0x0001180000000928ULL
+#define MIO_UART0_RFW 0x0001180000000930ULL
+#define MIO_UART0_USR 0x0001180000000938ULL
+#define MIO_UART0_TFL 0x0001180000000a00ULL
+#define MIO_UART0_RFL 0x0001180000000a08ULL
+#define MIO_UART0_SRR 0x0001180000000a10ULL
+#define MIO_UART0_SRTS 0x0001180000000a18ULL
+#define MIO_UART0_SBCR 0x0001180000000a20ULL
+#define MIO_UART0_SFE 0x0001180000000a30ULL
+#define MIO_UART0_SRT 0x0001180000000a38ULL
+#define MIO_UART0_STT 0x0001180000000b00ULL
+#define MIO_UART0_HTX 0x0001180000000b08ULL
+#define MIO_UART1_RBR 0x0001180000000c00ULL
+#define MIO_UART1_IER 0x0001180000000c08ULL
+#define MIO_UART1_IIR 0x0001180000000c10ULL
+#define MIO_UART1_LCR 0x0001180000000c18ULL
+#define MIO_UART1_MCR 0x0001180000000c20ULL
+#define MIO_UART1_LSR 0x0001180000000c28ULL
+#define MIO_UART1_MSR 0x0001180000000c30ULL
+#define MIO_UART1_SCR 0x0001180000000c38ULL
+#define MIO_UART1_THR 0x0001180000000c40ULL
+#define MIO_UART1_FCR 0x0001180000000c50ULL
+#define MIO_UART1_DLL 0x0001180000000c80ULL
+#define MIO_UART1_DLH 0x0001180000000c88ULL
+#define MIO_UART1_FAR 0x0001180000000d20ULL
+#define MIO_UART1_TFR 0x0001180000000d28ULL
+#define MIO_UART1_RFW 0x0001180000000d30ULL
+#define MIO_UART1_USR 0x0001180000000d38ULL
+#define MIO_UART1_TFL 0x0001180000000e00ULL
+#define MIO_UART1_RFL 0x0001180000000e08ULL
+#define MIO_UART1_SRR 0x0001180000000e10ULL
+#define MIO_UART1_SRTS 0x0001180000000e18ULL
+#define MIO_UART1_SBCR 0x0001180000000e20ULL
+#define MIO_UART1_SFE 0x0001180000000e30ULL
+#define MIO_UART1_SRT 0x0001180000000e38ULL
+#define MIO_UART1_STT 0x0001180000000f00ULL
+#define MIO_UART1_HTX 0x0001180000000f08ULL
+
+/* ---- bitmask_snprintf */
+
+/* XXX */
+
+/* ---- bus_space */
+
+#define MIO_UART0_BASE 0x0001180000000800ULL
+#define MIO_UART1_BASE 0x0001180000000c00ULL
+
+#define MIO_UART_RBR_OFFSET 0x0000
+#define MIO_UART_IER_OFFSET 0x0008
+#define MIO_UART_IIR_OFFSET 0x0010
+#define MIO_UART_LCR_OFFSET 0x0018
+#define MIO_UART_MCR_OFFSET 0x0020
+#define MIO_UART_LSR_OFFSET 0x0028
+#define MIO_UART_MSR_OFFSET 0x0030
+#define MIO_UART_SCR_OFFSET 0x0038
+#define MIO_UART_THR_OFFSET 0x0040
+#define MIO_UART_FCR_OFFSET 0x0050
+#define MIO_UART_DLL_OFFSET 0x0080
+#define MIO_UART_DLH_OFFSET 0x0088
+#define MIO_UART_FAR_OFFSET 0x0120
+#define MIO_UART_TFR_OFFSET 0x0128
+#define MIO_UART_RFW_OFFSET 0x0130
+#define MIO_UART_USR_OFFSET 0x0138
+#define MIO_UART_TFL_OFFSET 0x0200
+#define MIO_UART_RFL_OFFSET 0x0208
+#define MIO_UART_SRR_OFFSET 0x0210
+#define MIO_UART_SRTS_OFFSET 0x0218
+#define MIO_UART_SBCR_OFFSET 0x0220
+#define MIO_UART_SFE_OFFSET 0x0230
+#define MIO_UART_SRT_OFFSET 0x0238
+#define MIO_UART_STT_OFFSET 0x0300
+#define MIO_UART_HTX_OFFSET 0x0308
+
+#endif /* _CN30XXUARTREG_H_ */
diff --git a/sys/arch/octeon/dev/if_cnmac.c b/sys/arch/octeon/dev/if_cnmac.c
new file mode 100644
index 00000000000..0e648956b3b
--- /dev/null
+++ b/sys/arch/octeon/dev/if_cnmac.c
@@ -0,0 +1,1689 @@
+/* $OpenBSD: if_cnmac.c,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+#include <sys/cdefs.h>
+
+/*
+ * XXXSEIL
+ * If no free send buffer is available, free all the sent buffer and bail out.
+ */
+#define OCTEON_ETH_SEND_QUEUE_CHECK
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/pool.h>
+#include <sys/proc.h>
+#include <sys/mbuf.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/errno.h>
+#include <sys/device.h>
+#include <sys/queue.h>
+#include <sys/conf.h>
+#include <sys/stdint.h> /* uintptr_t */
+#include <sys/sysctl.h>
+#include <sys/syslog.h>
+#ifdef MBUF_TIMESTAMP
+#include <sys/time.h>
+#endif
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <net/route.h>
+
+#if NBPFILTER > 0
+#include <net/bpf.h>
+#endif
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+
+#include <machine/bus.h>
+#include <machine/intr.h>
+#include <machine/endian.h>
+#include <machine/octeonvar.h>
+#include <machine/octeon_model.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+
+#include <octeon/dev/cn30xxasxreg.h>
+#include <octeon/dev/cn30xxciureg.h>
+#include <octeon/dev/cn30xxnpireg.h>
+#include <octeon/dev/cn30xxgmxreg.h>
+#include <octeon/dev/cn30xxipdreg.h>
+#include <octeon/dev/cn30xxpipreg.h>
+#include <octeon/dev/cn30xxpowreg.h>
+#include <octeon/dev/cn30xxfaureg.h>
+#include <octeon/dev/cn30xxfpareg.h>
+#include <octeon/dev/cn30xxbootbusreg.h>
+#include <octeon/dev/cn30xxfpavar.h>
+#include <octeon/dev/cn30xxgmxvar.h>
+#include <octeon/dev/cn30xxfauvar.h>
+#include <octeon/dev/cn30xxpowvar.h>
+#include <octeon/dev/cn30xxipdvar.h>
+#include <octeon/dev/cn30xxpipvar.h>
+#include <octeon/dev/cn30xxpkovar.h>
+#include <octeon/dev/cn30xxasxvar.h>
+#include <octeon/dev/cn30xxsmivar.h>
+#include <octeon/dev/iobusvar.h>
+#include <octeon/dev/if_cnmacvar.h>
+
+#ifndef SET
+#define SET(t, f) ((t) |= (f))
+#define ISSET(t, f) ((t) & (f))
+#define CLR(t, f) ((t) &= ~(f))
+#endif
+
+#ifdef OCTEON_ETH_DEBUG
+#define OCTEON_ETH_KASSERT(x) KASSERT(x)
+#define OCTEON_ETH_KDASSERT(x) KDASSERT(x)
+#else
+#define OCTEON_ETH_KASSERT(x)
+#define OCTEON_ETH_KDASSERT(x)
+#endif
+
+/*
+ * Set the PKO to think command buffers are an odd length. This makes it so we
+ * never have to divide a comamnd across two buffers.
+ */
+#define OCTEON_POOL_NWORDS_CMD \
+ (((uint32_t)OCTEON_POOL_SIZE_CMD / sizeof(uint64_t)) - 1)
+#define FPA_COMMAND_BUFFER_POOL_NWORDS OCTEON_POOL_NWORDS_CMD /* XXX */
+
+#if NBPFILTER > 0
+#define OCTEON_ETH_TAP(ifp, m, dir) \
+ do { \
+ /* Pass this up to any BPF listeners. */ \
+ if ((ifp)->if_bpf) \
+ bpf_mtap((ifp)->if_bpf, (m), (dir)); \
+ } while (0/* CONSTCOND */)
+#else
+#define OCTEON_ETH_TAP(ifp, m, dir)
+#endif /* NBPFILTER > 0 */
+
+static void octeon_eth_buf_init(struct octeon_eth_softc *);
+
+static int octeon_eth_match(struct device *, void *, void *);
+static void octeon_eth_attach(struct device *, struct device *, void *);
+static void octeon_eth_pip_init(struct octeon_eth_softc *);
+static void octeon_eth_ipd_init(struct octeon_eth_softc *);
+static void octeon_eth_pko_init(struct octeon_eth_softc *);
+static void octeon_eth_asx_init(struct octeon_eth_softc *);
+static void octeon_eth_smi_init(struct octeon_eth_softc *);
+
+static void octeon_eth_board_mac_addr(uint8_t *, size_t, int);
+
+static int octeon_eth_mii_readreg(struct device *, int, int);
+static void octeon_eth_mii_writereg(struct device *, int, int, int);
+static void octeon_eth_mii_statchg(struct device *);
+
+static int octeon_eth_mediainit(struct octeon_eth_softc *);
+static void octeon_eth_mediastatus(struct ifnet *, struct ifmediareq *);
+static int octeon_eth_mediachange(struct ifnet *);
+
+static void octeon_eth_send_queue_flush_prefetch(struct octeon_eth_softc *);
+static void octeon_eth_send_queue_flush_fetch(struct octeon_eth_softc *);
+static void octeon_eth_send_queue_flush(struct octeon_eth_softc *);
+static void octeon_eth_send_queue_flush_sync(struct octeon_eth_softc *);
+static int octeon_eth_send_queue_is_full(struct octeon_eth_softc *);
+static void octeon_eth_send_queue_add(struct octeon_eth_softc *,
+ struct mbuf *, uint64_t *);
+static void octeon_eth_send_queue_del(struct octeon_eth_softc *,
+ struct mbuf **, uint64_t **);
+static int octeon_eth_buf_free_work(struct octeon_eth_softc *,
+ uint64_t *, uint64_t);
+static void octeon_eth_buf_ext_free_m(caddr_t, u_int, void *);
+static void octeon_eth_buf_ext_free_ext(caddr_t, u_int, void *);
+
+static int octeon_eth_ioctl(struct ifnet *, u_long, caddr_t);
+static void octeon_eth_watchdog(struct ifnet *);
+static int octeon_eth_init(struct ifnet *);
+static int octeon_eth_stop(struct ifnet *, int);
+static void octeon_eth_start(struct ifnet *);
+
+static int octeon_eth_send_cmd(struct octeon_eth_softc *, uint64_t,
+ uint64_t);
+static uint64_t octeon_eth_send_makecmd_w1(int, paddr_t);
+static uint64_t octeon_eth_send_makecmd_w0(uint64_t, uint64_t, size_t,
+ int);
+static int octeon_eth_send_makecmd_gbuf(struct octeon_eth_softc *,
+ struct mbuf *, uint64_t *, int *);
+static int octeon_eth_send_makecmd(struct octeon_eth_softc *,
+ struct mbuf *, uint64_t *, uint64_t *, uint64_t *);
+static int octeon_eth_send_buf(struct octeon_eth_softc *,
+ struct mbuf *, uint64_t *);
+static int octeon_eth_send(struct octeon_eth_softc *,
+ struct mbuf *);
+
+static int octeon_eth_reset(struct octeon_eth_softc *);
+static int octeon_eth_configure(struct octeon_eth_softc *);
+static int octeon_eth_configure_common(struct octeon_eth_softc *);
+
+static void octeon_eth_tick_free(void *arg);
+static void octeon_eth_tick_misc(void *);
+
+static int octeon_eth_recv_mbuf(struct octeon_eth_softc *,
+ uint64_t *, struct mbuf **);
+static int octeon_eth_recv_check_code(struct octeon_eth_softc *,
+ uint64_t);
+#if 0 /* not used */
+static int octeon_eth_recv_check_jumbo(struct octeon_eth_softc *,
+ uint64_t);
+#endif
+static int octeon_eth_recv_check_link(struct octeon_eth_softc *,
+ uint64_t);
+static int octeon_eth_recv_check(struct octeon_eth_softc *,
+ uint64_t);
+static int octeon_eth_recv(struct octeon_eth_softc *, uint64_t *);
+static void octeon_eth_recv_intr(void *, uint64_t *);
+
+/* device driver context */
+static struct octeon_eth_softc *octeon_eth_gsc[GMX_PORT_NUNITS];
+static void *octeon_eth_pow_recv_ih;
+
+/* sysctl'able parameters */
+int octeon_eth_param_pko_cmd_w0_n2 = 1;
+int octeon_eth_param_pip_dyn_rs = 1;
+int octeon_eth_param_redir = 0;
+int octeon_eth_param_pktbuf = 0;
+int octeon_eth_param_rate = 0;
+int octeon_eth_param_intr = 0;
+
+struct cfattach cnmac_ca = {sizeof(struct octeon_eth_softc),
+ octeon_eth_match, octeon_eth_attach, NULL, NULL};
+
+struct cfdriver cnmac_cd = {NULL, "cnmac", DV_IFNET};
+
+#ifdef OCTEON_ETH_DEBUG
+
+static const struct octeon_evcnt_entry octeon_evcnt_entries[] = {
+#define _ENTRY(name, type, parent, descr) \
+ OCTEON_EVCNT_ENTRY(struct octeon_eth_softc, name, type, parent, descr)
+ _ENTRY(rx, MISC, NULL, "rx"),
+ _ENTRY(rxint, INTR, NULL, "rx intr"),
+ _ENTRY(rxrs, MISC, NULL, "rx dynamic short"),
+ _ENTRY(rxbufpkalloc, MISC, NULL, "rx buf pkt alloc"),
+ _ENTRY(rxbufpkput, MISC, NULL, "rx buf pkt put"),
+ _ENTRY(rxbufwqalloc, MISC, NULL, "rx buf wqe alloc"),
+ _ENTRY(rxbufwqput, MISC, NULL, "rx buf wqe put"),
+ _ENTRY(rxerrcode, MISC, NULL, "rx code error"),
+ _ENTRY(rxerrfix, MISC, NULL, "rx fixup error"),
+ _ENTRY(rxerrjmb, MISC, NULL, "rx jmb error"),
+ _ENTRY(rxerrlink, MISC, NULL, "rx link error"),
+ _ENTRY(rxerroff, MISC, NULL, "rx offload error"),
+ _ENTRY(rxonperrshort, MISC, NULL, "rx onp fixup short error"),
+ _ENTRY(rxonperrpreamble, MISC, NULL, "rx onp fixup preamble error"),
+ _ENTRY(rxonperrcrc, MISC, NULL, "rx onp fixup crc error"),
+ _ENTRY(rxonperraddress, MISC, NULL, "rx onp fixup address error"),
+ _ENTRY(rxonponp, MISC, NULL, "rx onp fixup onp packets"),
+ _ENTRY(rxonpok, MISC, NULL, "rx onp fixup success packets"),
+ _ENTRY(tx, MISC, NULL, "tx"),
+ _ENTRY(txadd, MISC, NULL, "tx add"),
+ _ENTRY(txbufcballoc, MISC, NULL, "tx buf cb alloc"),
+ _ENTRY(txbufcbget, MISC, NULL, "tx buf cb get"),
+ _ENTRY(txbufgballoc, MISC, NULL, "tx buf gb alloc"),
+ _ENTRY(txbufgbget, MISC, NULL, "tx buf gb get"),
+ _ENTRY(txbufgbput, MISC, NULL, "tx buf gb put"),
+ _ENTRY(txdel, MISC, NULL, "tx del"),
+ _ENTRY(txerr, MISC, NULL, "tx error"),
+ _ENTRY(txerrcmd, MISC, NULL, "tx cmd error"),
+ _ENTRY(txerrgbuf, MISC, NULL, "tx gbuf error"),
+ _ENTRY(txerrlink, MISC, NULL, "tx link error"),
+ _ENTRY(txerrmkcmd, MISC, NULL, "tx makecmd error"),
+#undef _ENTRY
+};
+#endif
+
+/* XXX board-specific */
+static const int octeon_eth_phy_table[] = {
+#if defined __seil5__
+ 0x04, 0x01, 0x02
+#else
+ 0x02, 0x03, 0x22
+#endif
+};
+
+/* ---- buffer management */
+
+static const struct octeon_eth_pool_param {
+ int poolno;
+ size_t size;
+ size_t nelems;
+} octeon_eth_pool_params[] = {
+#define _ENTRY(x) { OCTEON_POOL_NO_##x, OCTEON_POOL_SIZE_##x, OCTEON_POOL_NELEMS_##x }
+ _ENTRY(PKT),
+ _ENTRY(WQE),
+ _ENTRY(CMD),
+ _ENTRY(SG)
+#undef _ENTRY
+};
+struct cn30xxfpa_buf *octeon_eth_pools[8/* XXX */];
+#define octeon_eth_fb_pkt octeon_eth_pools[OCTEON_POOL_NO_PKT]
+#define octeon_eth_fb_wqe octeon_eth_pools[OCTEON_POOL_NO_WQE]
+#define octeon_eth_fb_cmd octeon_eth_pools[OCTEON_POOL_NO_CMD]
+#define octeon_eth_fb_sg octeon_eth_pools[OCTEON_POOL_NO_SG]
+
+static void
+octeon_eth_buf_init(struct octeon_eth_softc *sc)
+{
+ static int once;
+ int i;
+ const struct octeon_eth_pool_param *pp;
+ struct cn30xxfpa_buf *fb;
+
+ if (once == 1)
+ return;
+ once = 1;
+
+ for (i = 0; i < (int)nitems(octeon_eth_pool_params); i++) {
+ pp = &octeon_eth_pool_params[i];
+ cn30xxfpa_buf_init(pp->poolno, pp->size, pp->nelems, &fb);
+ octeon_eth_pools[i] = fb;
+ }
+}
+
+/* ---- autoconf */
+
+static int
+octeon_eth_match(struct device *parent, void *match, void *aux)
+{
+ struct cfdata *cf = (struct cfdata *)match;
+ struct cn30xxgmx_attach_args *ga = aux;
+
+ if (strcmp(cf->cf_driver->cd_name, ga->ga_name) != 0) {
+ return 0;
+ }
+ return 1;
+}
+
+static void
+octeon_eth_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct octeon_eth_softc *sc = (void *)self;
+ struct cn30xxgmx_attach_args *ga = aux;
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+ uint8_t enaddr[ETHER_ADDR_LEN];
+
+ printf("\n");
+
+ sc->sc_regt = ga->ga_regt;
+ sc->sc_dmat = ga->ga_dmat;
+ sc->sc_port = ga->ga_portno;
+ sc->sc_port_type = ga->ga_port_type;
+ sc->sc_gmx = ga->ga_gmx;
+ sc->sc_gmx_port = ga->ga_gmx_port;
+
+ sc->sc_init_flag = 0;
+
+ /*
+ * XXX
+ * Setting PIP_IP_OFFSET[OFFSET] to 8 causes panic ... why???
+ */
+ sc->sc_ip_offset = 0/* XXX */;
+
+ octeon_eth_board_mac_addr(enaddr, sizeof(enaddr), sc->sc_port);
+ printf("%s: Ethernet address %s\n", sc->sc_dev.dv_xname,
+ ether_sprintf(enaddr));
+
+ /*
+ * live lock control notifications.
+ * XXX: use sysctl ???
+ */
+
+ octeon_eth_gsc[sc->sc_port] = sc;
+
+ SIMPLEQ_INIT(&sc->sc_sendq);
+ sc->sc_soft_req_thresh = 15/* XXX */;
+ sc->sc_ext_callback_cnt = 0;
+
+ cn30xxgmx_stats_init(sc->sc_gmx_port);
+
+ timeout_set(&sc->sc_tick_misc_ch, octeon_eth_tick_misc, sc);
+ timeout_set(&sc->sc_tick_free_ch, octeon_eth_tick_free, sc);
+
+ cn30xxfau_op_init(&sc->sc_fau_done,
+ OCTEON_CVMSEG_ETHER_OFFSET(sc->sc_port, csm_ether_fau_done),
+ OCT_FAU_REG_ADDR_END - (8 * (sc->sc_port + 1))/* XXX */);
+ cn30xxfau_op_set_8(&sc->sc_fau_done, 0);
+
+ octeon_eth_pip_init(sc);
+ octeon_eth_ipd_init(sc);
+ octeon_eth_pko_init(sc);
+ octeon_eth_asx_init(sc);
+ octeon_eth_smi_init(sc);
+
+ sc->sc_gmx_port->sc_ipd = sc->sc_ipd;
+ sc->sc_gmx_port->sc_port_asx = sc->sc_asx;
+ sc->sc_gmx_port->sc_port_mii = &sc->sc_mii;
+ sc->sc_gmx_port->sc_port_ac = &sc->sc_arpcom;
+
+ /* XXX */
+ sc->sc_pow = &cn30xxpow_softc;
+
+ octeon_eth_mediainit(sc);
+
+ strncpy(ifp->if_xname, sc->sc_dev.dv_xname, sizeof(ifp->if_xname));
+ ifp->if_softc = sc;
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+ ifp->if_ioctl = octeon_eth_ioctl;
+ ifp->if_start = octeon_eth_start;
+ ifp->if_watchdog = octeon_eth_watchdog;
+ ifp->if_stop = octeon_eth_stop; /* XXX */
+ IFQ_SET_MAXLEN(&ifp->if_snd, max(GATHER_QUEUE_SIZE, IFQ_MAXLEN));
+ IFQ_SET_READY(&ifp->if_snd);
+
+ ifp->if_capabilities = 0; /* XXX */
+
+ cn30xxgmx_set_mac_addr(sc->sc_gmx_port, enaddr);
+ cn30xxgmx_set_filter(sc->sc_gmx_port);
+
+ if_attach(ifp);
+
+ memcpy(sc->sc_arpcom.ac_enaddr, enaddr, ETHER_ADDR_LEN);
+ ether_ifattach(ifp);
+
+ /* XXX */
+ sc->sc_rate_recv_check_link_cap.tv_sec = 1;
+ sc->sc_rate_recv_check_jumbo_cap.tv_sec = 1;
+ sc->sc_rate_recv_check_code_cap.tv_sec = 1;
+
+#if 1
+ octeon_eth_buf_init(sc);
+#endif
+
+ if (octeon_eth_pow_recv_ih == NULL)
+ octeon_eth_pow_recv_ih = cn30xxpow_intr_establish(OCTEON_POW_GROUP_PIP,
+ IPL_NET, octeon_eth_recv_intr, NULL, NULL, sc->sc_dev.dv_xname);
+
+#if 0
+ /* Make sure the interface is shutdown during reboot. */
+ sc->sc_sdhook = shutdownhook_establish(octeon_eth_shutdown, sc);
+ if (sc->sc_sdhook == NULL)
+ printf("%s: WARNING: unable to establish shutdown hook\n",
+ sc->sc_dev.dv_xname);
+#endif
+
+ OCTEON_EVCNT_ATTACH_EVCNTS(sc, octeon_evcnt_entries,
+ sc->sc_dev.dv_xname);
+}
+
+/* ---- submodules */
+
+/* XXX */
+static void
+octeon_eth_pip_init(struct octeon_eth_softc *sc)
+{
+ struct cn30xxpip_attach_args pip_aa;
+
+ pip_aa.aa_port = sc->sc_port;
+ pip_aa.aa_regt = sc->sc_regt;
+ pip_aa.aa_tag_type = POW_TAG_TYPE_ORDERED/* XXX */;
+ pip_aa.aa_receive_group = OCTEON_POW_GROUP_PIP;
+ pip_aa.aa_ip_offset = sc->sc_ip_offset;
+ cn30xxpip_init(&pip_aa, &sc->sc_pip);
+}
+
+/* XXX */
+static void
+octeon_eth_ipd_init(struct octeon_eth_softc *sc)
+{
+ struct cn30xxipd_attach_args ipd_aa;
+
+ ipd_aa.aa_port = sc->sc_port;
+ ipd_aa.aa_regt = sc->sc_regt;
+ ipd_aa.aa_first_mbuff_skip = 184/* XXX */;
+ ipd_aa.aa_not_first_mbuff_skip = 0/* XXX */;
+ cn30xxipd_init(&ipd_aa, &sc->sc_ipd);
+}
+
+/* XXX */
+static void
+octeon_eth_pko_init(struct octeon_eth_softc *sc)
+{
+ struct cn30xxpko_attach_args pko_aa;
+
+ pko_aa.aa_port = sc->sc_port;
+ pko_aa.aa_regt = sc->sc_regt;
+ pko_aa.aa_cmdptr = &sc->sc_cmdptr;
+ pko_aa.aa_cmd_buf_pool = OCTEON_POOL_NO_CMD;
+ pko_aa.aa_cmd_buf_size = OCTEON_POOL_NWORDS_CMD;
+ cn30xxpko_init(&pko_aa, &sc->sc_pko);
+}
+
+/* XXX */
+static void
+octeon_eth_asx_init(struct octeon_eth_softc *sc)
+{
+ struct cn30xxasx_attach_args asx_aa;
+
+ asx_aa.aa_port = sc->sc_port;
+ asx_aa.aa_regt = sc->sc_regt;
+ cn30xxasx_init(&asx_aa, &sc->sc_asx);
+}
+
+static void
+octeon_eth_smi_init(struct octeon_eth_softc *sc)
+{
+ struct cn30xxsmi_attach_args smi_aa;
+
+ smi_aa.aa_port = sc->sc_port;
+ smi_aa.aa_regt = sc->sc_regt;
+ cn30xxsmi_init(&smi_aa, &sc->sc_smi);
+ cn30xxsmi_set_clock(sc->sc_smi, 0x1464ULL); /* XXX */
+}
+
+/* ---- XXX */
+
+#define ADDR2UINT64(u, a) \
+ do { \
+ u = \
+ (((uint64_t)a[0] << 40) | ((uint64_t)a[1] << 32) | \
+ ((uint64_t)a[2] << 24) | ((uint64_t)a[3] << 16) | \
+ ((uint64_t)a[4] << 8) | ((uint64_t)a[5] << 0)); \
+ } while (0)
+#define UINT642ADDR(a, u) \
+ do { \
+ a[0] = (uint8_t)((u) >> 40); a[1] = (uint8_t)((u) >> 32); \
+ a[2] = (uint8_t)((u) >> 24); a[3] = (uint8_t)((u) >> 16); \
+ a[4] = (uint8_t)((u) >> 8); a[5] = (uint8_t)((u) >> 0); \
+ } while (0)
+
+static void
+octeon_eth_board_mac_addr(uint8_t *enaddr, size_t size, int port)
+{
+ uint64_t addr;
+ int i;
+
+ /* XXX read a mac_dsc tuple from EEPROM */
+ for (i = 0; i < size; i++)
+ enaddr[i] = i;
+
+ ADDR2UINT64(addr, enaddr);
+ addr += port;
+ UINT642ADDR(enaddr, addr);
+}
+
+/* ---- media */
+
+static int
+octeon_eth_mii_readreg(struct device *self, int phy_no, int reg)
+{
+ struct octeon_eth_softc *sc = (struct octeon_eth_softc *)self;
+ int phy_addr = octeon_eth_phy_table[phy_no];
+
+ if (sc->sc_port >= (int)nitems(octeon_eth_phy_table) ||
+ phy_no != sc->sc_port) {
+ log(LOG_ERR,
+ "mii read address is mismatch, phy number %d.\n", phy_no);
+ return -1;
+ }
+ return cn30xxsmi_read(sc->sc_smi, phy_addr, reg);
+}
+
+static void
+octeon_eth_mii_writereg(struct device *self, int phy_no, int reg, int value)
+{
+ struct octeon_eth_softc *sc = (struct octeon_eth_softc *)self;
+ int phy_addr = octeon_eth_phy_table[phy_no];
+
+ if (sc->sc_port >= (int)nitems(octeon_eth_phy_table) ||
+ phy_no != sc->sc_port) {
+ log(LOG_ERR,
+ "mii write address is mismatch, phy number %d.\n", phy_no);
+ return;
+ }
+ cn30xxsmi_write(sc->sc_smi, phy_addr, reg, value);
+}
+
+static void
+octeon_eth_mii_statchg(struct device *self)
+{
+ struct octeon_eth_softc *sc = (struct octeon_eth_softc *)self;
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+
+ cn30xxpko_port_enable(sc->sc_pko, 0);
+ cn30xxgmx_port_enable(sc->sc_gmx_port, 0);
+
+ octeon_eth_reset(sc);
+
+ if (ISSET(ifp->if_flags, IFF_RUNNING))
+ cn30xxgmx_set_filter(sc->sc_gmx_port);
+
+ cn30xxpko_port_enable(sc->sc_pko, 1);
+ cn30xxgmx_port_enable(sc->sc_gmx_port, 1);
+}
+
+static int
+octeon_eth_mediainit(struct octeon_eth_softc *sc)
+{
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+
+ sc->sc_mii.mii_ifp = ifp;
+ sc->sc_mii.mii_readreg = octeon_eth_mii_readreg;
+ sc->sc_mii.mii_writereg = octeon_eth_mii_writereg;
+ sc->sc_mii.mii_statchg = octeon_eth_mii_statchg;
+ ifmedia_init(&sc->sc_mii.mii_media, 0, octeon_eth_mediachange,
+ octeon_eth_mediastatus);
+
+ mii_attach(&sc->sc_dev, &sc->sc_mii,
+ 0xffffffff, sc->sc_port, MII_OFFSET_ANY, MIIF_DOPAUSE);
+
+ /* XXX */
+ if (LIST_FIRST(&sc->sc_mii.mii_phys) != NULL) {
+ /* XXX */
+ ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_AUTO);
+ } else {
+ /* XXX */
+ ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER | IFM_NONE,
+ MII_MEDIA_NONE, NULL);
+ /* XXX */
+ ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_NONE);
+ }
+
+ return 0;
+}
+
+static void
+octeon_eth_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
+{
+ struct octeon_eth_softc *sc = ifp->if_softc;
+
+ mii_pollstat(&sc->sc_mii);
+ ifmr->ifm_status = sc->sc_mii.mii_media_status;
+ ifmr->ifm_active = sc->sc_mii.mii_media_active;
+ ifmr->ifm_active = (sc->sc_mii.mii_media_active & ~IFM_ETH_FMASK) |
+ sc->sc_gmx_port->sc_port_flowflags;
+}
+
+static int
+octeon_eth_mediachange(struct ifnet *ifp)
+{
+ struct octeon_eth_softc *sc = ifp->if_softc;
+
+ mii_mediachg(&sc->sc_mii);
+
+ return 0;
+}
+
+/* ---- send buffer garbage collection */
+
+static void
+octeon_eth_send_queue_flush_prefetch(struct octeon_eth_softc *sc)
+{
+ OCTEON_ETH_KASSERT(sc->sc_prefetch == 0);
+ cn30xxfau_op_inc_fetch_8(&sc->sc_fau_done, 0);
+ sc->sc_prefetch = 1;
+}
+
+static void
+octeon_eth_send_queue_flush_fetch(struct octeon_eth_softc *sc)
+{
+#ifndef OCTEON_ETH_DEBUG
+ if (!sc->sc_prefetch)
+ return;
+#endif
+ OCTEON_ETH_KASSERT(sc->sc_prefetch == 1);
+ sc->sc_hard_done_cnt = cn30xxfau_op_inc_read_8(&sc->sc_fau_done);
+ OCTEON_ETH_KASSERT(sc->sc_hard_done_cnt <= 0);
+ sc->sc_prefetch = 0;
+}
+
+static void
+octeon_eth_send_queue_flush(struct octeon_eth_softc *sc)
+{
+ const int64_t sent_count = sc->sc_hard_done_cnt;
+ int i;
+
+ OCTEON_ETH_KASSERT(sc->sc_flush == 0);
+ OCTEON_ETH_KASSERT(sent_count <= 0);
+
+ for (i = 0; i < 0 - sent_count; i++) {
+ struct mbuf *m;
+ uint64_t *gbuf;
+
+ octeon_eth_send_queue_del(sc, &m, &gbuf);
+
+ cn30xxfpa_buf_put_paddr(octeon_eth_fb_sg, CKSEG0_TO_PHYS(gbuf));
+ OCTEON_EVCNT_INC(sc, txbufgbput);
+
+ m_freem(m);
+ }
+
+ cn30xxfau_op_inc_fetch_8(&sc->sc_fau_done, i);
+ sc->sc_flush = i;
+}
+
+static void
+octeon_eth_send_queue_flush_sync(struct octeon_eth_softc *sc)
+{
+ if (sc->sc_flush == 0)
+ return;
+
+ OCTEON_ETH_KASSERT(sc->sc_flush > 0);
+
+ /* XXX */
+ cn30xxfau_op_inc_read_8(&sc->sc_fau_done);
+ sc->sc_soft_req_cnt -= sc->sc_flush;
+ OCTEON_ETH_KASSERT(sc->sc_soft_req_cnt >= 0);
+ /* XXX */
+
+ sc->sc_flush = 0;
+}
+
+static int
+octeon_eth_send_queue_is_full(struct octeon_eth_softc *sc)
+{
+#ifdef OCTEON_ETH_SEND_QUEUE_CHECK
+ int64_t nofree_cnt;
+
+ nofree_cnt = sc->sc_soft_req_cnt + sc->sc_hard_done_cnt;
+
+ if (__predict_false(nofree_cnt == GATHER_QUEUE_SIZE - 1)) {
+ octeon_eth_send_queue_flush(sc);
+ OCTEON_EVCNT_INC(sc, txerrgbuf);
+ octeon_eth_send_queue_flush_sync(sc);
+ return 1;
+ }
+
+#endif
+ return 0;
+}
+
+/*
+ * (Ab)use m_nextpkt and m_paddr to maintain mbuf chain and pointer to gather
+ * buffer. Other mbuf members may be used by m_freem(), so don't touch them!
+ */
+
+struct _send_queue_entry {
+ union {
+ struct mbuf _sqe_s_mbuf;
+ struct {
+ char _sqe_s_entry_pad[offsetof(struct mbuf, m_nextpkt)];
+ SIMPLEQ_ENTRY(_send_queue_entry) _sqe_s_entry_entry;
+ } _sqe_s_entry;
+ struct {
+ char _sqe_s_gbuf_pad[offsetof(struct mbuf, M_dat.MH.MH_pkthdr.rcvif)];
+ uint64_t *_sqe_s_gbuf_gbuf;
+ } _sqe_s_gbuf;
+ } _sqe_u;
+#define _sqe_entry _sqe_u._sqe_s_entry._sqe_s_entry_entry
+#define _sqe_gbuf _sqe_u._sqe_s_gbuf._sqe_s_gbuf_gbuf
+};
+
+static void
+octeon_eth_send_queue_add(struct octeon_eth_softc *sc, struct mbuf *m,
+ uint64_t *gbuf)
+{
+ struct _send_queue_entry *sqe = (struct _send_queue_entry *)m;
+
+ OCTEON_ETH_KASSERT(m->m_flags & M_PKTHDR);
+
+ sqe->_sqe_gbuf = gbuf;
+ SIMPLEQ_INSERT_TAIL(&sc->sc_sendq, sqe, _sqe_entry);
+
+ if (m->m_ext.ext_free != NULL)
+ sc->sc_ext_callback_cnt++;
+
+ OCTEON_EVCNT_INC(sc, txadd);
+}
+
+static void
+octeon_eth_send_queue_del(struct octeon_eth_softc *sc, struct mbuf **rm,
+ uint64_t **rgbuf)
+{
+ struct _send_queue_entry *sqe;
+
+ sqe = SIMPLEQ_FIRST(&sc->sc_sendq);
+ OCTEON_ETH_KASSERT(sqe != NULL);
+ SIMPLEQ_REMOVE_HEAD(&sc->sc_sendq, _sqe_entry);
+
+ *rm = (void *)sqe;
+ *rgbuf = sqe->_sqe_gbuf;
+
+ if ((*rm)->m_ext.ext_free != NULL) {
+ sc->sc_ext_callback_cnt--;
+ OCTEON_ETH_KASSERT(sc->sc_ext_callback_cnt >= 0);
+ }
+
+ OCTEON_EVCNT_INC(sc, txdel);
+}
+
+static int
+octeon_eth_buf_free_work(struct octeon_eth_softc *sc, uint64_t *work,
+ uint64_t word2)
+{
+ /* XXX when jumbo frame */
+ if (ISSET(word2, PIP_WQE_WORD2_IP_BUFS)) {
+ paddr_t addr;
+ paddr_t start_buffer;
+
+ addr = CKSEG0_TO_PHYS(work[3] & PIP_WQE_WORD3_ADDR);
+ start_buffer = addr & ~(2048 - 1);
+
+ cn30xxfpa_buf_put_paddr(octeon_eth_fb_pkt, start_buffer);
+ OCTEON_EVCNT_INC(sc, rxbufpkput);
+ }
+
+ cn30xxfpa_buf_put_paddr(octeon_eth_fb_wqe, CKSEG0_TO_PHYS(work));
+ OCTEON_EVCNT_INC(sc, rxbufwqput);
+
+ return 0;
+}
+
+static void
+octeon_eth_buf_ext_free_m(caddr_t buf, u_int size, void *arg)
+{
+ uint64_t *work = (void *)arg;
+#ifdef OCTEON_ETH_DEBUG
+ struct octeon_eth_softc *sc = (void *)(uintptr_t)work[0];
+#endif
+ int s = splnet();
+
+ OCTEON_EVCNT_INC(sc, rxrs);
+
+ cn30xxfpa_buf_put_paddr(octeon_eth_fb_wqe, CKSEG0_TO_PHYS(work));
+ OCTEON_EVCNT_INC(sc, rxbufwqput);
+
+ splx(s);
+}
+
+static void
+octeon_eth_buf_ext_free_ext(caddr_t buf, u_int size,
+ void *arg)
+{
+ uint64_t *work = (void *)arg;
+#ifdef OCTEON_ETH_DEBUG
+ struct octeon_eth_softc *sc = (void *)(uintptr_t)work[0];
+#endif
+ int s = splnet();
+
+ cn30xxfpa_buf_put_paddr(octeon_eth_fb_wqe, CKSEG0_TO_PHYS(work));
+ OCTEON_EVCNT_INC(sc, rxbufwqput);
+
+ cn30xxfpa_buf_put_paddr(octeon_eth_fb_pkt, CKSEG0_TO_PHYS(buf));
+ OCTEON_EVCNT_INC(sc, rxbufpkput);
+
+ splx(s);
+}
+
+/* ---- ifnet interfaces */
+
+static int
+octeon_eth_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+{
+ struct octeon_eth_softc *sc = ifp->if_softc;
+ struct ifreq *ifr = (struct ifreq *)data;
+ struct ifaddr *ifa = (struct ifaddr *)data;
+ int s, error = 0;
+
+ s = splnet();
+ switch (cmd) {
+ case SIOCSIFADDR:
+ if (!(ifp->if_flags & IFF_UP)) {
+ ifp->if_flags |= IFF_UP;
+ octeon_eth_init(ifp);
+ }
+#ifdef INET
+ if (ifa->ifa_addr->sa_family == AF_INET)
+ arp_ifinit(&sc->sc_arpcom, ifa);
+#endif /* INET */
+ break;
+
+ case SIOCSIFFLAGS:
+ if (ifp->if_flags & IFF_UP) {
+ if (ifp->if_flags & IFF_RUNNING)
+ error = ENETRESET;
+ else
+ octeon_eth_init(ifp);
+ } else {
+ if (ifp->if_flags & IFF_RUNNING)
+ octeon_eth_stop(ifp, 0);
+ }
+ break;
+ case SIOCSIFMEDIA:
+ /* Flow control requires full-duplex mode. */
+ if (IFM_SUBTYPE(ifr->ifr_media) == IFM_AUTO ||
+ (ifr->ifr_media & IFM_FDX) == 0) {
+ ifr->ifr_media &= ~IFM_ETH_FMASK;
+ }
+ if (IFM_SUBTYPE(ifr->ifr_media) != IFM_AUTO) {
+ if ((ifr->ifr_media & IFM_ETH_FMASK) == IFM_FLOW) {
+ ifr->ifr_media |=
+ IFM_ETH_TXPAUSE | IFM_ETH_RXPAUSE;
+ }
+ sc->sc_gmx_port->sc_port_flowflags =
+ ifr->ifr_media & IFM_ETH_FMASK;
+ }
+ /* FALLTHROUGH */
+ case SIOCGIFMEDIA:
+ /* XXX: Flow contorol */
+ error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
+ break;
+ default:
+ error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data);
+ if (error == ENETRESET) {
+ /*
+ * Multicast list has changed; set the hardware filter
+ * accordingly.
+ */
+ if (ISSET(ifp->if_flags, IFF_RUNNING))
+ cn30xxgmx_set_filter(sc->sc_gmx_port);
+ error = 0;
+ }
+ break;
+ }
+ octeon_eth_start(ifp);
+ splx(s);
+
+ return (error);
+}
+
+/* ---- send (output) */
+
+static uint64_t
+octeon_eth_send_makecmd_w0(uint64_t fau0, uint64_t fau1, size_t len, int segs)
+{
+ return cn30xxpko_cmd_word0(
+ OCT_FAU_OP_SIZE_64, /* sz1 */
+ OCT_FAU_OP_SIZE_64, /* sz0 */
+ 1, fau1, 1, fau0, /* s1, reg1, s0, reg0 */
+ 0, /* le */
+ octeon_eth_param_pko_cmd_w0_n2, /* n2 */
+ 1, 0, /* q, r */
+ (segs == 1) ? 0 : 1, /* g */
+ 0, 0, 1, /* ipoffp1, ii, df */
+ segs, (int)len); /* segs, totalbytes */
+}
+
+static uint64_t
+octeon_eth_send_makecmd_w1(int size, paddr_t addr)
+{
+ return cn30xxpko_cmd_word1(
+ 0, 0, /* i, back */
+ FPA_GATHER_BUFFER_POOL, /* pool */
+ size, addr); /* size, addr */
+}
+
+/* TODO: use bus_dma(9) */
+
+#define KVTOPHYS(addr) if_cnmac_kvtophys((vaddr_t)(addr))
+paddr_t if_cnmac_kvtophys(vaddr_t);
+
+paddr_t
+if_cnmac_kvtophys(vaddr_t kva)
+{
+ if (IS_XKPHYS(kva))
+ return XKPHYS_TO_PHYS(kva);
+ else if (kva >= CKSEG0_BASE && kva < CKSEG0_BASE + CKSEG_SIZE)
+ return CKSEG0_TO_PHYS(kva);
+ else if (kva >= CKSEG1_BASE && kva < CKSEG1_BASE + CKSEG_SIZE)
+ return CKSEG1_TO_PHYS(kva);
+
+ printf("kva %p is not be able to convert physical address\n", kva);
+ panic("if_cnmac_kvtophys");
+}
+
+static int
+octeon_eth_send_makecmd_gbuf(struct octeon_eth_softc *sc, struct mbuf *m0,
+ uint64_t *gbuf, int *rsegs)
+{
+ struct mbuf *m;
+ int segs = 0;
+ uint32_t laddr, rlen, nlen;
+
+ for (m = m0; m != NULL; m = m->m_next) {
+
+ if (__predict_false(m->m_len == 0))
+ continue;
+
+#if 0
+ OCTEON_ETH_KASSERT(((uint32_t)m->m_data & (PAGE_SIZE - 1))
+ == (kvtophys((vaddr_t)m->m_data) & (PAGE_SIZE - 1)));
+#endif
+
+ /*
+ * aligned 4k
+ */
+ laddr = (uintptr_t)m->m_data & (PAGE_SIZE - 1);
+
+ if (laddr + m->m_len > PAGE_SIZE) {
+ /* XXX */
+ rlen = PAGE_SIZE - laddr;
+ nlen = m->m_len - rlen;
+ *(gbuf + segs) = octeon_eth_send_makecmd_w1(rlen,
+ KVTOPHYS(m->m_data));
+ segs++;
+ if (segs > 63) {
+ return 1;
+ }
+ /* XXX */
+ } else {
+ rlen = 0;
+ nlen = m->m_len;
+ }
+
+ *(gbuf + segs) = octeon_eth_send_makecmd_w1(nlen,
+ KVTOPHYS((caddr_t)m->m_data + rlen));
+ segs++;
+ if (segs > 63) {
+ return 1;
+ }
+ }
+
+ OCTEON_ETH_KASSERT(m == NULL);
+
+ *rsegs = segs;
+
+ return 0;
+}
+
+static int
+octeon_eth_send_makecmd(struct octeon_eth_softc *sc, struct mbuf *m,
+ uint64_t *gbuf, uint64_t *rpko_cmd_w0, uint64_t *rpko_cmd_w1)
+{
+ uint64_t pko_cmd_w0, pko_cmd_w1;
+ int segs;
+ int result = 0;
+
+ if (octeon_eth_send_makecmd_gbuf(sc, m, gbuf, &segs)) {
+ log(LOG_WARNING, "%s: there are a lot of number of segments"
+ " of transmission data", sc->sc_dev.dv_xname);
+ result = 1;
+ goto done;
+ }
+
+ /*
+ * segs == 1 -> link mode (single continuous buffer)
+ * WORD1[size] is number of bytes pointed by segment
+ *
+ * segs > 1 -> gather mode (scatter-gather buffer)
+ * WORD1[size] is number of segments
+ */
+ pko_cmd_w0 = octeon_eth_send_makecmd_w0(sc->sc_fau_done.fd_regno,
+ 0, m->m_pkthdr.len, segs);
+ pko_cmd_w1 = octeon_eth_send_makecmd_w1(
+ (segs == 1) ? m->m_pkthdr.len : segs,
+ (segs == 1) ?
+ KVTOPHYS(m->m_data) :
+ CKSEG0_TO_PHYS(gbuf));
+
+ *rpko_cmd_w0 = pko_cmd_w0;
+ *rpko_cmd_w1 = pko_cmd_w1;
+
+done:
+ return result;
+}
+
+static int
+octeon_eth_send_cmd(struct octeon_eth_softc *sc, uint64_t pko_cmd_w0,
+ uint64_t pko_cmd_w1)
+{
+ uint64_t *cmdptr;
+ int result = 0;
+
+ cmdptr = (uint64_t *)PHYS_TO_CKSEG0(sc->sc_cmdptr.cmdptr);
+ cmdptr += sc->sc_cmdptr.cmdptr_idx;
+
+ OCTEON_ETH_KASSERT(cmdptr != NULL);
+
+ *cmdptr++ = pko_cmd_w0;
+ *cmdptr++ = pko_cmd_w1;
+
+ OCTEON_ETH_KASSERT(sc->sc_cmdptr.cmdptr_idx + 2 <= FPA_COMMAND_BUFFER_POOL_NWORDS - 1);
+
+ if (sc->sc_cmdptr.cmdptr_idx + 2 == FPA_COMMAND_BUFFER_POOL_NWORDS - 1) {
+ paddr_t buf;
+
+ buf = cn30xxfpa_buf_get_paddr(octeon_eth_fb_cmd);
+ if (buf == 0) {
+ log(LOG_WARNING,
+ "%s: can not allocate command buffer from free pool allocator\n",
+ sc->sc_dev.dv_xname);
+ result = 1;
+ goto done;
+ }
+ OCTEON_EVCNT_INC(sc, txbufcbget);
+ *cmdptr++ = buf;
+ sc->sc_cmdptr.cmdptr = (uint64_t)buf;
+ sc->sc_cmdptr.cmdptr_idx = 0;
+ } else {
+ sc->sc_cmdptr.cmdptr_idx += 2;
+ }
+
+ cn30xxpko_op_doorbell_write(sc->sc_port, sc->sc_port, 2);
+
+done:
+ return result;
+}
+
+static int
+octeon_eth_send_buf(struct octeon_eth_softc *sc, struct mbuf *m,
+ uint64_t *gbuf)
+{
+ int result = 0, error;
+ uint64_t pko_cmd_w0, pko_cmd_w1;
+
+ error = octeon_eth_send_makecmd(sc, m, gbuf, &pko_cmd_w0, &pko_cmd_w1);
+ if (error != 0) {
+ /* already logging */
+ OCTEON_EVCNT_INC(sc, txerrmkcmd);
+ result = error;
+ goto done;
+ }
+
+ error = octeon_eth_send_cmd(sc, pko_cmd_w0, pko_cmd_w1);
+ if (error != 0) {
+ /* already logging */
+ OCTEON_EVCNT_INC(sc, txerrcmd);
+ result = error;
+ }
+
+done:
+ return result;
+}
+
+static int
+octeon_eth_send(struct octeon_eth_softc *sc, struct mbuf *m)
+{
+ paddr_t gaddr = 0;
+ uint64_t *gbuf = NULL;
+ int result = 0, error;
+
+ OCTEON_EVCNT_INC(sc, tx);
+
+ gaddr = cn30xxfpa_buf_get_paddr(octeon_eth_fb_sg);
+ if (gaddr == 0) {
+ log(LOG_WARNING,
+ "%s: can not allocate gather buffer from free pool allocator\n",
+ sc->sc_dev.dv_xname);
+ OCTEON_EVCNT_INC(sc, txerrgbuf);
+ result = 1;
+ goto done;
+ }
+ OCTEON_EVCNT_INC(sc, txbufgbget);
+
+ gbuf = (uint64_t *)(uintptr_t)PHYS_TO_CKSEG0(gaddr);
+
+ OCTEON_ETH_KASSERT(gbuf != NULL);
+
+ error = octeon_eth_send_buf(sc, m, gbuf);
+ if (error != 0) {
+ /* already logging */
+ cn30xxfpa_buf_put_paddr(octeon_eth_fb_sg, gaddr);
+ OCTEON_EVCNT_INC(sc, txbufgbput);
+ result = error;
+ goto done;
+ }
+
+ octeon_eth_send_queue_add(sc, m, gbuf);
+
+done:
+ return result;
+}
+
+static void
+octeon_eth_start(struct ifnet *ifp)
+{
+ struct octeon_eth_softc *sc = ifp->if_softc;
+ struct mbuf *m;
+
+ /*
+ * performance tuning
+ * presend iobdma request
+ */
+ octeon_eth_send_queue_flush_prefetch(sc);
+
+ if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
+ goto last;
+
+ /* XXX assume that OCTEON doesn't buffer packets */
+ if (__predict_false(!cn30xxgmx_link_status(sc->sc_gmx_port))) {
+ /* dequeue and drop them */
+ while (1) {
+ IFQ_DEQUEUE(&ifp->if_snd, m);
+ if (m == NULL)
+ break;
+#if 0
+#ifdef DDB
+ m_print(m, "cd", printf);
+#endif
+ printf("%s: drop\n", sc->sc_dev.dv_xname);
+#endif
+ m_freem(m);
+ IF_DROP(&ifp->if_snd);
+ OCTEON_EVCNT_INC(sc, txerrlink);
+ }
+ goto last;
+ }
+
+ for (;;) {
+ IFQ_POLL(&ifp->if_snd, m);
+ if (__predict_false(m == NULL))
+ break;
+
+ octeon_eth_send_queue_flush_fetch(sc); /* XXX */
+
+ /*
+ * XXXSEIL
+ * If no free send buffer is available, free all the sent buffer
+ * and bail out.
+ */
+ if (octeon_eth_send_queue_is_full(sc)) {
+ return;
+ }
+ /* XXX */
+
+ IFQ_DEQUEUE(&ifp->if_snd, m);
+
+ OCTEON_ETH_TAP(ifp, m, BPF_DIRECTION_OUT);
+
+ /* XXX */
+ if (sc->sc_soft_req_cnt > sc->sc_soft_req_thresh)
+ octeon_eth_send_queue_flush(sc);
+ if (octeon_eth_send(sc, m)) {
+ ifp->if_oerrors++;
+ m_freem(m);
+ log(LOG_WARNING,
+ "%s: failed in the transmission of the packet\n",
+ sc->sc_dev.dv_xname);
+ OCTEON_EVCNT_INC(sc, txerr);
+ } else {
+ sc->sc_soft_req_cnt++;
+ }
+ if (sc->sc_flush)
+ octeon_eth_send_queue_flush_sync(sc);
+ /* XXX */
+
+ /*
+ * send next iobdma request
+ */
+ octeon_eth_send_queue_flush_prefetch(sc);
+ }
+
+/*
+ * XXXSEIL
+ * Don't schedule send-buffer-free callout every time - those buffers are freed
+ * by "free tick". This makes some packets like NFS slower, but it normally
+ * doesn't happen on SEIL.
+ */
+#ifdef OCTEON_ETH_USENFS
+ if (__predict_false(sc->sc_ext_callback_cnt > 0)) {
+ int timo;
+
+ /* ??? */
+ timo = hz - (100 * sc->sc_ext_callback_cnt);
+ if (timo < 10)
+ timo = 10;
+ callout_schedule(&sc->sc_tick_free_ch, timo);
+ }
+#endif
+
+last:
+ octeon_eth_send_queue_flush_fetch(sc);
+}
+
+static void
+octeon_eth_watchdog(struct ifnet *ifp)
+{
+ struct octeon_eth_softc *sc = ifp->if_softc;
+
+ printf("%s: device timeout\n", sc->sc_dev.dv_xname);
+
+ octeon_eth_configure(sc);
+
+ SET(ifp->if_flags, IFF_RUNNING);
+ CLR(ifp->if_flags, IFF_OACTIVE);
+ ifp->if_timer = 0;
+
+ octeon_eth_start(ifp);
+}
+
+static int
+octeon_eth_init(struct ifnet *ifp)
+{
+ struct octeon_eth_softc *sc = ifp->if_softc;
+
+ /* XXX don't disable commonly used parts!!! XXX */
+ if (sc->sc_init_flag == 0) {
+ /* Cancel any pending I/O. */
+ octeon_eth_stop(ifp, 0);
+
+ /* Initialize the device */
+ octeon_eth_configure(sc);
+
+ cn30xxpko_enable(sc->sc_pko);
+ cn30xxipd_enable(sc->sc_ipd);
+
+ sc->sc_init_flag = 1;
+ } else {
+ cn30xxgmx_port_enable(sc->sc_gmx_port, 1);
+ }
+ octeon_eth_mediachange(ifp);
+
+ cn30xxgmx_set_filter(sc->sc_gmx_port);
+
+ timeout_add_sec(&sc->sc_tick_misc_ch, 1);
+ timeout_add_sec(&sc->sc_tick_free_ch, 1);
+
+ SET(ifp->if_flags, IFF_RUNNING);
+ CLR(ifp->if_flags, IFF_OACTIVE);
+
+ return 0;
+}
+
+static int
+octeon_eth_stop(struct ifnet *ifp, int disable)
+{
+ struct octeon_eth_softc *sc = ifp->if_softc;
+
+ timeout_del(&sc->sc_tick_misc_ch);
+ timeout_del(&sc->sc_tick_free_ch);
+ timeout_del(&sc->sc_resume_ch);
+
+ mii_down(&sc->sc_mii);
+
+ cn30xxgmx_port_enable(sc->sc_gmx_port, 0);
+
+ /* Mark the interface as down and cancel the watchdog timer. */
+ CLR(ifp->if_flags, IFF_RUNNING | IFF_OACTIVE);
+ ifp->if_timer = 0;
+
+ return 0;
+}
+
+/* ---- misc */
+
+#define PKO_INDEX_MASK ((1ULL << 12/* XXX */) - 1)
+
+static int
+octeon_eth_reset(struct octeon_eth_softc *sc)
+{
+ cn30xxgmx_reset_speed(sc->sc_gmx_port);
+ cn30xxgmx_reset_flowctl(sc->sc_gmx_port);
+ cn30xxgmx_reset_timing(sc->sc_gmx_port);
+ cn30xxgmx_reset_board(sc->sc_gmx_port);
+
+ return 0;
+}
+
+static int
+octeon_eth_configure(struct octeon_eth_softc *sc)
+{
+ cn30xxgmx_port_enable(sc->sc_gmx_port, 0);
+
+ octeon_eth_reset(sc);
+
+ octeon_eth_configure_common(sc);
+
+ cn30xxpko_port_config(sc->sc_pko);
+ cn30xxpko_port_enable(sc->sc_pko, 1);
+ cn30xxpip_port_config(sc->sc_pip);
+
+ cn30xxgmx_tx_stats_rd_clr(sc->sc_gmx_port, 1);
+ cn30xxgmx_rx_stats_rd_clr(sc->sc_gmx_port, 1);
+
+ cn30xxgmx_port_enable(sc->sc_gmx_port, 1);
+
+ return 0;
+}
+
+static int
+octeon_eth_configure_common(struct octeon_eth_softc *sc)
+{
+ static int once;
+
+ if (once == 1)
+ return 0;
+ once = 1;
+
+#if 0
+ octeon_eth_buf_init(sc);
+#endif
+
+ cn30xxipd_config(sc->sc_ipd);
+ cn30xxpko_config(sc->sc_pko);
+
+ cn30xxpow_config(sc->sc_pow, OCTEON_POW_GROUP_PIP);
+
+ return 0;
+}
+
+static int
+octeon_eth_recv_mbuf(struct octeon_eth_softc *sc, uint64_t *work,
+ struct mbuf **rm)
+{
+ struct mbuf *m;
+ void (*ext_free)(caddr_t, u_int, void *);
+ void *ext_buf;
+ size_t ext_size;
+ void *data;
+ uint64_t word1 = work[1];
+ uint64_t word2 = work[2];
+ uint64_t word3 = work[3];
+
+ MGETHDR(m, M_NOWAIT, MT_DATA);
+ if (m == NULL)
+ return 1;
+ OCTEON_ETH_KASSERT(m != NULL);
+
+ if ((word2 & PIP_WQE_WORD2_IP_BUFS) == 0) {
+ /* Dynamic short */
+ ext_free = octeon_eth_buf_ext_free_m;
+ ext_buf = &work[4];
+ ext_size = 96;
+
+ data = &work[4 + sc->sc_ip_offset / sizeof(uint64_t)];
+ } else {
+ vaddr_t addr;
+ vaddr_t start_buffer;
+
+ addr = PHYS_TO_CKSEG0(word3 & PIP_WQE_WORD3_ADDR);
+ start_buffer = addr & ~(2048 - 1);
+
+ ext_free = octeon_eth_buf_ext_free_ext;
+ ext_buf = (void *)start_buffer;
+ ext_size = 2048;
+
+ data = (void *)addr;
+ }
+
+ /* embed sc pointer into work[0] for _ext_free evcnt */
+ work[0] = (uintptr_t)sc;
+
+ MEXTADD(m, ext_buf, ext_size, 0, ext_free, work);
+ OCTEON_ETH_KASSERT(ISSET(m->m_flags, M_EXT));
+
+ m->m_data = data;
+ m->m_len = m->m_pkthdr.len = (word1 & PIP_WQE_WORD1_LEN) >> 48;
+ m->m_pkthdr.rcvif = &sc->sc_arpcom.ac_if;
+#if 0
+ /*
+ * not readonly buffer
+ */
+ m->m_flags |= M_EXT_RW;
+#endif
+
+ *rm = m;
+
+ OCTEON_ETH_KASSERT(*rm != NULL);
+
+ return 0;
+}
+
+static int
+octeon_eth_recv_check_code(struct octeon_eth_softc *sc, uint64_t word2)
+{
+ uint64_t opecode = word2 & PIP_WQE_WORD2_NOIP_OPECODE;
+
+ if (__predict_true(!ISSET(word2, PIP_WQE_WORD2_NOIP_RE)))
+ return 0;
+
+ /* this error is harmless */
+ if (opecode == PIP_OVER_ERR)
+ return 0;
+
+ return 1;
+}
+
+#if 0 /* not used */
+static int
+octeon_eth_recv_check_jumbo(struct octeon_eth_softc *sc, uint64_t word2)
+{
+ if (__predict_false((word2 & PIP_WQE_WORD2_IP_BUFS) > (1ULL << 56)))
+ return 1;
+ return 0;
+}
+#endif
+
+static int
+octeon_eth_recv_check_link(struct octeon_eth_softc *sc, uint64_t word2)
+{
+ if (__predict_false(!cn30xxgmx_link_status(sc->sc_gmx_port)))
+ return 1;
+ return 0;
+}
+
+static int
+octeon_eth_recv_check(struct octeon_eth_softc *sc, uint64_t word2)
+{
+ if (__predict_false(octeon_eth_recv_check_link(sc, word2)) != 0) {
+ if (ratecheck(&sc->sc_rate_recv_check_link_last,
+ &sc->sc_rate_recv_check_link_cap))
+ log(LOG_DEBUG,
+ "%s: link is not up, the packet was dropped\n",
+ sc->sc_dev.dv_xname);
+ OCTEON_EVCNT_INC(sc, rxerrlink);
+ return 1;
+ }
+
+#if 0 /* XXX Performance tunig (Jumbo-frame is not supported yet!) */
+ if (__predict_false(octeon_eth_recv_check_jumbo(sc, word2)) != 0) {
+ /* XXX jumbo frame */
+ if (ratecheck(&sc->sc_rate_recv_check_jumbo_last,
+ &sc->sc_rate_recv_check_jumbo_cap))
+ log(LOG_DEBUG,
+ "jumbo frame was received\n");
+ OCTEON_EVCNT_INC(sc, rxerrjmb);
+ return 1;
+ }
+#endif
+
+ if (__predict_false(octeon_eth_recv_check_code(sc, word2)) != 0) {
+ if ((word2 & PIP_WQE_WORD2_NOIP_OPECODE) == PIP_WQE_WORD2_RE_OPCODE_LENGTH) {
+ /* no logging */
+ /* XXX inclement special error count */
+ } else if ((word2 & PIP_WQE_WORD2_NOIP_OPECODE) ==
+ PIP_WQE_WORD2_RE_OPCODE_PARTIAL) {
+ /* not an erorr. it's because of overload */
+ }
+ else {
+ if (ratecheck(&sc->sc_rate_recv_check_code_last,
+ &sc->sc_rate_recv_check_code_cap))
+ log(LOG_WARNING,
+ "%s: the reception error had occured, "
+ "the packet was dropped (error code = %lld)\n",
+ sc->sc_dev.dv_xname, word2 & PIP_WQE_WORD2_NOIP_OPECODE);
+ }
+ OCTEON_EVCNT_INC(sc, rxerrcode);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int
+octeon_eth_recv(struct octeon_eth_softc *sc, uint64_t *work)
+{
+ int result = 0;
+ struct ifnet *ifp;
+ struct mbuf *m;
+ uint64_t word2;
+
+ /* XXX */
+ /*
+ * performance tuning
+ * presend iobdma request
+ */
+ if (sc->sc_soft_req_cnt > sc->sc_soft_req_thresh) {
+ octeon_eth_send_queue_flush_prefetch(sc);
+ }
+ /* XXX */
+
+ OCTEON_ETH_KASSERT(sc != NULL);
+ OCTEON_ETH_KASSERT(work != NULL);
+
+ OCTEON_EVCNT_INC(sc, rx);
+
+ word2 = work[2];
+ ifp = &sc->sc_arpcom.ac_if;
+
+ OCTEON_ETH_KASSERT(ifp != NULL);
+
+ if (__predict_false(octeon_eth_recv_check(sc, word2) != 0)) {
+ ifp->if_ierrors++;
+ result = 1;
+ octeon_eth_buf_free_work(sc, work, word2);
+ goto drop;
+ }
+
+ if (__predict_false(octeon_eth_recv_mbuf(sc, work, &m) != 0)) {
+ ifp->if_ierrors++;
+ result = 1;
+ octeon_eth_buf_free_work(sc, work, word2);
+ goto drop;
+ }
+
+ /* work[0] .. work[3] may not be valid any more */
+
+ OCTEON_ETH_KASSERT(m != NULL);
+
+ cn30xxipd_offload(word2, m->m_data, &m->m_pkthdr.csum_flags);
+
+ /* XXX */
+ if (sc->sc_soft_req_cnt > sc->sc_soft_req_thresh) {
+ octeon_eth_send_queue_flush_fetch(sc);
+ octeon_eth_send_queue_flush(sc);
+ }
+ /* XXX */
+
+ OCTEON_ETH_TAP(ifp, m, BPF_DIRECTION_IN);
+
+ /* XXX */
+ if (sc->sc_flush)
+ octeon_eth_send_queue_flush_sync(sc);
+ /* XXX */
+
+ ether_input_mbuf(ifp, m);
+
+ return 0;
+
+drop:
+ /* XXX */
+ if (sc->sc_soft_req_cnt > sc->sc_soft_req_thresh) {
+ octeon_eth_send_queue_flush_fetch(sc);
+ }
+ /* XXX */
+
+ return result;
+}
+
+static void
+octeon_eth_recv_intr(void *data, uint64_t *work)
+{
+ struct octeon_eth_softc *sc;
+ int port;
+
+ OCTEON_ETH_KASSERT(work != NULL);
+
+ port = (work[1] & PIP_WQE_WORD1_IPRT) >> 42;
+
+ OCTEON_ETH_KASSERT(port < GMX_PORT_NUNITS);
+
+ sc = octeon_eth_gsc[port];
+
+ OCTEON_ETH_KASSERT(sc != NULL);
+ OCTEON_ETH_KASSERT(port == sc->sc_port);
+
+ /* XXX process all work queue entries anyway */
+
+ (void)octeon_eth_recv(sc, work);
+}
+
+/* ---- tick */
+
+/*
+ * octeon_eth_tick_free
+ *
+ * => garbage collect send gather buffer / mbuf
+ * => called at softclock
+ */
+static void
+octeon_eth_tick_free(void *arg)
+{
+ struct octeon_eth_softc *sc = arg;
+ int timo;
+ int s;
+
+ s = splnet();
+ /* XXX */
+ if (sc->sc_soft_req_cnt > 0) {
+ octeon_eth_send_queue_flush_prefetch(sc);
+ octeon_eth_send_queue_flush_fetch(sc);
+ octeon_eth_send_queue_flush(sc);
+ octeon_eth_send_queue_flush_sync(sc);
+ }
+ /* XXX */
+
+ /* XXX ??? */
+ timo = hz - (100 * sc->sc_ext_callback_cnt);
+ if (timo < 10)
+ timo = 10;
+ timeout_add_msec(&sc->sc_tick_free_ch, 1000 * timo / hz);
+ /* XXX */
+ splx(s);
+}
+
+/*
+ * octeon_eth_tick_misc
+ *
+ * => collect statistics
+ * => check link status
+ * => called at softclock
+ */
+static void
+octeon_eth_tick_misc(void *arg)
+{
+ struct octeon_eth_softc *sc = arg;
+ struct ifnet *ifp;
+ u_quad_t iqdrops, delta;
+ int s;
+
+ s = splnet();
+
+ ifp = &sc->sc_arpcom.ac_if;
+
+ iqdrops = ifp->if_iqdrops;
+ cn30xxgmx_stats(sc->sc_gmx_port);
+#ifdef OCTEON_ETH_DEBUG
+ delta = ifp->if_iqdrops - iqdrops;
+ printf("%s: %qu packets dropped at GMX FIFO\n",
+ ifp->if_xname, delta);
+#endif
+ cn30xxpip_stats(sc->sc_pip, ifp, sc->sc_port);
+ delta = ifp->if_iqdrops - iqdrops;
+#ifdef OCTEON_ETH_DEBUG
+ printf("%s: %qu packets dropped at PIP + GMX FIFO\n",
+ ifp->if_xname, delta);
+#endif
+
+ mii_tick(&sc->sc_mii);
+
+#ifdef OCTEON_ETH_FIXUP_ODD_NIBBLE_DYNAMIC
+ if (sc->sc_gmx_port->sc_proc_nibble_by_soft &&
+ sc->sc_gmx_port->sc_even_nibble_cnt > PROC_NIBBLE_SOFT_THRESHOLD) {
+#ifdef OCTEON_ETH_DEBUG
+ log(LOG_DEBUG, "%s: even nibble preamble count %d\n",
+ sc->sc_dev.dv_xname, sc->sc_gmx_port->sc_even_nibble_cnt);
+#endif
+ if (OCTEON_ETH_FIXUP_ODD_NIBBLE_MODEL_P(sc) &&
+ OCTEON_ETH_FIXUP_ODD_NIBBLE_DYNAMIC_SPEED_P(sc->sc_gmx_port, ifp)) {
+ log(LOG_NOTICE,
+ "%s: the preamble processing is switched to hardware\n",
+ sc->sc_dev.dv_xname);
+ }
+ sc->sc_gmx_port->sc_proc_nibble_by_soft = 0;
+ octeon_eth_mii_statchg((struct device *)sc);
+ sc->sc_gmx_port->sc_even_nibble_cnt = 0;
+ }
+#endif
+ splx(s);
+
+ timeout_add_sec(&sc->sc_tick_misc_ch, 1);
+}
diff --git a/sys/arch/octeon/dev/if_cnmacvar.h b/sys/arch/octeon/dev/if_cnmacvar.h
new file mode 100644
index 00000000000..d172cf41351
--- /dev/null
+++ b/sys/arch/octeon/dev/if_cnmacvar.h
@@ -0,0 +1,135 @@
+/* $OpenBSD: if_cnmacvar.h,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+#undef DEBUG
+#undef TENBASET_DBG
+#undef REGISTER_DUMP
+#ifdef DEBUG
+#define dprintf printf
+#else
+#define dprintf(...)
+#endif
+
+#define IS_MAC_MULTICASTBIT(addr) \
+ ((addr)[0] & 0x01)
+
+#define SEND_QUEUE_SIZE (32)
+#define GATHER_QUEUE_SIZE (1024)
+#define FREE_QUEUE_SIZE GATHER_QUEUE_SIZE
+#define RECV_QUEUE_SIZE (GATHER_QUEUE_SIZE * 2)
+
+#ifdef OCTEON_ETH_FIXUP_ODD_NIBBLE_DYNAMIC
+#define PROC_NIBBLE_SOFT_THRESHOLD 2000
+#endif
+
+struct _send_queue_entry;
+struct cn30xxpow_softc;
+struct cn30xxpip_softc;
+struct cn30xxipd_softc;
+struct cn30xxpko_softc;
+struct cn30xxasx_softc;
+struct cn30xxsmi_softc;
+struct cn30xxgmx_port_softc;
+struct cn30xxpow_softc;
+
+extern struct cn30xxpow_softc cn30xxpow_softc;
+
+struct octeon_eth_softc {
+ struct device sc_dev;
+ bus_space_tag_t sc_regt;
+ bus_dma_tag_t sc_dmat;
+
+ bus_dmamap_t sc_dmap;
+
+ void *sc_pow_recv_ih;
+ struct cn30xxpip_softc *sc_pip;
+ struct cn30xxipd_softc *sc_ipd;
+ struct cn30xxpko_softc *sc_pko;
+ struct cn30xxasx_softc *sc_asx;
+ struct cn30xxsmi_softc *sc_smi;
+ struct cn30xxgmx_softc *sc_gmx;
+ struct cn30xxgmx_port_softc
+ *sc_gmx_port;
+ struct cn30xxpow_softc
+ *sc_pow;
+
+ struct arpcom sc_arpcom;
+ struct mii_data sc_mii;
+
+ void *sc_sdhook;
+
+ struct timeout sc_tick_misc_ch;
+ struct timeout sc_tick_free_ch;
+ struct timeout sc_resume_ch;
+
+ int64_t sc_soft_req_cnt;
+ int64_t sc_soft_req_thresh;
+ int64_t sc_hard_done_cnt;
+ int sc_flush;
+ int sc_prefetch;
+ SIMPLEQ_HEAD(, _send_queue_entry)
+ sc_sendq;
+ uint64_t sc_ext_callback_cnt;
+
+ uint32_t sc_port;
+ uint32_t sc_port_type;
+ uint32_t sc_init_flag;
+
+ /*
+ * Redirection - received (input) packets are redirected (directly sent)
+ * to another port. Only meant to test hardware + driver performance.
+ *
+ * 0 - disabled
+ * >0 - redirected to ports that correspond to bits
+ * 0b001 (0x1) - Port 0
+ * 0b010 (0x2) - Port 1
+ * 0b100 (0x4) - Port 2
+ */
+ int sc_redir;
+
+ struct cn30xxfau_desc sc_fau_done;
+ struct cn30xxpko_cmdptr_desc
+ sc_cmdptr;
+
+ size_t sc_ip_offset;
+
+ struct timeval sc_rate_recv_check_link_last;
+ struct timeval sc_rate_recv_check_link_cap;
+ struct timeval sc_rate_recv_check_jumbo_last;
+ struct timeval sc_rate_recv_check_jumbo_cap;
+ struct timeval sc_rate_recv_check_code_last;
+ struct timeval sc_rate_recv_check_code_cap;
+
+#ifdef OCTEON_ETH_DEBUG
+ struct evcnt sc_ev_rx;
+ struct evcnt sc_ev_rxint;
+ struct evcnt sc_ev_rxrs;
+ struct evcnt sc_ev_rxbufpkalloc;
+ struct evcnt sc_ev_rxbufpkput;
+ struct evcnt sc_ev_rxbufwqalloc;
+ struct evcnt sc_ev_rxbufwqput;
+ struct evcnt sc_ev_rxerrcode;
+ struct evcnt sc_ev_rxerrfix;
+ struct evcnt sc_ev_rxerrjmb;
+ struct evcnt sc_ev_rxerrlink;
+ struct evcnt sc_ev_rxerroff;
+ struct evcnt sc_ev_rxonperrshort;
+ struct evcnt sc_ev_rxonperrpreamble;
+ struct evcnt sc_ev_rxonperrcrc;
+ struct evcnt sc_ev_rxonperraddress;
+ struct evcnt sc_ev_rxonponp;
+ struct evcnt sc_ev_rxonpok;
+ struct evcnt sc_ev_tx;
+ struct evcnt sc_ev_txadd;
+ struct evcnt sc_ev_txbufcballoc;
+ struct evcnt sc_ev_txbufcbget;
+ struct evcnt sc_ev_txbufgballoc;
+ struct evcnt sc_ev_txbufgbget;
+ struct evcnt sc_ev_txbufgbput;
+ struct evcnt sc_ev_txdel;
+ struct evcnt sc_ev_txerr;
+ struct evcnt sc_ev_txerrcmd;
+ struct evcnt sc_ev_txerrgbuf;
+ struct evcnt sc_ev_txerrlink;
+ struct evcnt sc_ev_txerrmkcmd;
+#endif
+};
diff --git a/sys/arch/octeon/dev/octeon_iobus.c b/sys/arch/octeon/dev/octeon_iobus.c
index f139f3349ff..d164ada4f2b 100644
--- a/sys/arch/octeon/dev/octeon_iobus.c
+++ b/sys/arch/octeon/dev/octeon_iobus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: octeon_iobus.c,v 1.1 2011/05/08 13:24:55 syuu Exp $ */
+/* $OpenBSD: octeon_iobus.c,v 1.2 2011/06/16 11:22:30 syuu Exp $ */
/*
* Copyright (c) 2000-2004 Opsycon AB (www.opsycon.se)
@@ -44,9 +44,11 @@
#include <machine/autoconf.h>
#include <machine/atomic.h>
#include <machine/intr.h>
+#include <machine/octeonvar.h>
#include <octeon/dev/octeonreg.h>
#include <octeon/dev/iobusvar.h>
+#include <octeon/dev/cn30xxgmxreg.h>
int iobusmatch(struct device *, void *, void *);
void iobusattach(struct device *, struct device *, void *);
@@ -152,12 +154,14 @@ struct machine_bus_dma_tag iobus_bus_dma_tag = {
#define IOBUSDEV(name, unitno, unit) \
{ name, unitno, unit, &iobus_tag, &iobus_bus_dma_tag }
const struct iobus_unit iobus_units[] = {
- { OCTEON_CF_BASE, 0 }, /* octcf */
- { 0, 0 }, /* pcibus */
+ { OCTEON_CF_BASE, 0 }, /* octcf */
+ { 0, 0 }, /* pcibus */
+ { GMX0_BASE_PORT0, CIU_INT_GMX_DRP0 } /* cn30xxgmx */
};
struct iobus_attach_args iobus_children[] = {
IOBUSDEV("octcf", 0, &iobus_units[0]),
IOBUSDEV("pcibus", 0, &iobus_units[1]),
+ IOBUSDEV("cn30xxgmx", 0, &iobus_units[2])
};
#undef IOBUSDEV
@@ -204,6 +208,7 @@ iobussubmatch(struct device *parent, void *vcf, void *args)
void
iobusattach(struct device *parent, struct device *self, void *aux)
{
+ struct octeon_config oc;
uint i;
/*
@@ -219,6 +224,14 @@ iobusattach(struct device *parent, struct device *self, void *aux)
octeon_intr_init();
+ /* XXX */
+ oc.mc_iobus_bust = &iobus_tag;
+ oc.mc_iobus_dmat = &iobus_bus_dma_tag;
+ void cn30xxfpa_bootstrap(struct octeon_config *);
+ cn30xxfpa_bootstrap(&oc);
+ void cn30xxpow_bootstrap(struct octeon_config *);
+ cn30xxpow_bootstrap(&oc);
+
/*
* Attach subdevices.
*/
diff --git a/sys/arch/octeon/include/octeon_model.h b/sys/arch/octeon/include/octeon_model.h
new file mode 100644
index 00000000000..c5af75b1c8e
--- /dev/null
+++ b/sys/arch/octeon/include/octeon_model.h
@@ -0,0 +1,77 @@
+/* $Id: octeon_model.h,v 1.1 2011/06/16 11:22:30 syuu Exp $ */
+
+/*
+ * Copyright (c) 2007
+ * Internet Initiative Japan, Inc. 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _MIPS_OCTEON_MODEL_H_
+#define _MIPS_OCTEON_MODEL_H_
+
+#define OCTEON_MODEL_CN38XX_REV1 0x000d0000
+#define OCTEON_MODEL_CN38XX_REV2 0x000d0001
+#define OCTEON_MODEL_CN38XX_REV3 0x000d0003
+#define OCTEON_MODEL_CN3100 0x000d0100
+#define OCTEON_MODEL_CN3020 0x000d0110
+#define OCTEON_MODEL_CN3010 0x000d0200
+#define OCTEON_MODEL_CN3005 0x000d0210
+#define OCTEON_MODEL_CN5010 0x000d0600
+#define OCTEON_MODEL_CN5010_PASS1_1 0x000d0601
+
+#define OCTEON_MODEL_MASK 0x00ffff10
+#define OCTEON_MODEL_REV_MASK 0x00ffff1f
+#define OCTEON_MODEL_FAMILY_MASK 0x00ffff00
+#define OCTEON_MODEL_FAMILY_REV_MASK 0x00ffff0f
+
+#define OCTEON_MODEL_FAMILY_CN58XX 0x000d0300
+#define OCTEON_MODEL_FAMILY_CN56XX 0x000d0400
+#define OCTEON_MODEL_FAMILY_CN38XX 0x000d0000
+#define OCTEON_MODEL_FAMILY_CN31XX 0x000d0100
+#define OCTEON_MODEL_FAMILY_CN30XX 0x000d0200
+#define OCTEON_MODEL_FAMILY_CN50XX 0x000d0600
+
+/*
+ * get chip id
+ */
+static inline uint32_t octeon_get_chipid(void)
+{
+ uint32_t tmp;
+
+ asm volatile (
+ " .set push \n"
+ " .set mips64 \n"
+ " .set noreorder \n"
+ " mfc0 %0, $15, 0 \n"
+ " .set pop \n"
+ : "=&r"(tmp) : );
+
+ return(tmp);
+}
+
+#define octeon_model(id) ((id) & OCTEON_MODEL_MASK)
+#define octeon_model_revision(id) ((id) & OCTEON_MODEL_REV_MASK)
+#define octeon_model_family(id) ((id) & OCTEON_MODEL_FAMILY_MASK)
+#define octeon_model_family_revision(id) ((id) & OCTEON_MODEL_FAMILY_REV_MASK)
+
+#endif
diff --git a/sys/arch/octeon/include/octeonvar.h b/sys/arch/octeon/include/octeonvar.h
new file mode 100644
index 00000000000..b4cff927f81
--- /dev/null
+++ b/sys/arch/octeon/include/octeonvar.h
@@ -0,0 +1,411 @@
+/* $NetBSD: maltavar.h,v 1.3 2002/03/18 10:10:16 simonb Exp $ */
+
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MIPS_OCTEON_OCTEONVAR_H_
+#define _MIPS_OCTEON_OCTEONVAR_H_
+
+#include <machine/bus.h>
+
+/* XXX elsewhere */
+#define _ASM_PROLOGUE \
+ " .set push \n" \
+ " .set noreorder \n"
+#define _ASM_PROLOGUE_MIPS64 \
+ _ASM_PROLOGUE \
+ " .set mips64 \n"
+#define _ASM_PROLOGUE_OCTEON \
+ _ASM_PROLOGUE \
+ " .set arch=octeon \n"
+#define _ASM_EPILOGUE \
+ " .set pop \n"
+/*
+ * subbits = __BITS64_GET(XXX, bits);
+ * bits = __BITS64_SET(XXX, subbits);
+ */
+#ifndef __BITS64_GET
+#define __BITS64_GET(name, bits) \
+ (((uint64_t)(bits) & name) >> name##_SHIFT)
+#endif
+#ifndef __BITS64_SET
+#define __BITS64_SET(name, subbits) \
+ (((uint64_t)(subbits) << name##_SHIFT) & name)
+#endif
+
+struct octeon_config {
+ bus_space_tag_t mc_iobus_bust;
+ bus_space_tag_t mc_bootbus_bust;
+
+ bus_dma_tag_t mc_iobus_dmat;
+ bus_dma_tag_t mc_bootbus_dmat;
+/*
+ struct mips_bus_dma_tag mc_core1_dmat;
+
+ struct extent *mc_io_ex;
+ struct extent *mc_mem_ex;
+
+ int mc_mallocsafe;
+*/
+};
+
+/*
+ * FPA map
+ */
+
+#define OCTEON_POOL_NO_PKT 0
+#define OCTEON_POOL_NO_WQE 1
+#define OCTEON_POOL_NO_CMD 2
+#define OCTEON_POOL_NO_SG 3
+#define OCTEON_POOL_NO_XXX_4 4
+#define OCTEON_POOL_NO_XXX_5 5
+#define OCTEON_POOL_NO_XXX_6 6
+#define OCTEON_POOL_NO_DUMP 7 /* FPA debug dump */
+
+#define OCTEON_POOL_SIZE_PKT 2048 /* 128 x 16 */
+#define OCTEON_POOL_SIZE_WQE 128 /* 128 x 1 */
+#define OCTEON_POOL_SIZE_CMD 1024 /* 128 x 8 */
+#define OCTEON_POOL_SIZE_SG 512 /* 128 x 4 */
+#define OCTEON_POOL_SIZE_XXX_4 0
+#define OCTEON_POOL_SIZE_XXX_5 0
+#define OCTEON_POOL_SIZE_XXX_6 0
+#define OCTEON_POOL_SIZE_XXX_7 0
+
+#define OCTEON_POOL_NELEMS_PKT 4096
+#define OCTEON_POOL_NELEMS_WQE 4096
+#define OCTEON_POOL_NELEMS_CMD 32
+#define OCTEON_POOL_NELEMS_SG 1024
+#define OCTEON_POOL_NELEMS_XXX_4 0
+#define OCTEON_POOL_NELEMS_XXX_5 0
+#define OCTEON_POOL_NELEMS_XXX_6 0
+#define OCTEON_POOL_NELEMS_XXX_7 0
+
+/*
+ * CVMSEG (``scratch'') memory map
+ */
+struct octeon_cvmseg_map {
+ /* 0-3 */
+ uint64_t csm_xxx_0;
+ uint64_t csm_xxx_1;
+ uint64_t csm_xxx_2;
+ uint64_t csm_pow_intr;
+
+ /* 4-19 */
+ struct octeon_cvmseg_ether_map {
+ uint64_t csm_ether_fau_req;
+ uint64_t csm_ether_fau_done;
+ uint64_t csm_ether_fau_cmdptr;
+ uint64_t csm_ether_xxx_3;
+ } csm_ether[4/* XXX */];
+
+ /* 20-32 */
+ uint64_t xxx_20_32[32 - 20];
+} __packed;
+#define OCTEON_CVMSEG_OFFSET(entry) \
+ offsetof(struct octeon_cvmseg_map, entry)
+#define OCTEON_CVMSEG_ETHER_OFFSET(n, entry) \
+ (offsetof(struct octeon_cvmseg_map, csm_ether) + \
+ sizeof(struct octeon_cvmseg_ether_map) * (n) + \
+ offsetof(struct octeon_cvmseg_ether_map, entry))
+
+/*
+ * FAU register map
+ *
+ * => FAU registers exist in FAU unit
+ * => devices (PKO) can access these registers
+ * => CPU can read those values after loading them into CVMSEG
+ */
+struct octeon_fau_map {
+ struct {
+ /* PKO command index */
+ uint64_t _fau_map_port_pkocmdidx;
+ /* send requested */
+ uint64_t _fau_map_port_txreq;
+ /* send completed */
+ uint64_t _fau_map_port_txdone;
+ /* XXX */
+ uint64_t _fau_map_port_pad;
+ } __packed _fau_map_port[3];
+};
+
+/*
+ * POW qos/group map
+ */
+
+#define OCTEON_POW_QOS_PIP 0
+#define OCTEON_POW_QOS_CORE1 1
+#define OCTEON_POW_QOS_XXX_2 2
+#define OCTEON_POW_QOS_XXX_3 3
+#define OCTEON_POW_QOS_XXX_4 4
+#define OCTEON_POW_QOS_XXX_5 5
+#define OCTEON_POW_QOS_XXX_6 6
+#define OCTEON_POW_QOS_XXX_7 7
+
+#define OCTEON_POW_GROUP_PIP 0
+#define OCTEON_POW_GROUP_XXX_1 1
+#define OCTEON_POW_GROUP_XXX_2 2
+#define OCTEON_POW_GROUP_XXX_3 3
+#define OCTEON_POW_GROUP_XXX_4 4
+#define OCTEON_POW_GROUP_XXX_5 5
+#define OCTEON_POW_GROUP_XXX_6 6
+#define OCTEON_POW_GROUP_CORE1_SEND 7
+#define OCTEON_POW_GROUP_CORE1_TASK_0 8
+#define OCTEON_POW_GROUP_CORE1_TASK_1 9
+#define OCTEON_POW_GROUP_CORE1_TASK_2 10
+#define OCTEON_POW_GROUP_CORE1_TASK_3 11
+#define OCTEON_POW_GROUP_CORE1_TASK_4 12
+#define OCTEON_POW_GROUP_CORE1_TASK_5 13
+#define OCTEON_POW_GROUP_CORE1_TASK_6 14
+#define OCTEON_POW_GROUP_CORE1_TASK_7 15
+
+#ifdef _KERNEL
+extern struct octeon_config octeon_configuration;
+
+void octeon_bus_io_init(bus_space_tag_t, void *);
+void octeon_bus_mem_init(bus_space_tag_t, void *);
+void octeon_cal_timer(int);
+void octeon_dma_init(struct octeon_config *);
+void octeon_intr_init(void);
+int octeon_get_ethaddr(int, u_int8_t *);
+#endif /* _KERNEL */
+
+static inline int
+ffs64(uint64_t val)
+{
+ int ret;
+
+ __asm __volatile ( \
+ _ASM_PROLOGUE_MIPS64
+ " dclz %0, %1 \n"
+ _ASM_EPILOGUE
+ : "=r"(ret) : "r"(val));
+ return 64 - ret;
+}
+
+/*
+ * Prefetch
+ *
+ * OCTEON_PREF normal (L1 and L2)
+ * OCTEON_PREF_L1 L1 only
+ * OCTEON_PREF_L2 L2 only
+ * OCTEON_PREF_DWB don't write back
+ * OCTEON_PREF_PFS prepare for store
+ */
+#define __OCTEON_PREF_N(n, base, offset) \
+ __asm __volatile ( \
+ " .set push \
+ " .set arch=octeon \n" \
+ " pref "#n", "#offset"(%[base]) \n" \
+ " .set pop \
+ : : [base] "d" (base) \
+ )
+#define __OCTEON_PREF_0(base, offset) __OCTEON_PREF_N(0, base, offset)
+#define __OCTEON_PREF_4(base, offset) __OCTEON_PREF_N(4, base, offset)
+#define __OCTEON_PREF_28(base, offset) __OCTEON_PREF_N(28, base, offset)
+#define __OCTEON_PREF_29(base, offset) __OCTEON_PREF_N(29, base, offset)
+#define __OCTEON_PREF_30(base, offset) __OCTEON_PREF_N(30, base, offset)
+#define OCTEON_PREF(base, offset) __OCTEON_PREF_0(base, offset)
+#define OCTEON_PREF_L1(base, offset) __OCTEON_PREF_4(base, offset)
+#define OCTEON_PREF_L2(base, offset) __OCTEON_PREF_28(base, offset)
+#define OCTEON_PREF_DWB(base, offset) __OCTEON_PREF_29(base, offset)
+#define OCTEON_PREF_PFS(base, offset) __OCTEON_PREF_30(base, offset)
+
+/*
+ * Sync
+ */
+#define OCTEON_SYNCCOMMON(name) \
+ __asm __volatile ( \
+ _ASM_PROLOGUE_OCTEON \
+ " "#name" \n" \
+ _ASM_EPILOGUE \
+ ::: "memory")
+#define OCTEON_SYNCIOBDMA __asm __volatile (".word 0x8f" : : :"memory")
+#define OCTEON_SYNCW __asm __volatile (".word 0x10f" : : )
+#define OCTEON_SYNC OCTEON_SYNCCOMMON(sync)
+#define OCTEON_SYNCWS __asm __volatile (".word 0x14f" : : )
+/* XXX backward compatibility */
+#if 1
+#define OCT_SYNCIOBDMA OCTEON_SYNCIOBDMA
+#define OCT_SYNCW OCTEON_SYNCW
+#define OCT_SYNC OCTEON_SYNC
+#define OCT_SYNCWS OCTEON_SYNCWS
+#endif
+
+static inline uint64_t
+octeon_xkphys_read_8(paddr_t address)
+{
+ volatile uint64_t *p =
+ (volatile uint64_t *)(PHYS_TO_XKPHYS(address, CCA_NC));
+ return (*p);
+}
+
+static inline void
+octeon_xkphys_write_8(paddr_t address, uint64_t value)
+{
+ *(volatile uint64_t *)(PHYS_TO_XKPHYS(address, CCA_NC)) = value;
+}
+
+/* XXX backward compatibility */
+#if 1
+#define octeon_read_csr(address) \
+ octeon_xkphys_read_8(address)
+#define octeon_write_csr(address, value) \
+ octeon_xkphys_write_8(address, value)
+#endif
+
+static inline void
+octeon_iobdma_write_8(uint64_t value)
+{
+ uint64_t addr = 0xffffffffffffa200ULL;
+
+ *(volatile uint64_t *)addr = value;
+}
+
+static inline uint64_t
+octeon_cvmseg_read_8(size_t offset)
+{
+ return octeon_xkphys_read_8(0xffffffffffff8000ULL + offset);
+}
+
+static inline void
+octeon_cvmseg_write_8(size_t offset, uint64_t value)
+{
+ octeon_xkphys_write_8(0xffffffffffff8000ULL + offset, value);
+}
+
+/* XXX */
+static inline uint32_t
+octeon_disable_interrupt(uint32_t *new)
+{
+ uint32_t s, tmp;
+
+ __asm __volatile (
+ _ASM_PROLOGUE
+ " mfc0 %[s], $12 \n"
+ " and %[tmp], %[s], ~1 \n"
+ " mtc0 %[tmp], $12 \n"
+ _ASM_EPILOGUE
+ : [s]"=&r"(s), [tmp]"=&r"(tmp));
+ if (new)
+ *new = tmp;
+ return s;
+}
+
+/* XXX */
+static inline void
+octeon_restore_status(uint32_t s)
+{
+ __asm __volatile (
+ _ASM_PROLOGUE
+ " mtc0 %[s], $12 \n"
+ _ASM_EPILOGUE
+ :: [s]"r"(s));
+}
+
+static inline uint64_t
+octeon_get_cycles(void)
+{
+#if defined(__mips_o32)
+ uint32_t s, lo, hi;
+
+ s = octeon_disable_interrupt((void *)0);
+ __asm __volatile (
+ _ASM_PROLOGUE_MIPS64
+ " dmfc0 %[lo], $9, 6 \n"
+ " add %[hi], %[lo], $0 \n"
+ " srl %[hi], 32 \n"
+ " sll %[lo], 32 \n"
+ " srl %[lo], 32 \n"
+ _ASM_EPILOGUE
+ : [lo]"=&r"(lo), [hi]"=&r"(hi));
+ octeon_restore_status(s);
+ return ((uint64_t)hi << 32) + (uint64_t)lo;
+#else
+ uint64_t tmp;
+
+ __asm __volatile (
+ _ASM_PROLOGUE_MIPS64
+ " dmfc0 %[tmp], $9, 6 \n"
+ _ASM_EPILOGUE
+ : [tmp]"=&r"(tmp));
+ return tmp;
+#endif
+}
+
+/* -------------------------------------------------------------------------- */
+
+/* ---- event counter */
+
+#if defined(OCTEON_ETH_DEBUG)
+#define OCTEON_EVCNT_INC(sc, name) \
+ do { (sc)->sc_ev_##name.ev_count++; } while (0)
+#define OCTEON_EVCNT_ADD(sc, name, n) \
+ do { (sc)->sc_ev_##name.ev_count += (n); } while (0)
+#define OCTEON_EVCNT_ATTACH_EVCNTS(sc, entries, devname) \
+do { \
+ int i; \
+ const struct octeon_evcnt_entry *ee; \
+ \
+ for (i = 0; i < (int)nitems(entries); i++) { \
+ ee = &(entries)[i]; \
+ evcnt_attach_dynamic( \
+ (struct evcnt *)((uintptr_t)(sc) + ee->ee_offset), \
+ ee->ee_type, ee->ee_parent, devname, \
+ ee->ee_name); \
+ } \
+} while (0)
+#else
+#define OCTEON_EVCNT_INC(sc, name)
+#define OCTEON_EVCNT_ADD(sc, name, n)
+#define OCTEON_EVCNT_ATTACH_EVCNTS(sc, entries, devname)
+#endif
+
+struct octeon_evcnt_entry {
+ size_t ee_offset;
+ int ee_type;
+ struct evcnt *ee_parent;
+ const char *ee_name;
+};
+
+#define OCTEON_EVCNT_ENTRY(_sc_type, _var, _ev_type, _parent, _name) \
+ { \
+ .ee_offset = offsetof(_sc_type, sc_ev_##_var), \
+ .ee_type = EVCNT_TYPE_##_ev_type, \
+ .ee_parent = _parent, \
+ .ee_name = _name \
+ }
+
+#endif /* _MIPS_OCTEON_OCTEONVAR_H_ */