Index: sys/dev/cadence/if_cgem.c =================================================================== --- sys/dev/cadence/if_cgem.c +++ sys/dev/cadence/if_cgem.c @@ -121,10 +121,12 @@ if_t ifp; struct mtx sc_mtx; device_t dev; + int hwtype; device_t miibus; u_int mii_media_active; /* last active media */ int if_old_flags; struct resource *mem_res; + struct resource *mem_res_mgmt; struct resource *irq_res; void *intrhand; struct callout tick_ch; @@ -224,6 +226,7 @@ #define WR4(sc, off, val) (bus_write_4((sc)->mem_res, (off), (val))) #define BARRIER(sc, off, len, flags) \ (bus_barrier((sc)->mem_res, (off), (len), (flags)) +#define WR4MGMT(sc, off, val) (bus_write_4((sc)->mem_res_mgmt, (off), (val))) #define CGEM_LOCK(sc) mtx_lock(&(sc)->sc_mtx) #define CGEM_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) @@ -1498,7 +1501,7 @@ WR4(sc, CGEM_NET_CFG, sc->net_cfg_shadow); #ifdef EXT_RESOURCES - if (sc->ref_clk != NULL) { + if (sc->ref_clk != NULL && sc->hwtype != HWTYPE_SIFIVE) { CGEM_UNLOCK(sc); if (clk_set_freq(sc->ref_clk, ref_clk_freq, 0)) device_printf(sc->dev, "could not set ref clk to %d\n", @@ -1513,6 +1516,11 @@ sc->ref_clk_num, ref_clk_freq); #endif + if (sc->hwtype == HWTYPE_SIFIVE) + WR4MGMT(sc, CGEM_MGMT_TX_CLK_SEL, + IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T ? + CGEM_MGMT_TX_CLK_SEL_GMII : CGEM_MGMT_TX_CLK_SEL_MII); + sc->mii_media_active = mii->mii_media_active; } @@ -1740,7 +1748,6 @@ if_t ifp = NULL; int rid, err; u_char eaddr[ETHER_ADDR_LEN]; - int hwtype; #ifndef EXT_RESOURCES phandle_t node; pcell_t cell; @@ -1750,20 +1757,20 @@ CGEM_LOCK_INIT(sc); /* Key off of compatible string and set hardware-specific options. */ - hwtype = ofw_bus_search_compatible(dev, compat_data)->ocd_data; - if (hwtype == HWTYPE_ZYNQMP) + sc->hwtype = ofw_bus_search_compatible(dev, compat_data)->ocd_data; + if (sc->hwtype == HWTYPE_ZYNQMP) sc->neednullqs = 1; - if (hwtype == HWTYPE_ZYNQ) + if (sc->hwtype == HWTYPE_ZYNQ) sc->rxhangwar = 1; #ifdef EXT_RESOURCES - if (hwtype == HWTYPE_ZYNQ || hwtype == HWTYPE_ZYNQMP) { + if (sc->hwtype == HWTYPE_ZYNQ || sc->hwtype == HWTYPE_ZYNQMP) { if (clk_get_by_ofw_name(dev, 0, "tx_clk", &sc->ref_clk) != 0) device_printf(dev, "could not retrieve reference clock.\n"); else if (clk_enable(sc->ref_clk) != 0) device_printf(dev, "could not enable clock.\n"); - } else if (hwtype == HWTYPE_SIFIVE) { + } else if (sc->hwtype == HWTYPE_SIFIVE) { if (clk_get_by_ofw_name(dev, 0, "pclk", &sc->ref_clk) != 0) device_printf(dev, "could not retrieve reference clock.\n"); @@ -1787,6 +1794,18 @@ return (ENOMEM); } + /* Get memory resource for GEMGXL Management Block (SiFive). */ + if (sc->hwtype == HWTYPE_SIFIVE) { + rid = 1; + sc->mem_res_mgmt = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &rid, RF_ACTIVE); + if (sc->mem_res_mgmt == NULL) { + device_printf(dev, + "could not allocate memory resources.\n"); + return (ENOMEM); + } + } + /* Get IRQ resource. */ rid = 0; sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, @@ -1894,6 +1913,11 @@ rman_get_rid(sc->mem_res), sc->mem_res); sc->mem_res = NULL; } + if (sc->mem_res_mgmt != NULL) { + bus_release_resource(dev, SYS_RES_MEMORY, + rman_get_rid(sc->mem_res_mgmt), sc->mem_res_mgmt); + sc->mem_res_mgmt = NULL; + } if (sc->irq_res != NULL) { if (sc->intrhand) bus_teardown_intr(dev, sc->irq_res, sc->intrhand); Index: sys/dev/cadence/if_cgem_hw.h =================================================================== --- sys/dev/cadence/if_cgem_hw.h +++ sys/dev/cadence/if_cgem_hw.h @@ -443,4 +443,17 @@ #endif }; +/* + * GEMGXL Management Control Registers for SiFive SoCs: + * + * Reference: SiFive FU740-C000 Manual v1p2, section 22.2. + */ +#define CGEM_MGMT_TX_CLK_SEL 0x000 +#define CGEM_MGMT_TX_CLK_SEL_GMII 0x0 +#define CGEM_MGMT_TX_CLK_SEL_MII 0x1 +#define CGEM_MGMT_CTRLSTAT_SPEED_MODE 0x020 +#define CGEM_MGMT_SPEED_MODE_10 0x0 +#define CGEM_MGMT_SPEED_MODE_100 0x1 +#define CGEM_MGMT_SPEED_MODE_1000 0x2 + #endif /* _IF_CGEM_HW_H_ */