[BACK]Return to if_ix.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / isa

Annotation of src/sys/dev/isa/if_ix.c, Revision 1.20

1.20    ! perry       1: /*     $NetBSD: if_ix.c,v 1.19 2004/09/14 20:20:47 drochner Exp $      */
1.1       pk          2:
                      3: /*-
                      4:  * Copyright (c) 1998 The NetBSD Foundation, Inc.
                      5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to The NetBSD Foundation
                      8:  * by Rafal K. Boni.
                      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:  * 3. All advertising materials mentioning features or use of this software
                     19:  *    must display the following acknowledgement:
                     20:  *     This product includes software developed by the NetBSD
                     21:  *     Foundation, Inc. and its contributors.
                     22:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     23:  *    contributors may be used to endorse or promote products derived
                     24:  *    from this software without specific prior written permission.
                     25:  *
                     26:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     27:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     28:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     29:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     30:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     31:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     32:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     33:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     34:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     35:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     36:  * POSSIBILITY OF SUCH DAMAGE.
                     37:  */
1.10      lukem      38:
                     39: #include <sys/cdefs.h>
1.20    ! perry      40: __KERNEL_RCSID(0, "$NetBSD: if_ix.c,v 1.19 2004/09/14 20:20:47 drochner Exp $");
1.1       pk         41:
                     42: #include <sys/param.h>
                     43: #include <sys/systm.h>
                     44: #include <sys/mbuf.h>
                     45: #include <sys/errno.h>
                     46: #include <sys/device.h>
                     47: #include <sys/protosw.h>
                     48: #include <sys/socket.h>
                     49:
                     50: #include <net/if.h>
                     51: #include <net/if_dl.h>
                     52: #include <net/if_types.h>
                     53: #include <net/if_media.h>
                     54: #include <net/if_ether.h>
                     55:
                     56: #include <machine/cpu.h>
                     57: #include <machine/bus.h>
                     58: #include <machine/intr.h>
                     59:
                     60: #include <dev/isa/isareg.h>
                     61: #include <dev/isa/isavar.h>
                     62:
                     63: #include <dev/ic/i82586reg.h>
                     64: #include <dev/ic/i82586var.h>
                     65: #include <dev/isa/if_ixreg.h>
                     66:
                     67: #ifdef IX_DEBUG
                     68: #define DPRINTF(x)     printf x
                     69: #else
1.2       pk         70: #define DPRINTF(x)
1.1       pk         71: #endif
                     72:
1.2       pk         73: int ix_media[] = {
1.1       pk         74:        IFM_ETHER | IFM_10_5,
                     75:        IFM_ETHER | IFM_10_2,
                     76:        IFM_ETHER | IFM_10_T,
                     77: };
                     78: #define NIX_MEDIA       (sizeof(ix_media) / sizeof(ix_media[0]))
                     79:
                     80: struct ix_softc {
1.2       pk         81:        struct ie_softc sc_ie;
1.1       pk         82:
1.2       pk         83:        bus_space_tag_t sc_regt;        /* space tag for registers */
                     84:        bus_space_handle_t sc_regh;     /* space handle for registers */
1.1       pk         85:
1.8       bjh21      86:        u_int8_t        use_pio;        /* use PIO rather than shared mem */
1.2       pk         87:        u_int16_t       irq_encoded;    /* encoded IRQ */
                     88:        void            *sc_ih;         /* interrupt handle */
1.1       pk         89: };
                     90:
1.20    ! perry      91: static void    ix_reset(struct ie_softc *, int);
        !            92: static void    ix_atten(struct ie_softc *, int);
        !            93: static int     ix_intrhook(struct ie_softc *, int);
1.1       pk         94:
1.20    ! perry      95: static void     ix_copyin(struct ie_softc *, void *, int, size_t);
        !            96: static void     ix_copyout(struct ie_softc *, const void *, int, size_t);
1.2       pk         97:
1.20    ! perry      98: static void    ix_bus_barrier(struct ie_softc *, int, int, int);
1.8       bjh21      99:
1.20    ! perry     100: static u_int16_t ix_read_16(struct ie_softc *, int);
        !           101: static void    ix_write_16(struct ie_softc *, int, u_int16_t);
        !           102: static void    ix_write_24(struct ie_softc *, int, int);
        !           103: static void    ix_zeromem (struct ie_softc *, int, int);
1.2       pk        104:
1.20    ! perry     105: static void    ix_mediastatus(struct ie_softc *, struct ifmediareq *);
1.1       pk        106:
1.20    ! perry     107: static u_int16_t ix_read_eeprom(bus_space_tag_t, bus_space_handle_t, int);
        !           108: static void    ix_eeprom_outbits(bus_space_tag_t, bus_space_handle_t, int, int);
        !           109: static int     ix_eeprom_inbits (bus_space_tag_t, bus_space_handle_t);
        !           110: static void    ix_eeprom_clock  (bus_space_tag_t, bus_space_handle_t, int);
1.1       pk        111:
1.20    ! perry     112: int ix_match(struct device *, struct cfdata *, void *);
        !           113: void ix_attach(struct device *, struct device *, void *);
1.1       pk        114:
                    115: /*
                    116:  * EtherExpress/16 support routines
                    117:  */
                    118: static void
                    119: ix_reset(sc, why)
1.2       pk        120:        struct ie_softc *sc;
                    121:        int why;
1.1       pk        122: {
1.2       pk        123:        struct ix_softc* isc = (struct ix_softc *) sc;
1.1       pk        124:
1.2       pk        125:        switch (why) {
                    126:        case CHIP_PROBE:
                    127:                bus_space_write_1(isc->sc_regt, isc->sc_regh, IX_ECTRL,
                    128:                                  IX_RESET_586);
                    129:                delay(100);
                    130:                bus_space_write_1(isc->sc_regt, isc->sc_regh, IX_ECTRL, 0);
                    131:                delay(100);
                    132:                break;
1.1       pk        133:
1.2       pk        134:        case CARD_RESET:
                    135:                break;
1.1       pk        136:     }
                    137: }
                    138:
                    139: static void
1.9       jdolecek  140: ix_atten(sc, why)
1.2       pk        141:        struct ie_softc *sc;
1.9       jdolecek  142:        int why;
1.1       pk        143: {
1.2       pk        144:        struct ix_softc* isc = (struct ix_softc *) sc;
                    145:        bus_space_write_1(isc->sc_regt, isc->sc_regh, IX_ATTN, 0);
1.1       pk        146: }
                    147:
                    148: static u_int16_t
