[BACK]Return to if_le_isa.c CVS log [TXT][DIR] Up to [local] / sys / dev / isa

Annotation of sys/dev/isa/if_le_isa.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: if_le_isa.c,v 1.19 2007/06/17 21:20:47 jasper Exp $   */
                      2: /*     $NetBSD: if_le_isa.c,v 1.2 1996/05/12 23:52:56 mycroft Exp $    */
                      3:
                      4: /*-
                      5:  * Copyright (c) 1995 Charles M. Hannum.  All rights reserved.
                      6:  * Copyright (c) 1992, 1993
                      7:  *     The Regents of the University of California.  All rights reserved.
                      8:  *
                      9:  * This code is derived from software contributed to Berkeley by
                     10:  * Ralph Campbell and Rick Macklem.
                     11:  *
                     12:  * Redistribution and use in source and binary forms, with or without
                     13:  * modification, are permitted provided that the following conditions
                     14:  * are met:
                     15:  * 1. Redistributions of source code must retain the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer.
                     17:  * 2. Redistributions in binary form must reproduce the above copyright
                     18:  *    notice, this list of conditions and the following disclaimer in the
                     19:  *    documentation and/or other materials provided with the distribution.
                     20:  * 3. Neither the name of the University nor the names of its contributors
                     21:  *    may be used to endorse or promote products derived from this software
                     22:  *    without specific prior written permission.
                     23:  *
                     24:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     25:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     26:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     27:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     28:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     29:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     30:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     31:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     32:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     33:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     34:  * SUCH DAMAGE.
                     35:  *
                     36:  *     @(#)if_le.c     8.2 (Berkeley) 11/16/93
                     37:  */
                     38:
                     39: #include "bpfilter.h"
                     40: #include "isadma.h"
                     41:
                     42: #include <sys/param.h>
                     43: #include <sys/systm.h>
                     44: #include <sys/mbuf.h>
                     45: #include <sys/syslog.h>
                     46: #include <sys/socket.h>
                     47: #include <sys/device.h>
                     48:
                     49: #include <net/if.h>
                     50: #include <net/if_media.h>
                     51:
                     52: #ifdef INET
                     53: #include <netinet/in.h>
                     54: #include <netinet/if_ether.h>
                     55: #endif
                     56:
                     57: #include <machine/cpu.h>
                     58: #include <machine/intr.h>
                     59:
                     60: #include <dev/isa/isareg.h>
                     61: #include <dev/isa/isavar.h>
                     62: #include <dev/isa/isadmavar.h>
                     63:
                     64: #include <dev/ic/am7990reg.h>
                     65: #include <dev/ic/am7990var.h>
                     66:
                     67: #include <dev/isa/if_levar.h>
                     68:
                     69: static char *card_type[] =
                     70:     { "unknown", "BICC Isolan", "NE2100", "DEPCA", "PCnet-ISA" };
                     71:
                     72: int    le_isa_probe(struct device *, void *, void *);
                     73: void   le_isa_attach(struct device *, struct device *, void *);
                     74:
                     75: struct cfattach le_isa_ca = {
                     76:        sizeof(struct le_softc), le_isa_probe, le_isa_attach
                     77: };
                     78:
                     79: int    depca_isa_probe(struct le_softc *, struct isa_attach_args *);
                     80: int    ne2100_isa_probe(struct le_softc *, struct isa_attach_args *);
                     81: int    bicc_isa_probe(struct le_softc *, struct isa_attach_args *);
                     82: int    lance_isa_probe(struct am7990_softc *);
                     83:
                     84: int
                     85: le_isa_probe(struct device *parent, void *match, void *aux)
                     86: {
                     87:        struct le_softc *lesc = match;
                     88:        struct isa_attach_args *ia = aux;
                     89:        u_int8_t bogusether[ETHER_ADDR_LEN] = { 255, 255, 255, 255, 255, 255 };
                     90:
                     91: #if NISADMA == 0
                     92:        if (ia->ia_drq != DRQUNK) {
                     93:                printf("cannot support dma lance devices\n");
                     94:                return 0;
                     95:        }
                     96: #endif
                     97:
                     98:        if (bicc_isa_probe(lesc, ia) == 0 && ne2100_isa_probe(lesc, ia) == 0 &&
                     99:            depca_isa_probe(lesc, ia) == 0)
                    100:                return (0);
                    101:
                    102:        if (bcmp(lesc->sc_am7990.sc_arpcom.ac_enaddr, bogusether,
                    103:            sizeof(bogusether)) == 0)
                    104:                return (0);
                    105:
                    106:        return (1);
                    107: }
                    108:
                    109: int
                    110: depca_isa_probe(struct le_softc *lesc, struct isa_attach_args *ia)
                    111: {
                    112:        struct am7990_softc *sc = &lesc->sc_am7990;
                    113:        bus_space_tag_t iot = lesc->sc_iot;
                    114:        bus_space_handle_t ioh = lesc->sc_ioh;
                    115:        int iosize = 16;
                    116:        int port;
                    117:
                    118: #if 0
                    119:        u_long sum, rom_sum;
                    120:        u_char x;
                    121: #endif
                    122:        int i;
                    123:
                    124:        if (bus_space_map(iot, ia->ia_iobase, iosize, 0, &ioh))
                    125:                return (0);
                    126:        lesc->sc_iot = iot;
                    127:        lesc->sc_ioh = ioh;
                    128:        lesc->sc_rap = DEPCA_RAP;
                    129:        lesc->sc_rdp = DEPCA_RDP;
                    130:        lesc->sc_card = DEPCA;
                    131:
                    132:        if (lance_isa_probe(sc) == 0) {
                    133:                bus_space_unmap(iot, ioh, iosize);
                    134:                return 0;
                    135:        }
                    136:
                    137:        bus_space_write_1(iot, ioh, DEPCA_CSR, DEPCA_CSR_DUM);
                    138:
                    139:        /*
                    140:         * Extract the physical MAC address from the ROM.
                    141:         *
                    142:         * The address PROM is 32 bytes wide, and we access it through
                    143:         * a single I/O port.  On each read, it rotates to the next
                    144:         * position.  We find the ethernet address by looking for a
                    145:         * particular sequence of bytes (0xff, 0x00, 0x55, 0xaa, 0xff,
                    146:         * 0x00, 0x55, 0xaa), and then reading the next 8 bytes (the
                    147:         * ethernet address and a checksum).
                    148:         *
                    149:         * It appears that the PROM can be at one of two locations, so
                    150:         * we just try both.
                    151:         */
                    152:        port = DEPCA_ADP;
                    153:        for (i = 0; i < 32; i++)
                    154:                if (bus_space_read_1(iot, ioh, port) == 0xff &&
                    155:                    bus_space_read_1(iot, ioh, port) == 0x00 &&
                    156:                    bus_space_read_1(iot, ioh, port) == 0x55 &&
                    157:                    bus_space_read_1(iot, ioh, port) == 0xaa &&
                    158:                    bus_space_read_1(iot, ioh, port) == 0xff &&
                    159:                    bus_space_read_1(iot, ioh, port) == 0x00 &&
                    160:                    bus_space_read_1(iot, ioh, port) == 0x55 &&
                    161:                    bus_space_read_1(iot, ioh, port) == 0xaa)
                    162:                        goto found;
                    163:        port = DEPCA_ADP + 1;
                    164:        for (i = 0; i < 32; i++)
                    165:                if (bus_space_read_1(iot, ioh, port) == 0xff &&
                    166:                    bus_space_read_1(iot, ioh, port) == 0x00 &&
                    167:                    bus_space_read_1(iot, ioh, port) == 0x55 &&
                    168:                    bus_space_read_1(iot, ioh, port) == 0xaa &&
                    169:                    bus_space_read_1(iot, ioh, port) == 0xff &&
                    170:                    bus_space_read_1(iot, ioh, port) == 0x00 &&
                    171:                    bus_space_read_1(iot, ioh, port) == 0x55 &&
                    172:                    bus_space_read_1(iot, ioh, port) == 0xaa)
                    173:                        goto found;
                    174:        printf("%s: address not found\n", sc->sc_dev.dv_xname);
                    175:        return 0;
                    176:
                    177: found:
                    178:        for (i = 0; i < sizeof(sc->sc_arpcom.ac_enaddr); i++)
                    179:                sc->sc_arpcom.ac_enaddr[i] = bus_space_read_1(iot, ioh, port);
                    180:
                    181: #if 0
                    182:        sum =
                    183:            (sc->sc_arpcom.ac_enaddr[0] <<  2) +
                    184:            (sc->sc_arpcom.ac_enaddr[1] << 10) +
                    185:            (sc->sc_arpcom.ac_enaddr[2] <<  1) +
                    186:            (sc->sc_arpcom.ac_enaddr[3] <<  9) +
                    187:            (sc->sc_arpcom.ac_enaddr[4] <<  0) +
                    188:            (sc->sc_arpcom.ac_enaddr[5] <<  8);
                    189:        sum = (sum & 0xffff) + (sum >> 16);
                    190:        sum = (sum & 0xffff) + (sum >> 16);
                    191:
                    192:        rom_sum = bus_space_read_1(iot, ioh, port);
                    193:        rom_sum |= bus_space_read_1(iot, ioh, port << 8);
                    194:
                    195:        if (sum != rom_sum) {
                    196:                printf("%s: checksum mismatch; calculated %04x != read %04x",
                    197:                    sc->sc_dev.dv_xname, sum, rom_sum);
                    198:                bus_space_unmap(iot, ioh, iosize);
                    199:                return 0;
                    200:        }
                    201: #endif
                    202:
                    203:        bus_space_write_1(iot, ioh, DEPCA_CSR, DEPCA_CSR_NORMAL);
                    204:
                    205:        ia->ia_iosize = iosize;
                    206:        ia->ia_drq = DRQUNK;
                    207:        bus_space_unmap(iot, ioh, ia->ia_iosize);
                    208:        return 1;
                    209: }
                    210:
                    211: int
                    212: ne2100_isa_probe(struct le_softc *lesc, struct isa_attach_args *ia)
                    213: {
                    214:        struct am7990_softc *sc = &lesc->sc_am7990;
                    215:        bus_space_tag_t iot = lesc->sc_iot;
                    216:        bus_space_handle_t ioh = lesc->sc_ioh;
                    217:        int iosize = 24;
                    218:        int i;
                    219:
                    220:        if (bus_space_map(iot, ia->ia_iobase, iosize, 0, &ioh))
                    221:                return (0);
                    222:        lesc->sc_iot = iot;
                    223:        lesc->sc_ioh = ioh;
                    224:        lesc->sc_rap = NE2100_RAP;
                    225:        lesc->sc_rdp = NE2100_RDP;
                    226:        lesc->sc_card = NE2100;
                    227:
                    228:        if (lance_isa_probe(sc) == 0) {
                    229:                bus_space_unmap(iot, ioh, iosize);
                    230:                return 0;
                    231:        }
                    232:
                    233:        /*
                    234:         * Extract the physical MAC address from the ROM.
                    235:         */
                    236:        for (i = 0; i < sizeof(sc->sc_arpcom.ac_enaddr); i++)
                    237:                sc->sc_arpcom.ac_enaddr[i] = bus_space_read_1(iot, ioh, i);
                    238:
                    239:        ia->ia_iosize = iosize;
                    240:        bus_space_unmap(iot, ioh, ia->ia_iosize);
                    241:        return 1;
                    242: }
                    243:
                    244: int
                    245: bicc_isa_probe(struct le_softc *lesc, struct isa_attach_args *ia)
                    246: {
                    247:        struct am7990_softc *sc = &lesc->sc_am7990;
                    248:        bus_space_handle_t ioh;
                    249:        bus_space_tag_t iot = ia->ia_iot;
                    250:        int iosize = 16;
                    251:        int i;
                    252:
                    253:        if (bus_space_map(iot, ia->ia_iobase, iosize, 0, &ioh))
                    254:                return (0);
                    255:        lesc->sc_iot = iot;
                    256:        lesc->sc_ioh = ioh;
                    257:        lesc->sc_rap = BICC_RAP;
                    258:        lesc->sc_rdp = BICC_RDP;
                    259:        lesc->sc_card = BICC;
                    260:
                    261:        if (lance_isa_probe(sc) == 0) {
                    262:                bus_space_unmap(iot, ioh, iosize);
                    263:                return 0;
                    264:        }
                    265:
                    266:        /*
                    267:         * Extract the physical MAC address from the ROM.
                    268:         */
                    269:        for (i = 0; i < sizeof(sc->sc_arpcom.ac_enaddr); i++)
                    270:                sc->sc_arpcom.ac_enaddr[i] = bus_space_read_1(iot, ioh, i * 2);
                    271:
                    272:        ia->ia_iosize = iosize;
                    273:        bus_space_unmap(iot, ioh, ia->ia_iosize);
                    274:        return 1;
                    275: }
                    276:
                    277: /*
                    278:  * Determine which chip is present on the card.
                    279:  */
                    280: int
                    281: lance_isa_probe(struct am7990_softc *sc)
                    282: {
                    283:
                    284:        /* Stop the LANCE chip and put it in a known state. */
                    285:        le_isa_wrcsr(sc, LE_CSR0, LE_C0_STOP);
                    286:        delay(100);
                    287:
                    288:        if (le_isa_rdcsr(sc, LE_CSR0) != LE_C0_STOP)
                    289:                return 0;
                    290:
                    291:        le_isa_wrcsr(sc, LE_CSR3, sc->sc_conf3);
                    292:        return 1;
                    293: }
                    294:
                    295: void
                    296: le_isa_attach(struct device *parent, struct device *self,
                    297:     void *aux)
                    298: {
                    299:        struct le_softc *lesc = (void *)self;
                    300:        struct am7990_softc *sc = &lesc->sc_am7990;
                    301:        struct isa_attach_args *ia = aux;
                    302:        bus_space_tag_t iot = ia->ia_iot;
                    303:        bus_space_handle_t ioh;
                    304:
                    305:        if (bus_space_map(iot, ia->ia_iobase, ia->ia_iosize, 0, &ioh))
                    306:                panic("%s: could not map I/O-ports", sc->sc_dev.dv_xname);
                    307:        lesc->sc_iot = iot;
                    308:        lesc->sc_ioh = ioh;
                    309:
                    310:        printf(": %s Ethernet\n", card_type[lesc->sc_card]);
                    311:
                    312:        if (lesc->sc_card == DEPCA) {
                    313:                u_char *mem, val;
                    314:                int i;
                    315:
                    316:                mem = sc->sc_mem = ISA_HOLE_VADDR(ia->ia_maddr);
                    317:
                    318:                val = 0xff;
                    319:                for (;;) {
                    320:                        for (i = 0; i < ia->ia_msize; i++)
                    321:                                mem[i] = val;
                    322:                        for (i = 0; i < ia->ia_msize; i++)
                    323:                                if (mem[i] != val) {
                    324:                                        printf("%s: failed to clear memory\n",
                    325:                                            sc->sc_dev.dv_xname);
                    326:                                        return;
                    327:                                }
                    328:                        if (val == 0x00)
                    329:                                break;
                    330:                        val -= 0x55;
                    331:                }
                    332:
                    333:                sc->sc_conf3 = LE_C3_ACON;
                    334:                sc->sc_addr = 0;
                    335:                sc->sc_memsize = ia->ia_msize;
                    336:        } else {
                    337:                sc->sc_mem = malloc(16384, M_DEVBUF, M_NOWAIT);
                    338:                if (sc->sc_mem == 0) {
                    339:                        printf("%s: couldn't allocate memory for card\n",
                    340:                            sc->sc_dev.dv_xname);
                    341:                        return;
                    342:                }
                    343:
                    344:                sc->sc_conf3 = 0;
                    345:                sc->sc_addr = kvtop(sc->sc_mem);
                    346:                sc->sc_memsize = 16384;
                    347:        }
                    348:
                    349:        sc->sc_copytodesc = am7990_copytobuf_contig;
                    350:        sc->sc_copyfromdesc = am7990_copyfrombuf_contig;
                    351:        sc->sc_copytobuf = am7990_copytobuf_contig;
                    352:        sc->sc_copyfrombuf = am7990_copyfrombuf_contig;
                    353:        sc->sc_zerobuf = am7990_zerobuf_contig;
                    354:
                    355:        sc->sc_rdcsr = le_isa_rdcsr;
                    356:        sc->sc_wrcsr = le_isa_wrcsr;
                    357:        sc->sc_hwreset = NULL;
                    358:        sc->sc_hwinit = NULL;
                    359:
                    360:        printf("%s", sc->sc_dev.dv_xname);
                    361:        am7990_config(sc);
                    362:
                    363: #if NISADMA > 0
                    364:        if (ia->ia_drq != DRQUNK)
                    365:                isadma_cascade(ia->ia_drq);
                    366: #endif
                    367:
                    368:        lesc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
                    369:            IPL_NET, le_isa_intredge, sc, sc->sc_dev.dv_xname);
                    370: }

CVSweb