diff options
Diffstat (limited to 'sys/arch/armv7/omap/if_cpsw.c')
-rw-r--r-- | sys/arch/armv7/omap/if_cpsw.c | 61 |
1 files changed, 54 insertions, 7 deletions
diff --git a/sys/arch/armv7/omap/if_cpsw.c b/sys/arch/armv7/omap/if_cpsw.c index d508ff04247..78eb6782785 100644 --- a/sys/arch/armv7/omap/if_cpsw.c +++ b/sys/arch/armv7/omap/if_cpsw.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_cpsw.c,v 1.32 2016/01/07 04:41:17 canacar Exp $ */ +/* $OpenBSD: if_cpsw.c,v 1.33 2016/03/02 01:31:41 canacar Exp $ */ /* $NetBSD: if_cpsw.c,v 1.3 2013/04/17 14:36:34 bouyer Exp $ */ /* @@ -148,6 +148,7 @@ struct cpsw_softc { volatile bool sc_txeoq; volatile bool sc_rxeoq; struct timeout sc_tick; + int sc_active_port; }; #define DEVNAME(_sc) ((_sc)->sc_dev.dv_xname) @@ -286,6 +287,45 @@ cpsw_get_mac_addr(struct cpsw_softc *sc) } } +static void +cpsw_mdio_init(struct cpsw_softc *sc) +{ + uint32_t alive, link; + u_int tries; + + sc->sc_active_port = 0; + + /* Initialze MDIO - ENABLE, PREAMBLE=0, FAULTENB, CLKDIV=0xFF */ + /* TODO Calculate MDCLK=CLK/(CLKDIV+1) */ + bus_space_write_4(sc->sc_bst, sc->sc_bsh, MDIOCONTROL, + (1<<30) | (1<<18) | 0xFF); + + for(tries = 0; tries < 1000; tries++) { + alive = bus_space_read_4(sc->sc_bst, sc->sc_bsh, MDIOALIVE) & 3; + if (alive) + break; + delay(1); + } + + if (alive == 0) { + printf("%s: no PHY is alive\n", DEVNAME(sc)); + return; + } + + link = bus_space_read_4(sc->sc_bst, sc->sc_bsh, MDIOLINK) & 3; + + if (alive == 3) { + /* both ports are alive, prefer one with link */ + if (link == 2) + sc->sc_active_port = 1; + } else if (alive == 2) + sc->sc_active_port = 1; + + /* Select the port to monitor */ + bus_space_write_4(sc->sc_bst, sc->sc_bsh, MDIOUSERPHYSEL0, + sc->sc_active_port); +} + void cpsw_attach(struct device *parent, struct device *self, void *aux) { @@ -391,6 +431,8 @@ cpsw_attach(struct device *parent, struct device *self, void *aux) sc->sc_mii.mii_writereg = cpsw_mii_writereg; sc->sc_mii.mii_statchg = cpsw_mii_statchg; + cpsw_mdio_init(sc); + ifmedia_init(&sc->sc_mii.mii_media, 0, cpsw_mediachange, cpsw_mediastatus); mii_attach(self, &sc->sc_mii, 0xffffffff, @@ -776,13 +818,14 @@ cpsw_init(struct ifnet *ifp) bus_space_write_4(sc->sc_bst, sc->sc_bsh, CPSW_PORT_P_SA_LO(i+1), ac->ac_enaddr[4] | (ac->ac_enaddr[5] << 8)); - /* Set MACCONTROL for ports 0,1: FULLDUPLEX(1), GMII_EN(5), + /* Set MACCONTROL for ports 0,1: FULLDUPLEX(0), GMII_EN(5), IFCTL_A(15), IFCTL_B(16) FIXME */ bus_space_write_4(sc->sc_bst, sc->sc_bsh, CPSW_SL_MACCONTROL(i), 1 | (1<<5) | (1<<15) | (1<<16)); - /* Set ALE port to forwarding(3) */ - bus_space_write_4(sc->sc_bst, sc->sc_bsh, CPSW_ALE_PORTCTL(i+1), 3); + /* Set ALE port to forwarding(3) on the active port */ + if (i == sc->sc_active_port) + bus_space_write_4(sc->sc_bst, sc->sc_bsh, CPSW_ALE_PORTCTL(i+1), 3); } /* Set Host Port Mapping */ @@ -834,6 +877,12 @@ cpsw_init(struct ifnet *ifp) bus_space_write_4(sc->sc_bst, sc->sc_bsh, CPSW_CPDMA_TX_CONTROL, 1); bus_space_write_4(sc->sc_bst, sc->sc_bsh, CPSW_CPDMA_RX_CONTROL, 1); + /* Enable interrupt pacing for C0 RX/TX (IMAX set to max intr/ms allowed) */ +#define CPSW_VBUSP_CLK_MHZ 2400 /* hardcoded for BBB */ + bus_space_write_4(sc->sc_bst, sc->sc_bsh, CPSW_WR_C_RX_IMAX(0), 2); + bus_space_write_4(sc->sc_bst, sc->sc_bsh, CPSW_WR_C_TX_IMAX(0), 2); + bus_space_write_4(sc->sc_bst, sc->sc_bsh, CPSW_WR_INT_CONTROL, 3 << 16 | CPSW_VBUSP_CLK_MHZ/4); + /* Enable TX and RX interrupt receive for core 0 */ bus_space_write_4(sc->sc_bst, sc->sc_bsh, CPSW_WR_C_TX_EN(0), 1); bus_space_write_4(sc->sc_bst, sc->sc_bsh, CPSW_WR_C_RX_EN(0), 1); @@ -852,9 +901,7 @@ cpsw_init(struct ifnet *ifp) bus_space_write_4(sc->sc_bst, sc->sc_bsh, CPSW_CPDMA_CPDMA_EOI_VECTOR, CPSW_INTROFF_TX); bus_space_write_4(sc->sc_bst, sc->sc_bsh, CPSW_CPDMA_CPDMA_EOI_VECTOR, CPSW_INTROFF_MISC); - /* Initialze MDIO - ENABLE, PREAMBLE=0, FAULTENB, CLKDIV=0xFF */ - /* TODO Calculate MDCLK=CLK/(CLKDIV+1) */ - bus_space_write_4(sc->sc_bst, sc->sc_bsh, MDIOCONTROL, (1<<30) | (1<<18) | 0xFF); + cpsw_mdio_init(sc); mii_mediachg(mii); |