1.3       pk        149: ix_read_eeprom(iot, ioh, location)
                    150:        bus_space_tag_t iot;
                    151:        bus_space_handle_t ioh;
1.2       pk        152:        int location;
1.1       pk        153: {
1.2       pk        154:        int ectrl, edata;
1.1       pk        155:
1.3       pk        156:        ectrl = bus_space_read_1(iot, ioh, IX_ECTRL);
1.2       pk        157:        ectrl &= IX_ECTRL_MASK;
                    158:        ectrl |= IX_ECTRL_EECS;
1.3       pk        159:        bus_space_write_1(iot, ioh, IX_ECTRL, ectrl);
1.2       pk        160:
1.3       pk        161:        ix_eeprom_outbits(iot, ioh, IX_EEPROM_READ, IX_EEPROM_OPSIZE1);
                    162:        ix_eeprom_outbits(iot, ioh, location, IX_EEPROM_ADDR_SIZE);
                    163:        edata = ix_eeprom_inbits(iot, ioh);
                    164:        ectrl = bus_space_read_1(iot, ioh, IX_ECTRL);
1.2       pk        165:        ectrl &= ~(IX_RESET_ASIC | IX_ECTRL_EEDI | IX_ECTRL_EECS);
1.3       pk        166:        bus_space_write_1(iot, ioh, IX_ECTRL, ectrl);
                    167:        ix_eeprom_clock(iot, ioh, 1);
                    168:        ix_eeprom_clock(iot, ioh, 0);
1.2       pk        169:        return (edata);
1.1       pk        170: }
                    171:
                    172: static void
1.3       pk        173: ix_eeprom_outbits(iot, ioh, edata, count)
                    174:        bus_space_tag_t iot;
                    175:        bus_space_handle_t ioh;
1.2       pk        176:        int edata, count;
1.1       pk        177: {
1.2       pk        178:        int ectrl, i;
1.1       pk        179:
1.3       pk        180:        ectrl = bus_space_read_1(iot, ioh, IX_ECTRL);
1.2       pk        181:        ectrl &= ~IX_RESET_ASIC;
                    182:        for (i = count - 1; i >= 0; i--) {
                    183:                ectrl &= ~IX_ECTRL_EEDI;
                    184:                if (edata & (1 << i)) {
                    185:                        ectrl |= IX_ECTRL_EEDI;
                    186:                }
1.3       pk        187:                bus_space_write_1(iot, ioh, IX_ECTRL, ectrl);
1.2       pk        188:                delay(1);       /* eeprom data must be setup for 0.4 uSec */
1.3       pk        189:                ix_eeprom_clock(iot, ioh, 1);
                    190:                ix_eeprom_clock(iot, ioh, 0);
1.2       pk        191:        }
                    192:        ectrl &= ~IX_ECTRL_EEDI;
1.3       pk        193:        bus_space_write_1(iot, ioh, IX_ECTRL, ectrl);
1.2       pk        194:        delay(1);               /* eeprom data must be held for 0.4 uSec */
1.1       pk        195: }
                    196:
                    197: static int
1.3       pk        198: ix_eeprom_inbits(iot, ioh)
                    199:        bus_space_tag_t iot;
                    200:        bus_space_handle_t ioh;
1.1       pk        201: {
1.2       pk        202:        int ectrl, edata, i;
1.1       pk        203:
1.3       pk        204:        ectrl = bus_space_read_1(iot, ioh, IX_ECTRL);
1.2       pk        205:        ectrl &= ~IX_RESET_ASIC;
                    206:        for (edata = 0, i = 0; i < 16; i++) {
                    207:                edata = edata << 1;
1.3       pk        208:                ix_eeprom_clock(iot, ioh, 1);
                    209:                ectrl = bus_space_read_1(iot, ioh, IX_ECTRL);
1.2       pk        210:                if (ectrl & IX_ECTRL_EEDO) {
                    211:                        edata |= 1;
                    212:                }
1.3       pk        213:                ix_eeprom_clock(iot, ioh, 0);
1.2       pk        214:        }
                    215:        return (edata);
1.1       pk        216: }
                    217:
                    218: static void
1.3       pk        219: ix_eeprom_clock(iot, ioh, state)
                    220:        bus_space_tag_t iot;
                    221:        bus_space_handle_t ioh;
1.2       pk        222:        int state;
1.1       pk        223: {
1.2       pk        224:        int ectrl;
1.1       pk        225:
1.3       pk        226:        ectrl = bus_space_read_1(iot, ioh, IX_ECTRL);
1.2       pk        227:        ectrl &= ~(IX_RESET_ASIC | IX_ECTRL_EESK);
                    228:        if (state) {
                    229:                ectrl |= IX_ECTRL_EESK;
                    230:        }
1.3       pk        231:        bus_space_write_1(iot, ioh, IX_ECTRL, ectrl);
1.2       pk        232:        delay(9);               /* EESK must be stable for 8.38 uSec */
1.1       pk        233: }
                    234:
                    235: static int
                    236: ix_intrhook(sc, where)
                    237:        struct ie_softc *sc;
                    238:        int where;
                    239: {
1.2       pk        240:        struct ix_softc* isc = (struct ix_softc *) sc;
1.1       pk        241:
1.2       pk        242:        switch (where) {
                    243:        case INTR_ENTER:
                    244:                /* entering ISR: disable card interrupts */
                    245:                bus_space_write_1(isc->sc_regt, isc->sc_regh,
                    246:                                  IX_IRQ, isc->irq_encoded);
                    247:                break;
                    248:
                    249:        case INTR_EXIT:
                    250:                /* exiting ISR: re-enable card interrupts */
                    251:                bus_space_write_1(isc->sc_regt, isc->sc_regh, IX_IRQ,
                    252:                                  isc->irq_encoded | IX_IRQ_ENABLE);
1.1       pk        253:        break;
                    254:     }
                    255:
                    256:     return 1;
                    257: }
                    258:
                    259:
                    260: static void
                    261: ix_copyin (sc, dst, offset, size)
                    262:         struct ie_softc *sc;
                    263:         void *dst;
                    264:         int offset;
                    265:         size_t size;
                    266: {
1.8       bjh21     267:        int i, dribble;
1.2       pk        268:        u_int8_t* bptr = dst;
1.8       bjh21     269:        u_int16_t* wptr = dst;
                    270:        struct ix_softc* isc = (struct ix_softc *) sc;
1.1       pk        271:
1.8       bjh21     272:        if (isc->use_pio) {
                    273:                /* Reset read pointer to the specified offset */
                    274:                bus_space_barrier(sc->bt, sc->bh, IX_DATAPORT, 2,
                    275:                                                  BUS_SPACE_BARRIER_READ);
                    276:                bus_space_write_2(sc->bt, sc->bh, IX_READPTR, offset);
                    277:                bus_space_barrier(sc->bt, sc->bh, IX_READPTR, 2,
                    278:                                                  BUS_SPACE_BARRIER_WRITE);
                    279:        } else {
1.2       pk        280:        bus_space_barrier(sc->bt, sc->bh, offset, size,
                    281:                          BUS_SPACE_BARRIER_READ);
1.8       bjh21     282:        }
1.1       pk        283:
1.2       pk        284:        if (offset % 2) {
1.8       bjh21     285:                if (isc->use_pio)
                    286:                        *bptr = bus_space_read_1(sc->bt, sc->bh, IX_DATAPORT);
                    287:                else
1.2       pk        288:                *bptr = bus_space_read_1(sc->bt, sc->bh, offset);
                    289:                offset++; bptr++; size--;
                    290:        }
                    291:
                    292:        dribble = size % 2;
1.8       bjh21     293:        wptr = (u_int16_t*) bptr;
                    294:
                    295:        if (isc->use_pio) {
                    296:                for(i = 0; i <  size / 2; i++) {
                    297:                        *wptr = bus_space_read_2(sc->bt, sc->bh, IX_DATAPORT);
                    298:                        wptr++;
                    299:                }
                    300:        } else {
                    301:                bus_space_read_region_2(sc->bt, sc->bh, offset,
                    302:                                        (u_int16_t *) bptr, size / 2);
                    303:        }
1.2       pk        304:
                    305:        if (dribble) {
                    306:                bptr += size - 1;
                    307:                offset += size - 1;
1.8       bjh21     308:
                    309:                if (isc->use_pio)
                    310:                        *bptr = bus_space_read_1(sc->bt, sc->bh, IX_DATAPORT);
                    311:                else
1.2       pk        312:                *bptr = bus_space_read_1(sc->bt, sc->bh, offset);
                    313:        }
1.1       pk        314: }
                    315:
                    316: static void
