1256752Sbrooks/*- 2256752Sbrooks * Copyright (c) 2013 Bjoern A. Zeeb 3256752Sbrooks * All rights reserved. 4256752Sbrooks * 5256752Sbrooks * This software was developed by SRI International and the University of 6256752Sbrooks * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-11-C-0249) 7256752Sbrooks * ("MRC2"), as part of the DARPA MRC research programme. 8256752Sbrooks * 9256752Sbrooks * Redistribution and use in source and binary forms, with or without 10256752Sbrooks * modification, are permitted provided that the following conditions 11256752Sbrooks * are met: 12256752Sbrooks * 1. Redistributions of source code must retain the above copyright 13256752Sbrooks * notice, this list of conditions and the following disclaimer. 14256752Sbrooks * 2. Redistributions in binary form must reproduce the above copyright 15256752Sbrooks * notice, this list of conditions and the following disclaimer in the 16256752Sbrooks * documentation and/or other materials provided with the distribution. 17256752Sbrooks * 18256752Sbrooks * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19256752Sbrooks * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20256752Sbrooks * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21256752Sbrooks * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22256752Sbrooks * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23256752Sbrooks * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24256752Sbrooks * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25256752Sbrooks * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26256752Sbrooks * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27256752Sbrooks * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28256752Sbrooks * SUCH DAMAGE. 29256752Sbrooks */ 30256752Sbrooks 31256752Sbrooks#include <sys/cdefs.h> 32256752Sbrooks__FBSDID("$FreeBSD$"); 33256752Sbrooks 34256752Sbrooks#include <sys/param.h> 35256752Sbrooks#include <sys/bus.h> 36256752Sbrooks#include <sys/kernel.h> 37256752Sbrooks#include <sys/module.h> 38256752Sbrooks#include <sys/rman.h> 39256752Sbrooks#include <sys/socket.h> 40256752Sbrooks#include <sys/systm.h> 41256752Sbrooks 42256752Sbrooks#include <machine/bus.h> 43256752Sbrooks#include <machine/resource.h> 44256752Sbrooks 45256752Sbrooks#include <net/ethernet.h> 46256752Sbrooks#include <net/if.h> 47256752Sbrooks#include <net/if_media.h> 48256752Sbrooks 49256752Sbrooks#include <dev/mii/mii.h> 50256752Sbrooks#include <dev/mii/miivar.h> 51256752Sbrooks 52256752Sbrooks 53256752Sbrooks#include <dev/fdt/fdt_common.h> 54256752Sbrooks#include <dev/ofw/openfirm.h> 55256752Sbrooks#include <dev/ofw/ofw_bus.h> 56256752Sbrooks#include <dev/ofw/ofw_bus_subr.h> 57256752Sbrooks 58256752Sbrooks#include <dev/altera/atse/if_atsereg.h> 59256752Sbrooks 60256752Sbrooks/* "device miibus" required. See GENERIC if you get errors here. */ 61256752Sbrooks#include "miibus_if.h" 62256752Sbrooks 63256752Sbrooksstatic int 64256752Sbrooksatse_probe_fdt(device_t dev) 65256752Sbrooks{ 66256752Sbrooks 67266152Sian if (!ofw_bus_status_okay(dev)) 68266152Sian return (ENXIO); 69266152Sian 70256752Sbrooks if (ofw_bus_is_compatible(dev, "altera,atse")) { 71256752Sbrooks device_set_desc(dev, "Altera Triple-Speed Ethernet MegaCore"); 72256752Sbrooks return (BUS_PROBE_DEFAULT); 73256752Sbrooks } 74256752Sbrooks return (ENXIO); 75256752Sbrooks} 76256752Sbrooks 77256752Sbrooksstatic int 78256752Sbrooksatse_attach_fdt(device_t dev) 79256752Sbrooks{ 80256752Sbrooks struct atse_softc *sc; 81256752Sbrooks int error; 82256752Sbrooks 83256752Sbrooks sc = device_get_softc(dev); 84256752Sbrooks sc->atse_dev = dev; 85256752Sbrooks sc->atse_unit = device_get_unit(dev); 86256752Sbrooks 87256752Sbrooks /* 88256752Sbrooks * FDT has the list of our resources. Given we are using multiple 89256752Sbrooks * memory regions and possibly multiple interrupts, we need to attach 90256752Sbrooks * them in the order specified in .dts: 91256752Sbrooks * MAC, RX and RXC FIFO, TX and TXC FIFO; RX INTR, TX INTR. 92256752Sbrooks */ 93256752Sbrooks 94256752Sbrooks /* MAC: Avalon-MM, atse management register region. */ 95256752Sbrooks sc->atse_mem_rid = 0; 96256752Sbrooks sc->atse_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 97256752Sbrooks &sc->atse_mem_rid, RF_ACTIVE); 98256752Sbrooks if (sc->atse_mem_res == NULL) { 99256752Sbrooks device_printf(dev, "failed to map memory for ctrl region\n"); 100256752Sbrooks error = ENXIO; 101256752Sbrooks goto err; 102256752Sbrooks } 103256752Sbrooks if (bootverbose) 104256752Sbrooks device_printf(sc->atse_dev, "MAC ctrl region at mem %p-%p\n", 105256752Sbrooks (void *)rman_get_start(sc->atse_mem_res), 106256752Sbrooks (void *)(rman_get_start(sc->atse_mem_res) + 107256752Sbrooks rman_get_size(sc->atse_mem_res))); 108256752Sbrooks 109256752Sbrooks /* 110256752Sbrooks * RX and RXC FIFO memory regions. 111256752Sbrooks * 0x00: 2 * 32bit FIFO data, 112256752Sbrooks * 0x20: 8 * 32bit FIFO ctrl, Avalon-ST Sink to Avalon-MM R-Slave. 113256752Sbrooks */ 114256752Sbrooks sc->atse_rx_mem_rid = 1; 115256752Sbrooks sc->atse_rx_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 116256752Sbrooks &sc->atse_rx_mem_rid, RF_ACTIVE); 117256752Sbrooks if (sc->atse_rx_mem_res == NULL) { 118256752Sbrooks device_printf(dev, "failed to map memory for RX FIFO\n"); 119256752Sbrooks error = ENXIO; 120256752Sbrooks goto err; 121256752Sbrooks } 122256752Sbrooks if (bootverbose) 123256752Sbrooks device_printf(sc->atse_dev, "RX FIFO at mem %p-%p\n", 124256752Sbrooks (void *)rman_get_start(sc->atse_rx_mem_res), 125256752Sbrooks (void *)(rman_get_start(sc->atse_rx_mem_res) + 126256752Sbrooks rman_get_size(sc->atse_rx_mem_res))); 127256752Sbrooks 128256752Sbrooks sc->atse_rxc_mem_rid = 2; 129256752Sbrooks sc->atse_rxc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 130256752Sbrooks &sc->atse_rxc_mem_rid, RF_ACTIVE); 131256752Sbrooks if (sc->atse_rxc_mem_res == NULL) { 132256752Sbrooks device_printf(dev, "failed to map memory for RXC FIFO\n"); 133256752Sbrooks error = ENXIO; 134256752Sbrooks goto err; 135256752Sbrooks } 136256752Sbrooks if (bootverbose) 137256752Sbrooks device_printf(sc->atse_dev, "RXC FIFO at mem %p-%p\n", 138256752Sbrooks (void *)rman_get_start(sc->atse_rxc_mem_res), 139256752Sbrooks (void *)(rman_get_start(sc->atse_rxc_mem_res) + 140256752Sbrooks rman_get_size(sc->atse_rxc_mem_res))); 141256752Sbrooks 142256752Sbrooks /* 143256752Sbrooks * TX and TXC FIFO memory regions. 144256752Sbrooks * 0x00: 2 * 32bit FIFO data, 145256752Sbrooks * 0x20: 8 * 32bit FIFO ctrl, Avalon-MM W-Slave to Avalon-ST Source. 146256752Sbrooks */ 147256752Sbrooks sc->atse_tx_mem_rid = 3; 148256752Sbrooks sc->atse_tx_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 149256752Sbrooks &sc->atse_tx_mem_rid, RF_ACTIVE); 150256752Sbrooks if (sc->atse_tx_mem_res == NULL) { 151256752Sbrooks device_printf(dev, "failed to map memory for TX FIFO\n"); 152256752Sbrooks error = ENXIO; 153256752Sbrooks goto err; 154256752Sbrooks } 155256752Sbrooks if (bootverbose) 156256752Sbrooks device_printf(sc->atse_dev, "TX FIFO at mem %p-%p\n", 157256752Sbrooks (void *)rman_get_start(sc->atse_tx_mem_res), 158256752Sbrooks (void *)(rman_get_start(sc->atse_tx_mem_res) + 159256752Sbrooks rman_get_size(sc->atse_tx_mem_res))); 160256752Sbrooks 161256752Sbrooks sc->atse_txc_mem_rid = 4; 162256752Sbrooks sc->atse_txc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 163256752Sbrooks &sc->atse_txc_mem_rid, RF_ACTIVE); 164256752Sbrooks if (sc->atse_txc_mem_res == NULL) { 165256752Sbrooks device_printf(dev, "failed to map memory for TXC FIFO\n"); 166256752Sbrooks error = ENXIO; 167256752Sbrooks goto err; 168256752Sbrooks } 169256752Sbrooks if (bootverbose) 170256752Sbrooks device_printf(sc->atse_dev, "TXC FIFO at mem %p-%p\n", 171256752Sbrooks (void *)rman_get_start(sc->atse_txc_mem_res), 172256752Sbrooks (void *)(rman_get_start(sc->atse_txc_mem_res) + 173256752Sbrooks rman_get_size(sc->atse_txc_mem_res))); 174256752Sbrooks 175256752Sbrooks /* (Optional) RX and TX IRQ. */ 176256752Sbrooks sc->atse_rx_irq_rid = 0; 177256752Sbrooks sc->atse_rx_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, 178256752Sbrooks &sc->atse_rx_irq_rid, RF_ACTIVE | RF_SHAREABLE); 179256752Sbrooks sc->atse_tx_irq_rid = 1; 180256752Sbrooks sc->atse_tx_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, 181256752Sbrooks &sc->atse_tx_irq_rid, RF_ACTIVE | RF_SHAREABLE); 182256752Sbrooks 183256752Sbrooks error = atse_attach(dev); 184256752Sbrooks if (error) 185256752Sbrooks goto err; 186256752Sbrooks 187256752Sbrooks return (0); 188256752Sbrooks 189256752Sbrookserr: 190256752Sbrooks /* Cleanup. */ 191256752Sbrooks atse_detach_resources(dev); 192256752Sbrooks 193256752Sbrooks return (error); 194256752Sbrooks} 195256752Sbrooks 196256752Sbrooksstatic device_method_t atse_methods_fdt[] = { 197256752Sbrooks /* Device interface */ 198256752Sbrooks DEVMETHOD(device_probe, atse_probe_fdt), 199256752Sbrooks DEVMETHOD(device_attach, atse_attach_fdt), 200256752Sbrooks DEVMETHOD(device_detach, atse_detach_dev), 201256752Sbrooks 202256752Sbrooks /* MII interface */ 203256752Sbrooks DEVMETHOD(miibus_readreg, atse_miibus_readreg), 204256752Sbrooks DEVMETHOD(miibus_writereg, atse_miibus_writereg), 205256752Sbrooks DEVMETHOD(miibus_statchg, atse_miibus_statchg), 206256752Sbrooks 207256752Sbrooks DEVMETHOD_END 208256752Sbrooks}; 209256752Sbrooks 210256752Sbrooksstatic driver_t atse_driver_fdt = { 211256752Sbrooks "atse", 212256752Sbrooks atse_methods_fdt, 213256752Sbrooks sizeof(struct atse_softc) 214256752Sbrooks}; 215256752Sbrooks 216256752SbrooksDRIVER_MODULE(atse, simplebus, atse_driver_fdt, atse_devclass, 0, 0); 217256752SbrooksDRIVER_MODULE(miibus, atse, miibus_driver, miibus_devclass, 0, 0); 218256752Sbrooks 219256752Sbrooks/* end */ 220