git: 2c135a2aecdb - main - e6000sw: support building without FDT
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 21 Aug 2023 15:27:29 UTC
The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=2c135a2aecdb979e34d651f33b2440372d7529d7 commit 2c135a2aecdb979e34d651f33b2440372d7529d7 Author: Luiz Otavio O Souza <loos@FreeBSD.org> AuthorDate: 2023-08-21 09:59:25 +0000 Commit: Kristof Provost <kp@FreeBSD.org> CommitDate: 2023-08-21 15:26:17 +0000 e6000sw: support building without FDT This enables the use of this driver on platorms without device tree, such as Netgate's XG-7100. Sponsored by: Rubicon Communications, LLC ("Netgate") --- sys/dev/etherswitch/e6000sw/e6000sw.c | 103 +++++++++++++++++++++++++++++++++- 1 file changed, 101 insertions(+), 2 deletions(-) diff --git a/sys/dev/etherswitch/e6000sw/e6000sw.c b/sys/dev/etherswitch/e6000sw/e6000sw.c index a7deaf1baf0b..768d1b927e3e 100644 --- a/sys/dev/etherswitch/e6000sw/e6000sw.c +++ b/sys/dev/etherswitch/e6000sw/e6000sw.c @@ -27,6 +27,8 @@ */ #include <sys/cdefs.h> +#include "opt_platform.h" + #include <sys/param.h> #include <sys/bus.h> #include <sys/errno.h> @@ -45,8 +47,12 @@ #include <dev/mii/mii.h> #include <dev/mii/miivar.h> +#ifdef FDT #include <dev/ofw/ofw_bus.h> #include <dev/ofw/ofw_bus_subr.h> +#else +#include <machine/stdarg.h> +#endif #include "e6000swreg.h" #include "etherswitch_if.h" @@ -72,7 +78,9 @@ MALLOC_DEFINE(M_E6000SW, "e6000sw", "e6000sw switch"); typedef struct e6000sw_softc { device_t dev; +#ifdef FDT phandle_t node; +#endif struct sx sx; if_t ifp[E6000SW_MAX_PORTS]; @@ -102,8 +110,10 @@ static etherswitch_info_t etherswitch_info = { static void e6000sw_identify(driver_t *, device_t); static int e6000sw_probe(device_t); +#ifdef FDT static int e6000sw_parse_fixed_link(e6000sw_softc_t *, phandle_t, uint32_t); static int e6000sw_parse_ethernet(e6000sw_softc_t *, phandle_t, uint32_t); +#endif static int e6000sw_attach(device_t); static int e6000sw_detach(device_t); static int e6000sw_read_xmdio(device_t, int, int, int); @@ -202,9 +212,16 @@ e6000sw_probe(device_t dev) { e6000sw_softc_t *sc; const char *description; +#ifdef FDT phandle_t switch_node; +#else + int is_6190; +#endif sc = device_get_softc(dev); + sc->dev = dev; + +#ifdef FDT switch_node = ofw_bus_find_compatible(OF_finddevice("/"), "marvell,mv88e6085"); if (switch_node == 0) { @@ -224,12 +241,26 @@ e6000sw_probe(device_t dev) if (bootverbose) device_printf(dev, "Found switch_node: 0x%x\n", switch_node); - sc->dev = dev; sc->node = switch_node; if (OF_getencprop(sc->node, "reg", &sc->sw_addr, sizeof(sc->sw_addr)) < 0) return (ENXIO); +#else + if (resource_int_value(device_get_name(sc->dev), + device_get_unit(sc->dev), "addr", &sc->sw_addr) != 0) + return (ENXIO); + if (resource_int_value(device_get_name(sc->dev), + device_get_unit(sc->dev), "is6190", &is_6190) != 0) + /* + * Check "is8190" to keep backward compatibility with + * older setups. + */ + resource_int_value(device_get_name(sc->dev), + device_get_unit(sc->dev), "is8190", &is_6190); + if (is_6190 != 0) + sc->swid = MV88E6190; +#endif if (sc->sw_addr < 0 || sc->sw_addr > 32) return (ENXIO); @@ -280,6 +311,7 @@ e6000sw_probe(device_t dev) return (BUS_PROBE_DEFAULT); } +#ifdef FDT static int e6000sw_parse_fixed_link(e6000sw_softc_t *sc, phandle_t node, uint32_t port) { @@ -355,6 +387,63 @@ e6000sw_parse_child_fdt(e6000sw_softc_t *sc, phandle_t child, int *pport) return (0); } +#else + +static int +e6000sw_check_hint_val(device_t dev, int *val, char *fmt, ...) +{ + char *resname; + int err, len; + va_list ap; + + len = min(strlen(fmt) * 2, 128); + if (len == 0) + return (-1); + resname = malloc(len, M_E6000SW, M_WAITOK); + memset(resname, 0, len); + va_start(ap, fmt); + vsnprintf(resname, len - 1, fmt, ap); + va_end(ap); + err = resource_int_value(device_get_name(dev), device_get_unit(dev), + resname, val); + free(resname, M_E6000SW); + + return (err); +} + +static int +e6000sw_parse_hinted_port(e6000sw_softc_t *sc, int port) +{ + int err, val; + + err = e6000sw_check_hint_val(sc->dev, &val, "port%ddisabled", port); + if (err == 0 && val != 0) + return (1); + + err = e6000sw_check_hint_val(sc->dev, &val, "port%dcpu", port); + if (err == 0 && val != 0) { + sc->cpuports_mask |= (1 << port); + sc->fixed_mask |= (1 << port); + if (bootverbose) + device_printf(sc->dev, "CPU port at %d\n", port); + } + err = e6000sw_check_hint_val(sc->dev, &val, "port%dspeed", port); + if (err == 0 && val != 0) { + sc->fixed_mask |= (1 << port); + if (val == 2500) + sc->fixed25_mask |= (1 << port); + } + + if (bootverbose) { + if ((sc->fixed_mask & (1 << port)) != 0) + device_printf(sc->dev, "fixed port at %d\n", port); + else + device_printf(sc->dev, "PHY at port %d\n", port); + } + + return (0); +} +#endif static int e6000sw_init_interface(e6000sw_softc_t *sc, int port) @@ -425,7 +514,9 @@ e6000sw_attach(device_t dev) { bool sgmii; e6000sw_softc_t *sc; +#ifdef FDT phandle_t child, ports; +#endif int err, port; uint32_t reg; @@ -447,7 +538,7 @@ e6000sw_attach(device_t dev) E6000SW_LOCK(sc); e6000sw_setup(dev, sc); - ports = ofw_bus_find_child(sc->node, "ports"); + sc->sc_tq = taskqueue_create("e6000sw_taskq", M_NOWAIT, taskqueue_thread_enqueue, &sc->sc_tq); @@ -455,6 +546,8 @@ e6000sw_attach(device_t dev) taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq", device_get_nameunit(dev)); +#ifdef FDT + ports = ofw_bus_find_child(sc->node, "ports"); if (ports == 0) { device_printf(dev, "failed to parse DTS: no ports found for " "switch\n"); @@ -468,6 +561,12 @@ e6000sw_attach(device_t dev) device_printf(sc->dev, "failed to parse DTS\n"); goto out_fail; } +#else + for (port = 0; port < sc->num_ports; port++) { + err = e6000sw_parse_hinted_port(sc, port); + if (err != 0) + continue; +#endif /* Port is in use. */ sc->ports_mask |= (1 << port);