1.2       pk        317: ix_copyout (sc, src, offset, size)
1.1       pk        318:         struct ie_softc *sc;
                    319:         const void *src;
                    320:         int offset;
                    321:         size_t size;
                    322: {
1.8       bjh21     323:        int i, dribble;
1.2       pk        324:        int osize = size;
                    325:        int ooffset = offset;
                    326:        const u_int8_t* bptr = src;
1.8       bjh21     327:        const u_int16_t* wptr = src;
                    328:        struct ix_softc* isc = (struct ix_softc *) sc;
                    329:
                    330:        if (isc->use_pio) {
                    331:                /* Reset write pointer to the specified offset */
                    332:                bus_space_write_2(sc->bt, sc->bh, IX_WRITEPTR, offset);
                    333:                bus_space_barrier(sc->bt, sc->bh, IX_WRITEPTR, 2,
                    334:                                                  BUS_SPACE_BARRIER_WRITE);
                    335:        }
1.2       pk        336:
                    337:        if (offset % 2) {
1.8       bjh21     338:                if (isc->use_pio)
                    339:                        bus_space_write_1(sc->bt, sc->bh, IX_DATAPORT, *bptr);
                    340:                else
1.2       pk        341:                bus_space_write_1(sc->bt, sc->bh, offset, *bptr);
                    342:                offset++; bptr++; size--;
                    343:        }
                    344:
                    345:        dribble = size % 2;
1.8       bjh21     346:        wptr = (u_int16_t*) bptr;
                    347:
                    348:        if (isc->use_pio) {
                    349:                for(i = 0; i < size / 2; i++) {
                    350:                        bus_space_write_2(sc->bt, sc->bh, IX_DATAPORT, *wptr);
                    351:                        wptr++;
                    352:                }
                    353:        } else {
                    354:                bus_space_write_region_2(sc->bt, sc->bh, offset,
                    355:                                         (u_int16_t *)bptr, size / 2);
                    356:        }
                    357:
1.2       pk        358:        if (dribble) {
                    359:                bptr += size - 1;
                    360:                offset += size - 1;
1.8       bjh21     361:
                    362:                if (isc->use_pio)
                    363:                        bus_space_write_1(sc->bt, sc->bh, IX_DATAPORT, *bptr);
                    364:                else
1.2       pk        365:                bus_space_write_1(sc->bt, sc->bh, offset, *bptr);
                    366:        }
1.1       pk        367:
1.8       bjh21     368:        if (isc->use_pio)
                    369:                bus_space_barrier(sc->bt, sc->bh, IX_DATAPORT, 2,
                    370:                                                  BUS_SPACE_BARRIER_WRITE);
                    371:        else
1.2       pk        372:        bus_space_barrier(sc->bt, sc->bh, ooffset, osize,
                    373:                          BUS_SPACE_BARRIER_WRITE);
1.1       pk        374: }
                    375:
1.8       bjh21     376: static void
                    377: ix_bus_barrier(sc, offset, length, flags)
                    378:         struct ie_softc *sc;
                    379:         int offset, length, flags;
                    380: {
                    381:        struct ix_softc* isc = (struct ix_softc *) sc;
                    382:
                    383:        if (isc->use_pio)
                    384:                bus_space_barrier(sc->bt, sc->bh, IX_DATAPORT, 2, flags);
                    385:        else
                    386:                bus_space_barrier(sc->bt, sc->bh, offset, length, flags);
                    387: }
                    388:
1.1       pk        389: static u_int16_t
                    390: ix_read_16 (sc, offset)
                    391:         struct ie_softc *sc;
                    392:         int offset;
                    393: {
1.8       bjh21     394:        struct ix_softc* isc = (struct ix_softc *) sc;
                    395:
                    396:        if (isc->use_pio) {
                    397:                bus_space_barrier(sc->bt, sc->bh, IX_DATAPORT, 2,
                    398:                                                  BUS_SPACE_BARRIER_READ);
                    399:
                    400:                /* Reset read pointer to the specified offset */
                    401:                bus_space_write_2(sc->bt, sc->bh, IX_READPTR, offset);
                    402:                bus_space_barrier(sc->bt, sc->bh, IX_READPTR, 2,
                    403:                                                  BUS_SPACE_BARRIER_WRITE);
                    404:
                    405:                return bus_space_read_2(sc->bt, sc->bh, IX_DATAPORT);
                    406:        } else {
                    407:                bus_space_barrier(sc->bt, sc->bh, offset, 2,
                    408:                                                  BUS_SPACE_BARRIER_READ);
1.1       pk        409:         return bus_space_read_2(sc->bt, sc->bh, offset);
1.8       bjh21     410:        }
1.1       pk        411: }
                    412:
                    413: static void
