-/* $OpenBSD: if_cpsw.c,v 1.34 2016/04/13 11:33:59 mpi Exp $ */
+/* $OpenBSD: if_cpsw.c,v 1.35 2016/06/26 09:06:35 jsg Exp $ */
/* $NetBSD: if_cpsw.c,v 1.3 2013/04/17 14:36:34 bouyer Exp $ */
/*
#include <sys/socket.h>
#include <machine/bus.h>
+#include <machine/fdt.h>
#include <net/if.h>
#include <net/if_media.h>
#include <arch/armv7/omap/sitara_cm.h>
#include <arch/armv7/omap/if_cpswreg.h>
+#include <dev/ofw/openfirm.h>
+
#define CPSW_TXFRAGS 16
#define OMAP2SCM_MAC_ID0_LO 0x630
#define DEVNAME(_sc) ((_sc)->sc_dev.dv_xname)
+int cpsw_match(struct device *, void *, void *);
void cpsw_attach(struct device *, struct device *, void *);
void cpsw_start(struct ifnet *);
struct cfattach cpsw_ca = {
sizeof(struct cpsw_softc),
- NULL,
+ cpsw_match,
cpsw_attach
};
sc->sc_active_port);
}
+int
+cpsw_match(struct device *parent, void *match, void *aux)
+{
+ struct fdt_attach_args *faa = aux;
+
+ return OF_is_compatible(faa->fa_node, "ti,cpsw");
+}
+
void
cpsw_attach(struct device *parent, struct device *self, void *aux)
{
struct cpsw_softc *sc = (struct cpsw_softc *)self;
- struct armv7_attach_args *aa = aux;
+ struct fdt_attach_args *faa = aux;
struct arpcom * const ac = &sc->sc_ac;
struct ifnet * const ifp = &ac->ac_if;
u_int32_t idver;
int error;
u_int i;
+ uint32_t intr[4];
+ uint32_t memsize;
+
+ if (faa->fa_nreg < 2 || (faa->fa_nintr != 4 && faa->fa_nintr != 12))
+ return;
+
+ for (i = 0; i < 4; i++) {
+ if (faa->fa_nintr == 4)
+ intr[i] = faa->fa_intr[i];
+ else
+ intr[i] = faa->fa_intr[(3 * i) + 1];
+ }
+
+ /*
+ * fa_reg[1] is size of CPSW_SS and CPSW_PORT
+ * fa_reg[3] is size of CPSW_WR
+ * we map a size that is a superset of both
+ */
+ memsize = 0x4000;
timeout_set(&sc->sc_tick, cpsw_tick, sc);
cpsw_get_mac_addr(sc);
- sc->sc_rxthih = arm_intr_establish(aa->aa_dev->irq[0] +
- CPSW_INTROFF_RXTH, IPL_NET, cpsw_rxthintr, sc, DEVNAME(sc));
- sc->sc_rxih = arm_intr_establish(aa->aa_dev->irq[0] +
- CPSW_INTROFF_RX, IPL_NET, cpsw_rxintr, sc, DEVNAME(sc));
- sc->sc_txih = arm_intr_establish(aa->aa_dev->irq[0] +
- CPSW_INTROFF_TX, IPL_NET, cpsw_txintr, sc, DEVNAME(sc));
- sc->sc_miscih = arm_intr_establish(aa->aa_dev->irq[0] +
- CPSW_INTROFF_MISC, IPL_NET, cpsw_miscintr, sc, DEVNAME(sc));
+ sc->sc_rxthih = arm_intr_establish(intr[0], IPL_NET, cpsw_rxthintr, sc,
+ DEVNAME(sc));
+ sc->sc_rxih = arm_intr_establish(intr[1], IPL_NET, cpsw_rxintr, sc,
+ DEVNAME(sc));
+ sc->sc_txih = arm_intr_establish(intr[2], IPL_NET, cpsw_txintr, sc,
+ DEVNAME(sc));
+ sc->sc_miscih = arm_intr_establish(intr[3], IPL_NET, cpsw_miscintr, sc,
+ DEVNAME(sc));
- sc->sc_bst = aa->aa_iot;
- sc->sc_bdt = aa->aa_dmat;
+ sc->sc_bst = faa->fa_iot;
+ sc->sc_bdt = faa->fa_dmat;
- error = bus_space_map(sc->sc_bst, aa->aa_dev->mem[0].addr,
- aa->aa_dev->mem[0].size, 0, &sc->sc_bsh);
+ error = bus_space_map(sc->sc_bst, faa->fa_reg[0],
+ memsize, 0, &sc->sc_bsh);
if (error) {
printf("can't map registers: %d\n", error);
return;
}
- sc->sc_txdescs_pa = aa->aa_dev->mem[0].addr +
+ sc->sc_txdescs_pa = faa->fa_reg[0] +
CPSW_CPPI_RAM_TXDESCS_BASE;
error = bus_space_subregion(sc->sc_bst, sc->sc_bsh,
CPSW_CPPI_RAM_TXDESCS_BASE, CPSW_CPPI_RAM_TXDESCS_SIZE,
return;
}
- sc->sc_rxdescs_pa = aa->aa_dev->mem[0].addr +
+ sc->sc_rxdescs_pa = faa->fa_reg[0] +
CPSW_CPPI_RAM_RXDESCS_BASE;
error = bus_space_subregion(sc->sc_bst, sc->sc_bsh,
CPSW_CPPI_RAM_RXDESCS_BASE, CPSW_CPPI_RAM_RXDESCS_SIZE,