diff options
author | Takuya ASADA <syuu@cvs.openbsd.org> | 2011-06-16 11:22:31 +0000 |
---|---|---|
committer | Takuya ASADA <syuu@cvs.openbsd.org> | 2011-06-16 11:22:31 +0000 |
commit | 1a37173011aa926dacdeed9b4905dcddd762260d (patch) | |
tree | 4f130233142d3061b6740b79287f9cabd0c9c584 /sys/arch | |
parent | 331a508ecdab0cd58a22c47b6fb2480222747255 (diff) |
Ethernet driver merged from IIJ's contribution code.
Diffstat (limited to 'sys/arch')
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 = ®s[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_ */ |