summaryrefslogtreecommitdiff
path: root/sys/arch/octeon
diff options
context:
space:
mode:
authorVisa Hankala <visa@cvs.openbsd.org>2016-06-22 13:09:36 +0000
committerVisa Hankala <visa@cvs.openbsd.org>2016-06-22 13:09:36 +0000
commit4eabd8f63f2d931a9c5d375c0e773cb72ce7a1f6 (patch)
tree6392428c1ce8f6bea2cc4c772576a577035e7990 /sys/arch/octeon
parentad1747a2d1db537a946a003b331e1280ac4ce939 (diff)
Add support for the second GMX interface on Octeon II. This enables
ports eth[0-3] on 8-port EdgeRouters. Currently, port eth0 maps to network interface cnmac4, eth1 to cnmac5 etc. ok dlg@, tested by martijn@
Diffstat (limited to 'sys/arch/octeon')
-rw-r--r--sys/arch/octeon/dev/cn30xxgmx.c33
-rw-r--r--sys/arch/octeon/dev/cn30xxgmxreg.h10
-rw-r--r--sys/arch/octeon/dev/cn30xxipd.c5
-rw-r--r--sys/arch/octeon/dev/if_cnmac.c6
-rw-r--r--sys/arch/octeon/dev/octeon_iobus.c31
-rw-r--r--sys/arch/octeon/include/octeonvar.h15
6 files changed, 59 insertions, 41 deletions
diff --git a/sys/arch/octeon/dev/cn30xxgmx.c b/sys/arch/octeon/dev/cn30xxgmx.c
index 48a9c688f47..cb8c66c67be 100644
--- a/sys/arch/octeon/dev/cn30xxgmx.c
+++ b/sys/arch/octeon/dev/cn30xxgmx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cn30xxgmx.c,v 1.24 2016/06/18 15:59:34 visa Exp $ */
+/* $OpenBSD: cn30xxgmx.c,v 1.25 2016/06/22 13:09:35 visa Exp $ */
/*
* Copyright (c) 2007 Internet Initiative Japan, Inc.
@@ -26,11 +26,6 @@
* SUCH DAMAGE.
*/
-/*
- * support GMX0 interface only
- * take no thought for other GMX interface
- */
-
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/types.h>
@@ -221,6 +216,7 @@ cn30xxgmx_attach(struct device *parent, struct device *self, void *aux)
printf("\n");
sc->sc_regt = aa->aa_bust; /* XXX why there are iot? */
+ sc->sc_unitno = aa->aa_unitno;
status = bus_space_map(sc->sc_regt, aa->aa_addr,
GMX0_BASE_IF_SIZE(sc->sc_nports), 0, &sc->sc_regh);
@@ -235,7 +231,7 @@ cn30xxgmx_attach(struct device *parent, struct device *self, void *aux)
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_no = GMX_PORT_NUM(sc->sc_unitno, 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,
@@ -271,19 +267,21 @@ cn30xxgmx_attach(struct device *parent, struct device *self, void *aux)
gmx_aa.ga_dmat = aa->aa_dmat;
gmx_aa.ga_addr = aa->aa_addr;
gmx_aa.ga_name = "cnmac";
- gmx_aa.ga_portno = i;
+ gmx_aa.ga_portno = port_sc->sc_port_no;
gmx_aa.ga_port_type = sc->sc_port_types[i];
gmx_aa.ga_gmx = sc;
gmx_aa.ga_gmx_port = port_sc;
- gmx_aa.ga_phy_addr = cn30xxgmx_port_phy_addr(i);
+ gmx_aa.ga_phy_addr = cn30xxgmx_port_phy_addr(
+ port_sc->sc_port_no);
if (gmx_aa.ga_phy_addr == -1)
- panic(": don't know phy address for port %d", i);
+ panic(": don't know phy address for port %d",
+ port_sc->sc_port_no);
config_found_sm(self, &gmx_aa,
cn30xxgmx_print, cn30xxgmx_submatch);
#ifdef OCTEON_ETH_DEBUG
- __cn30xxgmx_port_softc[i] = port_sc;
+ __cn30xxgmx_port_softc[port_sc->sc_port_no] = port_sc;
#endif
}
@@ -495,18 +493,19 @@ int
cn30xxgmx_tx_ovr_bp_enable(struct cn30xxgmx_port_softc *sc, int enable)
{
uint64_t ovr_bp;
+ int index = GMX_PORT_INDEX(sc->sc_port_no);
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);
+ CLR(ovr_bp, (1 << index) << TX_OVR_BP_EN_SHIFT);
+ SET(ovr_bp, (1 << index) << TX_OVR_BP_BP_SHIFT);
/* XXX really??? */
- SET(ovr_bp, (1 << sc->sc_port_no) << TX_OVR_BP_IGN_FULL_SHIFT);
+ SET(ovr_bp, (1 << index) << 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);
+ SET(ovr_bp, (1 << index) << TX_OVR_BP_EN_SHIFT);
+ CLR(ovr_bp, (1 << index) << TX_OVR_BP_BP_SHIFT);
/* XXX really??? */
- SET(ovr_bp, (1 << sc->sc_port_no) << TX_OVR_BP_IGN_FULL_SHIFT);
+ SET(ovr_bp, (1 << index) << TX_OVR_BP_IGN_FULL_SHIFT);
}
_GMX_WR8(sc, GMX0_TX_OVR_BP, ovr_bp);
return 0;
diff --git a/sys/arch/octeon/dev/cn30xxgmxreg.h b/sys/arch/octeon/dev/cn30xxgmxreg.h
index 7961cde436b..e1e650a6bd5 100644
--- a/sys/arch/octeon/dev/cn30xxgmxreg.h
+++ b/sys/arch/octeon/dev/cn30xxgmxreg.h
@@ -3,7 +3,7 @@
* DONT EDIT THIS FILE
*/
-/* $OpenBSD: cn30xxgmxreg.h,v 1.4 2016/06/18 15:43:08 visa Exp $ */
+/* $OpenBSD: cn30xxgmxreg.h,v 1.5 2016/06/22 13:09:35 visa Exp $ */
/*
* Copyright (c) 2007 Internet Initiative Japan, Inc.
@@ -636,8 +636,12 @@
/* for bus_space(9) */
-#define GMX_IF_NUNITS 1
-#define GMX_PORT_NUNITS 4
+#define GMX_PORT_NUNITS (3 * 16)
+#define GMX_PORT_NUM(g, i) ((g) * 16 + (i))
+#define GMX_PORT_IFACE(port) ((port) / 16)
+#define GMX_PORT_INDEX(port) ((port) % 16)
+
+#define GMX_BLOCK_SIZE 0x8000000
#define GMX0_BASE_PORT0 0x0001180008000000ULL
#define GMX0_BASE_PORT1 0x0001180008000800ULL
diff --git a/sys/arch/octeon/dev/cn30xxipd.c b/sys/arch/octeon/dev/cn30xxipd.c
index 39e9dc974a8..d28b264315a 100644
--- a/sys/arch/octeon/dev/cn30xxipd.c
+++ b/sys/arch/octeon/dev/cn30xxipd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cn30xxipd.c,v 1.8 2016/05/24 14:06:39 visa Exp $ */
+/* $OpenBSD: cn30xxipd.c,v 1.9 2016/06/22 13:09:35 visa Exp $ */
/*
* Copyright (c) 2007 Internet Initiative Japan, Inc.
@@ -35,6 +35,7 @@
#include <octeon/dev/cn30xxciureg.h>
#include <octeon/dev/cn30xxfpavar.h>
+#include <octeon/dev/cn30xxgmxreg.h>
#include <octeon/dev/cn30xxpipreg.h>
#include <octeon/dev/cn30xxipdreg.h>
#include <octeon/dev/cn30xxipdvar.h>
@@ -47,7 +48,7 @@ void cn30xxipd_dump(void);
void *cn30xxipd_intr_drop_ih;
-struct cn30xxipd_softc *__cn30xxipd_softc[3/* XXX */];
+struct cn30xxipd_softc *__cn30xxipd_softc[GMX_PORT_NUNITS];
#endif
/* XXX */
diff --git a/sys/arch/octeon/dev/if_cnmac.c b/sys/arch/octeon/dev/if_cnmac.c
index 0a53adbd236..a2e30d7d8d8 100644
--- a/sys/arch/octeon/dev/if_cnmac.c
+++ b/sys/arch/octeon/dev/if_cnmac.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_cnmac.c,v 1.51 2016/05/30 15:41:28 visa Exp $ */
+/* $OpenBSD: if_cnmac.c,v 1.52 2016/06/22 13:09:35 visa Exp $ */
/*
* Copyright (c) 2007 Internet Initiative Japan, Inc.
@@ -289,8 +289,8 @@ octeon_eth_attach(struct device *parent, struct device *self, void *aux)
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 */);
+ OCTEON_CVMSEG_ETHER_OFFSET(sc->sc_dev.dv_unit, csm_ether_fau_done),
+ OCT_FAU_REG_ADDR_END - (8 * (sc->sc_dev.dv_unit + 1))/* XXX */);
cn30xxfau_op_set_8(&sc->sc_fau_done, 0);
octeon_eth_pip_init(sc);
diff --git a/sys/arch/octeon/dev/octeon_iobus.c b/sys/arch/octeon/dev/octeon_iobus.c
index 7c3193fbb8d..cf3bc4bfaa9 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.15 2016/03/18 05:38:10 jmatthew Exp $ */
+/* $OpenBSD: octeon_iobus.c,v 1.16 2016/06/22 13:09:35 visa Exp $ */
/*
* Copyright (c) 2000-2004 Opsycon AB (www.opsycon.se)
@@ -44,6 +44,7 @@
#include <machine/intr.h>
#include <machine/octeonvar.h>
#include <machine/octeonreg.h>
+#include <machine/octeon_model.h>
#include <octeon/dev/iobusvar.h>
#include <octeon/dev/cn30xxgmxreg.h>
@@ -147,7 +148,6 @@ struct machine_bus_dma_tag iobus_bus_dma_tag = {
static const struct octeon_iobus_addrs iobus_addrs[] = {
{ "octcf", OCTEON_CF_BASE },
- { "cn30xxgmx", GMX0_BASE_PORT0 },
{ "octrng", OCTEON_RNG_BASE },
{ "dwctwo", USBN_BASE },
{ "amdcf", OCTEON_AMDCF_BASE},
@@ -203,8 +203,10 @@ iobussubmatch(struct device *parent, void *vcf, void *args)
void
iobusattach(struct device *parent, struct device *self, void *aux)
{
- struct device *sc = self;
+ struct iobus_attach_args aa;
struct octeon_config oc;
+ struct device *sc = self;
+ int chipid, i, ngmx;
/*
* Map and setup CIU control registers.
@@ -233,6 +235,27 @@ iobusattach(struct device *parent, struct device *self, void *aux)
* Attach all subdevices as described in the config file.
*/
config_search(iobussearch, self, sc);
+
+ chipid = octeon_get_chipid();
+ switch (octeon_model_family(chipid)) {
+ case OCTEON_MODEL_FAMILY_CN30XX:
+ case OCTEON_MODEL_FAMILY_CN50XX:
+ default:
+ ngmx = 1;
+ break;
+ case OCTEON_MODEL_FAMILY_CN61XX:
+ ngmx = 2;
+ break;
+ }
+ for (i = 0; i < ngmx; i++) {
+ aa.aa_name = "cn30xxgmx";
+ aa.aa_bust = &iobus_tag;
+ aa.aa_dmat = &iobus_bus_dma_tag;
+ aa.aa_addr = GMX0_BASE_PORT0 + GMX_BLOCK_SIZE * i;
+ aa.aa_irq = -1;
+ aa.aa_unitno = i;
+ config_found_sm(self, &aa, iobusprint, iobussubmatch);
+ }
}
int
@@ -255,6 +278,8 @@ iobussearch(struct device *parent, void *v, void *aux)
if (strcmp(iobus_addrs[i].name, cf->cf_driver->cd_name) == 0)
aa.aa_addr = iobus_addrs[i].address;
}
+ if (aa.aa_addr == -1)
+ return 0;
}
if (cf->cf_attach->ca_match(parent, cf, &aa) == 0)
diff --git a/sys/arch/octeon/include/octeonvar.h b/sys/arch/octeon/include/octeonvar.h
index e032e70af8e..60c9474577e 100644
--- a/sys/arch/octeon/include/octeonvar.h
+++ b/sys/arch/octeon/include/octeonvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: octeonvar.h,v 1.27 2016/05/30 15:41:28 visa Exp $ */
+/* $OpenBSD: octeonvar.h,v 1.28 2016/06/22 13:09:35 visa Exp $ */
/* $NetBSD: maltavar.h,v 1.3 2002/03/18 10:10:16 simonb Exp $ */
/*-
@@ -118,22 +118,11 @@ struct octeon_config {
* 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];
+ } csm_ether[12/* XXX */];
} __packed;
#define OCTEON_CVMSEG_OFFSET(entry) \
offsetof(struct octeon_cvmseg_map, entry)