root/dev/eisa/if_fea.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pdq_eisa_subprobe
  2. pdq_eisa_devinit
  3. pdq_eisa_match
  4. pdq_eisa_attach

    1 /*      $OpenBSD: if_fea.c,v 1.17 2004/05/12 06:35:10 tedu Exp $        */
    2 /*      $NetBSD: if_fea.c,v 1.9 1996/10/21 22:31:05 thorpej Exp $       */
    3 
    4 /*-
    5  * Copyright (c) 1995, 1996 Matt Thomas <matt@3am-software.com>
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. The name of the author may not be used to endorse or promote products
   14  *    derived from this software without specific prior written permission
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   26  *
   27  * Id: if_fea.c,v 1.6 1996/06/07 20:02:25 thomas Exp
   28  */
   29 
   30 /*
   31  * DEC PDQ FDDI Controller
   32  *
   33  *      This module support the DEFEA EISA FDDI Controller.
   34  */
   35 
   36 
   37 #include <sys/param.h>
   38 #include <sys/kernel.h>
   39 #include <sys/mbuf.h>
   40 #include <sys/protosw.h>
   41 #include <sys/socket.h>
   42 #include <sys/ioctl.h>
   43 #include <sys/errno.h>
   44 #include <sys/malloc.h>
   45 #include <sys/device.h>
   46 
   47 #include <net/if.h>
   48 #include <net/if_types.h>
   49 #include <net/if_dl.h>
   50 #include <net/route.h>
   51 
   52 #include "bpfilter.h"
   53 #if NBPFILTER > 0
   54 #include <net/bpf.h>
   55 #endif
   56 
   57 #ifdef INET
   58 #include <netinet/in.h>
   59 #include <netinet/in_systm.h>
   60 #include <netinet/in_var.h>
   61 #include <netinet/ip.h>
   62 #include <netinet/if_ether.h>
   63 #endif
   64 
   65 #include <net/if_fddi.h>
   66 
   67 #include <machine/cpu.h>
   68 #include <machine/bus.h>
   69 
   70 #include <dev/ic/pdqvar.h>
   71 #include <dev/ic/pdqreg.h>
   72 
   73 #include <dev/eisa/eisareg.h>
   74 #include <dev/eisa/eisavar.h>
   75 #include <dev/eisa/eisadevs.h>
   76 
   77 /*
   78  *
   79  */
   80 
   81 void pdq_eisa_subprobe(bus_space_tag_t, bus_space_handle_t,
   82     u_int32_t *, u_int32_t *, u_int32_t *);
   83 void pdq_eisa_devinit(pdq_softc_t *);
   84 int pdq_eisa_match(struct device *, void *, void *);
   85 void pdq_eisa_attach(struct device *, struct device *, void *);
   86 
   87 #define DEFEA_INTRENABLE                0x8     /* level interrupt */
   88 static int pdq_eisa_irqs[4] = { 9, 10, 11, 15 };
   89 
   90 void
   91 pdq_eisa_subprobe(bc, iobase, maddr, msize, irq)
   92         bus_space_tag_t bc;
   93         bus_space_handle_t iobase;
   94         u_int32_t *maddr;
   95         u_int32_t *msize;
   96         u_int32_t *irq;
   97 {
   98         if (irq != NULL)
   99                 *irq = pdq_eisa_irqs[PDQ_OS_IORD_8(bc, iobase,
  100                     PDQ_EISA_IO_CONFIG_STAT_0) & 3];
  101 
  102         *maddr = (PDQ_OS_IORD_8(bc, iobase, PDQ_EISA_MEM_ADD_CMP_0) << 8)
  103             | (PDQ_OS_IORD_8(bc, iobase, PDQ_EISA_MEM_ADD_CMP_1) << 16);
  104         *msize = (PDQ_OS_IORD_8(bc, iobase, PDQ_EISA_MEM_ADD_MASK_0) + 4) << 8;
  105 }
  106 
  107 void
  108 pdq_eisa_devinit(sc)
  109         pdq_softc_t *sc;
  110 {
  111         u_int8_t data;
  112         bus_space_tag_t tag;
  113 
  114         tag = sc->sc_bc;
  115 
  116         /*
  117          * Do the standard initialization for the DEFEA registers.
  118          */
  119         PDQ_OS_IOWR_8(tag, sc->sc_iobase, PDQ_EISA_FUNCTION_CTRL, 0x23);
  120         PDQ_OS_IOWR_8(tag, sc->sc_iobase, PDQ_EISA_IO_CMP_1_1,
  121             (sc->sc_iobase >> 8) & 0xF0);
  122         PDQ_OS_IOWR_8(tag, sc->sc_iobase, PDQ_EISA_IO_CMP_0_1,
  123             (sc->sc_iobase >> 8) & 0xF0);
  124         PDQ_OS_IOWR_8(tag, sc->sc_iobase, PDQ_EISA_SLOT_CTRL, 0x01);
  125         data = PDQ_OS_IORD_8(tag, sc->sc_iobase, PDQ_EISA_BURST_HOLDOFF);
  126 #if defined(PDQ_IOMAPPED)
  127         PDQ_OS_IOWR_8(tag, sc->sc_iobase, PDQ_EISA_BURST_HOLDOFF, data & ~1);
  128 #else
  129         PDQ_OS_IOWR_8(tag, sc->sc_iobase, PDQ_EISA_BURST_HOLDOFF, data | 1);
  130 #endif
  131         data = PDQ_OS_IORD_8(tag, sc->sc_iobase, PDQ_EISA_IO_CONFIG_STAT_0);
  132         PDQ_OS_IOWR_8(tag, sc->sc_iobase, PDQ_EISA_IO_CONFIG_STAT_0,
  133             data | DEFEA_INTRENABLE);
  134 }
  135 
  136 int
  137 pdq_eisa_match(parent, match, aux)
  138         struct device *parent;
  139         void *match;
  140         void *aux;
  141 {
  142         struct eisa_attach_args *ea = (struct eisa_attach_args *) aux;
  143 
  144         if (strncmp(ea->ea_idstring, "DEC300", 6) == 0)
  145                 return (1);
  146         return (0);
  147 }
  148 
  149 void
  150 pdq_eisa_attach(parent, self, aux)
  151         struct device *parent;
  152         struct device *self;
  153         void *aux;
  154 {
  155         pdq_softc_t *sc = (pdq_softc_t *) self;
  156         struct eisa_attach_args *ea = (struct eisa_attach_args *) aux;
  157         u_int32_t irq, maddr, msize;
  158         eisa_intr_handle_t ih;
  159         const char *intrstr;
  160 
  161         sc->sc_iotag = ea->ea_iot;
  162         bcopy(sc->sc_dev.dv_xname, sc->sc_if.if_xname, IFNAMSIZ);
  163         sc->sc_if.if_flags = 0;
  164         sc->sc_if.if_softc = sc;
  165 
  166         /*
  167          * NOTE: sc_bc is an alias for sc_csrtag and sc_membase is
  168          * an alias for sc_csrhandle.  sc_iobase is used here to
  169          * check the card's configuration.
  170          */
  171 
  172         if (bus_space_map(sc->sc_iotag, EISA_SLOT_ADDR(ea->ea_slot),
  173             EISA_SLOT_SIZE, 0, &sc->sc_iobase)) {
  174                 printf("\n%s: failed to map I/O!\n", sc->sc_dev.dv_xname);
  175                 return;
  176         }
  177 
  178         pdq_eisa_subprobe(sc->sc_iotag, sc->sc_iobase, &maddr, &msize, &irq);
  179 
  180 #if defined(PDQ_IOMAPPED)
  181         sc->sc_csrtag = sc->sc_iotag;
  182         sc->sc_csrhandle = sc->sc_iobase;
  183 #else
  184         if (maddr == 0 || msize == 0) {
  185                 printf("\n%s: error: memory not enabled! ECU reconfiguration"
  186                     " required\n", sc->sc_dev.dv_xname);
  187                 return;
  188         }
  189 
  190         if (bus_space_map(sc->sc_csrtag, maddr, msize, 0, &sc->sc_csrhandle)) {
  191                 bus_space_unmap(sc->sc_iotag, sc->sc_iobase, EISA_SLOT_SIZE);
  192                 printf("\n%s: failed to map memory (0x%x-0x%x)!\n",
  193                     sc->sc_dev.dv_xname, maddr, maddr + msize - 1);
  194                 return;
  195         }
  196 #endif
  197         pdq_eisa_devinit(sc);
  198         sc->sc_pdq = pdq_initialize(sc->sc_bc, sc->sc_membase,
  199             sc->sc_if.if_xname, 0, (void *) sc, PDQ_DEFEA);
  200         if (sc->sc_pdq == NULL) {
  201                 printf("%s: initialization failed\n", sc->sc_dev.dv_xname);
  202                 return;
  203         }
  204 
  205         if (eisa_intr_map(ea->ea_ec, irq, &ih)) {
  206                 printf("%s: couldn't map interrupt (%d)\n",
  207                     sc->sc_dev.dv_xname, irq);
  208                 return;
  209         }
  210         intrstr = eisa_intr_string(ea->ea_ec, ih);
  211         sc->sc_ih = eisa_intr_establish(ea->ea_ec, ih, IST_LEVEL, IPL_NET,
  212             (int (*)(void *)) pdq_interrupt, sc->sc_pdq, sc->sc_dev.dv_xname);
  213         if (sc->sc_ih == NULL) {
  214                 printf("%s: couldn't establish interrupt", sc->sc_dev.dv_xname);
  215                 if (intrstr != NULL)
  216                         printf(" at %s", intrstr);
  217                 printf("\n");
  218                 return;
  219         }
  220         if (intrstr != NULL)
  221                 printf(": interrupting at %s\n", intrstr);
  222 
  223         bcopy((caddr_t) sc->sc_pdq->pdq_hwaddr.lanaddr_bytes,
  224             sc->sc_arpcom.ac_enaddr, 6);
  225 
  226         pdq_ifattach(sc, NULL);
  227 
  228         sc->sc_ats = shutdownhook_establish((void (*)(void *)) pdq_hwreset,
  229             sc->sc_pdq);
  230         if (sc->sc_ats == NULL)
  231                 printf("%s: warning: couldn't establish shutdown hook\n",
  232                     self->dv_xname);
  233 #if !defined(PDQ_IOMAPPED)
  234         printf("%s: using iomem 0x%x-0x%x\n", sc->sc_dev.dv_xname, maddr,
  235             maddr + msize - 1);
  236 #endif
  237 }
  238 
  239 struct cfattach fea_ca = {
  240         sizeof(pdq_softc_t), pdq_eisa_match, pdq_eisa_attach
  241 };
  242 
  243 struct cfdriver fea_cd = {
  244         0, "fea", DV_IFNET
  245 };

/* [<][>][^][v][top][bottom][index][help] */