The branch main has been updated by kp:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=2c135a2aecdb979e34d651f33b2440372d7529d7

commit 2c135a2aecdb979e34d651f33b2440372d7529d7
Author:     Luiz Otavio O Souza <l...@freebsd.org>
AuthorDate: 2023-08-21 09:59:25 +0000
Commit:     Kristof Provost <k...@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);

Reply via email to