1296177Sjhibbits/*- 2296177Sjhibbits * Copyright (c) 2012 Semihalf. 3296177Sjhibbits * All rights reserved. 4296177Sjhibbits * 5296177Sjhibbits * Redistribution and use in source and binary forms, with or without 6296177Sjhibbits * modification, are permitted provided that the following conditions 7296177Sjhibbits * are met: 8296177Sjhibbits * 1. Redistributions of source code must retain the above copyright 9296177Sjhibbits * notice, this list of conditions and the following disclaimer. 10296177Sjhibbits * 2. Redistributions in binary form must reproduce the above copyright 11296177Sjhibbits * notice, this list of conditions and the following disclaimer in the 12296177Sjhibbits * documentation and/or other materials provided with the distribution. 13296177Sjhibbits * 14296177Sjhibbits * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15296177Sjhibbits * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16296177Sjhibbits * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17296177Sjhibbits * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18296177Sjhibbits * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19296177Sjhibbits * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20296177Sjhibbits * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21296177Sjhibbits * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22296177Sjhibbits * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23296177Sjhibbits * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24296177Sjhibbits * SUCH DAMAGE. 25296177Sjhibbits */ 26296177Sjhibbits 27296177Sjhibbits#include <sys/cdefs.h> 28296177Sjhibbits__FBSDID("$FreeBSD$"); 29296177Sjhibbits 30296177Sjhibbits#include <sys/param.h> 31296177Sjhibbits#include <sys/systm.h> 32296177Sjhibbits#include <sys/kernel.h> 33296177Sjhibbits#include <sys/bus.h> 34296177Sjhibbits#include <sys/module.h> 35296177Sjhibbits#include <sys/socket.h> 36296177Sjhibbits 37296177Sjhibbits#include <powerpc/mpc85xx/mpc85xx.h> 38296177Sjhibbits 39296177Sjhibbits#include <net/if.h> 40296177Sjhibbits#include <net/if_media.h> 41296177Sjhibbits 42296177Sjhibbits#include <dev/mii/mii.h> 43296177Sjhibbits#include <dev/mii/miivar.h> 44296177Sjhibbits 45296177Sjhibbits#include <dev/fdt/fdt_common.h> 46296177Sjhibbits#include <dev/ofw/ofw_bus.h> 47296177Sjhibbits#include <dev/ofw/ofw_bus_subr.h> 48296177Sjhibbits#include <dev/ofw/openfirm.h> 49296177Sjhibbits 50296177Sjhibbits#include "miibus_if.h" 51296177Sjhibbits 52296177Sjhibbits#include <contrib/ncsw/inc/Peripherals/fm_port_ext.h> 53296177Sjhibbits#include <contrib/ncsw/inc/xx_ext.h> 54296177Sjhibbits 55296177Sjhibbits#include "if_dtsec.h" 56296177Sjhibbits 57296177Sjhibbits 58296177Sjhibbitsstatic int dtsec_fdt_probe(device_t dev); 59296177Sjhibbitsstatic int dtsec_fdt_attach(device_t dev); 60296177Sjhibbits 61296177Sjhibbitsstatic device_method_t dtsec_methods[] = { 62296177Sjhibbits /* Device interface */ 63296177Sjhibbits DEVMETHOD(device_probe, dtsec_fdt_probe), 64296177Sjhibbits DEVMETHOD(device_attach, dtsec_fdt_attach), 65296177Sjhibbits DEVMETHOD(device_detach, dtsec_detach), 66296177Sjhibbits 67296177Sjhibbits DEVMETHOD(device_shutdown, dtsec_shutdown), 68296177Sjhibbits DEVMETHOD(device_suspend, dtsec_suspend), 69296177Sjhibbits DEVMETHOD(device_resume, dtsec_resume), 70296177Sjhibbits 71296177Sjhibbits /* Bus interface */ 72296177Sjhibbits DEVMETHOD(bus_print_child, bus_generic_print_child), 73296177Sjhibbits DEVMETHOD(bus_driver_added, bus_generic_driver_added), 74296177Sjhibbits 75296177Sjhibbits /* MII interface */ 76296177Sjhibbits DEVMETHOD(miibus_readreg, dtsec_miibus_readreg), 77296177Sjhibbits DEVMETHOD(miibus_writereg, dtsec_miibus_writereg), 78296177Sjhibbits DEVMETHOD(miibus_statchg, dtsec_miibus_statchg), 79296177Sjhibbits 80296177Sjhibbits { 0, 0 } 81296177Sjhibbits}; 82296177Sjhibbits 83296177Sjhibbitsstatic driver_t dtsec_driver = { 84296177Sjhibbits "dtsec", 85296177Sjhibbits dtsec_methods, 86296177Sjhibbits sizeof(struct dtsec_softc), 87296177Sjhibbits}; 88296177Sjhibbits 89296177Sjhibbitsstatic devclass_t dtsec_devclass; 90296177SjhibbitsDRIVER_MODULE(dtsec, dpaa, dtsec_driver, dtsec_devclass, 0, 0); 91296177SjhibbitsDRIVER_MODULE(miibus, dtsec, miibus_driver, miibus_devclass, 0, 0); 92296177SjhibbitsMODULE_DEPEND(dtsec, ether, 1, 1, 1); 93296177SjhibbitsMODULE_DEPEND(dtsec, miibus, 1, 1, 1); 94296177Sjhibbits 95296177Sjhibbitsstatic int 96296177Sjhibbitsdtsec_fdt_probe(device_t dev) 97296177Sjhibbits{ 98296177Sjhibbits 99296177Sjhibbits if (!ofw_bus_is_compatible(dev, "fsl,dpa-ethernet")) 100296177Sjhibbits return (ENXIO); 101296177Sjhibbits 102296177Sjhibbits device_set_desc(dev, "Freescale Data Path Triple Speed Ethernet " 103296177Sjhibbits "Controller"); 104296177Sjhibbits 105296177Sjhibbits return (BUS_PROBE_DEFAULT); 106296177Sjhibbits} 107296177Sjhibbits 108296177Sjhibbitsstatic int 109296177Sjhibbitsdtsec_fdt_attach(device_t dev) 110296177Sjhibbits{ 111296177Sjhibbits struct dtsec_softc *sc; 112296177Sjhibbits phandle_t node, enet_node, phy_node; 113296177Sjhibbits phandle_t fman_rxtx_node[2]; 114296177Sjhibbits char phy_type[6]; 115296177Sjhibbits 116296177Sjhibbits sc = device_get_softc(dev); 117296177Sjhibbits node = ofw_bus_get_node(dev); 118296177Sjhibbits 119296177Sjhibbits if (OF_getprop(node, "fsl,fman-mac", (void *)&enet_node, 120296177Sjhibbits sizeof(enet_node)) == -1) { 121296177Sjhibbits device_printf(dev, "Could not load fsl,fman-mac property " 122296177Sjhibbits "from DTS\n"); 123296177Sjhibbits return (ENXIO); 124296177Sjhibbits } 125296177Sjhibbits 126296177Sjhibbits enet_node = OF_instance_to_package(enet_node); 127296177Sjhibbits 128296177Sjhibbits if (OF_getprop(enet_node, "local-mac-address", 129296177Sjhibbits (void *)sc->sc_mac_addr, 6) == -1) { 130296177Sjhibbits if (device_get_unit(dev) != 0) { 131296177Sjhibbits device_printf(dev, 132296177Sjhibbits "Could not load local-mac-addr property " 133296177Sjhibbits "from DTS\n"); 134296177Sjhibbits return (ENXIO); 135296177Sjhibbits } 136296177Sjhibbits sc->sc_hidden = true; 137296177Sjhibbits } 138296177Sjhibbits 139296177Sjhibbits /* Get link speed */ 140296177Sjhibbits if (fdt_is_compatible(enet_node, "fsl,fman-1g-mac") != 0) 141296177Sjhibbits sc->sc_eth_dev_type = ETH_DTSEC; 142296177Sjhibbits else if (fdt_is_compatible(enet_node, "fsl,fman-10g-mac") != 0) 143296177Sjhibbits sc->sc_eth_dev_type = ETH_10GSEC; 144296177Sjhibbits else 145296177Sjhibbits return(ENXIO); 146296177Sjhibbits 147296177Sjhibbits /* Get MAC memory offset in SoC */ 148296177Sjhibbits if (OF_getprop(enet_node, "reg", (void *)&sc->sc_mac_mem_offset, 149296177Sjhibbits sizeof(sc->sc_mac_mem_offset)) <= 0) 150296177Sjhibbits return (ENXIO); 151296177Sjhibbits 152296177Sjhibbits /* Get PHY address */ 153296177Sjhibbits if (OF_getprop(enet_node, "phy-handle", (void *)&phy_node, 154296177Sjhibbits sizeof(phy_node)) <= 0) 155296177Sjhibbits return (ENXIO); 156296177Sjhibbits 157296177Sjhibbits phy_node = OF_instance_to_package(phy_node); 158296177Sjhibbits 159296177Sjhibbits if (OF_getprop(phy_node, "reg", (void *)&sc->sc_phy_addr, 160296177Sjhibbits sizeof(sc->sc_phy_addr)) <= 0) 161296177Sjhibbits return (ENXIO); 162296177Sjhibbits 163296177Sjhibbits /* Get PHY connection type */ 164296177Sjhibbits if (OF_getprop(enet_node, "phy-connection-type", (void *)phy_type, 165296177Sjhibbits sizeof(phy_type)) <= 0) 166296177Sjhibbits return (ENXIO); 167296177Sjhibbits 168296177Sjhibbits if (!strcmp(phy_type, "sgmii")) 169296177Sjhibbits sc->sc_mac_enet_mode = e_ENET_MODE_SGMII_1000; 170296177Sjhibbits else if (!strcmp(phy_type, "rgmii")) 171296177Sjhibbits sc->sc_mac_enet_mode = e_ENET_MODE_RGMII_1000; 172296177Sjhibbits else if (!strcmp(phy_type, "xgmii")) 173296177Sjhibbits /* We set 10 Gigabit mode flag however we don't support it */ 174296177Sjhibbits sc->sc_mac_enet_mode = e_ENET_MODE_XGMII_10000; 175296177Sjhibbits else 176296177Sjhibbits return (ENXIO); 177296177Sjhibbits 178296177Sjhibbits /* Get RX/TX port handles */ 179296177Sjhibbits if (OF_getprop(enet_node, "fsl,port-handles", (void *)fman_rxtx_node, 180296177Sjhibbits sizeof(fman_rxtx_node)) <= 0) 181296177Sjhibbits return (ENXIO); 182296177Sjhibbits 183296177Sjhibbits if (fman_rxtx_node[0] == 0) 184296177Sjhibbits return (ENXIO); 185296177Sjhibbits 186296177Sjhibbits if (fman_rxtx_node[1] == 0) 187296177Sjhibbits return (ENXIO); 188296177Sjhibbits 189296177Sjhibbits fman_rxtx_node[0] = OF_instance_to_package(fman_rxtx_node[0]); 190296177Sjhibbits fman_rxtx_node[1] = OF_instance_to_package(fman_rxtx_node[1]); 191296177Sjhibbits 192296177Sjhibbits if (fdt_is_compatible(fman_rxtx_node[0], "fsl,fman-port-1g-rx") == 0) 193296177Sjhibbits return (ENXIO); 194296177Sjhibbits 195296177Sjhibbits if (fdt_is_compatible(fman_rxtx_node[1], "fsl,fman-port-1g-tx") == 0) 196296177Sjhibbits return (ENXIO); 197296177Sjhibbits 198296177Sjhibbits /* Get RX port HW id */ 199296177Sjhibbits if (OF_getprop(fman_rxtx_node[0], "reg", (void *)&sc->sc_port_rx_hw_id, 200296177Sjhibbits sizeof(sc->sc_port_rx_hw_id)) <= 0) 201296177Sjhibbits return (ENXIO); 202296177Sjhibbits 203296177Sjhibbits /* Get TX port HW id */ 204296177Sjhibbits if (OF_getprop(fman_rxtx_node[1], "reg", (void *)&sc->sc_port_tx_hw_id, 205296177Sjhibbits sizeof(sc->sc_port_tx_hw_id)) <= 0) 206296177Sjhibbits return (ENXIO); 207296177Sjhibbits 208296177Sjhibbits /* Get QMan channel */ 209296177Sjhibbits if (OF_getprop(fman_rxtx_node[1], "fsl,qman-channel-id", 210296177Sjhibbits (void *)&sc->sc_port_tx_qman_chan, 211296177Sjhibbits sizeof(sc->sc_port_tx_qman_chan)) <= 0) 212296177Sjhibbits return (ENXIO); 213296177Sjhibbits 214296177Sjhibbits return (dtsec_attach(dev)); 215296177Sjhibbits} 216