The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/mvme/if_ie_mvme.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: if_ie_mvme.c,v 1.6 2003/07/14 15:47:19 lukem Exp $     */
    2 
    3 /*-
    4  * Copyright (c) 1999, 2002 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Steve C. Woodford.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *      This product includes software developed by the NetBSD
   21  *      Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 #include <sys/cdefs.h>
   40 __KERNEL_RCSID(0, "$NetBSD: if_ie_mvme.c,v 1.6 2003/07/14 15:47:19 lukem Exp $");
   41 
   42 #include <sys/param.h>
   43 #include <sys/systm.h>
   44 #include <sys/mbuf.h>
   45 #include <sys/errno.h>
   46 #include <sys/device.h>
   47 #include <sys/protosw.h>
   48 #include <sys/socket.h>
   49 
   50 #include <net/if.h>
   51 #include <net/if_dl.h>
   52 #include <net/if_types.h>
   53 #include <net/if_ether.h>
   54 #include <net/if_media.h>
   55 
   56 #include <uvm/uvm_extern.h>
   57 
   58 #include <machine/autoconf.h>
   59 #include <machine/cpu.h>
   60 #include <machine/bus.h>
   61 
   62 #include <dev/ic/i82586reg.h>
   63 #include <dev/ic/i82586var.h>
   64 
   65 #include <dev/mvme/if_iereg.h>
   66 #include <dev/mvme/pcctwovar.h>
   67 #include <dev/mvme/pcctworeg.h>
   68 
   69 
   70 int ie_pcctwo_match __P((struct device *, struct cfdata *, void *));
   71 void ie_pcctwo_attach __P((struct device *, struct device *, void *));
   72 
   73 struct ie_pcctwo_softc {
   74         struct ie_softc ps_ie;
   75         bus_space_tag_t ps_bust;
   76         bus_space_handle_t ps_bush;
   77         struct evcnt ps_evcnt;
   78 };
   79 
   80 CFATTACH_DECL(ie_pcctwo, sizeof(struct ie_pcctwo_softc),
   81     ie_pcctwo_match, ie_pcctwo_attach, NULL, NULL);
   82 
   83 extern struct cfdriver ie_cd;
   84 
   85 
   86 /* Functions required by the i82586 MI driver */
   87 static void ie_reset __P((struct ie_softc *, int));
   88 static int ie_intrhook __P((struct ie_softc *, int));
   89 static void ie_hwinit __P((struct ie_softc *));
   90 static void ie_atten __P((struct ie_softc *, int));
   91 
   92 static void ie_copyin __P((struct ie_softc *, void *, int, size_t));
   93 static void ie_copyout __P((struct ie_softc *, const void *, int, size_t));
   94 
   95 static u_int16_t ie_read_16 __P((struct ie_softc *, int));
   96 static void ie_write_16 __P((struct ie_softc *, int, u_int16_t));
   97 static void ie_write_24 __P((struct ie_softc *, int, int));
   98 
   99 /*
  100  * i82596 Support Routines for MVME1[67][27] and MVME187 Boards
  101  */
  102 static void
  103 ie_reset(sc, why)
  104         struct ie_softc *sc;
  105         int why;
  106 {
  107         struct ie_pcctwo_softc *ps;
  108         u_int32_t scp_addr;
  109 
  110         ps = (struct ie_pcctwo_softc *) sc;
  111 
  112         switch (why) {
  113         case CHIP_PROBE:
  114         case CARD_RESET:
  115                 bus_space_write_2(ps->ps_bust, ps->ps_bush, IE_MPUREG_UPPER,
  116                     IE_PORT_RESET);
  117                 bus_space_write_2(ps->ps_bust, ps->ps_bush, IE_MPUREG_LOWER, 0);
  118                 delay(1000);
  119 
  120                 /*
  121                  * Set the BUSY and BUS_USE bytes here, since the MI code
  122                  * incorrectly assumes it can use byte addressing to set it.
  123                  * (due to wrong-endianess of the chip)
  124                  */
  125                 ie_write_16(sc, IE_ISCP_BUSY(sc->iscp), 1);
  126                 ie_write_16(sc, IE_SCP_BUS_USE(sc->scp), IE_BUS_USE);
  127 
  128                 scp_addr = sc->scp + (u_int) sc->sc_iobase;
  129                 scp_addr |= IE_PORT_ALT_SCP;
  130 
  131                 bus_space_write_2(ps->ps_bust, ps->ps_bush, IE_MPUREG_UPPER,
  132                     scp_addr & 0xffff);
  133                 bus_space_write_2(ps->ps_bust, ps->ps_bush, IE_MPUREG_LOWER,
  134                     (scp_addr >> 16) & 0xffff);
  135                 delay(1000);
  136                 break;
  137         }
  138 }
  139 
  140 /* ARGSUSED */
  141 static int
  142 ie_intrhook(sc, when)
  143         struct ie_softc *sc;
  144         int when;
  145 {
  146         struct ie_pcctwo_softc *ps;
  147         u_int8_t reg;
  148 
  149         ps = (struct ie_pcctwo_softc *) sc;
  150 
  151         if (when == INTR_EXIT) {
  152                 reg = pcc2_reg_read(sys_pcctwo, PCC2REG_ETH_ICSR);
  153                 reg |= PCCTWO_ICR_ICLR;
  154                 pcc2_reg_write(sys_pcctwo, PCC2REG_ETH_ICSR, reg);
  155         }
  156         return (0);
  157 }
  158 
  159 /* ARGSUSED */
  160 static void
  161 ie_hwinit(sc)
  162         struct ie_softc *sc;
  163 {
  164         u_int8_t reg;
  165 
  166         reg = pcc2_reg_read(sys_pcctwo, PCC2REG_ETH_ICSR);
  167         reg |= PCCTWO_ICR_IEN | PCCTWO_ICR_ICLR;
  168         pcc2_reg_write(sys_pcctwo, PCC2REG_ETH_ICSR, reg);
  169 }
  170 
  171 /* ARGSUSED */
  172 static void
  173 ie_atten(sc, reason)
  174         struct ie_softc *sc;
  175         int reason;
  176 {
  177         struct ie_pcctwo_softc *ps;
  178 
  179         ps = (struct ie_pcctwo_softc *) sc;
  180         bus_space_write_4(ps->ps_bust, ps->ps_bush, IE_MPUREG_CA, 0);
  181 }
  182 
  183 static void
  184 ie_copyin(sc, dst, offset, size)
  185         struct ie_softc *sc;
  186         void *dst;
  187         int offset;
  188         size_t size;
  189 {
  190         if (size == 0)          /* This *can* happen! */
  191                 return;
  192 
  193 #if 0
  194         bus_space_read_region_1(sc->bt, sc->bh, offset, dst, size);
  195 #else
  196         /* A minor optimisation ;-) */
  197         memcpy(dst, (void *) ((u_long) sc->bh + (u_long) offset), size);
  198 #endif
  199 }
  200 
  201 static void
  202 ie_copyout(sc, src, offset, size)
  203         struct ie_softc *sc;
  204         const void *src;
  205         int offset;
  206         size_t size;
  207 {
  208         if (size == 0)          /* This *can* happen! */
  209                 return;
  210 
  211 #if 0
  212         bus_space_write_region_1(sc->bt, sc->bh, offset, src, size);
  213 #else
  214         /* A minor optimisation ;-) */
  215         memcpy((void *) ((u_long) sc->bh + (u_long) offset), src, size);
  216 #endif
  217 }
  218 
  219 static u_int16_t
  220 ie_read_16(sc, offset)
  221         struct ie_softc *sc;
  222         int offset;
  223 {
  224 
  225         return (bus_space_read_2(sc->bt, sc->bh, offset));
  226 }
  227 
  228 static void
  229 ie_write_16(sc, offset, value)
  230         struct ie_softc *sc;
  231         int offset;
  232         u_int16_t value;
  233 {
  234 
  235         bus_space_write_2(sc->bt, sc->bh, offset, value);
  236 }
  237 
  238 static void
  239 ie_write_24(sc, offset, addr)
  240         struct ie_softc *sc;
  241         int offset;
  242         int addr;
  243 {
  244 
  245         addr += (int) sc->sc_iobase;
  246 
  247         bus_space_write_2(sc->bt, sc->bh, offset, addr & 0xffff);
  248         bus_space_write_2(sc->bt, sc->bh, offset + 2, (addr >> 16) & 0x00ff);
  249 }
  250 
  251 /* ARGSUSED */
  252 int
  253 ie_pcctwo_match(parent, cf, args)
  254         struct device *parent;
  255         struct cfdata *cf;
  256         void *args;
  257 {
  258         struct pcctwo_attach_args *pa;
  259 
  260         pa = args;
  261 
  262         if (strcmp(pa->pa_name, ie_cd.cd_name))
  263                 return (0);
  264 
  265         pa->pa_ipl = cf->pcctwocf_ipl;
  266 
  267         return (1);
  268 }
  269 
  270 /* ARGSUSED */
  271 void
  272 ie_pcctwo_attach(parent, self, args)
  273         struct device *parent;
  274         struct device *self;
  275         void *args;
  276 {
  277         struct pcctwo_attach_args *pa;
  278         struct ie_pcctwo_softc *ps;
  279         struct ie_softc *sc;
  280         bus_dma_segment_t seg;
  281         int rseg;
  282 
  283         pa = (struct pcctwo_attach_args *) args;
  284         ps = (struct ie_pcctwo_softc *) self;
  285         sc = (struct ie_softc *) self;
  286 
  287         /* Map the MPU controller registers in PCCTWO space */
  288         ps->ps_bust = pa->pa_bust;
  289         bus_space_map(pa->pa_bust, pa->pa_offset, IE_MPUREG_SIZE,
  290             0, &ps->ps_bush);
  291 
  292         /* Get contiguous DMA-able memory for the IE chip */
  293         if (bus_dmamem_alloc(pa->pa_dmat, ether_data_buff_size, PAGE_SIZE, 0,
  294                 &seg, 1, &rseg,
  295                 BUS_DMA_NOWAIT | BUS_DMA_ONBOARD_RAM | BUS_DMA_24BIT) != 0) {
  296                 printf("%s: Failed to allocate ether buffer\n", self->dv_xname);
  297                 return;
  298         }
  299         if (bus_dmamem_map(pa->pa_dmat, &seg, rseg, ether_data_buff_size,
  300             (caddr_t *) & sc->sc_maddr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) {
  301                 printf("%s: Failed to map ether buffer\n", self->dv_xname);
  302                 bus_dmamem_free(pa->pa_dmat, &seg, rseg);
  303                 return;
  304         }
  305         sc->bt = pa->pa_bust;
  306         sc->bh = (bus_space_handle_t) sc->sc_maddr;     /* XXXSCW Better way? */
  307         sc->sc_iobase = (void *) seg.ds_addr;
  308         sc->sc_msize = ether_data_buff_size;
  309         memset(sc->sc_maddr, 0, ether_data_buff_size);
  310 
  311         sc->hwreset = ie_reset;
  312         sc->hwinit = ie_hwinit;
  313         sc->chan_attn = ie_atten;
  314         sc->intrhook = ie_intrhook;
  315         sc->memcopyin = ie_copyin;
  316         sc->memcopyout = ie_copyout;
  317         sc->ie_bus_barrier = NULL;
  318         sc->ie_bus_read16 = ie_read_16;
  319         sc->ie_bus_write16 = ie_write_16;
  320         sc->ie_bus_write24 = ie_write_24;
  321         sc->sc_mediachange = NULL;
  322         sc->sc_mediastatus = NULL;
  323 
  324         sc->scp = 0;
  325         sc->iscp = sc->scp + ((IE_SCP_SZ + 15) & ~15);
  326         sc->scb = sc->iscp + IE_ISCP_SZ;
  327         sc->buf_area = sc->scb + IE_SCB_SZ;
  328         sc->buf_area_sz = sc->sc_msize - (sc->buf_area - sc->scp);
  329 
  330         /*
  331          * BUS_USE -> Interrupt Active High (edge-triggered),
  332          *            Lock function enabled,
  333          *            Internal bus throttle timer triggering,
  334          *            82586 operating mode.
  335          */
  336         ie_write_16(sc, IE_SCP_BUS_USE(sc->scp), IE_BUS_USE);
  337         ie_write_24(sc, IE_SCP_ISCP(sc->scp), sc->iscp);
  338         ie_write_16(sc, IE_ISCP_SCB(sc->iscp), sc->scb);
  339         ie_write_24(sc, IE_ISCP_BASE(sc->iscp), sc->scp);
  340 
  341         /* This has the side-effect of resetting the chip */
  342         i82586_proberam(sc);
  343 
  344         /* Attach the MI back-end */
  345         i82586_attach(sc, "onboard", mvme_ea, NULL, 0, 0);
  346 
  347         /* Register the event counter */
  348         evcnt_attach_dynamic(&ps->ps_evcnt, EVCNT_TYPE_INTR,
  349             pcctwointr_evcnt(pa->pa_ipl), "ether", sc->sc_dev.dv_xname);
  350 
  351         /* Finally, hook the hardware interrupt */
  352         pcctwointr_establish(PCCTWOV_LANC_IRQ, i82586_intr, pa->pa_ipl, sc,
  353             &ps->ps_evcnt);
  354 }

Cache object: aca415137874d85f148e4a813e2d4da9


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.