if_fpa.c revision 119418
121826Sjoerg/*- 221826Sjoerg * Copyright (c) 1995, 1996 Matt Thomas <matt@3am-software.com> 321826Sjoerg * All rights reserved. 421826Sjoerg * 521826Sjoerg * Redistribution and use in source and binary forms, with or without 621826Sjoerg * modification, are permitted provided that the following conditions 721826Sjoerg * are met: 821826Sjoerg * 1. Redistributions of source code must retain the above copyright 921826Sjoerg * notice, this list of conditions and the following disclaimer. 1021826Sjoerg * 2. The name of the author may not be used to endorse or promote products 1197748Sschweikh * derived from this software without specific prior written permission 1221826Sjoerg * 1321826Sjoerg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1421826Sjoerg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1521826Sjoerg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1621826Sjoerg * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1721826Sjoerg * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 1821826Sjoerg * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1921826Sjoerg * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2021826Sjoerg * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2121826Sjoerg * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2221826Sjoerg * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2321826Sjoerg * 2421826Sjoerg * 2521826Sjoerg */ 2621826Sjoerg 27119418Sobrien#include <sys/cdefs.h> 28119418Sobrien__FBSDID("$FreeBSD: head/sys/dev/pdq/if_fpa.c 119418 2003-08-24 17:55:58Z obrien $"); 29119418Sobrien 3021826Sjoerg/* 3121826Sjoerg * DEC PDQ FDDI Controller; code for BSD derived operating systems 3221826Sjoerg * 3321826Sjoerg * This module supports the DEC DEFPA PCI FDDI Controller 3421826Sjoerg */ 3521826Sjoerg 3621826Sjoerg#include <sys/param.h> 3793383Smdodd#include <sys/systm.h> 3821826Sjoerg#include <sys/kernel.h> 3921826Sjoerg#include <sys/socket.h> 4021826Sjoerg 4193383Smdodd#include <sys/module.h> 4293383Smdodd#include <sys/bus.h> 4321826Sjoerg 4493383Smdodd#include <machine/bus_memio.h> 4593383Smdodd#include <machine/bus_pio.h> 4670594Speter#include <machine/bus.h> 4770594Speter#include <machine/resource.h> 4893383Smdodd#include <sys/rman.h> 4921826Sjoerg 5093383Smdodd#include <net/if.h> 5193383Smdodd#include <net/if_arp.h> 5293383Smdodd#include <net/if_media.h> 5393383Smdodd#include <net/fddi.h> 5421826Sjoerg 5593383Smdodd#include <dev/pci/pcivar.h> 5693383Smdodd#include <dev/pci/pcireg.h> 5793383Smdodd 5893383Smdodd#include <dev/pdq/pdq_freebsd.h> 5993383Smdodd#include <dev/pdq/pdqreg.h> 6093383Smdodd 6121826Sjoerg#define DEC_VENDORID 0x1011 6221826Sjoerg#define DEFPA_CHIPID 0x000F 6321826Sjoerg 6421826Sjoerg#define DEFPA_LATENCY 0x88 6521826Sjoerg 6621826Sjoerg#define PCI_CFLT 0x0C /* Configuration Latency */ 6721826Sjoerg#define PCI_CBMA 0x10 /* Configuration Base Memory Address */ 6821826Sjoerg#define PCI_CBIO 0x14 /* Configuration Base I/O Address */ 6921826Sjoerg 7093383Smdoddstatic int pdq_pci_probe (device_t); 7193383Smdoddstatic int pdq_pci_attach (device_t); 7293383Smdoddstatic int pdq_pci_detach (device_t); 7393383Smdoddstatic void pdq_pci_shutdown (device_t); 7493383Smdoddstatic void pdq_pci_ifintr (void *); 7593383Smdodd 7670594Speterstatic void 7770594Speterpdq_pci_ifintr(void *arg) 7821826Sjoerg{ 7993383Smdodd device_t dev; 8070594Speter pdq_softc_t *sc; 8121826Sjoerg 8293383Smdodd dev = (device_t)arg; 8393383Smdodd sc = device_get_softc(dev); 8493383Smdodd 8593383Smdodd PDQ_LOCK(sc); 8621826Sjoerg (void) pdq_interrupt(sc->sc_pdq); 8793383Smdodd PDQ_UNLOCK(sc); 8893383Smdodd 8993383Smdodd return; 9021826Sjoerg} 9121826Sjoerg 9221826Sjoerg/* 9370594Speter * This is the PCI configuration support. 9421826Sjoerg */ 9570594Speterstatic int 9670594Speterpdq_pci_probe(device_t dev) 9721826Sjoerg{ 9870594Speter if (pci_get_vendor(dev) == DEC_VENDORID && 9970594Speter pci_get_device(dev) == DEFPA_CHIPID) { 10070594Speter device_set_desc(dev, "Digital DEFPA PCI FDDI Controller"); 10193383Smdodd return (0); 10221826Sjoerg } 10393383Smdodd 10493383Smdodd return (ENXIO); 10521826Sjoerg} 10621826Sjoerg 10721826Sjoergstatic int 10870594Speterpdq_pci_attach(device_t dev) 10921826Sjoerg{ 11070594Speter pdq_softc_t *sc; 11193383Smdodd struct ifnet *ifp; 11293383Smdodd u_int32_t command; 11393383Smdodd int error; 11421826Sjoerg 11570594Speter sc = device_get_softc(dev); 11693383Smdodd ifp = &sc->arpcom.ac_if; 11721826Sjoerg 11893383Smdodd sc->dev = dev; 11993383Smdodd 12093383Smdodd /* 12193383Smdodd * Map control/status registers. 12293383Smdodd */ 12393383Smdodd pci_enable_busmaster(dev); 12493383Smdodd 12593383Smdodd command = pci_read_config(dev, PCIR_LATTIMER, 1); 12693383Smdodd if (command < DEFPA_LATENCY) { 12793383Smdodd command = DEFPA_LATENCY; 12893383Smdodd pci_write_config(dev, PCIR_LATTIMER, command, 1); 12993383Smdodd } 13093383Smdodd 13193383Smdodd sc->mem_rid = PCI_CBMA; 13293383Smdodd sc->mem_type = SYS_RES_MEMORY; 13393383Smdodd sc->mem = bus_alloc_resource(dev, sc->mem_type, &sc->mem_rid, 13493383Smdodd 0, ~0, 1, RF_ACTIVE); 13593383Smdodd if (!sc->mem) { 13693383Smdodd device_printf(dev, "Unable to allocate I/O space resource.\n"); 13793383Smdodd error = ENXIO; 13870594Speter goto bad; 13993383Smdodd } 14093383Smdodd sc->mem_bsh = rman_get_bushandle(sc->mem); 14193383Smdodd sc->mem_bst = rman_get_bustag(sc->mem); 14293383Smdodd 14393383Smdodd sc->irq_rid = 0; 14493383Smdodd sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid, 14593383Smdodd 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE); 14693383Smdodd if (!sc->irq) { 14793383Smdodd device_printf(dev, "Unable to allocate interrupt resource.\n"); 14893383Smdodd error = ENXIO; 14970594Speter goto bad; 15093383Smdodd } 15193383Smdodd 15293383Smdodd ifp->if_name = "fpa"; 15393383Smdodd ifp->if_unit = device_get_unit(dev); 15493383Smdodd 15593383Smdodd sc->sc_pdq = pdq_initialize(sc->mem_bst, sc->mem_bsh, 15693383Smdodd ifp->if_name, ifp->if_unit, 15793383Smdodd (void *)sc, PDQ_DEFPA); 15893383Smdodd if (sc->sc_pdq == NULL) { 15993383Smdodd device_printf(dev, "Initialization failed.\n"); 16093383Smdodd error = ENXIO; 16170594Speter goto bad; 16293383Smdodd } 16321826Sjoerg 16493383Smdodd error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET, 16593383Smdodd pdq_pci_ifintr, dev, &sc->irq_ih); 16693383Smdodd if (error) { 16793383Smdodd device_printf(dev, "Failed to setup interrupt handler.\n"); 16893383Smdodd error = ENXIO; 16993383Smdodd goto bad; 17093383Smdodd } 17193383Smdodd 17293383Smdodd bcopy((caddr_t) sc->sc_pdq->pdq_hwaddr.lanaddr_bytes, 17393383Smdodd (caddr_t) sc->arpcom.ac_enaddr, FDDI_ADDR_LEN); 17493383Smdodd pdq_ifattach(sc); 17593383Smdodd 17693383Smdodd return (0); 17770594Speterbad: 17893383Smdodd pdq_free(dev); 17993383Smdodd return (error); 18021826Sjoerg} 18121826Sjoerg 18293383Smdoddstatic int 18393383Smdoddpdq_pci_detach (dev) 18493383Smdodd device_t dev; 18593383Smdodd{ 18693383Smdodd pdq_softc_t *sc; 18793383Smdodd 18893383Smdodd sc = device_get_softc(dev); 18993383Smdodd pdq_ifdetach(sc); 19093383Smdodd 19193383Smdodd return (0); 19293383Smdodd} 19393383Smdodd 19421826Sjoergstatic void 19570594Speterpdq_pci_shutdown(device_t dev) 19621826Sjoerg{ 19770594Speter pdq_softc_t *sc; 19821826Sjoerg 19970594Speter sc = device_get_softc(dev); 20070594Speter pdq_hwreset(sc->sc_pdq); 20193383Smdodd 20293383Smdodd return; 20321826Sjoerg} 20421826Sjoerg 20570594Speterstatic device_method_t pdq_pci_methods[] = { 20670594Speter /* Device interface */ 20770594Speter DEVMETHOD(device_probe, pdq_pci_probe), 20870594Speter DEVMETHOD(device_attach, pdq_pci_attach), 20993383Smdodd DEVMETHOD(device_detach, pdq_pci_detach), 21070594Speter DEVMETHOD(device_shutdown, pdq_pci_shutdown), 21193383Smdodd 21270594Speter { 0, 0 } 21321826Sjoerg}; 21493383Smdodd 21570594Speterstatic driver_t pdq_pci_driver = { 21670594Speter "fpa", 21770594Speter pdq_pci_methods, 21870594Speter sizeof(pdq_softc_t), 21921826Sjoerg}; 22093383Smdodd 221113506SmdoddDRIVER_MODULE(fpa, pci, pdq_pci_driver, pdq_devclass, 0, 0); 222113506SmdoddMODULE_DEPEND(fpa, pci, 1, 1, 1); 223113506SmdoddMODULE_DEPEND(fpa, fddi, 1, 1, 1); 224