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

Annotation of sys/dev/ic/ne2000.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: ne2000.c,v 1.23 2006/11/07 01:46:59 brad Exp $        */
                      2: /*     $NetBSD: ne2000.c,v 1.12 1998/06/10 01:15:50 thorpej Exp $      */
                      3:
                      4: /*-
                      5:  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
                      6:  * All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to The NetBSD Foundation
                      9:  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
                     10:  * NASA Ames Research Center.
                     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. All advertising materials mentioning features or use of this software
                     21:  *    must display the following acknowledgement:
                     22:  *     This product includes software developed by the NetBSD
                     23:  *     Foundation, Inc. and its contributors.
                     24:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     25:  *    contributors may be used to endorse or promote products derived
                     26:  *    from this software without specific prior written permission.
                     27:  *
                     28:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     29:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     30:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     31:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     32:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     33:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     34:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     35:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     36:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     37:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     38:  * POSSIBILITY OF SUCH DAMAGE.
                     39:  */
                     40:
                     41: /*
                     42:  * Device driver for National Semiconductor DS8390/WD83C690 based ethernet
                     43:  * adapters.
                     44:  *
                     45:  * Copyright (c) 1994, 1995 Charles M. Hannum.  All rights reserved.
                     46:  *
                     47:  * Copyright (C) 1993, David Greenman.  This software may be used, modified,
                     48:  * copied, distributed, and sold, in both source and binary form provided that
                     49:  * the above copyright and these terms are retained.  Under no circumstances is
                     50:  * the author responsible for the proper functioning of this software, nor does
                     51:  * the author assume any responsibility for damages incurred with its use.
                     52:  */
                     53:
                     54: /*
                     55:  * Common code shared by all NE2000-compatible Ethernet interfaces.
                     56:  */
                     57:
                     58: #include <sys/param.h>
                     59: #include <sys/systm.h>
                     60: #include <sys/device.h>
                     61: #include <sys/socket.h>
                     62: #include <sys/mbuf.h>
                     63: #include <sys/syslog.h>
                     64:
                     65: #include <net/if.h>
                     66: #include <net/if_dl.h>
                     67: #include <net/if_types.h>
                     68: #include <net/if_media.h>
                     69:
                     70: #include <netinet/in.h>
                     71: #include <netinet/if_ether.h>
                     72:
                     73: #include <machine/bus.h>
                     74:
                     75: #include <dev/ic/dp8390reg.h>
                     76: #include <dev/ic/dp8390var.h>
                     77:
                     78: #include <dev/ic/ne2000reg.h>
                     79: #include <dev/ic/ne2000var.h>
                     80:
                     81: #include <dev/ic/ax88190reg.h>
                     82:
                     83: int    ne2000_write_mbuf(struct dp8390_softc *, struct mbuf *, int);
                     84: int    ne2000_ring_copy(struct dp8390_softc *, int, caddr_t, u_short);
                     85: void   ne2000_read_hdr(struct dp8390_softc *, int, struct dp8390_ring *);
                     86: int    ne2000_test_mem(struct dp8390_softc *);
                     87:
                     88: void   ne2000_writemem(bus_space_tag_t, bus_space_handle_t,
                     89:            bus_space_tag_t, bus_space_handle_t, u_int8_t *, int, size_t, int);
                     90: void   ne2000_readmem(bus_space_tag_t, bus_space_handle_t,
                     91:            bus_space_tag_t, bus_space_handle_t, int, u_int8_t *, size_t, int);
                     92:
                     93: #define ASIC_BARRIER(asict, asich) \
                     94:        bus_space_barrier((asict), (asich), 0, 0x10, \
                     95:            BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE)
                     96:
                     97: struct cfdriver ne_cd = {
                     98:        NULL, "ne", DV_IFNET
                     99: };
                    100:
                    101: int
                    102: ne2000_attach(struct ne2000_softc *nsc, u_int8_t *myea)
                    103: {
                    104:        struct dp8390_softc *dsc = &nsc->sc_dp8390;
                    105:        bus_space_tag_t nict = dsc->sc_regt;
                    106:        bus_space_handle_t nich = dsc->sc_regh;
                    107:        bus_space_tag_t asict = nsc->sc_asict;
                    108:        bus_space_handle_t asich = nsc->sc_asich;
                    109:        u_int8_t romdata[16];
                    110:        int memsize, i, useword;
                    111:
                    112:        /*
                    113:         * Detect it again unless caller specified it; this gives us
                    114:         * the memory size.
                    115:         */
                    116:        if (nsc->sc_type == NE2000_TYPE_UNKNOWN)
                    117:                nsc->sc_type = ne2000_detect(nsc);
                    118:
                    119:        /*
                    120:         * 8k of memory for NE1000, 16k otherwise.
                    121:         */
                    122:        switch (nsc->sc_type) {
                    123:        case NE2000_TYPE_UNKNOWN:
                    124:        default:
                    125:                printf(": where did the card go?\n");
                    126:                return (1);
                    127:        case NE2000_TYPE_NE1000:
                    128:                memsize = 8192;
                    129:                useword = 0;
                    130:                break;
                    131:        case NE2000_TYPE_NE2000:
                    132:        case NE2000_TYPE_AX88190:               /* XXX really? */
                    133:        case NE2000_TYPE_AX88790:
                    134:        case NE2000_TYPE_DL10019:
                    135:        case NE2000_TYPE_DL10022:
                    136:                memsize = 8192 * 2;
                    137:                useword = 1;
                    138:                break;
                    139:        }
                    140:
                    141:        nsc->sc_useword = useword;
                    142:
                    143:        dsc->cr_proto = ED_CR_RD2;
                    144:        if (nsc->sc_type == NE2000_TYPE_AX88190 ||
                    145:            nsc->sc_type == NE2000_TYPE_AX88790) {
                    146:                dsc->rcr_proto = ED_RCR_INTT;
                    147:                dsc->sc_flags |= DP8390_DO_AX88190_WORKAROUND;
                    148:        } else
                    149:                dsc->rcr_proto = 0;
                    150:
                    151:        /*
                    152:         * DCR gets:
                    153:         *
                    154:         *      FIFO threshold to 8, No auto-init Remote DMA,
                    155:         *      byte order=80x86.
                    156:         *
                    157:         * NE1000 gets byte-wide DMA, NE2000 gets word-wide DMA.
                    158:         */
                    159:        dsc->dcr_reg = ED_DCR_FT1 | ED_DCR_LS | (useword ? ED_DCR_WTS : 0);
                    160:
                    161:        dsc->test_mem = ne2000_test_mem;
                    162:        dsc->ring_copy = ne2000_ring_copy;
                    163:        dsc->write_mbuf = ne2000_write_mbuf;
                    164:        dsc->read_hdr = ne2000_read_hdr;
                    165:
                    166:        /* Registers are linear. */
                    167:        for (i = 0; i < 16; i++)
                    168:                dsc->sc_reg_map[i] = i;
                    169:
                    170:        /*
                    171:         * NIC memory doens't start at zero on an NE board.
                    172:         * The start address is tied to the bus width.
                    173:         * (It happens to be computed the same way as mem size.)
                    174:         */
                    175:        dsc->mem_start = memsize;
                    176:
                    177: #ifdef GWETHER
                    178:        {
                    179:                int x, mstart = 0;
                    180:                int8_t pbuf0[ED_PAGE_SIZE], pbuf[ED_PAGE_SIZE],
                    181:                    tbuf[ED_PAGE_SIZE];
                    182:
                    183:                for (i = 0; i < ED_PAGE_SIZE; i++)
                    184:                        pbuf0[i] = 0;
                    185:
                    186:                /* Search for the start of RAM. */
                    187:                for (x = 1; x < 256; x++) {
                    188:                        ne2000_writemem(nict, nich, asict, asich, pbuf0,
                    189:                            x << ED_PAGE_SHIFT, ED_PAGE_SIZE, useword);
                    190:                        ne2000_readmem(nict, nich, asict, asich,
                    191:                            x << ED_PAGE_SHIFT, tbuf, ED_PAGE_SIZE, useword);
                    192:                        if (bcmp(pbuf0, tbuf, ED_PAGE_SIZE) == 0) {
                    193:                                for (i = 0; i < ED_PAGE_SIZE; i++)
                    194:                                        pbuf[i] = 255 - x;
                    195:                                ne2000_writemem(nict, nich, asict, asich,
                    196:                                    pbuf, x << ED_PAGE_SHIFT, ED_PAGE_SIZE,
                    197:                                    useword);
                    198:                                ne2000_readmem(nict, nich, asict, asich,
                    199:                                    x << ED_PAGE_SHIFT, tbuf, ED_PAGE_SIZE,
                    200:                                    useword);
                    201:                                if (bcmp(pbuf, tbuf, ED_PAGE_SIZE) == 0) {
                    202:                                        mstart = x << ED_PAGE_SHIFT;
                    203:                                        memsize = ED_PAGE_SIZE;
                    204:                                        break;
                    205:                                }
                    206:                        }
                    207:                }
                    208:
                    209:                if (mstart == 0) {
                    210:                        printf(": cannot find start of RAM\n");
                    211:                        return;
                    212:                }
                    213:
                    214:                /* Search for the end of RAM. */
                    215:                for (++x; x < 256; x++) {
                    216:                        ne2000_writemem(nict, nich, asict, asich, pbuf0,
                    217:                            x << ED_PAGE_SHIFT, ED_PAGE_SIZE, useword);
                    218:                        ne2000_readmem(nict, nich, asict, asich,
                    219:                            x << ED_PAGE_SHIFT, tbuf, ED_PAGE_SIZE, useword);
                    220:                        if (bcmp(pbuf0, tbuf, ED_PAGE_SIZE) == 0) {
                    221:                                for (i = 0; i < ED_PAGE_SIZE; i++)
                    222:                                        pbuf[i] = 255 - x;
                    223:                                ne2000_writemem(nict, nich, asict, asich,
                    224:                                    pbuf, x << ED_PAGE_SHIFT, ED_PAGE_SIZE,
                    225:                                    useword);
                    226:                                ne2000_readmem(nict, nich, asict, asich,
                    227:                                    x << ED_PAGE_SHIFT, tbuf, ED_PAGE_SIZE,
                    228:                                    useword);
                    229:                                if (bcmp(pbuf, tbuf, ED_PAGE_SIZE) == 0)
                    230:                                        memsize += ED_PAGE_SIZE;
                    231:                                else
                    232:                                        break;
                    233:                        } else
                    234:                                break;
                    235:                }
                    236:
                    237:                printf(": RAM start 0x%x, size %d\n",
                    238:                    mstart, memsize);
                    239:
                    240:                dsc->mem_start = mstart;
                    241:        }
                    242: #endif /* GWETHER */
                    243:
                    244:        dsc->mem_size = memsize;
                    245:
                    246:        if (myea == NULL) {
                    247:                /* Read the station address. */
                    248:                if (nsc->sc_type == NE2000_TYPE_AX88190 ||
                    249:                    nsc->sc_type == NE2000_TYPE_AX88790) {
                    250:                        /* Select page 0 registers. */
                    251:                        NIC_BARRIER(nict, nich);
                    252:                        bus_space_write_1(nict, nich, ED_P0_CR,
                    253:                            ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
                    254:                        NIC_BARRIER(nict, nich);
                    255:                        /* Select word transfer. */
                    256:                        bus_space_write_1(nict, nich, ED_P0_DCR, ED_DCR_WTS);
                    257:                        NIC_BARRIER(nict, nich);
                    258:                        ne2000_readmem(nict, nich, asict, asich,
                    259:                            AX88190_NODEID_OFFSET, dsc->sc_arpcom.ac_enaddr,
                    260:                            ETHER_ADDR_LEN, useword);
                    261:                } else {
                    262:                        ne2000_readmem(nict, nich, asict, asich, 0, romdata,
                    263:                            sizeof(romdata), useword);
                    264:                        for (i = 0; i < ETHER_ADDR_LEN; i++)
                    265:                                dsc->sc_arpcom.ac_enaddr[i] =
                    266:                                    romdata[i * (useword ? 2 : 1)];
                    267:                }
                    268:        } else
                    269:                bcopy(myea, dsc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN);
                    270:
                    271:        /* Clear any pending interrupts that might have occurred above. */
                    272:        NIC_BARRIER(nict, nich);
                    273:        bus_space_write_1(nict, nich, ED_P0_ISR, 0xff);
                    274:        NIC_BARRIER(nict, nich);
                    275:
                    276:        if (dsc->sc_media_init == NULL)
                    277:                dsc->sc_media_init = dp8390_media_init;
                    278:
                    279:        if (dp8390_config(dsc)) {
                    280:                printf(": setup failed\n");
                    281:                return (1);
                    282:        }
                    283:
                    284:        /*
                    285:         * We need to compute mem_ring a bit differently; override the
                    286:         * value set up in dp8390_config().
                    287:         */
                    288:        dsc->mem_ring =
                    289:            dsc->mem_start + ((dsc->txb_cnt * ED_TXBUF_SIZE) << ED_PAGE_SHIFT);
                    290:
                    291:        return (0);
                    292: }
                    293:
                    294: /*
                    295:  * Detect an NE-2000 or compatible.  Returns a model code.
                    296:  */
                    297: int
                    298: ne2000_detect(struct ne2000_softc *nsc)
                    299: {
                    300:        struct dp8390_softc *dsc = &nsc->sc_dp8390;
                    301:        bus_space_tag_t nict = dsc->sc_regt;
                    302:        bus_space_handle_t nich = dsc->sc_regh;
                    303:        bus_space_tag_t asict = nsc->sc_asict;
                    304:        bus_space_handle_t asich = nsc->sc_asich;
                    305:        static u_int8_t test_pattern[32] = "THIS is A memory TEST pattern";
                    306:        u_int8_t test_buffer[32], tmp;
                    307:        int state, i, rv = 0;
                    308:
                    309:        state = dsc->sc_enabled;
                    310:        dsc->sc_enabled = 0;
                    311:
                    312:        /* Reset the board. */
                    313: #ifdef GWETHER
                    314:        bus_space_write_1(asict, asich, NE2000_ASIC_RESET, 0);
                    315:        ASIC_BARRIER(asict, asich);
                    316:        delay(200);
                    317: #endif /* GWETHER */
                    318:        tmp = bus_space_read_1(asict, asich, NE2000_ASIC_RESET);
                    319:        ASIC_BARRIER(asict, asich);
                    320:        delay(10000);
                    321:
                    322:        /*
                    323:         * I don't know if this is necessary; probably cruft leftover from
                    324:         * Clarkson packet driver code. Doesn't do a thing on the boards I've
                    325:         * tested. -DG [note that a outb(0x84, 0) seems to work here, and is
                    326:         * non-invasive...but some boards don't seem to reset and I don't have
                    327:         * complete documentation on what the 'right' thing to do is...so we do
                    328:         * the invasive thing for now.  Yuck.]
                    329:         */
                    330:        bus_space_write_1(asict, asich, NE2000_ASIC_RESET, tmp);
                    331:        ASIC_BARRIER(asict, asich);
                    332:        delay(5000);
                    333:
                    334:        /*
                    335:         * This is needed because some NE clones apparently don't reset the
                    336:         * NIC properly (or the NIC chip doesn't reset fully on power-up).
                    337:         * XXX - this makes the probe invasive!  Done against my better
                    338:         * judgement.  -DLG
                    339:         */
                    340:        bus_space_write_1(nict, nich, ED_P0_CR,
                    341:            ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STP);
                    342:        NIC_BARRIER(nict, nich);
                    343:
                    344:        delay(5000);
                    345:
                    346:        /*
                    347:         * Generic probe routine for testing for the existence of a DS8390.
                    348:         * Must be performed  after the NIC has just been reset.  This
                    349:         * works by looking at certain register values that are guaranteed
                    350:         * to be initialized a certain way after power-up or reset.
                    351:         *
                    352:         * Specifically:
                    353:         *
                    354:         *      Register                reset bits      set bits
                    355:         *      --------                ----------      --------
                    356:         *      CR                      TXP, STA        RD2, STP
                    357:         *      ISR                                     RST
                    358:         *      IMR                     <all>
                    359:         *      DCR                                     LAS
                    360:         *      TCR                     LB1, LB0
                    361:         *
                    362:         * We only look at CR and ISR, however, since looking at the others
                    363:         * would require changing register pages, which would be intrusive
                    364:         * if this isn't an 8390.
                    365:         */
                    366:
                    367:        tmp = bus_space_read_1(nict, nich, ED_P0_CR);
                    368:        if ((tmp & (ED_CR_RD2 | ED_CR_TXP | ED_CR_STA | ED_CR_STP)) !=
                    369:            (ED_CR_RD2 | ED_CR_STP))
                    370:                goto out;
                    371:
                    372:        tmp = bus_space_read_1(nict, nich, ED_P0_ISR);
                    373:        if ((tmp & ED_ISR_RST) != ED_ISR_RST)
                    374:                goto out;
                    375:
                    376:        bus_space_write_1(nict, nich,
                    377:            ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
                    378:        NIC_BARRIER(nict, nich);
                    379:
                    380:        for (i = 0; i < 100; i++) {
                    381:                if ((bus_space_read_1(nict, nich, ED_P0_ISR) & ED_ISR_RST) ==
                    382:                    ED_ISR_RST) {
                    383:                        /* Ack the reset bit. */
                    384:                        bus_space_write_1(nict, nich, ED_P0_ISR, ED_ISR_RST);
                    385:                        NIC_BARRIER(nict, nich);
                    386:                        break;
                    387:                }
                    388:                delay(100);
                    389:        }
                    390:
                    391: #if 0
                    392:        /* XXX */
                    393:        if (i == 100)
                    394:                goto out;
                    395: #endif
                    396:
                    397:        /*
                    398:         * Test the ability to read and write to the NIC memory.  This has
                    399:         * the side effect of determining if this is an NE1000 or an NE2000.
                    400:         */
                    401:
                    402:        /*
                    403:         * This prevents packets from being stored in the NIC memory when
                    404:         * the readmem routine turns on the start bit in the CR.
                    405:         */
                    406:        bus_space_write_1(nict, nich, ED_P0_RCR, ED_RCR_MON);
                    407:        NIC_BARRIER(nict, nich);
                    408:
                    409:        /* Temporarily initialize DCR for byte operations. */
                    410:        bus_space_write_1(nict, nich, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
                    411:
                    412:        bus_space_write_1(nict, nich, ED_P0_PSTART, 8192 >> ED_PAGE_SHIFT);
                    413:        bus_space_write_1(nict, nich, ED_P0_PSTOP, 16384 >> ED_PAGE_SHIFT);
                    414:
                    415:        /*
                    416:         * Write a test pattern in byte mode.  If this fails, then there
                    417:         * probably isn't any memory at 8k - which likely means that the
                    418:         * board is an NE2000.
                    419:         */
                    420:        ne2000_writemem(nict, nich, asict, asich, test_pattern, 8192,
                    421:            sizeof(test_pattern), 0);
                    422:        ne2000_readmem(nict, nich, asict, asich, 8192, test_buffer,
                    423:            sizeof(test_buffer), 0);
                    424:
                    425:        if (bcmp(test_pattern, test_buffer, sizeof(test_pattern))) {
                    426:                /* not an NE1000 - try NE2000 */
                    427:                bus_space_write_1(nict, nich, ED_P0_DCR,
                    428:                    ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS);
                    429:                bus_space_write_1(nict, nich, ED_P0_PSTART,
                    430:                    16384 >> ED_PAGE_SHIFT);
                    431:                bus_space_write_1(nict, nich, ED_P0_PSTOP,
                    432:                    32768 >> ED_PAGE_SHIFT);
                    433:
                    434:                /*
                    435:                 * Write the test pattern in word mode.  If this also fails,
                    436:                 * then we don't know what this board is.
                    437:                 */
                    438:                ne2000_writemem(nict, nich, asict, asich, test_pattern, 16384,
                    439:                    sizeof(test_pattern), 1);
                    440:                ne2000_readmem(nict, nich, asict, asich, 16384, test_buffer,
                    441:                    sizeof(test_buffer), 1);
                    442:
                    443:                if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)))
                    444:                        goto out;       /* not an NE2000 either */
                    445:
                    446:                rv = NE2000_TYPE_NE2000;
                    447:        } else {
                    448:                /* We're an NE1000. */
                    449:                rv = NE2000_TYPE_NE1000;
                    450:        }
                    451:
                    452:        /* Clear any pending interrupts that might have occurred above. */
                    453:        NIC_BARRIER(nict, nich);
                    454:        bus_space_write_1(nict, nich, ED_P0_ISR, 0xff);
                    455:
                    456:  out:
                    457:        dsc->sc_enabled = state;
                    458:
                    459:        return (rv);
                    460: }
                    461:
                    462: /*
                    463:  * Write an mbuf chain to the destination NIC memory address using programmed
                    464:  * I/O.
                    465:  */
                    466: int
                    467: ne2000_write_mbuf(struct dp8390_softc *sc, struct mbuf *m, int buf)
                    468: {
                    469:        struct ne2000_softc *nsc = (struct ne2000_softc *)sc;
                    470:        bus_space_tag_t nict = sc->sc_regt;
                    471:        bus_space_handle_t nich = sc->sc_regh;
                    472:        bus_space_tag_t asict = nsc->sc_asict;
                    473:        bus_space_handle_t asich = nsc->sc_asich;
                    474:        int savelen;
                    475:        int maxwait = 100;      /* about 120us */
                    476:
                    477:        savelen = m->m_pkthdr.len;
                    478:
                    479:        /* Select page 0 registers. */
                    480:        NIC_BARRIER(nict, nich);
                    481:        bus_space_write_1(nict, nich, ED_P0_CR,
                    482:            ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
                    483:        NIC_BARRIER(nict, nich);
                    484:
                    485:        /* Reset remote DMA complete flag. */
                    486:        bus_space_write_1(nict, nich, ED_P0_ISR, ED_ISR_RDC);
                    487:        NIC_BARRIER(nict, nich);
                    488:
                    489:        /* Set up DMA byte count. */
                    490:        bus_space_write_1(nict, nich, ED_P0_RBCR0, savelen);
                    491:        bus_space_write_1(nict, nich, ED_P0_RBCR1, savelen >> 8);
                    492:
                    493:        /* Set up destination address in NIC mem. */
                    494:        bus_space_write_1(nict, nich, ED_P0_RSAR0, buf);
                    495:        bus_space_write_1(nict, nich, ED_P0_RSAR1, buf >> 8);
                    496:
                    497:        /* Set remote DMA write. */
                    498:        NIC_BARRIER(nict, nich);
                    499:        bus_space_write_1(nict, nich,
                    500:            ED_P0_CR, ED_CR_RD1 | ED_CR_PAGE_0 | ED_CR_STA);
                    501:        NIC_BARRIER(nict, nich);
                    502:
                    503:        /*
                    504:         * Transfer the mbuf chain to the NIC memory.  NE2000 cards
                    505:         * require that data be transferred as words, and only words,
                    506:         * so that case requires some extra code to patch over odd-length
                    507:         * mbufs.
                    508:         */
                    509:        if (nsc->sc_type == NE2000_TYPE_NE1000) {
                    510:                /* NE1000s are easy. */
                    511:                for (; m != 0; m = m->m_next) {
                    512:                        if (m->m_len) {
                    513:                                bus_space_write_multi_1(asict, asich,
                    514:                                    NE2000_ASIC_DATA, mtod(m, u_int8_t *),
                    515:                                    m->m_len);
                    516:                        }
                    517:                }
                    518:        } else {
                    519:                /* NE2000s are a bit trickier. */
                    520:                u_int8_t *data, savebyte[2];
                    521:                int l, leftover;
                    522: #ifdef DIAGNOSTIC
                    523:                u_int8_t *lim;
                    524: #endif
                    525:                /* Start out with no leftover data. */
                    526:                leftover = 0;
                    527:                savebyte[0] = savebyte[1] = 0;
                    528:
                    529:                for (; m != 0; m = m->m_next) {
                    530:                        l = m->m_len;
                    531:                        if (l == 0)
                    532:                                continue;
                    533:                        data = mtod(m, u_int8_t *);
                    534: #ifdef DIAGNOSTIC
                    535:                        lim = data + l;
                    536: #endif
                    537:                        while (l > 0) {
                    538:                                if (leftover) {
                    539:                                        /*
                    540:                                         * Data left over (from mbuf or
                    541:                                         * realignment).  Buffer the next
                    542:                                         * byte, and write it and the
                    543:                                         * leftover data out.
                    544:                                         */
                    545:                                        savebyte[1] = *data++;
                    546:                                        l--;
                    547:                                        bus_space_write_raw_multi_2(asict,
                    548:                                            asich, NE2000_ASIC_DATA,
                    549:                                            savebyte, 2);
                    550:                                        leftover = 0;
                    551:                                } else if (ALIGNED_POINTER(data,
                    552:                                           u_int16_t) == 0) {
                    553:                                        /*
                    554:                                         * Unaligned data; buffer the next
                    555:                                         * byte.
                    556:                                         */
                    557:                                        savebyte[0] = *data++;
                    558:                                        l--;
                    559:                                        leftover = 1;
                    560:                                } else {
                    561:                                        /*
                    562:                                         * Aligned data; output contiguous
                    563:                                         * words as much as we can, then
                    564:                                         * buffer the remaining byte, if any.
                    565:                                         */
                    566:                                        leftover = l & 1;
                    567:                                        l &= ~1;
                    568:                                        bus_space_write_raw_multi_2(asict,
                    569:                                            asich, NE2000_ASIC_DATA, data, l);
                    570:                                        data += l;
                    571:                                        if (leftover)
                    572:                                                savebyte[0] = *data++;
                    573:                                        l = 0;
                    574:                                }
                    575:                        }
                    576:                        if (l < 0)
                    577:                                panic("ne2000_write_mbuf: negative len");
                    578: #ifdef DIAGNOSTIC
                    579:                        if (data != lim)
                    580:                                panic("ne2000_write_mbuf: data != lim");
                    581: #endif
                    582:                }
                    583:                if (leftover) {
                    584:                        savebyte[1] = 0;
                    585:                        bus_space_write_raw_multi_2(asict, asich,
                    586:                            NE2000_ASIC_DATA, savebyte, 2);
                    587:                }
                    588:        }
                    589:        NIC_BARRIER(nict, nich);
                    590:
                    591:        /* AX88796 doesn't seem to have remote DMA complete */
                    592:        if (sc->sc_flags & DP8390_NO_REMOTE_DMA_COMPLETE)
                    593:                return (savelen);
                    594:
                    595:        /*
                    596:         * Wait for remote DMA to complete.  This is necessary because on the
                    597:         * transmit side, data is handled internally by the NIC in bursts, and
                    598:         * we can't start another remote DMA until this one completes.  Not
                    599:         * waiting causes really bad things to happen - like the NIC wedging
                    600:         * the bus.
                    601:         */
                    602:        while (((bus_space_read_1(nict, nich, ED_P0_ISR) & ED_ISR_RDC) !=
                    603:            ED_ISR_RDC) && --maxwait) {
                    604:                bus_space_read_1(nict, nich, ED_P0_CRDA1);
                    605:                bus_space_read_1(nict, nich, ED_P0_CRDA0);
                    606:                NIC_BARRIER(nict, nich);
                    607:                DELAY(1);
                    608:        }
                    609:
                    610:        if (maxwait == 0) {
                    611:                log(LOG_WARNING,
                    612:                    "%s: remote transmit DMA failed to complete\n",
                    613:                    sc->sc_dev.dv_xname);
                    614:                dp8390_reset(sc);
                    615:        }
                    616:
                    617:        return (savelen);
                    618: }
                    619:
                    620: /*
                    621:  * Given a source and destination address, copy 'amount' of a packet from
                    622:  * the ring buffer into a linear destination buffer.  Takes into account
                    623:  * ring-wrap.
                    624:  */
                    625: int
                    626: ne2000_ring_copy(struct dp8390_softc *sc, int src, caddr_t dst,
                    627:     u_short amount)
                    628: {
                    629:        struct ne2000_softc *nsc = (struct ne2000_softc *)sc;
                    630:        bus_space_tag_t nict = sc->sc_regt;
                    631:        bus_space_handle_t nich = sc->sc_regh;
                    632:        bus_space_tag_t asict = nsc->sc_asict;
                    633:        bus_space_handle_t asich = nsc->sc_asich;
                    634:        u_short tmp_amount;
                    635:        int useword = nsc->sc_useword;
                    636:
                    637:        /* Does copy wrap to lower addr in ring buffer? */
                    638:        if (src + amount > sc->mem_end) {
                    639:                tmp_amount = sc->mem_end - src;
                    640:
                    641:                /* Copy amount up to end of NIC memory. */
                    642:                ne2000_readmem(nict, nich, asict, asich, src,
                    643:                    (u_int8_t *)dst, tmp_amount, useword);
                    644:
                    645:                amount -= tmp_amount;
                    646:                src = sc->mem_ring;
                    647:                dst += tmp_amount;
                    648:        }
                    649:
                    650:        ne2000_readmem(nict, nich, asict, asich, src, (u_int8_t *)dst,
                    651:            amount, useword);
                    652:
                    653:        return (src + amount);
                    654: }
                    655:
                    656: void
                    657: ne2000_read_hdr(struct dp8390_softc *sc, int buf, struct dp8390_ring *hdr)
                    658: {
                    659:        struct ne2000_softc *nsc = (struct ne2000_softc *)sc;
                    660:
                    661:        ne2000_readmem(sc->sc_regt, sc->sc_regh, nsc->sc_asict, nsc->sc_asich,
                    662:            buf, (u_int8_t *)hdr, sizeof(struct dp8390_ring),
                    663:            nsc->sc_useword);
                    664: #if BYTE_ORDER == BIG_ENDIAN
                    665:        hdr->count = swap16(hdr->count);
                    666: #endif
                    667: }
                    668:
                    669: int
                    670: ne2000_test_mem(struct dp8390_softc *sc)
                    671: {
                    672:        /* Noop. */
                    673:        return (0);
                    674: }
                    675:
                    676: /*
                    677:  * Given a NIC memory source address and a host memory destination address,
                    678:  * copy 'amount' from NIC to host using programmed i/o.  The 'amount' is
                    679:  * rounded up to a word - ok as long as mbufs are word sized.
                    680:  */
                    681: void
                    682: ne2000_readmem(bus_space_tag_t nict, bus_space_handle_t nich,
                    683:     bus_space_tag_t asict, bus_space_handle_t asich, int src,
                    684:     u_int8_t *dst, size_t amount, int useword)
                    685: {
                    686:
                    687:        /* Select page 0 registers. */
                    688:        NIC_BARRIER(nict, nich);
                    689:        bus_space_write_1(nict, nich, ED_P0_CR,
                    690:            ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
                    691:        NIC_BARRIER(nict, nich);
                    692:
                    693:        /* Round up to a word. */
                    694:        if (amount & 1)
                    695:                ++amount;
                    696:
                    697:        /* Set up DMA byte count. */
                    698:        bus_space_write_1(nict, nich, ED_P0_RBCR0, amount);
                    699:        bus_space_write_1(nict, nich, ED_P0_RBCR1, amount >> 8);
                    700:
                    701:        /* Set up source address in NIC mem. */
                    702:        bus_space_write_1(nict, nich, ED_P0_RSAR0, src);
                    703:        bus_space_write_1(nict, nich, ED_P0_RSAR1, src >> 8);
                    704:
                    705:        NIC_BARRIER(nict, nich);
                    706:        bus_space_write_1(nict, nich, ED_P0_CR,
                    707:            ED_CR_RD0 | ED_CR_PAGE_0 | ED_CR_STA);
                    708:
                    709:        ASIC_BARRIER(asict, asich);
                    710:        if (useword)
                    711:                bus_space_read_raw_multi_2(asict, asich, NE2000_ASIC_DATA,
                    712:                    dst, amount);
                    713:        else
                    714:                bus_space_read_multi_1(asict, asich, NE2000_ASIC_DATA,
                    715:                    dst, amount);
                    716: }
                    717:
                    718: /*
                    719:  * Stripped down routine for writing a linear buffer to NIC memory.  Only
                    720:  * used in the probe routine to test the memory.  'len' must be even.
                    721:  */
                    722: void
                    723: ne2000_writemem(bus_space_tag_t nict, bus_space_handle_t nich,
                    724:     bus_space_tag_t asict, bus_space_handle_t asich, u_int8_t *src,
                    725:     int dst, size_t len, int useword)
                    726: {
                    727:        int maxwait = 100;      /* about 120us */
                    728:
                    729:        /* Select page 0 registers. */
                    730:        NIC_BARRIER(nict, nich);
                    731:        bus_space_write_1(nict, nich, ED_P0_CR,
                    732:            ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
                    733:        NIC_BARRIER(nict, nich);
                    734:
                    735:        /* Reset remote DMA complete flag. */
                    736:        bus_space_write_1(nict, nich, ED_P0_ISR, ED_ISR_RDC);
                    737:        NIC_BARRIER(nict, nich);
                    738:
                    739:        /* Set up DMA byte count. */
                    740:        bus_space_write_1(nict, nich, ED_P0_RBCR0, len);
                    741:        bus_space_write_1(nict, nich, ED_P0_RBCR1, len >> 8);
                    742:
                    743:        /* Set up destination address in NIC mem. */
                    744:        bus_space_write_1(nict, nich, ED_P0_RSAR0, dst);
                    745:        bus_space_write_1(nict, nich, ED_P0_RSAR1, dst >> 8);
                    746:
                    747:        /* Set remote DMA write. */
                    748:        NIC_BARRIER(nict, nich);
                    749:        bus_space_write_1(nict, nich, ED_P0_CR,
                    750:            ED_CR_RD1 | ED_CR_PAGE_0 | ED_CR_STA);
                    751:        NIC_BARRIER(nict, nich);
                    752:
                    753:        ASIC_BARRIER(asict, asich);
                    754:        if (useword)
                    755:                bus_space_write_raw_multi_2(asict, asich, NE2000_ASIC_DATA,
                    756:                    src, len);
                    757:        else
                    758:                bus_space_write_multi_1(asict, asich, NE2000_ASIC_DATA,
                    759:                    src, len);
                    760:        ASIC_BARRIER(asict, asich);
                    761:
                    762:        /*
                    763:         * Wait for remote DMA to complete.  This is necessary because on the
                    764:         * transmit side, data is handled internally by the NIC in bursts, and
                    765:         * we can't start another remote DMA until this one completes.  Not
                    766:         * waiting causes really bad things to happen - like the NIC wedging
                    767:         * the bus.
                    768:         */
                    769:        while (((bus_space_read_1(nict, nich, ED_P0_ISR) & ED_ISR_RDC) !=
                    770:            ED_ISR_RDC) && --maxwait)
                    771:                DELAY(1);
                    772: }
                    773:
                    774: int
                    775: ne2000_detach(struct ne2000_softc *sc, int flags)
                    776: {
                    777:        return (dp8390_detach(&sc->sc_dp8390, flags));
                    778: }

CVSweb