1264601Sbz/*- 2264601Sbz * Copyright (c) 2013-2014 Bjoern A. Zeeb 3264601Sbz * All rights reserved. 4264601Sbz * 5264601Sbz * This software was developed by SRI International and the University of 6264601Sbz * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-11-C-0249 7264601Sbz * ("MRC2"), as part of the DARPA MRC research programme. 8264601Sbz * 9264601Sbz * Redistribution and use in source and binary forms, with or without 10264601Sbz * modification, are permitted provided that the following conditions 11264601Sbz * are met: 12264601Sbz * 1. Redistributions of source code must retain the above copyright 13264601Sbz * notice, this list of conditions and the following disclaimer. 14264601Sbz * 2. Redistributions in binary form must reproduce the above copyright 15264601Sbz * notice, this list of conditions and the following disclaimer in the 16264601Sbz * documentation and/or other materials provided with the distribution. 17264601Sbz * 18264601Sbz * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19264601Sbz * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20264601Sbz * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21264601Sbz * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22264601Sbz * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23264601Sbz * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24264601Sbz * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25264601Sbz * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26264601Sbz * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27264601Sbz * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28264601Sbz * SUCH DAMAGE. 29264601Sbz * 30264601Sbz * This driver is modelled after atse(4). We need to seriously reduce the 31264601Sbz * per-driver code we have to write^wcopy & paste. 32264601Sbz */ 33264601Sbz 34264601Sbz#include <sys/cdefs.h> 35264601Sbz__FBSDID("$FreeBSD: releng/10.2/sys/dev/netfpga10g/nf10bmac/if_nf10bmac_fdt.c 270061 2014-08-16 14:30:46Z bz $"); 36264601Sbz 37264601Sbz#include <sys/param.h> 38264601Sbz#include <sys/bus.h> 39264601Sbz#include <sys/kernel.h> 40264601Sbz#include <sys/module.h> 41264601Sbz#include <sys/rman.h> 42264601Sbz#include <sys/socket.h> 43264601Sbz#include <sys/systm.h> 44264601Sbz 45264601Sbz#include <machine/bus.h> 46264601Sbz#include <machine/resource.h> 47264601Sbz 48264601Sbz#include <net/ethernet.h> 49264601Sbz#include <net/if.h> 50264601Sbz#include <net/if_media.h> 51264601Sbz#include <net/if_var.h> 52264601Sbz 53264601Sbz#include <dev/fdt/fdt_common.h> 54264601Sbz#include <dev/ofw/openfirm.h> 55264601Sbz#include <dev/ofw/ofw_bus.h> 56264601Sbz#include <dev/ofw/ofw_bus_subr.h> 57264601Sbz 58264601Sbz#include "if_nf10bmacreg.h" 59264601Sbz 60264601Sbzstatic int 61264601Sbznf10bmac_probe_fdt(device_t dev) 62264601Sbz{ 63264601Sbz 64264601Sbz if (!ofw_bus_status_okay(dev)) 65264601Sbz return (ENXIO); 66264601Sbz 67264601Sbz if (ofw_bus_is_compatible(dev, "netfpag10g,nf10bmac")) { 68264601Sbz device_set_desc(dev, "NetFPGA-10G Embedded CPU Ethernet Core"); 69264601Sbz return (BUS_PROBE_DEFAULT); 70264601Sbz } 71264601Sbz 72264601Sbz return (ENXIO); 73264601Sbz} 74264601Sbz 75264601Sbzstatic int 76264601Sbznf10bmac_attach_fdt(device_t dev) 77264601Sbz{ 78264601Sbz struct nf10bmac_softc *sc; 79264601Sbz int error; 80264601Sbz 81264601Sbz sc = device_get_softc(dev); 82264601Sbz sc->nf10bmac_dev = dev; 83264601Sbz sc->nf10bmac_unit = device_get_unit(dev); 84264601Sbz 85264601Sbz /* 86264601Sbz * FDT lists our resources. For convenience we use three different 87264601Sbz * mappings. We need to attach them in the oder specified in .dts: 88270061Sbz * LOOP (size 0x1f), TX (0x2f), RX (0x2f), INTR (0xf). 89264601Sbz */ 90264601Sbz 91270061Sbz /* 92270061Sbz * LOOP memory region (this could be a general control region). 93270061Sbz * 0x00: 32/64bit register to enable a Y-"lopback". 94270061Sbz */ 95270061Sbz sc->nf10bmac_ctrl_rid = 0; 96270061Sbz sc->nf10bmac_ctrl_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 97270061Sbz &sc->nf10bmac_ctrl_rid, RF_ACTIVE); 98270061Sbz if (sc->nf10bmac_ctrl_res == NULL) { 99270061Sbz device_printf(dev, "failed to map memory for CTRL region\n"); 100270061Sbz error = ENXIO; 101270061Sbz goto err; 102270061Sbz } 103270061Sbz if (bootverbose) 104270061Sbz device_printf(sc->nf10bmac_dev, "CTRL region at mem %p-%p\n", 105270061Sbz (void *)rman_get_start(sc->nf10bmac_ctrl_res), 106270061Sbz (void *)(rman_get_start(sc->nf10bmac_ctrl_res) + 107270061Sbz rman_get_size(sc->nf10bmac_ctrl_res))); 108270061Sbz 109264601Sbz /* 110264601Sbz * TX and TX metadata FIFO memory region. 111270061Sbz * 0x00: 32/64bit FIFO data, 112270061Sbz * 0x08: 32/64bit FIFO metadata, 113270061Sbz * 0x10: 32/64bit packet length. 114264601Sbz */ 115270061Sbz sc->nf10bmac_tx_mem_rid = 1; 116264601Sbz sc->nf10bmac_tx_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 117264601Sbz &sc->nf10bmac_tx_mem_rid, RF_ACTIVE); 118264601Sbz if (sc->nf10bmac_tx_mem_res == NULL) { 119264601Sbz device_printf(dev, "failed to map memory for TX FIFO\n"); 120264601Sbz error = ENXIO; 121264601Sbz goto err; 122264601Sbz } 123264601Sbz if (bootverbose) 124264601Sbz device_printf(sc->nf10bmac_dev, "TX FIFO at mem %p-%p\n", 125264601Sbz (void *)rman_get_start(sc->nf10bmac_tx_mem_res), 126264601Sbz (void *)(rman_get_start(sc->nf10bmac_tx_mem_res) + 127264601Sbz rman_get_size(sc->nf10bmac_tx_mem_res))); 128264601Sbz 129264601Sbz /* 130264601Sbz * RX and RXC metadata FIFO memory region. 131270061Sbz * 0x00: 32/64bit FIFO data, 132270061Sbz * 0x08: 32/64bit FIFO metadata, 133270061Sbz * 0x10: 32/64bit packet length. 134264601Sbz */ 135270061Sbz sc->nf10bmac_rx_mem_rid = 2; 136264601Sbz sc->nf10bmac_rx_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 137264601Sbz &sc->nf10bmac_rx_mem_rid, RF_ACTIVE); 138264601Sbz if (sc->nf10bmac_rx_mem_res == NULL) { 139264601Sbz device_printf(dev, "failed to map memory for RX FIFO\n"); 140264601Sbz error = ENXIO; 141264601Sbz goto err; 142264601Sbz } 143264601Sbz if (bootverbose) 144264601Sbz device_printf(sc->nf10bmac_dev, "RX FIFO at mem %p-%p\n", 145264601Sbz (void *)rman_get_start(sc->nf10bmac_rx_mem_res), 146264601Sbz (void *)(rman_get_start(sc->nf10bmac_rx_mem_res) + 147264601Sbz rman_get_size(sc->nf10bmac_rx_mem_res))); 148264601Sbz 149264601Sbz /* 150270061Sbz * Interrupt handling registers. 151270061Sbz * 0x00: 32/64bit register to clear (and disable) the RX interrupt. 152270061Sbz * 0x08: 32/64bit register to enable or disable the RX interrupt. 153264601Sbz */ 154270061Sbz sc->nf10bmac_intr_rid = 3; 155270061Sbz sc->nf10bmac_intr_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 156270061Sbz &sc->nf10bmac_intr_rid, RF_ACTIVE); 157270061Sbz if (sc->nf10bmac_intr_res == NULL) { 158270061Sbz device_printf(dev, "failed to map memory for INTR region\n"); 159264601Sbz error = ENXIO; 160264601Sbz goto err; 161264601Sbz } 162264601Sbz if (bootverbose) 163270061Sbz device_printf(sc->nf10bmac_dev, "INTR region at mem %p-%p\n", 164270061Sbz (void *)rman_get_start(sc->nf10bmac_intr_res), 165270061Sbz (void *)(rman_get_start(sc->nf10bmac_intr_res) + 166270061Sbz rman_get_size(sc->nf10bmac_intr_res))); 167264601Sbz 168270061Sbz /* (Optional) RX and TX IRQ. */ 169270061Sbz sc->nf10bmac_rx_irq_rid = 0; 170270061Sbz sc->nf10bmac_rx_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, 171270061Sbz &sc->nf10bmac_rx_irq_rid, RF_ACTIVE | RF_SHAREABLE); 172270061Sbz 173264601Sbz error = nf10bmac_attach(dev); 174264601Sbz if (error) 175264601Sbz goto err; 176264601Sbz 177264601Sbz return (0); 178264601Sbz 179264601Sbzerr: 180264601Sbz /* Cleanup. */ 181264601Sbz nf10bmac_detach_resources(dev); 182264601Sbz 183264601Sbz return (error); 184264601Sbz} 185264601Sbz 186264601Sbzstatic device_method_t nf10bmac_methods_fdt[] = { 187264601Sbz /* Device interface */ 188264601Sbz DEVMETHOD(device_probe, nf10bmac_probe_fdt), 189264601Sbz DEVMETHOD(device_attach, nf10bmac_attach_fdt), 190264601Sbz DEVMETHOD(device_detach, nf10bmac_detach_dev), 191264601Sbz 192264601Sbz DEVMETHOD_END 193264601Sbz}; 194264601Sbz 195264601Sbzstatic driver_t nf10bmac_driver_fdt = { 196264601Sbz "nf10bmac", 197264601Sbz nf10bmac_methods_fdt, 198264601Sbz sizeof(struct nf10bmac_softc) 199264601Sbz}; 200264601Sbz 201264601SbzDRIVER_MODULE(nf10bmac, simplebus, nf10bmac_driver_fdt, nf10bmac_devclass, 0,0); 202264601Sbz 203264601Sbz/* end */ 204