Module Name:    src
Committed By:   matt
Date:           Thu Jan 19 17:35:58 UTC 2012

Added Files:
        src/sys/arch/mips/rmi [matt-nb5-mips64]: rmixl_poe_pci.c rmixl_poereg.h
            rmixl_sae_pci.c

Log Message:
PCI attachments (mostly stubs) for some XLP devices.
POE = Packet Ordering Engine
SAE = Security Acceleration Engine


To generate a diff of this commit:
cvs rdiff -u -r0 -r1.1.2.1 src/sys/arch/mips/rmi/rmixl_poe_pci.c \
    src/sys/arch/mips/rmi/rmixl_poereg.h \
    src/sys/arch/mips/rmi/rmixl_sae_pci.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Added files:

Index: src/sys/arch/mips/rmi/rmixl_poe_pci.c
diff -u /dev/null src/sys/arch/mips/rmi/rmixl_poe_pci.c:1.1.2.1
--- /dev/null	Thu Jan 19 17:35:58 2012
+++ src/sys/arch/mips/rmi/rmixl_poe_pci.c	Thu Jan 19 17:35:58 2012
@@ -0,0 +1,274 @@
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas of 3am Software Foundry.
+ *
+ * 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 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.
+ */
+
+#include <sys/cdefs.h>
+
+__KERNEL_RCSID(1, "$NetBSD: rmixl_poe_pci.c,v 1.1.2.1 2012/01/19 17:35:58 matt Exp $");
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/bus.h>
+#include <sys/percpu.h>
+#include <sys/kmem.h>
+
+#include "locators.h"
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcidevs.h>
+
+#include <mips/rmi/rmixlreg.h>
+#include <mips/rmi/rmixlvar.h>
+
+#include <mips/rmi/rmixl_poereg.h>
+#include <mips/rmi/rmixl_fmnvar.h>
+
+#include "locators.h"
+
+#ifdef DEBUG
+int xlpoe_debug = 0;
+#define	DPRINTF(x, ...)	do { if (xlpoe_debug) printf(x, ## __VA_ARGS__); } while (0)
+#else
+#define	DPRINTF(x)
+#endif
+
+struct xlpoe_softc;
+
+static int	xlpoe_pci_match(device_t, cfdata_t, void *);
+static void	xlpoe_pci_attach(device_t, device_t, void *);
+static int	xlpoe_intr(void *);
+static int	xlpoe_msg_intr(void *, rmixl_fmn_rxmsg_t *);
+
+static void	xlpoe_percpu_evcnt_attach(void *, void *, struct cpu_info *);
+static void	xlpoe_find_memory(struct xlpoe_softc *);
+
+struct xlpoe_class {
+	paddr_t pcl_spill_enq_base;
+	paddr_t pcl_spill_deq_base;
+	size_t pcl_spill_enq_maxline;
+	size_t pcl_spill_deq_maxline;
+
+	size_t pcl_max_msg;		// max # of POE buffers
+	size_t pcl_max_loc_buf_stg;	// max # of local POE buffers
+};
+
+struct xlpoe_softc {
+	device_t sc_dev;
+	pci_chipset_tag_t sc_pc;
+	pcitag_t sc_tag;
+	bus_space_tag_t sc_bst;
+	bus_space_handle_t sc_bsh;
+
+	size_t sc_nflows;
+	size_t sc_nonchip;
+	size_t sc_noffchip;
+
+	struct xlpoe_class sc_classes[RMIXLP_POE_NCLASS];
+	paddr_t sc_msg_storage_base;
+	paddr_t sc_msg_storage_limit;
+	paddr_t sc_fbp_base;
+	paddr_t sc_fbp_limit;
+
+	percpu_t *sc_percpu_ev;
+};
+
+CFATTACH_DECL_NEW(xlpoe_pci, sizeof(struct xlpoe_softc),
+    xlpoe_pci_match, xlpoe_pci_attach, NULL, NULL);
+
+static int
+xlpoe_pci_match(device_t parent, cfdata_t cf, void *aux)
+{
+	struct pci_attach_args * const pa = aux;
+
+	if (pa->pa_id == PCI_ID_CODE(PCI_VENDOR_NETLOGIC, PCI_PRODUCT_NETLOGIC_XLP_POE))
+		return 1;
+
+	/*
+	 * For some on the XLP3xxL, POE has a product_id of 0.
+	 */
+	if (pa->pa_tag == RMIXLP_POE_PCITAG)
+		return 1;
+
+        return 0;
+}
+
+static void
+xlpoe_pci_attach(device_t parent, device_t self, void *aux)
+{
+	struct pci_attach_args * const pa = aux;
+	struct xlpoe_softc * const sc = device_private(self);
+	bus_addr_t base;
+	bus_size_t size;
+	char buf[8];
+
+	sc->sc_dev = self;
+	sc->sc_pc = pa->pa_pc;
+	sc->sc_tag = pa->pa_tag;
+	sc->sc_nflows = pci_conf_read(sc->sc_pc, sc->sc_tag,
+	    PCI_RMIXLP_POE_FLOWS);
+	sc->sc_nonchip = pci_conf_read(sc->sc_pc, sc->sc_tag,
+	    PCI_RMIXLP_ONCHIP);
+	sc->sc_noffchip = pci_conf_read(sc->sc_pc, sc->sc_tag,
+	    PCI_RMIXLP_OFFCHIP);
+
+	/*
+	 * Why isn't this accessible via a BAR?
+	 */
+	if (pci_mapreg_map(pa, PCI_BAR0, PCI_MAPREG_TYPE_MEM, 0,
+		    &sc->sc_bst, &sc->sc_bsh, &base, &size) != 0) {
+		aprint_error(": can't map registers\n");
+		return;
+	}
+
+	aprint_naive(": XLP POE Controller\n");
+	aprint_normal(": XLP Packet Ordering Engine\n");
+
+	format_bytes(buf, sizeof(buf), sc->sc_nonchip);
+	aprint_normal_dev(sc->sc_dev, "%zu flows, messages: %s on-chip",
+	    sc->sc_nflows, buf);
+
+	format_bytes(buf, sizeof(buf), sc->sc_noffchip);
+	aprint_normal(", %s off-chip\n", buf);
+
+	aprint_normal_dev(sc->sc_dev, "BAR[0] (%zuKB @ %#"
+	    PRIxBUSADDR") mapped at %#"PRIxBSH"\n",
+	    (size_t)size >> 10, base, sc->sc_bsh);
+
+	/*
+	 * Now allocate and attach the per-cpu evcnt.
+	 * We can't allocate the evcnt structure(s) directly since
+	 * percpu will move the contents of percpu memory around and 
+	 * corrupt the pointers in the evcnts themselves.  Remember, any
+	 * problem can be solved with sufficient indirection.
+	 */
+	sc->sc_percpu_ev = percpu_alloc(sizeof(struct evcnt *));
+	percpu_foreach(sc->sc_percpu_ev, xlpoe_percpu_evcnt_attach, sc);
+
+	const pcireg_t statinfo = pci_conf_read(sc->sc_pc, sc->sc_tag,
+	    PCI_RMIXLP_STATID);
+
+	const size_t stid_start = PCI_RMIXLP_STATID_BASE(statinfo);
+	const size_t stid_count = PCI_RMIXLP_STATID_COUNT(statinfo);
+	if (stid_count) {
+		aprint_normal_dev(sc->sc_dev, "%zu station%s starting at %zu\n",
+		    stid_count, (stid_count == 1 ? "" : "s"), stid_start);
+	}
+
+	pci_intr_handle_t pcih;
+	pci_intr_map(pa, &pcih);
+
+	if (pci_intr_establish(pa->pa_pc, pcih, IPL_VM, xlpoe_intr, sc) == NULL) {
+		aprint_error_dev(self, "failed to establish interrupt\n");
+	} else {
+		const char * const intrstr = pci_intr_string(pa->pa_pc, pcih);
+		aprint_normal_dev(self, "interrupting at %s\n", intrstr);
+	}
+
+	if (NULL == rmixl_fmn_intr_establish(RMIXLP_FMN_STID_POE,
+		    xlpoe_msg_intr, sc)) {
+		aprint_error_dev(self, "failed to establish FMN msg interrupt\n");
+	}
+
+	xlpoe_find_memory(sc);
+}
+
+static int
+xlpoe_intr(void *v)
+{
+	struct xlpoe_softc * const sc = v;
+
+	panic("%s(%p)", device_xname(sc->sc_dev), v);
+}
+
+static int
+xlpoe_msg_intr(void *v, rmixl_fmn_rxmsg_t *msg)
+{
+	struct xlpoe_softc * const sc = v;
+	struct evcnt **ev_p = percpu_getref(sc->sc_percpu_ev);
+
+	(*ev_p)->ev_count++;
+
+	percpu_putref(sc->sc_percpu_ev);
+	return 0;
+}
+
+static void
+xlpoe_percpu_evcnt_attach(void *v0, void *v1, struct cpu_info *ci)
+{
+	struct evcnt ** const ev_p = v0;
+	const char * const xname = device_xname(ci->ci_dev);
+
+	struct evcnt * const ev = kmem_zalloc(sizeof(*ev), KM_SLEEP);
+
+	*ev_p = ev;
+
+	evcnt_attach_dynamic(ev, EVCNT_TYPE_MISC, NULL, xname, "poe msg");
+}
+
+static paddr_t
+xlpoe_read_base(struct xlpoe_softc *sc, bus_size_t r_lo, bus_size_t r_hi)
+{
+	paddr_t lo = pci_conf_read(sc->sc_pc, sc->sc_tag, r_lo);
+	paddr_t hi = pci_conf_read(sc->sc_pc, sc->sc_tag, r_hi);
+
+	return lo + (hi << 32);
+}
+
+static void
+xlpoe_find_memory(struct xlpoe_softc *sc)
+{
+	sc->sc_msg_storage_base = xlpoe_read_base(sc,
+	    RMIXLP_POE_MSG_STORAGE_BASE_L, RMIXLP_POE_MSG_STORAGE_BASE_H);
+	sc->sc_msg_storage_limit = sc->sc_msg_storage_base + 28*1024;
+
+	sc->sc_fbp_base = xlpoe_read_base(sc,
+	    RMIXLP_POE_FBP_BASE_L, RMIXLP_POE_FBP_BASE_H);
+	sc->sc_fbp_limit = sc->sc_fbp_base + 56*1024;
+
+	for (size_t cl = 0; cl < RMIXLP_POE_NCLASS; cl++) {
+		struct xlpoe_class * const pcl = &sc->sc_classes[cl];
+		pcl->pcl_spill_enq_base =
+		    xlpoe_read_base(sc, RMIXLP_POE_CL_ENQ_SPILL_BASE_L(cl),
+			RMIXLP_POE_CL_ENQ_SPILL_BASE_H(cl));
+		pcl->pcl_spill_deq_base =
+		    xlpoe_read_base(sc, RMIXLP_POE_CL_DEQ_SPILL_BASE_L(cl),
+			RMIXLP_POE_CL_DEQ_SPILL_BASE_H(cl));
+		pcl->pcl_spill_enq_maxline = pcl->pcl_spill_enq_base 
+		    + pci_conf_read(sc->sc_pc, sc->sc_tag, 
+			RMIXLP_POE_CL_ENQ_SPILL_MAXLINE(cl));
+		pcl->pcl_spill_deq_maxline = pcl->pcl_spill_deq_base 
+		    + pci_conf_read(sc->sc_pc, sc->sc_tag, 
+			RMIXLP_POE_CL_DEQ_SPILL_MAXLINE(cl));
+
+		pcl->pcl_max_msg = pci_conf_read(sc->sc_pc, sc->sc_tag, 
+		    RMIXLP_POE_MAX_MSG_CL(cl));
+		pcl->pcl_max_loc_buf_stg = pci_conf_read(sc->sc_pc, sc->sc_tag, 
+		    RMIXLP_POE_MAX_LOC_BUF_STG_CL(cl));
+	}
+}
Index: src/sys/arch/mips/rmi/rmixl_poereg.h
diff -u /dev/null src/sys/arch/mips/rmi/rmixl_poereg.h:1.1.2.1
--- /dev/null	Thu Jan 19 17:35:58 2012
+++ src/sys/arch/mips/rmi/rmixl_poereg.h	Thu Jan 19 17:35:58 2012
@@ -0,0 +1,162 @@
+/*	$NetBSD: rmixl_poereg.h,v 1.1.2.1 2012/01/19 17:35:58 matt Exp $	*/
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas of 3am Software Foundry.
+ *
+ * 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 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_RMI_RMIXL_POEREG_H_
+#define _MIPS_RMI_RMIXL_POEREG_H_
+
+/* Class Enqueue/Dequeue and Message Base Address Registers */
+#define	RMIXLP_POE_NCLASS	8
+#define	RMIXLP_POE_CL_ENQ_SPILL_BASE_L(n)	_RMIXL_OFFSET(0x40+2*(n)) // Class n Enqueue Spill Base Address Low Register
+#define	RMIXLP_POE_CL_ENQ_SPILL_BASE_H(n)	_RMIXL_OFFSET(0x41+2*(n)) // Class n Enqueue Spill Base Address High Register
+
+#define	RMIXLP_POE_CL_DEQ_SPILL_BASE_L(n)		_RMIXL_OFFSET(0x50+2*(n)) // Class n Dequeue Spill Base Address Low Register
+#define	RMIXLP_POE_CL_DEQ_SPILL_BASE_H(n)	_RMIXL_OFFSET(0x51+2*(n)) // Class n Dequeue Spill Base Address High Register
+
+#define	RMIXLP_POE_MSG_STORAGE_BASE_L		_RMIXL_OFFSET(0x60) // Message Storage Base Address Low Register
+#define	RMIXLP_POE_MSG_STORAGE_BASE_H		_RMIXL_OFFSET(0x61) // Message Storage Base Address High Register
+
+#define	RMIXLP_POE_FBP_BASE_L			_RMIXL_OFFSET(0x62) // Free Buffer Pool Base Address Low Register
+#define	RMIXLP_POE_FBP_BASE_H			_RMIXL_OFFSET(0x63) // Free Buffer Pool Base Address High Register
+
+/* Class Enqueue/Dequeue Maximum Offset From Base Address Registers */
+#define	RMIXLP_POE_CL_ENQ_SPILL_MAXLINE(n)	_RMIXL_OFFSET(0x64+(n)) // Class n Enqueue Spill Maximum Offset From Base Address Register
+#define	RMIXLP_POE_CL_DEQ_SPILL_MAXLINE(n)	_RMIXL_OFFSET(0x6C+(n)) // Class n Dequeue Spill Maximum Offset From Base Address Register
+
+/* Maximum POE Buffers Registers */
+#define	RMIXLP_POE_NFLOW	8
+#define	RMIXLP_POE_MAX_FLOW_MSG_REG(n)		_RMIXL_OFFSET(0x80+(n)) // Maximum Per-Flow POE Buffer Register n
+
+#define	RMIXLP_POE_MAX_MSG_CL(n)		_RMIXL_OFFSET(0x88+(n)) // Maximum Class n POE Buffer Register
+
+#define	RMIXLP_POE_MAX_LOC_BUF_STG_CL(n)	_RMIXL_OFFSET(0x90+(n)) // Maximum Class n Local POE Buffer Register
+
+/* Enqueue Message Count Registers */
+#define	RMIXLP_POE_CL_SIZE(n)			_RMIXL_OFFSET(0x98+(n)) // Class n Enqueue Message Count Register
+
+/* Receive Message Error Registers */
+#define	RMIXLP_POE_ERR_MSG_REG(n)		_RMIXL_OFFSET(0xA0+(n)) // Receive Error Message_Register n
+
+/* Statistics Registers */
+#define	RMIXLP_POE_OOO_MSG_CNT_LO		_RMIXL_OFFSET(0xA8) // Out of Order Message Count Low Register
+#define	RMIXLP_POE_IN_ORDER_MSG_CNT_LO		_RMIXL_OFFSET(0xA9) // In Order Message Count Low Register
+#define	RMIXLP_POE_LOC_BUF_STOR_CNT_LO		_RMIXL_OFFSET(0xAA) // Local Buffer Storage Count Low Register
+#define	RMIXLP_POE_EXT_BUF_STOR_CNT_LO		_RMIXL_OFFSET(0xAB) // External Buffer Storage Count Low Register
+#define	RMIXLP_POE_LOC_BUF_ALLOC_CNT_LO		_RMIXL_OFFSET(0xAC) // Local Buffer Allocation Count Low Register
+#define	RMIXLP_POE_EXT_BUF_ALLOC_CNT_LO		_RMIXL_OFFSET(0xAD) // External Buffer Allocation Count Low Register
+#define	RMIXLP_POE_OOO_MSG_CNT_HI		_RMIXL_OFFSET(0xAE) // Out of Order Message Count High Register
+#define	RMIXLP_POE_IN_ORDER_MSG_CNT_HI		_RMIXL_OFFSET(0xAF) // In Order Message Count High Register
+#define	RMIXLP_POE_LOC_BUF_STOR_CNT_HI		_RMIXL_OFFSET(0xB0) // Local Buffer Storage Count High Register
+#define	RMIXLP_POE_EXT_BUF_STOR_CNT_HI		_RMIXL_OFFSET(0xB1) // External Buffer Storage Count High Register
+#define	RMIXLP_POE_LOC_BUF_ALLOC_CNT_HI		_RMIXL_OFFSET(0xB2) // Local Buffer Allocation Count High Register
+#define	RMIXLP_POE_EXT_BUF_ALLOC_CNT_HI		_RMIXL_OFFSET(0xB3) // External Buffer Allocation Count High Register
+#define	RMIXLP_POE_MODE_ERROR_FLOW_ID		_RMIXL_OFFSET(0xB4) // Mode Error Flow ID Register
+#define	RMIXLP_POE_STATISTICS_ENABLE		_RMIXL_OFFSET(0xB5) // Statistics Enable Register
+#define	RMIXLP_POE_MAX_SIZE_FLOW		_RMIXL_OFFSET(0xB6) // Maximum Size Flow Register
+#define	RMIXLP_POE_MAX_SIZE			_RMIXL_OFFSET(0xB7) // Maximum Size Register
+
+/* Free Buffer Pool Configuration Registers */
+#define	RMIXLP_POE_FBP_SP			_RMIXL_OFFSET(0xB8) // Free Buffer Pool Stack Pointer Register
+#define	RMIXLP_POE_FBP_SP_EN			_RMIXL_OFFSET(0xB9) // Free Buffer Pool Stack Pointer Enable Register
+#define	RMIXLP_POE_LOC_ALLOC_EN			_RMIXL_OFFSET(0xBA) // Local Message Allocation Enable Register
+#define	RMIXLP_POE_EXT_ALLOC_EN			_RMIXL_OFFSET(0xBB) // External Message Allocation Enable Register
+
+#define	RMIXLP_POE_NDISTR			16
+#define	RMIXLP_POE_DISTR_DROP_CNT(n)		_RMIXL_OFFSET(0x100+(n)) // Distribution n Vector Drop Count Register
+
+#define	RMIXLP_POE_CLASS_DROP_CNT(n)		_RMIXL_OFFSET(0x110+(n)) // Class n Drop Count Register
+
+#define	RMIXLP_POE_DISTR_C_DROP_CNT(n)		_RMIXL_OFFSET(0x118+(n)) // Distribution Class 0 Drop Count Register
+#define	RMIXLP_POE_CPU_DROP_CNT			_RMIXL_OFFSET(0x120) // CPU Drop Count Register
+#define	RMIXLP_POE_MAX_FLOW_DROP_CNT		_RMIXL_OFFSET(0x121) // Maximum Flow Drop Count Register
+
+/* Interrupt Registers */
+#define	RMIXLP_POE_INTERRUPT_VEC		_RMIXL_OFFSET(0x180) // Packet Ordering Engine Interrupt Vector Register
+#define	RMIXLP_POE_INTERRUPT_MASK		_RMIXL_OFFSET(0x181) // Packet Ordering Engine Interrupt Mask Register
+#define	RMIXLP_POE_FATAL_ERROR_MASK		_RMIXL_OFFSET(0x182) // Packet Ordering Engine Fatal Error Mask
+#define	RMIXLP_POE_IODATA_IC_CONFIG		_RMIXL_OFFSET(0x183) // Packet Ordering Engine I/O Data Interconnect Configuration
+#define	RMIXLP_POE_TIMEOUT_TIMER		_RMIXL_OFFSET(0x184) // Packet Ordering Engine Time-out Timer
+#define	RMIXLP_POE_CACHE_ALLOC_EN		_RMIXL_OFFSET(0x185) // Packet Ordering Engine Cache Allocation Enable Register
+
+/* ECC Error Count Registers */
+#define	RMIXLP_POE_FBP_ECC_ERR_CNT		_RMIXL_OFFSET(0x186) // Free Buffer Pool ECC Error Count
+#define	RMIXLP_POE_MSG_STOR_ECC_ERR_CNT		_RMIXL_OFFSET(0x187) // Message Storage Errors Register
+#define	RMIXLP_POE_FID_INFO_ECC_ERR_CNT		_RMIXL_OFFSET(0x188) // Flow Information Errors Register
+#define	RMIXLP_POE_MSG_INFO_ECC_ERR_CNT		_RMIXL_OFFSET(0x189) // Message Information Errors Register
+#define	RMIXLP_POE_LL_ECC_ERR_CNT		_RMIXL_OFFSET(0x18A) // Linked List Errors Register
+#define	RMIXLP_POE_SIZE_ECC_ERR_CNT		_RMIXL_OFFSET(0x18B) // Size Errors Register
+#define	RMIXLP_POE_FMN_TXCR_ECC_ERR_CNT		_RMIXL_OFFSET(0x18C) // Fast Message Network Transmit Errors Register
+#define	RMIXLP_POE_ENQ_INSPIL_ECC_ERR_CNT	_RMIXL_OFFSET(0x18D) // Enqueue Spill Input Errors Register
+#define	RMIXLP_POE_ENQ_OUTSPIL_ECC_ERR_CNT	_RMIXL_OFFSET(0x18E) // Enqueue Spill Output Errors Register
+#define	RMIXLP_POE_DEQ_OUTSPIL_ECC_ERR_CNT	_RMIXL_OFFSET(0x18F) // Dequeue Spill Output Errors Register
+#define	RMIXLP_POE_ENQD_MSG_SENT		_RMIXL_OFFSET(0x190) // Enqueue Message Sent Register
+#define	RMIXLP_POE_ENQD_MSG_CNT			_RMIXL_OFFSET(0x191) // Enqueue Message Count Register
+
+/* FID Info RAM Indirect Access Registers */
+#define	RMIXLP_POE_FID_RDATA			_RMIXL_OFFSET(0x192) // FID Flow Read Data Register
+#define	RMIXLP_POE_FID_WDATA			_RMIXL_OFFSET(0x193) // FID Flow Read Write Register
+#define	RMIXLP_POE_FID_CMD			_RMIXL_OFFSET(0x194) // FID Indirect Access Command Register
+#define	RMIXLP_POE_FID_ADR			_RMIXL_OFFSET(0x195) // FID Flow Info Address Register
+
+/* Message Information SRAM Indirect Access Registers */
+#define	RMIXLP_POE_MSG_INFO_CMD			_RMIXL_OFFSET(0x196) // Message Information Command Register
+#define	RMIXLP_POE_MSG_INFO_ADR			_RMIXL_OFFSET(0x197) // Message Information Read Address Register
+#define	RMIXLP_POE_MSG_INFO_RDATA		_RMIXL_OFFSET(0x198) // Message Information Read Data Register
+
+/* Linked List SRAM Indirect Access Registers */
+#define	RMIXLP_POE_LL_CMD			_RMIXL_OFFSET(0x199) // Linked List Command Register
+#define	RMIXLP_POE_LL_ADR			_RMIXL_OFFSET(0x19A) // Linked List Read Address Register
+#define	RMIXLP_POE_LL_RDATA			_RMIXL_OFFSET(0x19B) // Linked List Read Data Register
+
+/* Message Storage SRAM Indirect Access Registers */
+#define	RMIXLP_POE_MSG_STG_CMD			_RMIXL_OFFSET(0x19C) // Message Storage Command Register
+#define	RMIXLP_POE_MSG_STG_ADR			_RMIXL_OFFSET(0x19D) // Message Storage Read Address Register
+#define	RMIXLP_POE_MSG_STG_RDATA		_RMIXL_OFFSET(0x19E) // Message Storage Read Data Register
+
+/* Distribution Vector Masking Thresholds Registers */
+#define	RMIXLP_POE_NDISTR_THRESHOLD		4
+#define	RMIXLP_POE_DISTR_THRESHOLD(n)		_RMIXL_OFFSET(0x200+(n)) // Distribution Vector Threshold n Register
+#define	RMIXLP_POE_DEST_THRESHOLD		_RMIXL_OFFSET(0x204) // Destination Threshold Register
+#define	RMIXLP_POE_DISTR_LOGIC_EN		_RMIXL_OFFSET(0x205) // Distribution Logic Enable Register
+#define	RMIXLP_POE_ENQ_SPILL_THOLD		_RMIXL_OFFSET(0x208) // Distribution Vector Enqueue Spill Threshold Register
+#define	RMIXLP_POE_DEQ_SPILL_THOLD		_RMIXL_OFFSET(0x209) // Distribution Vector Dequeue Spill Threshold Register
+#define	RMIXLP_POE_DEQ_SPILL_TIMER		_RMIXL_OFFSET(0x20A) // Distribution Vector Dequeue Spill Timer Register
+#define	RMIXLP_POE_DISTR_CLASS_DROP_EN		_RMIXL_OFFSET(0x20B) // Distribution Vector Class Drop Enable Register
+#define	RMIXLP_POE_DISTR_VEC_DROP_EN		_RMIXL_OFFSET(0x20C) // Distribution Vector Drop Enable Register
+#define	RMIXLP_POE_DISTR_DROP_TIMER		_RMIXL_OFFSET(0x20D) // Distribution Vector Drop Timer Register
+
+/* Error Registers */
+#define	RMIXLP_POE_NERROR_LOG			3
+#define	RMIXLP_POE_ERROR_LOG(n)			_RMIXL_OFFSET(0x20E+(n)) // POE Error Log Word n
+#define	RMIXLP_POE_NERROR_INJ_CTL		2
+#define	RMIXLP_POE_ERROR_INJ_CTL_0		_RMIXL_OFFSET(0x211+(n)) // POE Error Injection Control Word 0
+#define	RMIXLP_POE_RESET			_RMIXL_OFFSET(0x213) // POE Reset Register
+#define	RMIXLP_POE_TRANSMIT_TIMER		_RMIXL_OFFSET(0x214) // POE Transmit Timer Register
+
+#endif /* _MIPS_RMI_RMIXL_POEREG_H_ */
Index: src/sys/arch/mips/rmi/rmixl_sae_pci.c
diff -u /dev/null src/sys/arch/mips/rmi/rmixl_sae_pci.c:1.1.2.1
--- /dev/null	Thu Jan 19 17:35:58 2012
+++ src/sys/arch/mips/rmi/rmixl_sae_pci.c	Thu Jan 19 17:35:58 2012
@@ -0,0 +1,133 @@
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas of 3am Software Foundry.
+ *
+ * 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 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.
+ */
+
+#include <sys/cdefs.h>
+
+__KERNEL_RCSID(1, "$NetBSD: rmixl_sae_pci.c,v 1.1.2.1 2012/01/19 17:35:58 matt Exp $");
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/bus.h>
+
+#include "locators.h"
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcidevs.h>
+
+#include <mips/rmi/rmixlreg.h>
+#include <mips/rmi/rmixlvar.h>
+
+#include "locators.h"
+
+#ifdef DEBUG
+int xlsae_debug = 0;
+#define	DPRINTF(x, ...)	do { if (xlsae_debug) printf(x, ## __VA_ARGS__); } while (0)
+#else
+#define	DPRINTF(x)
+#endif
+
+static	int xlsae_pci_match(device_t, cfdata_t, void *);
+static	void xlsae_pci_attach(device_t, device_t, void *);
+static	int xlsae_intr(void *);
+
+struct	xlsae_softc {
+	device_t sc_dev;
+	pci_chipset_tag_t sc_pc;
+	pcitag_t sc_tag;
+	bus_space_tag_t sc_bst;
+	bus_space_handle_t sc_bsh;
+};
+
+CFATTACH_DECL_NEW(xlsae_pci, sizeof(struct xlsae_softc),
+    xlsae_pci_match, xlsae_pci_attach, NULL, NULL);
+
+static int
+xlsae_pci_match(device_t parent, cfdata_t cf, void *aux)
+{
+	struct pci_attach_args * const pa = aux;
+
+	if (pa->pa_id == PCI_ID_CODE(PCI_VENDOR_NETLOGIC, PCI_PRODUCT_NETLOGIC_XLP_SAE))
+		return 1;
+
+        return 0;
+}
+
+static void
+xlsae_pci_attach(device_t parent, device_t self, void *aux)
+{
+	struct rmixl_config * const rcp = &rmixl_configuration;
+	struct pci_attach_args * const pa = aux;
+	struct xlsae_softc * const sc = device_private(self);
+
+	sc->sc_dev = self;
+	sc->sc_bst = &rcp->rc_pci_ecfg_eb_memt;
+	sc->sc_pc = pa->pa_pc;
+	sc->sc_tag = pa->pa_tag;
+
+	/*
+	 * Why isn't this accessible via a BAR?
+	 */
+	if (bus_space_subregion(sc->sc_bst, rcp->rc_pci_ecfg_eb_memh,
+		    pa->pa_tag, 0, &sc->sc_bsh)) {
+		aprint_error(": can't map registers\n");
+		return;
+	}
+
+	aprint_naive(": XLP SAE Controller\n");
+	aprint_normal(": XLP Security Acceration Engine\n");
+
+	const pcireg_t statinfo = pci_conf_read(sc->sc_pc, sc->sc_tag,
+	    PCI_RMIXLP_STATID);
+
+	const size_t stid_start = PCI_RMIXLP_STATID_BASE(statinfo);
+	const size_t stid_count = PCI_RMIXLP_STATID_COUNT(statinfo);
+	if (stid_count) {
+		aprint_normal_dev(sc->sc_dev, "%zu station%s starting at %zu\n",
+		    stid_count, (stid_count == 1 ? "" : "s"), stid_start);
+	}
+
+	pci_intr_handle_t pcih;
+	pci_intr_map(pa, &pcih);
+
+	if (pci_intr_establish(pa->pa_pc, pcih, IPL_VM, xlsae_intr, sc) == NULL) {
+		aprint_error_dev(self, "failed to establish interrupt\n");
+	} else {
+		const char * const intrstr = pci_intr_string(pa->pa_pc, pcih);
+		aprint_normal_dev(self, "interrupting at %s\n", intrstr);
+	}
+}
+
+static int
+xlsae_intr(void *v)
+{
+	struct xlsae_softc * const sc = v;
+
+	panic("%s(%p)", device_xname(sc->sc_dev), v);
+}

Reply via email to