1.2       pk        414: ix_write_16 (sc, offset, value)
1.1       pk        415:         struct ie_softc *sc;
                    416:         int offset;
                    417:         u_int16_t value;
                    418: {
1.8       bjh21     419:        struct ix_softc* isc = (struct ix_softc *) sc;
                    420:
                    421:        if (isc->use_pio) {
                    422:                /* Reset write pointer to the specified offset */
                    423:                bus_space_write_2(sc->bt, sc->bh, IX_WRITEPTR, offset);
                    424:                bus_space_barrier(sc->bt, sc->bh, IX_WRITEPTR, 2,
                    425:                                                  BUS_SPACE_BARRIER_WRITE);
                    426:
                    427:                bus_space_write_2(sc->bt, sc->bh, IX_DATAPORT, value);
                    428:                bus_space_barrier(sc->bt, sc->bh, IX_DATAPORT, 2,
                    429:                                                  BUS_SPACE_BARRIER_WRITE);
                    430:        } else {
1.1       pk        431:         bus_space_write_2(sc->bt, sc->bh, offset, value);
1.8       bjh21     432:                bus_space_barrier(sc->bt, sc->bh, offset, 2,
                    433:                                                  BUS_SPACE_BARRIER_WRITE);
                    434:        }
1.1       pk        435: }
                    436:
                    437: static void
                    438: ix_write_24 (sc, offset, addr)
                    439:         struct ie_softc *sc;
                    440:         int offset, addr;
                    441: {
1.8       bjh21     442:        char* ptr;
                    443:        struct ix_softc* isc = (struct ix_softc *) sc;
                    444:        int val = addr + (u_long) sc->sc_maddr - (u_long) sc->sc_iobase;
                    445:
                    446:        if (isc->use_pio) {
                    447:                /* Reset write pointer to the specified offset */
                    448:                bus_space_write_2(sc->bt, sc->bh, IX_WRITEPTR, offset);
                    449:                bus_space_barrier(sc->bt, sc->bh, IX_WRITEPTR, 2,
                    450:                                                  BUS_SPACE_BARRIER_WRITE);
                    451:
                    452:                ptr = (char*) &val;
                    453:                bus_space_write_2(sc->bt, sc->bh, IX_DATAPORT,
                    454:                                                  *((u_int16_t *)ptr));
                    455:                bus_space_write_2(sc->bt, sc->bh, IX_DATAPORT,
                    456:                                                  *((u_int16_t *)(ptr + 2)));
                    457:                bus_space_barrier(sc->bt, sc->bh, IX_DATAPORT, 2,
                    458:                                                  BUS_SPACE_BARRIER_WRITE);
                    459:        } else {
                    460:                bus_space_write_4(sc->bt, sc->bh, offset, val);
                    461:                bus_space_barrier(sc->bt, sc->bh, offset, 4,
                    462:                                                  BUS_SPACE_BARRIER_WRITE);
                    463:        }
                    464: }
                    465:
                    466: static void
                    467: ix_zeromem(sc, offset, count)
                    468:         struct ie_softc *sc;
                    469:         int offset, count;
                    470: {
                    471:        int i;
                    472:        int dribble;
                    473:        struct ix_softc* isc = (struct ix_softc *) sc;
                    474:
                    475:        if (isc->use_pio) {
                    476:                /* Reset write pointer to the specified offset */
                    477:                bus_space_write_2(sc->bt, sc->bh, IX_WRITEPTR, offset);
                    478:                bus_space_barrier(sc->bt, sc->bh, IX_WRITEPTR, 2,
                    479:                                                  BUS_SPACE_BARRIER_WRITE);
                    480:
                    481:                if (offset % 2) {
                    482:                        bus_space_write_1(sc->bt, sc->bh, IX_DATAPORT, 0);
                    483:                        count--;
                    484:                }
                    485:
                    486:                dribble = count % 2;
                    487:                for(i = 0; i < count / 2; i++)
                    488:                        bus_space_write_2(sc->bt, sc->bh, IX_DATAPORT, 0);
                    489:
                    490:                if (dribble)
                    491:                        bus_space_write_1(sc->bt, sc->bh, IX_DATAPORT, 0);
                    492:
                    493:                bus_space_barrier(sc->bt, sc->bh, IX_DATAPORT, 2,
                    494:                                                  BUS_SPACE_BARRIER_WRITE);
                    495:        } else {
                    496:                bus_space_set_region_1(sc->bt, sc->bh, offset, 0, count);
                    497:                bus_space_barrier(sc->bt, sc->bh, offset, count,
                    498:                                                  BUS_SPACE_BARRIER_WRITE);
                    499:        }
1.1       pk        500: }
                    501:
                    502: static void
                    503: ix_mediastatus(sc, ifmr)
1.2       pk        504:         struct ie_softc *sc;
                    505:         struct ifmediareq *ifmr;
1.1       pk        506: {
                    507:         struct ifmedia *ifm = &sc->sc_media;
                    508:
                    509:         /*
1.2       pk        510:          * The currently selected media is always the active media.
1.1       pk        511:          */
                    512:         ifmr->ifm_active = ifm->ifm_cur->ifm_media;
                    513: }
                    514:
                    515: int
                    516: ix_match(parent, cf, aux)
1.2       pk        517:        struct device *parent;
                    518:        struct cfdata *cf;
                    519:        void *aux;
