Index: sys/arm64/conf/ESPRESSO =================================================================== --- /dev/null +++ sys/arm64/conf/ESPRESSO @@ -0,0 +1,14 @@ +# +# ESPRESSO -- Generic kernel configuration file for FreeBSD/arm64 for the ESPRESSObin +# +# $FreeBSD: head/sys/arm64/conf/GENERIC-UP 325096 2017-10-29 08:17:03Z eadler $ + +include GENERIC +ident ESPRESSO + +device etherswitch +device miiproxy +device iicbus + +device mdio +device e6000sw Index: sys/dev/etherswitch/e6000sw/e6000sw.c =================================================================== --- sys/dev/etherswitch/e6000sw/e6000sw.c +++ sys/dev/etherswitch/e6000sw/e6000sw.c @@ -45,8 +45,8 @@ #include #include -#include #include +#include #include "e6000swreg.h" #include "etherswitch_if.h" @@ -92,6 +92,8 @@ static void e6000sw_identify(driver_t *, device_t); static int e6000sw_probe(device_t); +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); static int e6000sw_attach(device_t); static int e6000sw_detach(device_t); static int e6000sw_readphy(device_t, int, int); @@ -197,15 +199,17 @@ { e6000sw_softc_t *sc; const char *description; - phandle_t dsa_node, switch_node; + phandle_t switch_node; - dsa_node = fdt_find_compatible(OF_finddevice("/"), - "marvell,dsa", 0); - switch_node = OF_child(dsa_node); + switch_node = ofw_bus_find_compatible(OF_finddevice("/"), + "marvell,mv88e6085"); if (switch_node == 0) return (ENXIO); + if (bootverbose) + device_printf(dev, "Found switch_node: 0x%x\n", switch_node); + sc = device_get_softc(dev); sc->dev = dev; sc->node = switch_node; @@ -214,8 +218,12 @@ sizeof(sc->sw_addr)) < 0) return (ENXIO); - if (!OF_hasprop(sc->node, "single-chip-addressing") && - (sc->sw_addr != 0 && (sc->sw_addr % 2) == 0)) + /* + * According to the Linux source code, all of the Switch IDs we support + * are multi_chip capable, and should go into multi-chip mode if the + * sw_addr != 0. + */ + if (!OF_hasprop(sc->node, "single-chip-addressing") && sc->sw_addr != 0) sc->multi_chip = true; /* @@ -262,10 +270,58 @@ } static int -e6000sw_parse_child_fdt(e6000sw_softc_t *sc, phandle_t child, int *pport) +e6000sw_parse_fixed_link(e6000sw_softc_t *sc, phandle_t fixed_link, uint32_t port) { - char *name, *portlabel; int speed; + if (fixed_link != 0) { + sc->fixed_mask |= (1 << port); + + if (OF_getencprop(fixed_link, "speed", &speed, sizeof(speed))> 0) { + if (speed == 2500 && + (MVSWITCH(sc, MV88E6141) || + MVSWITCH(sc, MV88E6341))) { + sc->fixed25_mask |= (1 << port); + } + } else { + device_printf(sc->dev, + "Port %d has a fixed-link node without a speed " + "property\n", port); + + return (ENXIO); + } + } + + return (0); +} + +static int +e6000sw_parse_ethernet(e6000sw_softc_t *sc, phandle_t port_handle, uint32_t port) { + phandle_t fixed_link, switch_eth, switch_eth_handle; + + if (OF_getencprop(port_handle, "ethernet", (void*)&switch_eth_handle, + sizeof(switch_eth_handle)) > 0) { + if (switch_eth_handle > 0) { + switch_eth = OF_node_from_xref(switch_eth_handle); + + fixed_link = ofw_bus_find_child(switch_eth, + "fixed-link"); + + if (e6000sw_parse_fixed_link(sc, fixed_link, port) != 0) { + return (ENXIO); + } + + } else + device_printf(sc->dev, + "Port %d has ethernet property but it points " + "to an invalid location\n", port); + } + + return (0); +} + +static int +e6000sw_parse_child_fdt(e6000sw_softc_t *sc, phandle_t child, int *pport) +{ phandle_t fixed_link; uint32_t port; @@ -278,32 +334,13 @@ return (ENXIO); *pport = port; - if (OF_getprop_alloc(child, "label", (void **)&portlabel) > 0) { - if (strncmp(portlabel, "cpu", 3) == 0) { - device_printf(sc->dev, "CPU port at %d\n", port); - sc->cpuports_mask |= (1 << port); - sc->fixed_mask |= (1 << port); - } - free(portlabel, M_OFWPROP); - } + fixed_link = ofw_bus_find_child(child, "fixed-link"); + if (e6000sw_parse_fixed_link(sc, fixed_link, port) != 0) + return (ENXIO); + + if (e6000sw_parse_ethernet(sc, child, port) != 0) + return (ENXIO); - fixed_link = OF_child(child); - if (fixed_link != 0 && - OF_getprop_alloc(fixed_link, "name", (void **)&name) > 0) { - if (strncmp(name, "fixed-link", 10) == 0) { - /* Assume defaults: 1g - full-duplex. */ - sc->fixed_mask |= (1 << port); - if (OF_getencprop(fixed_link, "speed", &speed, - sizeof(speed)) > 0) { - if (speed == 2500 && - (MVSWITCH(sc, MV88E6141) || - MVSWITCH(sc, MV88E6341))) { - sc->fixed25_mask |= (1 << port); - } - } - } - free(name, M_OFWPROP); - } if ((sc->fixed_mask & (1 << port)) != 0) device_printf(sc->dev, "fixed port at %d\n", port); else @@ -354,7 +391,7 @@ e6000sw_attach(device_t dev) { e6000sw_softc_t *sc; - phandle_t child; + phandle_t child, ports; int err, port; uint32_t reg; @@ -371,7 +408,15 @@ E6000SW_LOCK(sc); e6000sw_setup(dev, sc); - for (child = OF_child(sc->node); child != 0; child = OF_peer(child)) { + ports = ofw_bus_find_child(sc->node, "ports"); + + if (ports == 0) { + device_printf(dev, "failed to parse DTS: no ports found for " + "switch\n"); + return (ENXIO); + } + + for (child = OF_child(ports); child != 0; child = OF_peer(child)) { err = e6000sw_parse_child_fdt(sc, child, &port); if (err != 0) { device_printf(sc->dev, "failed to parse DTS\n"); Index: sys/dev/neta/if_mvneta.c =================================================================== --- sys/dev/neta/if_mvneta.c +++ sys/dev/neta/if_mvneta.c @@ -189,8 +189,10 @@ STATIC void mvneta_update_mib(struct mvneta_softc *); /* Switch */ +STATIC boolean_t mvneta_find_ethernet_prop_switch(phandle_t, phandle_t); STATIC boolean_t mvneta_has_switch(device_t); + #define mvneta_sc_lock(sc) mtx_lock(&sc->mtx) #define mvneta_sc_unlock(sc) mtx_unlock(&sc->mtx) @@ -412,23 +414,38 @@ } STATIC boolean_t -mvneta_has_switch(device_t self) +mvneta_find_ethernet_prop_switch(phandle_t ethernet, phandle_t node) { - phandle_t node, switch_node, switch_eth, switch_eth_handle; + boolean_t ret; + phandle_t child, switch_eth_handle, switch_eth; - node = ofw_bus_get_node(self); - switch_node = - ofw_bus_find_compatible(OF_finddevice("/"), "marvell,dsa"); - switch_eth = 0; + for (child = OF_child(node); child != 0; child = OF_peer(child)) { + if (OF_getencprop(child, "ethernet", (void*)&switch_eth_handle, + sizeof(switch_eth_handle)) > 0) { + if (switch_eth_handle > 0) { + switch_eth = OF_node_from_xref( + switch_eth_handle); - OF_getencprop(switch_node, "dsa,ethernet", - (void*)&switch_eth_handle, sizeof(switch_eth_handle)); + if (switch_eth == ethernet) + return (true); + } + } - if (switch_eth_handle > 0) - switch_eth = OF_node_from_xref(switch_eth_handle); + ret = mvneta_find_ethernet_prop_switch(ethernet, child); + if (ret != 0) + return (ret); + } - /* Return true if dsa,ethernet cell points to us */ - return (node == switch_eth); + return (false); +} + +STATIC boolean_t +mvneta_has_switch(device_t self) +{ + phandle_t node; + + node = ofw_bus_get_node(self); + return mvneta_find_ethernet_prop_switch(node, OF_finddevice("/")); } STATIC int @@ -799,6 +816,8 @@ if_link_state_change(sc->ifp, LINK_STATE_UP); if (mvneta_has_switch(self)) { + if (bootverbose) + device_printf(self, "This device is attached to a switch\n"); child = device_add_child(sc->dev, "mdio", -1); if (child == NULL) { ether_ifdetach(sc->ifp); @@ -807,6 +826,8 @@ } bus_generic_attach(sc->dev); bus_generic_attach(child); + } else if (bootverbose) { + device_printf(self, "This device is not attached to a switch\n"); } /* Configure MAC media */