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

Cache object: a1c18a53ac18a2bbec7c1d771feaa40c


[ 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.