1.1       pk        520: {
1.2       pk        521:        int i;
                    522:        int rv = 0;
                    523:        bus_addr_t maddr;
                    524:        bus_size_t msize;
                    525:        u_short checksum = 0;
                    526:        bus_space_handle_t ioh;
1.3       pk        527:        bus_space_tag_t iot;
1.2       pk        528:        u_int8_t val, bart_config;
                    529:        u_short pg, adjust, decode, edecode;
1.3       pk        530:        u_short board_id, id_var1, id_var2, irq, irq_encoded;
1.2       pk        531:        struct isa_attach_args * const ia = aux;
                    532:        short irq_translate[] = {0, 0x09, 0x03, 0x04, 0x05, 0x0a, 0x0b, 0};
                    533:
1.13      thorpej   534:        if (ia->ia_nio < 1)
                    535:                return (0);
                    536:        if (ia->ia_niomem < 1)
                    537:                return (0);
                    538:        if (ia->ia_nirq < 1)
                    539:                return (0);
                    540:
                    541:        if (ISA_DIRECT_CONFIG(ia))
                    542:                return (0);
                    543:
1.3       pk        544:        iot = ia->ia_iot;
                    545:
1.19      drochner  546:        if (ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT)
1.13      thorpej   547:                return (0);
                    548:
                    549:        if (bus_space_map(iot, ia->ia_io[0].ir_addr,
1.2       pk        550:                          IX_IOSIZE, 0, &ioh) != 0) {
                    551:                DPRINTF(("Can't map io space at 0x%x\n", ia->ia_iobase));
                    552:                return (0);
                    553:        }
                    554:
                    555:        /* XXX: reset any ee16 at the current iobase */
1.3       pk        556:        bus_space_write_1(iot, ioh, IX_ECTRL, IX_RESET_ASIC);
                    557:        bus_space_write_1(iot, ioh, IX_ECTRL, 0);
1.2       pk        558:        delay(240);
                    559:
                    560:        /* now look for ee16. */
                    561:        board_id = id_var1 = id_var2 = 0;
                    562:        for (i = 0; i < 4 ; i++) {
1.3       pk        563:                id_var1 = bus_space_read_1(iot, ioh, IX_ID_PORT);
1.2       pk        564:                id_var2 = ((id_var1 & 0x03) << 2);
                    565:                board_id |= (( id_var1 >> 4)  << id_var2);
                    566:        }
                    567:
                    568:        if (board_id != IX_ID) {
                    569:                DPRINTF(("BART ID mismatch (got 0x%04x, expected 0x%04x)\n",
                    570:                        board_id, IX_ID));
                    571:                goto out;
                    572:        }
                    573:
                    574:        /*
                    575:         * The shared RAM size and location of the EE16 is encoded into
                    576:         * EEPROM location 6.  The location of the first set bit tells us
                    577:         * the memory address (0xc0000 + (0x4000 * FSB)), where FSB is the
                    578:         * number of the first set bit.  The zeroes are then shifted out,
                    579:         * and the results is the memory size (1 = 16k, 3 = 32k, 7 = 48k,
                    580:         * 0x0f = 64k).
                    581:         *
                    582:         * Examples:
                    583:         *   0x3c -> 64k@0xc8000, 0x70 -> 48k@0xd0000, 0xc0 -> 32k@0xd8000
                    584:         *   0x80 -> 16k@0xdc000.
                    585:         *
                    586:         * Side note: this comes from reading the old driver rather than
                    587:         * from a more definitive source, so it could be out-of-whack
                    588:         * with what the card can do...
                    589:         */
                    590:
1.3       pk        591:        val = ix_read_eeprom(iot, ioh, 6) & 0xff;
1.18      mycroft   592:        for (pg = 0; pg < 8; pg++) {
1.2       pk        593:                if (val & 1)
                    594:                        break;
1.18      mycroft   595:                val >>= 1;
1.2       pk        596:        }
                    597:
1.8       bjh21     598:        maddr = 0xc0000 + (pg * 0x4000);
1.2       pk        599:
                    600:        switch (val) {
1.8       bjh21     601:        case 0x00:
1.18      mycroft   602:                maddr = 0;
1.8       bjh21     603:                msize = 0;
                    604:                break;
                    605:
1.2       pk        606:        case 0x01:
                    607:                msize = 16 * 1024;
                    608:                break;
                    609:
                    610:        case 0x03:
                    611:                msize = 32 * 1024;
                    612:                break;
                    613:
                    614:        case 0x07:
                    615:                msize = 48 * 1024;
                    616:                break;
                    617:
                    618:        case 0x0f:
                    619:                msize = 64 * 1024;
                    620:                break;
                    621:
                    622:        default:
                    623:                DPRINTF(("invalid memory size %02x\n", val));
                    624:                goto out;
                    625:        }
                    626:
1.19      drochner  627:        if (ia->ia_iomem[0].ir_addr != ISA_UNKNOWN_IOMEM &&
1.13      thorpej   628:            ia->ia_iomem[0].ir_addr != maddr) {
1.2       pk        629:                DPRINTF((
                    630:                  "ix_match: memaddr of board @ 0x%x doesn't match config\n",
                    631:                  ia->ia_iobase));
                    632:                goto out;
                    633:        }
                    634:
1.19      drochner  635:        if (ia->ia_iomem[0].ir_size != ISA_UNKNOWN_IOSIZ &&
1.13      thorpej   636:            ia->ia_iomem[0].ir_size != msize) {
1.2       pk        637:                DPRINTF((
                    638:                   "ix_match: memsize of board @ 0x%x doesn't match config\n",
                    639:                   ia->ia_iobase));
                    640:                goto out;
                    641:        }
                    642:
                    643:        /* need to put the 586 in RESET, and leave it */
1.3       pk        644:        bus_space_write_1(iot, ioh, IX_ECTRL, IX_RESET_586);
1.2       pk        645:
                    646:        /* read the eeprom and checksum it, should == IX_ID */
                    647:        for(i = 0; i < 0x40; i++)
1.3       pk        648:                checksum += ix_read_eeprom(iot, ioh, i);
1.2       pk        649:
                    650:        if (checksum != IX_ID) {
                    651:                DPRINTF(("checksum mismatch (got 0x%04x, expected 0x%04x\n",
                    652:                        checksum, IX_ID));
                    653:                goto out;
                    654:        }
                    655:
                    656:        /*
1.8       bjh21     657:         * Only do the following bit if using memory-mapped access.  For
                    658:         * boards with no mapped memory, we use PIO.  We also use PIO for
                    659:         * boards with 16K of mapped memory, as those setups don't seem
                    660:         * to work otherwise.
1.2       pk        661:         */
1.8       bjh21     662:        if (msize != 0 && msize != 16384) {
                    663:                /* Set board up with memory-mapping info */
1.2       pk        664:        adjust = IX_MCTRL_FMCS16 | (pg & 0x3) << 2;
1.13      thorpej   665:        decode = ((1 << (ia->ia_iomem[0].ir_size / 16384)) - 1) << pg;
1.2       pk        666:        edecode = ((~decode >> 4) & 0xF0) | (decode >> 8);
                    667:
1.3       pk        668:        bus_space_write_1(iot, ioh, IX_MEMDEC, decode & 0xFF);
                    669:        bus_space_write_1(iot, ioh, IX_MCTRL, adjust);
                    670:        bus_space_write_1(iot, ioh, IX_MPCTRL, (~decode & 0xFF));
1.2       pk        671:
1.8       bjh21     672:                /* XXX disable Exxx */
                    673:                bus_space_write_1(iot, ioh, IX_MECTRL, edecode);
                    674:        }
1.2       pk        675:
                    676:        /*
                    677:         * Get the encoded interrupt number from the EEPROM, check it
                    678:         * against the passed in IRQ.  Issue a warning if they do not
1.19      drochner  679:         * match, and fail the probe.  If irq is 'ISA_UNKNOWN_IRQ' then we
1.2       pk        680:         * use the EEPROM irq, and continue.
                    681:         */
1.3       pk        682:        irq_encoded = ix_read_eeprom(iot, ioh, IX_EEPROM_CONFIG1);
                    683:        irq_encoded = (irq_encoded & IX_EEPROM_IRQ) >> IX_EEPROM_IRQ_SHIFT;
                    684:        irq = irq_translate[irq_encoded];
1.19      drochner  685:        if (ia->ia_irq[0].ir_irq != ISA_UNKNOWN_IRQ &&
1.13      thorpej   686:            irq != ia->ia_irq[0].ir_irq) {
1.2       pk        687:                DPRINTF(("board IRQ %d does not match config\n", irq));
                    688:                goto out;
                    689:        }
                    690:
                    691:        /* disable the board interrupts */
1.3       pk        692:        bus_space_write_1(iot, ioh, IX_IRQ, irq_encoded);
1.2       pk        693:
1.3       pk        694:        bart_config = bus_space_read_1(iot, ioh, IX_CONFIG);
1.2       pk        695:        bart_config |= IX_BART_LOOPBACK;
                    696:        bart_config |= IX_BART_MCS16_TEST; /* inb doesn't get bit! */
1.3       pk        697:        bus_space_write_1(iot, ioh, IX_CONFIG, bart_config);
                    698:        bart_config = bus_space_read_1(iot, ioh, IX_CONFIG);
1.2       pk        699:
1.3       pk        700:        bus_space_write_1(iot, ioh, IX_ECTRL, 0);
1.2       pk        701:        delay(100);
                    702:
                    703:        rv = 1;
1.13      thorpej   704:
                    705:        ia->ia_nio = 1;
                    706:        ia->ia_io[0].ir_size = IX_IOSIZE;
                    707:
                    708:        ia->ia_niomem = 1;
                    709:        ia->ia_iomem[0].ir_addr = maddr;
                    710:        ia->ia_iomem[0].ir_size = msize;
                    711:
                    712:        ia->ia_nirq = 1;
                    713:        ia->ia_irq[0].ir_irq = irq;
                    714:
1.2       pk        715:        DPRINTF(("ix_match: found board @ 0x%x\n", ia->ia_iobase));
1.1       pk        716:
                    717: out:
1.3       pk        718:        bus_space_unmap(iot, ioh, IX_IOSIZE);
1.2       pk        719:        return (rv);
1.1       pk        720: }
                    721:
                    722: void
                    723: ix_attach(parent, self, aux)
