Add support for the second GMX interface on Octeon II. This enables
authorvisa <visa@openbsd.org>
Wed, 22 Jun 2016 13:09:35 +0000 (13:09 +0000)
committervisa <visa@openbsd.org>
Wed, 22 Jun 2016 13:09:35 +0000 (13:09 +0000)
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@

sys/arch/octeon/dev/cn30xxgmx.c
sys/arch/octeon/dev/cn30xxgmxreg.h
sys/arch/octeon/dev/cn30xxipd.c
sys/arch/octeon/dev/if_cnmac.c
sys/arch/octeon/dev/octeon_iobus.c
sys/arch/octeon/include/octeonvar.h

index 48a9c68..cb8c66c 100644 (file)
@@ -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.
  * 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;
index 7961cde..e1e650a 100644 (file)
@@ -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.
 
 /* 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
index 39e9dc9..d28b264 100644 (file)
@@ -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 */
index 0a53adb..a2e30d7 100644 (file)
@@ -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);
index 7c3193f..cf3bc4b 100644 (file)
@@ -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)
index e032e70..60c9474 100644 (file)
@@ -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)