[BACK]Return to if_ae_nubus.c CVS log [TXT][DIR] Up to [local] / sys / arch / mac68k / dev

Annotation of sys/arch/mac68k/dev/if_ae_nubus.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: if_ae_nubus.c,v 1.17 2007/01/22 13:17:45 martin Exp $ */
                      2: /*     $NetBSD: if_ae_nubus.c,v 1.17 1997/05/01 18:17:16 briggs Exp $  */
                      3:
                      4: /*
                      5:  * Copyright (C) 1997 Scott Reynolds
                      6:  * All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. The name of the author may not be used to endorse or promote products
                     17:  *    derived from this software without specific prior written permission.
                     18:  *
                     19:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     20:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     21:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     22:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     23:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     24:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     25:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     26:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     27:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     28:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     29:  */
                     30: /*
                     31:  * Some parts are derived from code adapted for MacBSD by Brad Parker
                     32:  * <brad@fcr.com>.
                     33:  *
                     34:  * Currently supports:
                     35:  *     Apple NB Ethernet Card
                     36:  *     Apple NB Ethernet Card II
                     37:  *     Interlan A310 NuBus Ethernet card
                     38:  *     Cayman Systems GatorCard
                     39:  *     Asante MacCon II/E
                     40:  *     Kinetics EtherPort SE/30
                     41:  */
                     42:
                     43: #define        AE_OLD_GET_ENADDR
                     44:
                     45: #include <sys/param.h>
                     46: #include <sys/device.h>
                     47: #include <sys/errno.h>
                     48: #include <sys/ioctl.h>
                     49: #include <sys/socket.h>
                     50: #include <sys/syslog.h>
                     51: #include <sys/systm.h>
                     52:
                     53: #include <net/if.h>
                     54:
                     55: #ifdef INET
                     56: #include <netinet/in.h>
                     57: #include <netinet/if_ether.h>
                     58: #endif
                     59:
                     60: #include <machine/bus.h>
                     61: #include <machine/viareg.h>
                     62:
                     63: #include <net/if_media.h>
                     64:
                     65: #include <dev/ic/dp8390reg.h>
                     66: #include <dev/ic/dp8390var.h>
                     67: #include <mac68k/dev/nubus.h>
                     68: #include <mac68k/dev/if_aevar.h>
                     69: #include <mac68k/dev/if_aereg.h>
                     70:
                     71: static int     ae_nubus_match(struct device *, void *, void *);
                     72: static void    ae_nubus_attach(struct device *, struct device *, void *);
                     73: static int     ae_nb_card_vendor(bus_space_tag_t, bus_space_handle_t,
                     74:                    struct nubus_attach_args *);
                     75: static int     ae_nb_get_enaddr(bus_space_tag_t, bus_space_handle_t,
                     76:                    struct nubus_attach_args *, u_int8_t *);
                     77: #ifdef DEBUG
                     78: static void    ae_nb_watchdog(struct ifnet *);
                     79: #endif
                     80:
                     81: struct cfattach ae_nubus_ca = {
                     82:        sizeof(struct dp8390_softc), ae_nubus_match, ae_nubus_attach
                     83: };
                     84:
                     85: static int
                     86: ae_nubus_match(parent, vcf, aux)
                     87:        struct device *parent;
                     88:        void *vcf;
                     89:        void *aux;
                     90: {
                     91:        struct nubus_attach_args *na = (struct nubus_attach_args *) aux;
                     92:        bus_space_handle_t bsh;
                     93:        int rv = 0;
                     94:
                     95:        if (bus_space_map(na->na_tag, NUBUS_SLOT2PA(na->slot), NBMEMSIZE,
                     96:            0, &bsh))
                     97:                return (0);
                     98:
                     99:        if (na->category == NUBUS_CATEGORY_NETWORK &&
                    100:            na->type == NUBUS_TYPE_ETHERNET) {
                    101:                switch (ae_nb_card_vendor(na->na_tag, bsh, na)) {
                    102:                case DP8390_VENDOR_APPLE:
                    103:                case DP8390_VENDOR_ASANTE:
                    104:                case DP8390_VENDOR_FARALLON:
                    105:                case DP8390_VENDOR_INTERLAN:
                    106:                case DP8390_VENDOR_KINETICS:
                    107:                case DP8390_VENDOR_CABLETRON:
                    108:                        rv = 1;
                    109:                        break;
                    110:                case DP8390_VENDOR_DAYNA:
                    111:                case DP8390_VENDOR_FOCUS:
                    112:                        /* not supported yet */
                    113:                        /* FALLTHROUGH */
                    114:                default:
                    115:                        rv = 0;
                    116:                        break;
                    117:                }
                    118:        }
                    119:
                    120:        bus_space_unmap(na->na_tag, bsh, NBMEMSIZE);
                    121:
                    122:        return (rv);
                    123: }
                    124:
                    125: /*
                    126:  * Install interface into kernel networking data structures
                    127:  */
                    128: static void
                    129: ae_nubus_attach(parent, self, aux)
                    130:        struct device *parent, *self;
                    131:        void   *aux;
                    132: {
                    133:        struct dp8390_softc *sc = (struct dp8390_softc *)self;
                    134:        struct nubus_attach_args *na = (struct nubus_attach_args *) aux;
                    135: #ifdef DEBUG
                    136:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
                    137: #endif
                    138:        bus_space_tag_t bst;
                    139:        bus_space_handle_t bsh;
                    140:        int i, success;
                    141:        const char *cardtype;
                    142:
                    143:        bst = na->na_tag;
                    144:        if (bus_space_map(bst, NUBUS_SLOT2PA(na->slot), NBMEMSIZE,
                    145:            0, &bsh)) {
                    146:                printf(": can't map memory space\n");
                    147:                return;
                    148:        }
                    149:
                    150:        sc->sc_regt = sc->sc_buft = bst;
                    151:        sc->sc_flags = self->dv_cfdata->cf_flags;
                    152:
                    153:        cardtype = nubus_get_card_name(bst, bsh, na->fmt);
                    154:
                    155:        sc->is790 = 0;
                    156:
                    157:        sc->mem_start = 0;
                    158:        sc->mem_size = 0;
                    159:
                    160:        success = 0;
                    161:
                    162:        switch (ae_nb_card_vendor(bst, bsh, na)) {
                    163:        case DP8390_VENDOR_APPLE:       /* Apple-compatible cards */
                    164:        case DP8390_VENDOR_ASANTE:
                    165:                /* Map register offsets */
                    166:                for (i = 0; i < 16; i++) /* reverse order, longword aligned */
                    167:                        sc->sc_reg_map[i] = (15 - i) << 2;
                    168:
                    169:                sc->dcr_reg = (ED_DCR_FT1 | ED_DCR_WTS | ED_DCR_LS);
                    170:                if (bus_space_subregion(bst, bsh,
                    171:                    AE_REG_OFFSET, AE_REG_SIZE, &sc->sc_regh)) {
                    172:                        printf(": failed to map register space\n");
                    173:                        break;
                    174:                }
                    175:                if ((sc->mem_size = ae_size_card_memory(bst, bsh,
                    176:                    AE_DATA_OFFSET)) == 0) {
                    177:                        printf(": failed to determine size of RAM.\n");
                    178:                        break;
                    179:                }
                    180:                if (bus_space_subregion(bst, bsh,
                    181:                    AE_DATA_OFFSET, sc->mem_size, &sc->sc_bufh)) {
                    182:                        printf(": failed to map register space\n");
                    183:                        break;
                    184:                }
                    185: #ifdef AE_OLD_GET_ENADDR
                    186:                /* Get station address from on-board ROM */
                    187:                for (i = 0; i < ETHER_ADDR_LEN; ++i)
                    188:                        sc->sc_arpcom.ac_enaddr[i] =
                    189:                            bus_space_read_1(bst, bsh, (AE_ROM_OFFSET + i * 2));
                    190: #else
                    191:                if (ae_nb_get_enaddr(bst, bsh, na, sc->sc_arpcom.ac_enaddr)) {
                    192:                        printf(": can't find MAC address\n");
                    193:                        break;
                    194:                }
                    195: #endif
                    196:
                    197:                success = 1;
                    198:                break;
                    199:
                    200:        case DP8390_VENDOR_DAYNA:
                    201:                /* Map register offsets */
                    202:                for (i = 0; i < 16; i++) /* normal order, longword aligned */
                    203:                        sc->sc_reg_map[i] = i << 2;
                    204:
                    205:                sc->dcr_reg = (ED_DCR_FT1 | ED_DCR_WTS | ED_DCR_LS);
                    206:                if (bus_space_subregion(bst, bsh,
                    207:                    DP_REG_OFFSET, AE_REG_SIZE, &sc->sc_regh)) {
                    208:                        printf(": failed to map register space\n");
                    209:                        break;
                    210:                }
                    211:                sc->mem_size = 8192;
                    212:                if (bus_space_subregion(bst, bsh,
                    213:                    DP_DATA_OFFSET, sc->mem_size, &sc->sc_bufh)) {
                    214:                        printf(": failed to map register space\n");
                    215:                        break;
                    216:                }
                    217: #ifdef AE_OLD_GET_ENADDR
                    218:                /* Get station address from on-board ROM */
                    219:                for (i = 0; i < ETHER_ADDR_LEN; ++i)
                    220:                        sc->sc_arpcom.ac_enaddr[i] =
                    221:                            bus_space_read_1(bst, bsh, (DP_ROM_OFFSET + i * 2));
                    222: #else
                    223:                if (ae_nb_get_enaddr(bst, bsh, na, sc->sc_arpcom.ac_enaddr)) {
                    224:                        printf(": can't find MAC address\n");
                    225:                        break;
                    226:                }
                    227: #endif
                    228:
                    229:        case DP8390_VENDOR_FARALLON:
                    230:                /* Map register offsets */
                    231:                for (i = 0; i < 16; i++) /* reverse order, longword aligned */
                    232:                        sc->sc_reg_map[i] = (15 - i) << 2;
                    233:
                    234:                sc->dcr_reg = (ED_DCR_FT1 | ED_DCR_WTS | ED_DCR_LS);
                    235:                if (bus_space_subregion(bst, bsh,
                    236:                    AE_REG_OFFSET, AE_REG_SIZE, &sc->sc_regh)) {
                    237:                        printf(": failed to map register space\n");
                    238:                        break;
                    239:                }
                    240:                if ((sc->mem_size = ae_size_card_memory(bst, bsh,
                    241:                    AE_DATA_OFFSET)) == 0) {
                    242:                        printf(": failed to determine size of RAM.\n");
                    243:                        break;
                    244:                }
                    245:                if (bus_space_subregion(bst, bsh,
                    246:                    AE_DATA_OFFSET, sc->mem_size, &sc->sc_bufh)) {
                    247:                        printf(": failed to map register space\n");
                    248:                        break;
                    249:                }
                    250: #ifdef AE_OLD_GET_ENADDR
                    251:                /* Get station address from on-board ROM */
                    252:                for (i = 0; i < ETHER_ADDR_LEN; ++i)
                    253:                        sc->sc_arpcom.ac_enaddr[i] =
                    254:                            bus_space_read_1(bst, bsh, (FE_ROM_OFFSET + i));
                    255: #endif
                    256:
                    257:                success = 1;
                    258:                break;
                    259:
                    260:        case DP8390_VENDOR_INTERLAN:
                    261:                /* Map register offsets */
                    262:                for (i = 0; i < 16; i++) /* normal order, longword aligned */
                    263:                        sc->sc_reg_map[i] = i << 2;
                    264:
                    265:                sc->dcr_reg = (ED_DCR_FT1 | ED_DCR_WTS | ED_DCR_LS);
                    266:                if (bus_space_subregion(bst, bsh,
                    267:                    GC_REG_OFFSET, AE_REG_SIZE, &sc->sc_regh)) {
                    268:                        printf(": failed to map register space\n");
                    269:                        break;
                    270:                }
                    271:                if ((sc->mem_size = ae_size_card_memory(bst, bsh,
                    272:                    GC_DATA_OFFSET)) == 0) {
                    273:                        printf(": failed to determine size of RAM.\n");
                    274:                        break;
                    275:                }
                    276:                if (bus_space_subregion(bst, bsh,
                    277:                    GC_DATA_OFFSET, sc->mem_size, &sc->sc_bufh)) {
                    278:                        printf(": failed to map register space\n");
                    279:                        break;
                    280:                }
                    281:
                    282:                /* reset the NIC chip */
                    283:                bus_space_write_1(bst, bsh, GC_RESET_OFFSET, 0);
                    284:
                    285:                if (ae_nb_get_enaddr(bst, bsh, na, sc->sc_arpcom.ac_enaddr)) {
                    286:                        /* Fall back to snarf directly from ROM.  Ick.  */
                    287:                        for (i = 0; i < ETHER_ADDR_LEN; ++i)
                    288:                                sc->sc_arpcom.ac_enaddr[i] =
                    289:                                    bus_space_read_1(bst, bsh,
                    290:                                        (GC_ROM_OFFSET + i * 4));
                    291:                }
                    292:
                    293:                success = 1;
                    294:                break;
                    295:
                    296:        case DP8390_VENDOR_KINETICS:
                    297:                /* Map register offsets */
                    298:                for (i = 0; i < 16; i++) /* normal order, longword aligned */
                    299:                        sc->sc_reg_map[i] = i << 2;
                    300:
                    301:                /* sc->use16bit = 0; */
                    302:                if (bus_space_subregion(bst, bsh,
                    303:                    KE_REG_OFFSET, AE_REG_SIZE, &sc->sc_regh)) {
                    304:                        printf(": failed to map register space\n");
                    305:                        break;
                    306:                }
                    307:                if ((sc->mem_size = ae_size_card_memory(bst, bsh,
                    308:                    KE_DATA_OFFSET)) == 0) {
                    309:                        printf(": failed to determine size of RAM.\n");
                    310:                        break;
                    311:                }
                    312:                if (bus_space_subregion(bst, bsh,
                    313:                    KE_DATA_OFFSET, sc->mem_size, &sc->sc_bufh)) {
                    314:                        printf(": failed to map register space\n");
                    315:                        break;
                    316:                }
                    317:                if (ae_nb_get_enaddr(bst, bsh, na, sc->sc_arpcom.ac_enaddr)) {
                    318:                        printf(": can't find MAC address\n");
                    319:                        break;
                    320:                }
                    321:
                    322:                success = 1;
                    323:                break;
                    324:        case DP8390_VENDOR_CABLETRON:
                    325:                /* Map register offsets */
                    326:                for (i = 0; i < 16; i++)
                    327:                    sc->sc_reg_map[i] = i << 1; /* normal order, word aligned */
                    328:
                    329:                sc->dcr_reg = (ED_DCR_FT1 | ED_DCR_WTS | ED_DCR_LS);
                    330:                if (bus_space_subregion(bst, bsh,
                    331:                    CT_REG_OFFSET, AE_REG_SIZE, &sc->sc_regh)) {
                    332:                        printf(": failed to map register space\n");
                    333:                        break;
                    334:                }
                    335:                if ((sc->mem_size = ae_size_card_memory(bst, bsh,
                    336:                    CT_DATA_OFFSET)) == 0) {
                    337:                        printf(": failed to determine size of RAM.\n");
                    338:                        break;
                    339:                }
                    340:                if (bus_space_subregion(bst, bsh,
                    341:                    CT_DATA_OFFSET, sc->mem_size, &sc->sc_bufh)) {
                    342:                        printf(": failed to map register space\n");
                    343:                        break;
                    344:                }
                    345:                if (ae_nb_get_enaddr(bst, bsh, na, sc->sc_arpcom.ac_enaddr)) {
                    346:                        printf(": can't find MAC address\n");
                    347:                        break;
                    348:                }
                    349:                success = 1;
                    350:        default:
                    351:                break;
                    352:        }
                    353:
                    354:        if (!success) {
                    355:                bus_space_unmap(bst, bsh, NBMEMSIZE);
                    356:                return;
                    357:        }
                    358:
                    359:        /*
                    360:         * Override test_mem and write_mbuf functions; other defaults
                    361:         * already work properly.
                    362:         */
                    363:        sc->test_mem = ae_test_mem;
                    364:        sc->write_mbuf = ae_write_mbuf;
                    365: #ifdef DEBUG
                    366:        ifp->if_watchdog = ae_nb_watchdog;      /* Override watchdog */
                    367: #endif
                    368:        sc->sc_media_init = dp8390_media_init;
                    369:
                    370:        /* Interface is always enabled. */
                    371:        sc->sc_enabled = 1;
                    372:
                    373:        printf(": %s, %dKB memory", cardtype, sc->mem_size / 1024);
                    374:
                    375:        if (dp8390_config(sc)) {
                    376:                bus_space_unmap(bst, bsh, NBMEMSIZE);
                    377:                return;
                    378:        }
                    379:
                    380:        /* make sure interrupts are vectored to us */
                    381:        add_nubus_intr(na->slot, dp8390_intr, sc, sc->sc_dev.dv_xname);
                    382: }
                    383:
                    384: static int
                    385: ae_nb_card_vendor(bst, bsh, na)
                    386:        bus_space_tag_t bst;
                    387:        bus_space_handle_t bsh;
                    388:        struct nubus_attach_args *na;
                    389: {
                    390:        int vendor;
                    391:
                    392:        switch (na->drsw) {
                    393:        case NUBUS_DRSW_3COM:
                    394:                switch (na->drhw) {
                    395:                case NUBUS_DRHW_APPLE_SN:
                    396:                case NUBUS_DRHW_APPLE_SNT:
                    397:                        vendor = DP8390_VENDOR_UNKNOWN;
                    398:                        break;
                    399:                default:
                    400:                        vendor = DP8390_VENDOR_APPLE;
                    401:                        break;
                    402:                }
                    403:                break;
                    404:        case NUBUS_DRSW_APPLE:
                    405:                if (na->drhw == NUBUS_DRHW_ASANTE_LC) {
                    406:                        vendor = DP8390_VENDOR_UNKNOWN;
                    407:                        break;
                    408:                }
                    409:                /* FALLTHROUGH */
                    410:        case NUBUS_DRSW_DAYNA2:
                    411:        case NUBUS_DRSW_TECHWORKS:
                    412:        case NUBUS_DRSW_TFLLAN:
                    413:                if (na->drhw == NUBUS_DRHW_CABLETRON) {
                    414:                        vendor = DP8390_VENDOR_CABLETRON;
                    415:                } else {
                    416:                        vendor = DP8390_VENDOR_APPLE;
                    417:                }
                    418:                break;
                    419:        case NUBUS_DRSW_ASANTE:
                    420:                vendor = DP8390_VENDOR_ASANTE;
                    421:                break;
                    422:        case NUBUS_DRSW_FARALLON:
                    423:                vendor = DP8390_VENDOR_FARALLON;
                    424:                break;
                    425:        case NUBUS_DRSW_FOCUS:
                    426:                vendor = DP8390_VENDOR_FOCUS;
                    427:                break;
                    428:        case NUBUS_DRSW_GATOR:
                    429:                switch (na->drhw) {
                    430:                default:
                    431:                case NUBUS_DRHW_INTERLAN:
                    432:                        vendor = DP8390_VENDOR_INTERLAN;
                    433:                        break;
                    434:                case NUBUS_DRHW_KINETICS:
                    435:                        if (strncmp(nubus_get_card_name(bst, bsh, na->fmt),
                    436:                            "EtherPort", 9) == 0)
                    437:                                vendor = DP8390_VENDOR_KINETICS;
                    438:                        else
                    439:                                vendor = DP8390_VENDOR_DAYNA;
                    440:                        break;
                    441:                }
                    442:                break;
                    443:        default:
                    444:                vendor = DP8390_VENDOR_UNKNOWN;
                    445:        }
                    446:        return vendor;
                    447: }
                    448:
                    449: static int
                    450: ae_nb_get_enaddr(bst, bsh, na, ep)
                    451:        bus_space_tag_t bst;
                    452:        bus_space_handle_t bsh;
                    453:        struct nubus_attach_args *na;
                    454:        u_int8_t *ep;
                    455: {
                    456:        nubus_dir dir;
                    457:        nubus_dirent dirent;
                    458:        int rv;
                    459:
                    460:        /*
                    461:         * XXX - note hardwired resource IDs here (0x80); these are
                    462:         * assumed to be used by all cards, but should be fixed when
                    463:         * we find out more about Ethernet card resources.
                    464:         */
                    465:        nubus_get_main_dir(na->fmt, &dir);
                    466:        switch (ae_nb_card_vendor(bst, bsh, na)) {
                    467:        case DP8390_VENDOR_APPLE:
                    468:                if (na->drsw == NUBUS_DRSW_TFLLAN) {    /* TFL LAN E410/E420 */
                    469:                        rv = nubus_find_rsrc(bst, bsh, na->fmt,
                    470:                            &dir, 0x80, &dirent);
                    471:                        break;
                    472:                }
                    473:                /* FALLTHROUGH */
                    474:        default:
                    475:                rv = nubus_find_rsrc(bst, bsh, na->fmt, &dir, 0x80, &dirent);
                    476:                break;
                    477:        }
                    478:        if (rv <= 0)
                    479:                return 1;
                    480:        nubus_get_dir_from_rsrc(na->fmt, &dirent, &dir);
                    481:        if (nubus_find_rsrc(bst, bsh, na->fmt, &dir, 0x80, &dirent) <= 0)
                    482:                return 1;
                    483:        if (nubus_get_ind_data(bst, bsh,
                    484:            na->fmt, &dirent, ep, ETHER_ADDR_LEN) <= 0)
                    485:                return 1;
                    486:
                    487:        return 0;
                    488: }
                    489:
                    490: #ifdef DEBUG
                    491: static void
                    492: ae_nb_watchdog(ifp)
                    493:        struct ifnet *ifp;
                    494: {
                    495:        struct dp8390_softc *sc = ifp->if_softc;
                    496:        extern via2hand_t via2intrs[7];
                    497:
                    498: /*
                    499:  * This is a kludge!  The via code seems to miss slot interrupts
                    500:  * sometimes.  This kludges around that by calling the handler
                    501:  * by hand if the watchdog is activated. -- XXX (akb)
                    502:  * XXX note that this assumes the nubus handler is first in the chain.
                    503:  */
                    504:        if (!SLIST_EMPTY(&via2intrs[1])) {
                    505:                struct via2hand *vh = SLIST_FIRST(&via2intrs[1]);
                    506:                (void)(*vh->vh_fn)(vh->vh_arg);
                    507:        }
                    508:
                    509:        log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
                    510:        ++sc->sc_arpcom.ac_if.if_oerrors;
                    511:
                    512:        dp8390_reset(sc);
                    513: }
                    514: #endif

CVSweb