1.2       pk        724:        struct device *parent;
                    725:        struct device *self;
                    726:        void   *aux;
                    727: {
                    728:        struct ix_softc *isc = (void *)self;
                    729:        struct ie_softc *sc = &isc->sc_ie;
                    730:        struct isa_attach_args *ia = aux;
                    731:
                    732:        int media;
1.8       bjh21     733:        int i, memsize;
1.2       pk        734:        u_int8_t bart_config;
1.3       pk        735:        bus_space_tag_t iot;
1.8       bjh21     736:        u_int8_t bpat, bval;
                    737:        u_int16_t wpat, wval;
1.2       pk        738:        bus_space_handle_t ioh, memh;
1.3       pk        739:        u_short irq_encoded;
1.2       pk        740:        u_int8_t ethaddr[ETHER_ADDR_LEN];
                    741:
1.3       pk        742:        iot = ia->ia_iot;
                    743:
1.8       bjh21     744:        /*
                    745:         * Shared memory access seems to fail on 16K mapped boards, so
                    746:         * disable shared memory access if the board is in 16K mode.  If
                    747:         * no memory is mapped, we have no choice but to use PIO
                    748:         */
1.13      thorpej   749:        isc->use_pio = (ia->ia_iomem[0].ir_size <= (16 * 1024));
1.8       bjh21     750:
1.13      thorpej   751:        if (bus_space_map(iot, ia->ia_io[0].ir_addr,
                    752:                          ia->ia_io[0].ir_size, 0, &ioh) != 0) {
1.2       pk        753:
                    754:                DPRINTF(("\n%s: can't map i/o space 0x%x-0x%x\n",
1.13      thorpej   755:                          sc->sc_dev.dv_xname, ia->ia_[0].ir_addr,
                    756:                          ia->ia_io[0].ir_addr + ia->ia_io[0].ir_size - 1));
1.2       pk        757:                return;
                    758:        }
                    759:
1.8       bjh21     760:        /* We map memory even if using PIO so something else doesn't grab it */
1.13      thorpej   761:        if (ia->ia_iomem[0].ir_size) {
                    762:        if (bus_space_map(ia->ia_memt, ia->ia_iomem[0].ir_addr,
                    763:                          ia->ia_iomem[0].ir_size, 0, &memh) != 0) {
1.2       pk        764:                DPRINTF(("\n%s: can't map iomem space 0x%x-0x%x\n",
1.13      thorpej   765:                        sc->sc_dev.dv_xname, ia->ia_iomem[0].ir_addr,
                    766:                        ia->ia_iomem[0].ir_addr + ia->ia_iomem[0].ir_size - 1));
                    767:                bus_space_unmap(iot, ioh, ia->ia_io[0].ir_size);
1.2       pk        768:                return;
                    769:        }
1.8       bjh21     770:        }
1.2       pk        771:
1.3       pk        772:        isc->sc_regt = iot;
1.2       pk        773:        isc->sc_regh = ioh;
                    774:
                    775:        /*
                    776:         * Get the hardware ethernet address from the EEPROM and
                    777:         * save it in the softc for use by the 586 setup code.
                    778:         */
1.8       bjh21     779:        wval = ix_read_eeprom(iot, ioh, IX_EEPROM_ENET_HIGH);
                    780:        ethaddr[1] = wval & 0xFF;
                    781:        ethaddr[0] = wval >> 8;
                    782:        wval = ix_read_eeprom(iot, ioh, IX_EEPROM_ENET_MID);
                    783:        ethaddr[3] = wval & 0xFF;
                    784:        ethaddr[2] = wval >> 8;
                    785:        wval = ix_read_eeprom(iot, ioh, IX_EEPROM_ENET_LOW);
                    786:        ethaddr[5] = wval & 0xFF;
                    787:        ethaddr[4] = wval >> 8;
1.2       pk        788:
                    789:        sc->hwinit = NULL;
                    790:        sc->hwreset = ix_reset;
                    791:        sc->chan_attn = ix_atten;
                    792:        sc->intrhook = ix_intrhook;
                    793:
                    794:        sc->memcopyin = ix_copyin;
                    795:        sc->memcopyout = ix_copyout;
1.8       bjh21     796:
                    797:        /* If using PIO, make sure to setup single-byte read/write functions */
                    798:        if (isc->use_pio) {
                    799:                sc->ie_bus_barrier = ix_bus_barrier;
                    800:        } else {
                    801:                sc->ie_bus_barrier = NULL;
                    802:        }
                    803:
1.2       pk        804:        sc->ie_bus_read16 = ix_read_16;
                    805:        sc->ie_bus_write16 = ix_write_16;
                    806:        sc->ie_bus_write24 = ix_write_24;
                    807:
                    808:        sc->do_xmitnopchain = 0;
                    809:
                    810:        sc->sc_mediachange = NULL;
                    811:        sc->sc_mediastatus = ix_mediastatus;
                    812:
1.8       bjh21     813:        if (isc->use_pio) {
                    814:                sc->bt = iot;
                    815:                sc->bh = ioh;
                    816:
                    817:                /*
                    818:                 * If using PIO, the memory size is bounded by on-card memory,
                    819:                 * not by how much is mapped into the memory-mapped region, so
                    820:                 * determine how much total memory we have to play with here.
                    821:                 */
                    822:                for(memsize = 64 * 1024; memsize; memsize -= 16 * 1024) {
                    823:                        /* warm up shared memory, the zero it all out */
                    824:                        ix_zeromem(sc, 0, 32);
                    825:                        ix_zeromem(sc, 0, memsize);
                    826:
                    827:                        /* Reset write pointer to the start of RAM */
                    828:                        bus_space_write_2(iot, ioh, IX_WRITEPTR, 0);
                    829:                        bus_space_barrier(iot, ioh, IX_WRITEPTR, 2,
                    830:                                                    BUS_SPACE_BARRIER_WRITE);
                    831:
                    832:                        /* write test pattern */
1.12      rafal     833:                        for(i = 0, wpat = 1; i < memsize; i += 2) {
1.8       bjh21     834:                                bus_space_write_2(iot, ioh, IX_DATAPORT, wpat);
                    835:                                wpat += 3;
                    836:                        }
                    837:
                    838:                        /* Flush all reads & writes to data port */
                    839:                        bus_space_barrier(iot, ioh, IX_DATAPORT, 2,
                    840:                                                    BUS_SPACE_BARRIER_READ |
                    841:                                                    BUS_SPACE_BARRIER_WRITE);
                    842:
                    843:                        /* Reset read pointer to beginning of card RAM */
                    844:                        bus_space_write_2(iot, ioh, IX_READPTR, 0);
                    845:                        bus_space_barrier(iot, ioh, IX_READPTR, 2,
                    846:                                                    BUS_SPACE_BARRIER_WRITE);
                    847:
                    848:                        /* read and verify test pattern */
                    849:                        for(i = 0, wpat = 1; i < memsize; i += 2) {
                    850:                                wval = bus_space_read_2(iot, ioh, IX_DATAPORT);
                    851:
                    852:                                if (wval != wpat)
                    853:                                        break;
                    854:
                    855:                                wpat += 3;
                    856:                        }
                    857:
                    858:                        /* If we failed, try next size down */
                    859:                        if (i != memsize)
                    860:                                continue;
                    861:
                    862:                        /* Now try it all with byte reads/writes */
                    863:                        ix_zeromem(sc, 0, 32);
                    864:                        ix_zeromem(sc, 0, memsize);
                    865:
                    866:                        /* Reset write pointer to start of card RAM */
                    867:                        bus_space_write_2(iot, ioh, IX_WRITEPTR, 0);
                    868:                        bus_space_barrier(iot, ioh, IX_WRITEPTR, 2,
                    869:                                                    BUS_SPACE_BARRIER_WRITE);
                    870:
                    871:                        /* write out test pattern */
                    872:                        for(i = 0, bpat = 1; i < memsize; i++) {
                    873:                                bus_space_write_1(iot, ioh, IX_DATAPORT, bpat);
                    874:                                bpat += 3;
                    875:                        }
                    876:
                    877:                        /* Flush all reads & writes to data port */
                    878:                        bus_space_barrier(iot, ioh, IX_DATAPORT, 2,
                    879:                                                    BUS_SPACE_BARRIER_READ |
                    880:                                                    BUS_SPACE_BARRIER_WRITE);
                    881:
                    882:                        /* Reset read pointer to beginning of card RAM */
                    883:                        bus_space_write_2(iot, ioh, IX_READPTR, 0);
                    884:                        bus_space_barrier(iot, ioh, IX_READPTR, 2,
                    885:                                                    BUS_SPACE_BARRIER_WRITE);
                    886:
                    887:                        /* read and verify test pattern */
                    888:                        for(i = 0, bpat = 1; i < memsize; i++) {
                    889:                                bval = bus_space_read_1(iot, ioh, IX_DATAPORT);
                    890:
                    891:                                if (bval != bpat)
                    892:                                bpat += 3;
                    893:                        }
                    894:
                    895:                        /* If we got through all of memory, we're done! */
                    896:                        if (i == memsize)
                    897:                                break;
                    898:                }
                    899:
                    900:                /* Memory tests failed, punt... */
                    901:                if (memsize == 0)  {
                    902:                        DPRINTF(("\n%s: can't determine size of on-card RAM\n",
                    903:                                sc->sc_dev.dv_xname));
1.13      thorpej   904:                        bus_space_unmap(iot, ioh, ia->ia_io[0].ir_size);
1.8       bjh21     905:                        return;
                    906:                }
                    907:
                    908:                sc->bt = iot;
                    909:                sc->bh = ioh;
                    910:
                    911:                sc->sc_msize = memsize;
                    912:                sc->sc_maddr = (void*) 0;
                    913:        } else {
1.2       pk        914:        sc->bt = ia->ia_memt;
                    915:        sc->bh = memh;
                    916:
1.13      thorpej   917:        sc->sc_msize = ia->ia_iomem[0].ir_size;
1.6       augustss  918:        sc->sc_maddr = (void *)memh;
1.8       bjh21     919:        }
                    920:
                    921:        /* Map i/o space. */
1.6       augustss  922:        sc->sc_iobase = (char *)sc->sc_maddr + sc->sc_msize - (1 << 24);
1.2       pk        923:
                    924:        /* set up pointers to important on-card control structures */
                    925:        sc->iscp = 0;
                    926:        sc->scb = IE_ISCP_SZ;
                    927:        sc->scp = sc->sc_msize + IE_SCP_ADDR - (1 << 24);
                    928:
                    929:        sc->buf_area = sc->scb + IE_SCB_SZ;
                    930:        sc->buf_area_sz = sc->sc_msize - IE_ISCP_SZ - IE_SCB_SZ - IE_SCP_SZ;
                    931:
                    932:        /* zero card memory */
1.8       bjh21     933:        ix_zeromem(sc, 0, 32);
                    934:        ix_zeromem(sc, 0, sc->sc_msize);
1.2       pk        935:
                    936:        /* set card to 16-bit bus mode */
1.8       bjh21     937:        if (isc->use_pio) {
                    938:                bus_space_write_2(sc->bt, sc->bh, IX_WRITEPTR,
                    939:                                            IE_SCP_BUS_USE((u_long)sc->scp));
                    940:                bus_space_barrier(sc->bt, sc->bh, IX_WRITEPTR, 2,
                    941:                                                  BUS_SPACE_BARRIER_WRITE);
                    942:
1.11      fredette  943:                bus_space_write_1(sc->bt, sc->bh, IX_DATAPORT,
                    944:                                  IE_SYSBUS_16BIT);
1.8       bjh21     945:        } else {
                    946:                bus_space_write_1(sc->bt, sc->bh,
1.11      fredette  947:                                  IE_SCP_BUS_USE((u_long)sc->scp),
                    948:                                  IE_SYSBUS_16BIT);
1.8       bjh21     949:        }
1.2       pk        950:
                    951:        /* set up pointers to key structures */
                    952:        ix_write_24(sc, IE_SCP_ISCP((u_long)sc->scp), (u_long) sc->iscp);
                    953:        ix_write_16(sc, IE_ISCP_SCB((u_long)sc->iscp), (u_long) sc->scb);
                    954:        ix_write_24(sc, IE_ISCP_BASE((u_long)sc->iscp), (u_long) sc->iscp);
                    955:
                    956:        /* flush setup of pointers, check if chip answers */
1.8       bjh21     957:        if (isc->use_pio) {
                    958:                bus_space_barrier(sc->bt, sc->bh, 0, IX_IOSIZE,
                    959:                                  BUS_SPACE_BARRIER_WRITE);
                    960:        } else {
1.2       pk        961:        bus_space_barrier(sc->bt, sc->bh, 0, sc->sc_msize,
                    962:                          BUS_SPACE_BARRIER_WRITE);
1.8       bjh21     963:        }
                    964:
1.2       pk        965:        if (!i82586_proberam(sc)) {
                    966:                DPRINTF(("\n%s: Can't talk to i82586!\n",
                    967:                        sc->sc_dev.dv_xname));
1.13      thorpej   968:                bus_space_unmap(iot, ioh, ia->ia_io[0].ir_size);
1.8       bjh21     969:
1.13      thorpej   970:                if (ia->ia_iomem[0].ir_size)
                    971:                bus_space_unmap(ia->ia_memt, memh, ia->ia_iomem[0].ir_size);
1.2       pk        972:                return;
                    973:        }
                    974:
                    975:        /* Figure out which media is being used... */
1.3       pk        976:        if (ix_read_eeprom(iot, ioh, IX_EEPROM_CONFIG1) &
                    977:                                IX_EEPROM_MEDIA_EXT) {
                    978:                if (ix_read_eeprom(iot, ioh, IX_EEPROM_MEDIA) &
                    979:                                IX_EEPROM_MEDIA_TP)
1.2       pk        980:                        media = IFM_ETHER | IFM_10_T;
                    981:                else
                    982:                        media = IFM_ETHER | IFM_10_2;
                    983:        } else
                    984:                media = IFM_ETHER | IFM_10_5;
                    985:
                    986:        /* Take the card out of lookback */
1.3       pk        987:        bart_config = bus_space_read_1(iot, ioh, IX_CONFIG);
1.2       pk        988:        bart_config &= ~IX_BART_LOOPBACK;
                    989:        bart_config |= IX_BART_MCS16_TEST; /* inb doesn't get bit! */
1.3       pk        990:        bus_space_write_1(iot, ioh, IX_CONFIG, bart_config);
                    991:        bart_config = bus_space_read_1(iot, ioh, IX_CONFIG);
                    992:
                    993:        irq_encoded = ix_read_eeprom(iot, ioh,
                    994:                                     IX_EEPROM_CONFIG1);
                    995:        irq_encoded = (irq_encoded & IX_EEPROM_IRQ) >> IX_EEPROM_IRQ_SHIFT;
1.2       pk        996:
                    997:        /* Enable interrupts */
1.3       pk        998:        bus_space_write_1(iot, ioh, IX_IRQ,
                    999:                          irq_encoded | IX_IRQ_ENABLE);
                   1000:
1.8       bjh21    1001:        /* Flush all writes to registers */
1.13      thorpej  1002:        bus_space_barrier(iot, ioh, 0, ia->ia_io[0].ir_size,
                   1003:            BUS_SPACE_BARRIER_WRITE);
1.8       bjh21    1004:
1.3       pk       1005:        isc->irq_encoded = irq_encoded;
1.2       pk       1006:
                   1007:        i82586_attach(sc, "EtherExpress/16", ethaddr,
                   1008:                      ix_media, NIX_MEDIA, media);
1.8       bjh21    1009:
                   1010:        if (isc->use_pio)
                   1011:                printf("%s: unsupported memory config, using PIO to access %d bytes of memory\n", sc->sc_dev.dv_xname, sc->sc_msize);
1.2       pk       1012:
1.13      thorpej  1013:        isc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq,
                   1014:            IST_EDGE, IPL_NET, i82586_intr, sc);
1.2       pk       1015:        if (isc->sc_ih == NULL)
                   1016:                DPRINTF(("\n%s: can't establish interrupt\n",
                   1017:                        sc->sc_dev.dv_xname));
1.1       pk       1018: }
                   1019:
1.16      thorpej  1020: CFATTACH_DECL(ix, sizeof(struct ix_softc),
1.17      thorpej  1021:     ix_match, ix_attach, NULL, NULL);

CVSweb <webmaster@jp.NetBSD.org>