diff --git a/sys/dev/neta/if_mvneta.c b/sys/dev/neta/if_mvneta.c --- a/sys/dev/neta/if_mvneta.c +++ b/sys/dev/neta/if_mvneta.c @@ -65,6 +65,8 @@ #include #include +#include + #include #include @@ -200,9 +202,6 @@ STATIC int mvneta_miibus_readreg(device_t, int, int); STATIC int mvneta_miibus_writereg(device_t, int, int, int); -/* Clock */ -STATIC uint32_t mvneta_get_clk(void); - static device_method_t mvneta_methods[] = { /* Device interface */ DEVMETHOD(device_detach, mvneta_detach), @@ -344,16 +343,6 @@ { mvneta_rxtxth_intr, "MVNETA aggregated interrupt" }, }; -STATIC uint32_t -mvneta_get_clk() -{ -#if defined(__aarch64__) - return (A3700_TCLK_250MHZ); -#else - return (get_tclk()); -#endif -} - static int mvneta_set_mac_address(struct mvneta_softc *sc, uint8_t *addr) { @@ -541,7 +530,9 @@ #if !defined(__aarch64__) uint32_t reg; #endif - +#if defined(__aarch64__) + clk_t clk; +#endif sc = device_get_softc(self); sc->dev = self; @@ -563,6 +554,27 @@ MVNETA_WRITE(sc, MVNETA_PRXINIT, 0x00000001); MVNETA_WRITE(sc, MVNETA_PTXINIT, 0x00000001); +#if defined(__aarch64__) + error = clk_get_by_ofw_index(sc->dev, ofw_bus_get_node(sc->dev), 0, + &clk); + if (error != 0) { + device_printf(sc->dev, + "Cannot get clock, using default frequency: %d\n", + A3700_TCLK_250MHZ); + sc->clk_freq = A3700_TCLK_250MHZ; + } else { + error = clk_get_freq(clk, &sc->clk_freq); + if (error != 0) { + device_printf(sc->dev, + "Cannot obtain frequency from parent clock\n"); + bus_release_resources(sc->dev, res_spec, sc->res); + return (error); + } + } +#else + sc->clk_freq = get_tclk(); +#endif + #if !defined(__aarch64__) /* * Disable port snoop for buffers and descriptors @@ -1380,7 +1392,7 @@ rx = MVNETA_RX_RING(sc, q); rx->dma = rx->cpu = 0; rx->queue_th_received = MVNETA_RXTH_COUNT; - rx->queue_th_time = (mvneta_get_clk() / 1000) / 10; /* 0.1 [ms] */ + rx->queue_th_time = (sc->clk_freq / 1000) / 10; /* 0.1 [ms] */ /* Initialize LRO */ rx->lro_enabled = FALSE; @@ -3389,7 +3401,7 @@ mvneta_rx_lockq(sc, arg->queue); rx = MVNETA_RX_RING(sc, arg->queue); time_mvtclk = rx->queue_th_time; - time_us = ((uint64_t)time_mvtclk * 1000ULL * 1000ULL) / mvneta_get_clk(); + time_us = ((uint64_t)time_mvtclk * 1000ULL * 1000ULL) / sc->clk_freq; mvneta_rx_unlockq(sc, arg->queue); mvneta_sc_unlock(sc); @@ -3406,8 +3418,7 @@ mvneta_sc_unlock(sc); return (EINVAL); } - time_mvtclk = - (uint64_t)mvneta_get_clk() * (uint64_t)time_us / (1000ULL * 1000ULL); + time_mvtclk = sc->clk_freq * (uint64_t)time_us / (1000ULL * 1000ULL); rx->queue_th_time = time_mvtclk; reg = MVNETA_PRXITTH_RITT(rx->queue_th_time); MVNETA_WRITE(sc, MVNETA_PRXITTH(arg->queue), reg); diff --git a/sys/dev/neta/if_mvnetavar.h b/sys/dev/neta/if_mvnetavar.h --- a/sys/dev/neta/if_mvnetavar.h +++ b/sys/dev/neta/if_mvnetavar.h @@ -258,6 +258,8 @@ struct mtx mtx; struct resource *res[2]; void *ih_cookie[1]; + + uint64_t clk_freq; struct ifnet *ifp; uint32_t mvneta_if_flags;