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/ic/depca.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: depca.c,v 1.10 2003/08/07 16:31:01 agc Exp $   */
    2 
    3 /*-
    4  * Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
    9  * Simulation Facility, NASA Ames Research Center.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  * 3. All advertising materials mentioning features or use of this software
   20  *    must display the following acknowledgement:
   21  *      This product includes software developed by the NetBSD
   22  *      Foundation, Inc. and its contributors.
   23  * 4. Neither the name of The NetBSD Foundation nor the names of its
   24  *    contributors may be used to endorse or promote products derived
   25  *    from this software without specific prior written permission.
   26  *
   27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   37  * POSSIBILITY OF SUCH DAMAGE.
   38  */
   39 
   40 /*-
   41  * Copyright (c) 1992, 1993
   42  *      The Regents of the University of California.  All rights reserved.
   43  *
   44  * This code is derived from software contributed to Berkeley by
   45  * Ralph Campbell and Rick Macklem.
   46  *
   47  * Redistribution and use in source and binary forms, with or without
   48  * modification, are permitted provided that the following conditions
   49  * are met:
   50  * 1. Redistributions of source code must retain the above copyright
   51  *    notice, this list of conditions and the following disclaimer.
   52  * 2. Redistributions in binary form must reproduce the above copyright
   53  *    notice, this list of conditions and the following disclaimer in the
   54  *    documentation and/or other materials provided with the distribution.
   55  * 3. Neither the name of the University nor the names of its contributors
   56  *    may be used to endorse or promote products derived from this software
   57  *    without specific prior written permission.
   58  *
   59  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   60  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   61  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   62  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   63  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   64  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   65  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   66  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   67  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   68  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   69  * SUCH DAMAGE.
   70  *
   71  *      @(#)if_le.c     8.2 (Berkeley) 11/16/93
   72  */
   73 
   74 #include <sys/cdefs.h>
   75 __KERNEL_RCSID(0, "$NetBSD: depca.c,v 1.10 2003/08/07 16:31:01 agc Exp $");
   76 
   77 #include <sys/param.h>
   78 #include <sys/systm.h>
   79 #include <sys/mbuf.h>
   80 #include <sys/syslog.h>
   81 #include <sys/socket.h>
   82 #include <sys/device.h>
   83 
   84 #include <net/if.h>
   85 #include <net/if_ether.h>
   86 #include <net/if_media.h>
   87 
   88 #include <machine/cpu.h>
   89 #include <machine/intr.h>
   90 #include <machine/bus.h>
   91 
   92 #include <dev/isa/isareg.h>
   93 #include <dev/isa/isavar.h>
   94 
   95 #include <dev/ic/lancereg.h>
   96 #include <dev/ic/lancevar.h>
   97 #include <dev/ic/am7990reg.h>
   98 #include <dev/ic/am7990var.h>
   99 #include <dev/ic/depcareg.h>
  100 #include <dev/ic/depcavar.h>
  101 
  102 struct le_depca_softc {
  103         struct am7990_softc sc_am7990;  /* glue to MI code */
  104 
  105         void *sc_ih;
  106 };
  107 
  108 int     le_depca_match(struct device *, struct cfdata *, void *);
  109 void    le_depca_attach(struct device *, struct device *, void *);
  110 
  111 CFATTACH_DECL(le_depca, sizeof(struct le_depca_softc),
  112     le_depca_match, le_depca_attach, NULL, NULL);
  113 
  114 void    depca_copytobuf(struct lance_softc *, void *, int, int);
  115 void    depca_copyfrombuf(struct lance_softc *, void *, int, int);
  116 void    depca_zerobuf(struct lance_softc *, int, int);
  117 
  118 struct depca_attach_args {
  119         const char *da_name;
  120 };
  121 
  122 int     depca_print(void *, const char *);
  123 
  124 void
  125 depca_attach(struct depca_softc *sc)
  126 {
  127         struct depca_attach_args da;
  128 
  129         da.da_name = "le";
  130 
  131         (void) config_found(&sc->sc_dev, &da, depca_print);
  132 }
  133 
  134 int
  135 depca_print(void *aux, const char *pnp)
  136 {
  137         struct depca_attach_args *da = aux;
  138 
  139         if (pnp)
  140                 aprint_normal("%s at %s", da->da_name, pnp);
  141 
  142         return (UNCONF);
  143 }
  144 
  145 void
  146 depca_wrcsr(struct lance_softc *sc, u_int16_t port, u_int16_t val)
  147 {
  148         struct depca_softc *dsc = (void *) sc->sc_dev.dv_parent;
  149 
  150         bus_space_write_2(dsc->sc_iot, dsc->sc_ioh, DEPCA_RAP, port);
  151         bus_space_write_2(dsc->sc_iot, dsc->sc_ioh, DEPCA_RDP, val);
  152 }
  153 
  154 u_int16_t
  155 depca_rdcsr(struct lance_softc *sc, u_int16_t port)
  156 {
  157         struct depca_softc *dsc = (void *) sc->sc_dev.dv_parent;
  158 
  159         bus_space_write_2(dsc->sc_iot, dsc->sc_ioh, DEPCA_RAP, port);
  160         return (bus_space_read_2(dsc->sc_iot, dsc->sc_ioh, DEPCA_RDP));
  161 }
  162 
  163 int
  164 depca_readprom(bus_space_tag_t iot, bus_space_handle_t ioh, u_int8_t *laddr)
  165 {
  166         int port, i;
  167 
  168         /*
  169          * Extract the physical MAC address from the ROM.
  170          *
  171          * The address PROM is 32 bytes wide, and we access it through
  172          * a single I/O port.  On each read, it rotates to the next
  173          * position.  We find the ethernet address by looking for a
  174          * particular sequence of bytes (0xff, 0x00, 0x55, 0xaa, 0xff,
  175          * 0x00, 0x55, 0xaa), and then reading the next 8 bytes (the
  176          * ethernet address and a checksum).
  177          *
  178          * It appears that the PROM can be at one of two locations, so
  179          * we just try both.
  180          */
  181         port = DEPCA_ADP;
  182         for (i = 0; i < 32; i++)
  183                 if (bus_space_read_1(iot, ioh, port) == 0xff &&
  184                     bus_space_read_1(iot, ioh, port) == 0x00 &&
  185                     bus_space_read_1(iot, ioh, port) == 0x55 &&
  186                     bus_space_read_1(iot, ioh, port) == 0xaa &&
  187                     bus_space_read_1(iot, ioh, port) == 0xff &&
  188                     bus_space_read_1(iot, ioh, port) == 0x00 &&
  189                     bus_space_read_1(iot, ioh, port) == 0x55 &&
  190                     bus_space_read_1(iot, ioh, port) == 0xaa)
  191                         goto found;
  192         port = DEPCA_ADP + 1;
  193         for (i = 0; i < 32; i++)
  194                 if (bus_space_read_1(iot, ioh, port) == 0xff &&
  195                     bus_space_read_1(iot, ioh, port) == 0x00 &&
  196                     bus_space_read_1(iot, ioh, port) == 0x55 &&
  197                     bus_space_read_1(iot, ioh, port) == 0xaa &&
  198                     bus_space_read_1(iot, ioh, port) == 0xff &&
  199                     bus_space_read_1(iot, ioh, port) == 0x00 &&
  200                     bus_space_read_1(iot, ioh, port) == 0x55 &&
  201                     bus_space_read_1(iot, ioh, port) == 0xaa)
  202                         goto found;
  203         printf("depca: address not found\n");
  204         return (-1);
  205 
  206 found:
  207 
  208         if (laddr) {
  209                 for (i = 0; i < 6; i++)
  210                         laddr[i] = bus_space_read_1(iot, ioh, port);
  211         }
  212 
  213 #if 0
  214         sum =
  215             (laddr[0] <<  2) +
  216             (laddr[1] << 10) +
  217             (laddr[2] <<  1) +
  218             (laddr[3] <<  9) +
  219             (laddr[4] <<  0) +
  220             (laddr[5] <<  8);
  221         sum = (sum & 0xffff) + (sum >> 16);
  222         sum = (sum & 0xffff) + (sum >> 16);
  223 
  224         rom_sum = bus_space_read_1(iot, ioh, port);
  225         rom_sum |= bus_space_read_1(iot, ioh, port) << 8;
  226 
  227         if (sum != rom_sum) {
  228                 printf("depca: checksum mismatch; calculated %04x != read %04x",
  229                        sum, rom_sum);
  230                 return (-1);
  231         }
  232 #endif
  233 
  234         return (0);
  235 }
  236 
  237 int
  238 le_depca_match(struct device *parent, struct cfdata *match, void *aux)
  239 {
  240         struct depca_attach_args *da = aux;
  241 
  242         return (strcmp(da->da_name, match->cf_name) == 0);
  243 }
  244 
  245 void
  246 le_depca_attach(struct device *parent, struct device *self, void *aux)
  247 {
  248         struct depca_softc *dsc = (void *) parent;
  249         struct le_depca_softc *lesc = (void *) self;
  250         struct lance_softc *sc = &lesc->sc_am7990.lsc;
  251         u_int8_t val;
  252         int i;
  253 
  254         printf("\n");
  255 
  256         /* I/O and memory spaces already mapped. */
  257 
  258         if (depca_readprom(dsc->sc_iot, dsc->sc_ioh, sc->sc_enaddr)) {
  259                 printf("%s: can't read PROM\n", self->dv_xname);
  260                 return;
  261         }
  262 
  263         bus_space_write_2(dsc->sc_iot, dsc->sc_ioh, DEPCA_CSR,
  264             DEPCA_CSR_DUM | DEPCA_CSR_IEN | DEPCA_CSR_SHE |
  265             (dsc->sc_memsize == 32*1024 ? DEPCA_CSR_LOW32K : 0));
  266 
  267         val = 0xff;
  268         for (;;) {
  269                 u_int8_t cv;
  270 
  271                 bus_space_set_region_1(dsc->sc_memt, dsc->sc_memh, 0, val,
  272                     dsc->sc_memsize);
  273                 for (i = 0; i < dsc->sc_memsize; i++) {
  274                         cv = bus_space_read_1(dsc->sc_memt, dsc->sc_memh, i);
  275                         if (cv != val) {
  276                                 printf("%s: failed to clear memory at %d "
  277                                     "(0x%02x != 0x%02x)\n",
  278                                     sc->sc_dev.dv_xname, i, cv, val);
  279                                 return;
  280                         }
  281                 }
  282                 if (val == 0x00)
  283                         break;
  284                 val -= 0x55;
  285         }
  286 
  287         sc->sc_conf3 = LE_C3_ACON;
  288         sc->sc_mem = 0;                 /* Not used. */
  289         sc->sc_addr = 0;
  290         sc->sc_memsize = dsc->sc_memsize;
  291 
  292         sc->sc_copytodesc = depca_copytobuf;
  293         sc->sc_copyfromdesc = depca_copyfrombuf;
  294         sc->sc_copytobuf = depca_copytobuf;
  295         sc->sc_copyfrombuf = depca_copyfrombuf;
  296         sc->sc_zerobuf = depca_zerobuf;
  297 
  298         sc->sc_rdcsr = depca_rdcsr;
  299         sc->sc_wrcsr = depca_wrcsr;
  300         sc->sc_hwinit = NULL;
  301 
  302         printf("%s", sc->sc_dev.dv_xname);
  303         am7990_config(&lesc->sc_am7990);
  304 
  305         lesc->sc_ih = (*dsc->sc_intr_establish)(dsc, sc);
  306 }
  307 
  308 /*
  309  * Controller interrupt.
  310  */
  311 int
  312 depca_intredge(void *arg)
  313 {
  314 
  315         if (am7990_intr(arg) == 0)
  316                 return (0);
  317         for (;;)
  318                 if (am7990_intr(arg) == 0)
  319                         return (1);
  320 }
  321 
  322 /*
  323  * DEPCA shared memory access functions.
  324  */
  325 
  326 void
  327 depca_copytobuf(struct lance_softc *sc, void *from, int boff, int len)
  328 {
  329         struct depca_softc *dsc = (void *) sc->sc_dev.dv_parent;
  330 
  331         bus_space_write_region_1(dsc->sc_memt, dsc->sc_memh, boff,
  332             from, len);
  333 }
  334 
  335 void
  336 depca_copyfrombuf(struct lance_softc *sc, void *to, int boff, int len)
  337 {
  338         struct depca_softc *dsc = (void *) sc->sc_dev.dv_parent;
  339 
  340         bus_space_read_region_1(dsc->sc_memt, dsc->sc_memh, boff,
  341             to, len);
  342 }
  343 
  344 void
  345 depca_zerobuf(struct lance_softc *sc, int boff, int len)
  346 {
  347         struct depca_softc *dsc = (void *) sc->sc_dev.dv_parent;
  348 
  349         bus_space_set_region_1(dsc->sc_memt, dsc->sc_memh, boff,
  350             0x00, len);
  351 }

Cache object: b680e87a2077f943fc75c363bd2b44a0


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