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

Cache object: 636deaea926ba1830ad97eea3241af32


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