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

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

1.1       nbrk        1: /*     $OpenBSD: i82596.c,v 1.26 2006/03/25 22:41:43 djm Exp $ */
                      2: /*     $NetBSD: i82586.c,v 1.18 1998/08/15 04:42:42 mycroft Exp $      */
                      3:
                      4: /*-
                      5:  * Copyright (c) 1998 The NetBSD Foundation, Inc.
                      6:  * All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to The NetBSD Foundation
                      9:  * by Paul Kranenburg and Charles M. Hannum.
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  * 3. All advertising materials mentioning features or use of this software
                     20:  *    must display the following acknowledgement:
                     21:  *        This product includes software developed by the NetBSD
                     22:  *        Foundation, Inc. and its contributors.
                     23:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     24:  *    contributors may be used to endorse or promote products derived
                     25:  *    from this software without specific prior written permission.
                     26:  *
                     27:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     28:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     29:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     30:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     31:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     32:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     33:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     34:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     35:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     36:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     37:  * POSSIBILITY OF SUCH DAMAGE.
                     38:  */
                     39: /*-
                     40:  * Copyright (c) 1997 Paul Kranenburg.
                     41:  * Copyright (c) 1992, 1993, University of Vermont and State
                     42:  *  Agricultural College.
                     43:  * Copyright (c) 1992, 1993, Garrett A. Wollman.
                     44:  *
                     45:  * Portions:
                     46:  * Copyright (c) 1994, 1995, Rafal K. Boni
                     47:  * Copyright (c) 1990, 1991, William F. Jolitz
                     48:  * Copyright (c) 1990, The Regents of the University of California
                     49:  *
                     50:  * All rights reserved.
                     51:  *
                     52:  * Redistribution and use in source and binary forms, with or without
                     53:  * modification, are permitted provided that the following conditions
                     54:  * are met:
                     55:  * 1. Redistributions of source code must retain the above copyright
                     56:  *    notice, this list of conditions and the following disclaimer.
                     57:  * 2. Redistributions in binary form must reproduce the above copyright
                     58:  *    notice, this list of conditions and the following disclaimer in the
                     59:  *    documentation and/or other materials provided with the distribution.
                     60:  * 3. All advertising materials mentioning features or use of this software
                     61:  *    must display the following acknowledgement:
                     62:  *     This product includes software developed by the University of Vermont
                     63:  *     and State Agricultural College and Garrett A. Wollman, by William F.
                     64:  *     Jolitz, and by the University of California, Berkeley, Lawrence
                     65:  *     Berkeley Laboratory, and its contributors.
                     66:  * 4. Neither the names of the Universities nor the names of the authors
                     67:  *    may be used to endorse or promote products derived from this software
                     68:  *    without specific prior written permission.
                     69:  *
                     70:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     71:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     72:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     73:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR AUTHORS BE LIABLE
                     74:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     75:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     76:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     77:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     78:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     79:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     80:  * SUCH DAMAGE.
                     81:  */
                     82: /*
                     83:  * Intel 82586/82596 Ethernet chip
                     84:  * Register, bit, and structure definitions.
                     85:  *
                     86:  * Original StarLAN driver written by Garrett Wollman with reference to the
                     87:  * Clarkson Packet Driver code for this chip written by Russ Nelson and others.
                     88:  *
                     89:  * BPF support code taken from hpdev/if_le.c, supplied with tcpdump.
                     90:  *
                     91:  * 3C507 support is loosely based on code donated to NetBSD by Rafal Boni.
                     92:  *
                     93:  * Majorly cleaned up and 3C507 code merged by Charles Hannum.
                     94:  *
                     95:  * Converted to SUN ie driver by Charles D. Cranor,
                     96:  *             October 1994, January 1995.
                     97:  * This sun version based on i386 version 1.30.
                     98:  */
                     99: /*
                    100:  * The i82596 is a very painful chip, found in sun3's, sun-4/100's
                    101:  * sun-4/200's, and VME based suns.  The byte order is all wrong for a
                    102:  * SUN, making life difficult.  Programming this chip is mostly the same,
                    103:  * but certain details differ from system to system.  This driver is
                    104:  * written so that different "ie" interfaces can be controled by the same
                    105:  * driver.
                    106:  */
                    107:
                    108: /*
                    109: Mode of operation:
                    110:
                    111:    We run the 82596 in a standard Ethernet mode.  We keep NFRAMES
                    112:    received frame descriptors around for the receiver to use, and
                    113:    NRXBUF associated receive buffer descriptors, both in a circular
                    114:    list.  Whenever a frame is received, we rotate both lists as
                    115:    necessary.  (The 596 treats both lists as a simple queue.)  We also
                    116:    keep a transmit command around so that packets can be sent off
                    117:    quickly.
                    118:
                    119:    We configure the adapter in AL-LOC = 1 mode, which means that the
                    120:    Ethernet/802.3 MAC header is placed at the beginning of the receive
                    121:    buffer rather than being split off into various fields in the RFD.
                    122:    This also means that we must include this header in the transmit
                    123:    buffer as well.
                    124:
                    125:    By convention, all transmit commands, and only transmit commands,
                    126:    shall have the I (IE_CMD_INTR) bit set in the command.  This way,
                    127:    when an interrupt arrives at i82596_intr(), it is immediately possible
                    128:    to tell what precisely caused it.  ANY OTHER command-sending
                    129:    routines should run at splnet(), and should post an acknowledgement
                    130:    to every interrupt they generate.
                    131:
                    132:    To save the expense of shipping a command to 82596 every time we
                    133:    want to send a frame, we use a linked list of commands consisting
                    134:    of alternate XMIT and NOP commands. The links of these elements
                    135:    are manipulated (in i82596_xmit()) such that the NOP command loops back
                    136:    to itself whenever the following XMIT command is not yet ready to
                    137:    go. Whenever an XMIT is ready, the preceding NOP link is pointed
                    138:    at it, while its own link field points to the following NOP command.
                    139:    Thus, a single transmit command sets off an interlocked traversal
                    140:    of the xmit command chain, with the host processor in control of
                    141:    the synchronization.
                    142: */
                    143:
                    144: #include "bpfilter.h"
                    145:
                    146: #include <sys/param.h>
                    147: #include <sys/systm.h>
                    148: #include <sys/mbuf.h>
                    149: #include <sys/socket.h>
                    150: #include <sys/ioctl.h>
                    151: #include <sys/errno.h>
                    152: #include <sys/syslog.h>
                    153: #include <sys/device.h>
                    154:
                    155: #include <net/if.h>
                    156: #include <net/if_dl.h>
                    157: #include <net/if_types.h>
                    158: #include <net/if_media.h>
                    159:
                    160: #if NBPFILTER > 0
                    161: #include <net/bpf.h>
                    162: #endif
                    163:
                    164: #ifdef INET
                    165: #include <netinet/in.h>
                    166: #include <netinet/in_systm.h>
                    167: #include <netinet/in_var.h>
                    168: #include <netinet/ip.h>
                    169: #include <netinet/if_ether.h>
                    170: #endif
                    171:
                    172: #include <uvm/uvm_extern.h>
                    173:
                    174: #include <machine/bus.h>
                    175:
                    176: #include <dev/ic/i82596reg.h>
                    177: #include <dev/ic/i82596var.h>
                    178:
                    179: static char *padbuf;
                    180:
                    181: void   i82596_reset(struct ie_softc *, int);
                    182: void   i82596_watchdog(struct ifnet *);
                    183: int    i82596_init(struct ie_softc *);
                    184: int    i82596_ioctl(struct ifnet *, u_long, caddr_t);
                    185: void   i82596_start(struct ifnet *);
                    186:
                    187: int    i82596_rint(struct ie_softc *, int);
                    188: int    i82596_tint(struct ie_softc *, int);
                    189:
                    190: int    i82596_mediachange(struct ifnet *);
                    191: void   i82596_mediastatus(struct ifnet *, struct ifmediareq *);
                    192:
                    193: int    i82596_readframe(struct ie_softc *, int);
                    194: int    i82596_get_rbd_list(struct ie_softc *,
                    195:                                             u_int16_t *, u_int16_t *, int *);
                    196: void   i82596_release_rbd_list(struct ie_softc *, u_int16_t, u_int16_t);
                    197: int    i82596_drop_frames(struct ie_softc *);
                    198: int    i82596_chk_rx_ring(struct ie_softc *);
                    199:
                    200: void   i82596_start_transceiver(struct ie_softc *);
                    201: void   i82596_stop(struct ie_softc *);
                    202: void   i82596_xmit(struct ie_softc *);
                    203:
                    204: void   i82596_setup_bufs(struct ie_softc *);
                    205: void   i82596_simple_command(struct ie_softc *, int, int);
                    206: int    ie_cfg_setup(struct ie_softc *, int, int, int);
                    207: int    ie_ia_setup(struct ie_softc *, int);
                    208: void   ie_run_tdr(struct ie_softc *, int);
                    209: int    ie_mc_setup(struct ie_softc *, int);
                    210: void   ie_mc_reset(struct ie_softc *);
                    211: int    i82596_cmd_wait(struct ie_softc *);
                    212:
                    213: #ifdef I82596_DEBUG
                    214: void   print_rbd(struct ie_softc *, int);
                    215: #endif
                    216:
                    217: struct cfdriver ie_cd = {
                    218:        NULL, "ie", DV_IFNET
                    219: };
                    220:
                    221: /*
                    222:  * generic i82596 probe routine
                    223:  */
                    224: int
                    225: i82596_probe(sc)
                    226:        struct ie_softc *sc;
                    227: {
                    228:        int i;
                    229:
                    230:        sc->scp = sc->sc_msize - IE_SCP_SZ;
                    231:        sc->iscp = 0;
                    232:        sc->scb = 32;
                    233:
                    234:        (sc->ie_bus_write16)(sc, IE_ISCP_BUSY(sc->iscp), 1);
                    235:        (sc->ie_bus_write16)(sc, IE_ISCP_SCB(sc->iscp), sc->scb);
                    236:        (sc->ie_bus_write24)(sc, IE_ISCP_BASE(sc->iscp), sc->sc_maddr);
                    237:        (sc->ie_bus_write24)(sc, IE_SCP_ISCP(sc->scp), sc->sc_maddr);
                    238:        (sc->ie_bus_write16)(sc, IE_SCP_BUS_USE(sc->scp), sc->sysbus);
                    239:
                    240:        (sc->hwreset)(sc, IE_CARD_RESET);
                    241:
                    242:        if ((sc->ie_bus_read16)(sc, IE_ISCP_BUSY(sc->iscp))) {
                    243: #ifdef I82596_DEBUG
                    244:                printf("%s: ISCP set failed\n", sc->sc_dev.dv_xname);
                    245: #endif
                    246:                return 0;
                    247:        }
                    248:
                    249:        if (sc->port) {
                    250:                (sc->ie_bus_write24)(sc, sc->scp, 0);
                    251:                (sc->ie_bus_write24)(sc, IE_SCP_TEST(sc->scp), -1);
                    252:                (sc->port)(sc, IE_PORT_TEST);
                    253:                for (i = 9000; i-- &&
                    254:                             (sc->ie_bus_read16)(sc, IE_SCP_TEST(sc->scp));
                    255:                     DELAY(100))
                    256:                        ;
                    257:        }
                    258:
                    259:        return 1;
                    260: }
                    261:
                    262: /*
                    263:  * Front-ends call this function to attach to the MI driver.
                    264:  *
                    265:  * The front-end has responsibility for managing the ICP and ISCP
                    266:  * structures. Both of these are opaque to us.  Also, the front-end
                    267:  * chooses a location for the SCB which is expected to be addressable
                    268:  * (through `sc->scb') as an offset against the shared-memory bus handle.
                    269:  *
                    270:  * The following MD interface function must be setup by the front-end
                    271:  * before calling here:
                    272:  *
                    273:  *     hwreset                 - board dependent reset
                    274:  *     hwinit                  - board dependent initialization
                    275:  *     chan_attn               - channel attention
                    276:  *     intrhook                - board dependent interrupt processing
                    277:  *     memcopyin               - shared memory copy: board to KVA
                    278:  *     memcopyout              - shared memory copy: KVA to board
                    279:  *     ie_bus_read16           - read a sixteen-bit i82596 pointer
                    280:  *     ie_bus_write16          - write a sixteen-bit i82596 pointer
                    281:  *     ie_bus_write24          - write a twenty-four-bit i82596 pointer
                    282:  *
                    283:  */
                    284: void
                    285: i82596_attach(sc, name, etheraddr, media, nmedia, defmedia)
                    286:        struct ie_softc *sc;
                    287:        const char *name;
                    288:        u_int8_t *etheraddr;
                    289:         int *media, nmedia, defmedia;
                    290: {
                    291:        int i;
                    292:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
                    293:
                    294:        /* Setup SCP+ISCP */
                    295:        (sc->ie_bus_write16)(sc, IE_ISCP_BUSY(sc->iscp), 1);
                    296:        (sc->ie_bus_write16)(sc, IE_ISCP_SCB(sc->iscp), sc->scb);
                    297:        (sc->ie_bus_write24)(sc, IE_ISCP_BASE(sc->iscp), sc->sc_maddr);
                    298:        (sc->ie_bus_write24)(sc, IE_SCP_ISCP(sc->scp), sc->sc_maddr +sc->iscp);
                    299:        (sc->ie_bus_write16)(sc, IE_SCP_BUS_USE(sc->scp), sc->sysbus);
                    300:        (sc->hwreset)(sc, IE_CARD_RESET);
                    301:
                    302:        /* Setup Iface */
                    303:        bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
                    304:        ifp->if_softc = sc;
                    305:        ifp->if_start = i82596_start;
                    306:        ifp->if_ioctl = i82596_ioctl;
                    307:        ifp->if_watchdog = i82596_watchdog;
                    308:        ifp->if_flags =
                    309: #ifdef I82596_DEBUG
                    310:                IFF_DEBUG |
                    311: #endif
                    312:                IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
                    313:        IFQ_SET_READY(&ifp->if_snd);
                    314:
                    315:         /* Initialize media goo. */
                    316:         ifmedia_init(&sc->sc_media, 0, i82596_mediachange, i82596_mediastatus);
                    317:         if (media != NULL) {
                    318:                 for (i = 0; i < nmedia; i++)
                    319:                         ifmedia_add(&sc->sc_media, media[i], 0, NULL);
                    320:                 ifmedia_set(&sc->sc_media, defmedia);
                    321:         } else {
                    322:                 ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
                    323:                 ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL);
                    324:         }
                    325:
                    326:        if (padbuf == NULL) {
                    327:                padbuf = malloc(ETHER_MIN_LEN - ETHER_CRC_LEN, M_DEVBUF,
                    328:                    M_NOWAIT);
                    329:                if (padbuf == NULL) {
                    330:                        printf("%s: can't allocate pad buffer\n",
                    331:                            sc->sc_dev.dv_xname);
                    332:                        return;
                    333:                }
                    334:                bzero(padbuf, ETHER_MIN_LEN - ETHER_CRC_LEN);
                    335:        }
                    336:
                    337:        /* Attach the interface. */
                    338:        if_attach(ifp);
                    339:        ether_ifattach(ifp);
                    340:
                    341:        printf(" %s v%d.%d, address %s\n", name, sc->sc_vers / 10,
                    342:               sc->sc_vers % 10, ether_sprintf(etheraddr));
                    343: }
                    344:
                    345:
                    346: /*
                    347:  * Device timeout/watchdog routine.
                    348:  * Entered if the device neglects to generate an interrupt after a
                    349:  * transmit has been started on it.
                    350:  */
                    351: void
                    352: i82596_watchdog(ifp)
                    353:        struct ifnet *ifp;
                    354: {
                    355:        struct ie_softc *sc = ifp->if_softc;
                    356:
                    357:        log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
                    358:        ++ifp->if_oerrors;
                    359:
                    360:        i82596_reset(sc, 1);
                    361: }
                    362:
                    363: int
                    364: i82596_cmd_wait(sc)
                    365:        struct ie_softc *sc;
                    366: {
                    367:        /* spin on i82596 command acknowledge; wait at most 0.9 (!) seconds */
                    368:        int i, off;
                    369:
                    370:        for (i = 180000; i--; DELAY(5)) {
                    371:                /* Read the command word */
                    372:                off = IE_SCB_CMD(sc->scb);
                    373:                bus_space_barrier(sc->bt, sc->bh, off, 2,
                    374:                                  BUS_SPACE_BARRIER_READ);
                    375:                if ((sc->ie_bus_read16)(sc, off) == 0) {
                    376: #ifdef I82596_DEBUG
                    377:                        if (sc->sc_debug & IED_CMDS)
                    378:                                printf("%s: cmd_wait after %d usec\n",
                    379:                                    sc->sc_dev.dv_xname, (180000 - i) * 5);
                    380: #endif
                    381:                        return (0);
                    382:                }
                    383:        }
                    384:
                    385: #ifdef I82596_DEBUG
                    386:        if (sc->sc_debug & IED_CMDS)
                    387:                printf("i82596_cmd_wait: timo(%ssync): scb status: %b\n",
                    388:                    sc->async_cmd_inprogress? "a" : "",
                    389:                    sc->ie_bus_read16(sc, IE_SCB_STATUS(sc->scb)),
                    390:                    IE_STAT_BITS);
                    391: #endif
                    392:        return (1);     /* Timeout */
                    393: }
                    394:
                    395: /*
                    396:  * Send a command to the controller and wait for it to either complete
                    397:  * or be accepted, depending on the command.  If the command pointer
                    398:  * is null, then pretend that the command is not an action command.
                    399:  * If the command pointer is not null, and the command is an action
                    400:  * command, wait for one of the MASK bits to turn on in the command's
                    401:  * status field.
                    402:  * If ASYNC is set, we just call the chip's attention and return.
                    403:  * We may have to wait for the command's acceptance later though.
                    404:  */
                    405: int
                    406: i82596_start_cmd(sc, cmd, iecmdbuf, mask, async)
                    407:        struct ie_softc *sc;
                    408:        int cmd;
                    409:        int iecmdbuf;
                    410:        int mask;
                    411:        int async;
                    412: {
                    413:        int i, off;
                    414:
                    415: #ifdef I82596_DEBUG
                    416:        if (sc->sc_debug & IED_CMDS)
                    417:                printf("start_cmd: %p, %x, %x, %b, %ssync\n",
                    418:                       sc, cmd, iecmdbuf, mask, IE_STAT_BITS, async?"a":"");
                    419: #endif
                    420:        if (sc->async_cmd_inprogress != 0) {
                    421:                /*
                    422:                 * If previous command was issued asynchronously, wait
                    423:                 * for it now.
                    424:                 */
                    425:                if (i82596_cmd_wait(sc) != 0)
                    426:                        return (1);
                    427:                sc->async_cmd_inprogress = 0;
                    428:        }
                    429:
                    430:        off = IE_SCB_CMD(sc->scb);
                    431:        (sc->ie_bus_write16)(sc, off, cmd);
                    432:        bus_space_barrier(sc->bt, sc->bh, off, 2, BUS_SPACE_BARRIER_WRITE);
                    433:        (sc->chan_attn)(sc);
                    434:
                    435:        if (async) {
                    436:                sc->async_cmd_inprogress = 1;
                    437:                return (0);
                    438:        }
                    439:
                    440:        if (IE_ACTION_COMMAND(cmd) && iecmdbuf) {
                    441:                int status;
                    442:                /*
                    443:                 * Now spin-lock waiting for status.  This is not a very nice
                    444:                 * thing to do, and can kill performance pretty well...
                    445:                 * According to the packet driver, the minimum timeout
                    446:                 * should be .369 seconds.
                    447:                 */
                    448:                for (i = 73800; i--; DELAY(5)) {
                    449:                        /* Read the command status */
                    450:                        off = IE_CMD_COMMON_STATUS(iecmdbuf);
                    451:                        bus_space_barrier(sc->bt, sc->bh, off, 2,
                    452:                            BUS_SPACE_BARRIER_READ);
                    453:                        status = (sc->ie_bus_read16)(sc, off);
                    454:                        if (status & mask) {
                    455: #ifdef I82596_DEBUG
                    456:                                if (sc->sc_debug & IED_CMDS)
                    457:                                        printf("%s: cmd status %b\n",
                    458:                                            sc->sc_dev.dv_xname,
                    459:                                            status, IE_STAT_BITS);
                    460: #endif
                    461:                                return (0);
                    462:                        }
                    463:                }
                    464:
                    465:        } else {
                    466:                /*
                    467:                 * Otherwise, just wait for the command to be accepted.
                    468:                 */
                    469:                return (i82596_cmd_wait(sc));
                    470:        }
                    471:
                    472:        /* Timeout */
                    473:        return (1);
                    474: }
                    475:
                    476: /*
                    477:  * Transfer accumulated chip error counters to IF.
                    478:  */
                    479: static __inline void
                    480: i82596_count_errors(struct ie_softc *sc)
                    481: {
                    482:        int scb = sc->scb;
                    483:
                    484:        sc->sc_arpcom.ac_if.if_ierrors +=
                    485:            sc->ie_bus_read16(sc, IE_SCB_ERRCRC(scb)) +
                    486:            sc->ie_bus_read16(sc, IE_SCB_ERRALN(scb)) +
                    487:            sc->ie_bus_read16(sc, IE_SCB_ERRRES(scb)) +
                    488:            sc->ie_bus_read16(sc, IE_SCB_ERROVR(scb));
                    489:
                    490:        /* Clear error counters */
                    491:        sc->ie_bus_write16(sc, IE_SCB_ERRCRC(scb), 0);
                    492:        sc->ie_bus_write16(sc, IE_SCB_ERRALN(scb), 0);
                    493:        sc->ie_bus_write16(sc, IE_SCB_ERRRES(scb), 0);
                    494:        sc->ie_bus_write16(sc, IE_SCB_ERROVR(scb), 0);
                    495: }
                    496:
                    497: static __inline void
                    498: i82596_rx_errors(struct ie_softc *sc, int fn, int status)
                    499: {
                    500:        log(LOG_ERR, "%s: rx error (frame# %d): %b\n", sc->sc_dev.dv_xname, fn,
                    501:            status, IE_FD_STATUSBITS);
                    502: }
                    503:
                    504: /*
                    505:  * i82596 interrupt entry point.
                    506:  */
                    507: int
                    508: i82596_intr(v)
                    509:        void *v;
                    510: {
                    511:        register struct ie_softc *sc = v;
                    512:        register u_int status;
                    513:        register int off;
                    514:
                    515:        off = IE_SCB_STATUS(sc->scb);
                    516:        bus_space_barrier(sc->bt, sc->bh, off, 2, BUS_SPACE_BARRIER_READ);
                    517:        status = sc->ie_bus_read16(sc, off) /* & IE_ST_WHENCE */;
                    518:
                    519:        if ((status & IE_ST_WHENCE) == 0) {
                    520:                if (sc->intrhook)
                    521:                        (sc->intrhook)(sc, IE_INTR_EXIT);
                    522:
                    523:                return (0);
                    524:        }
                    525:
                    526: loop:
                    527:        /* Ack interrupts FIRST in case we receive more during the ISR. */
                    528:        i82596_start_cmd(sc, status & IE_ST_WHENCE, 0, 0, 1);
                    529:
                    530:        if (status & (IE_ST_FR | IE_ST_RNR)) {
                    531:                if (sc->intrhook)
                    532:                        (sc->intrhook)(sc, IE_INTR_ENRCV);
                    533:
                    534:                if (i82596_rint(sc, status) != 0)
                    535:                        goto reset;
                    536:        }
                    537:
                    538:        if (status & IE_ST_CX) {
                    539:                if (sc->intrhook)
                    540:                        (sc->intrhook)(sc, IE_INTR_ENSND);
                    541:
                    542:                if (i82596_tint(sc, status) != 0)
                    543:                        goto reset;
                    544:        }
                    545:
                    546: #ifdef I82596_DEBUG
                    547:        if ((status & IE_ST_CNA) && (sc->sc_debug & IED_CNA))
                    548:                printf("%s: cna; status=%b\n", sc->sc_dev.dv_xname,
                    549:                        status, IE_ST_BITS);
                    550: #endif
                    551:        if (sc->intrhook)
                    552:                (sc->intrhook)(sc, IE_INTR_LOOP);
                    553:
                    554:        /*
                    555:         * Interrupt ACK was posted asynchronously; wait for
                    556:         * completion here before reading SCB status again.
                    557:         *
                    558:         * If ACK fails, try to reset the chip, in hopes that
                    559:         * it helps.
                    560:         */
                    561:        if (i82596_cmd_wait(sc))
                    562:                goto reset;
                    563:
                    564:        bus_space_barrier(sc->bt, sc->bh, off, 2, BUS_SPACE_BARRIER_READ);
                    565:        status = sc->ie_bus_read16(sc, off);
                    566:        if ((status & IE_ST_WHENCE) != 0)
                    567:                goto loop;
                    568:
                    569: out:
                    570:        if (sc->intrhook)
                    571:                (sc->intrhook)(sc, IE_INTR_EXIT);
                    572:        return (1);
                    573:
                    574: reset:
                    575:        i82596_cmd_wait(sc);
                    576:        i82596_reset(sc, 1);
                    577:        goto out;
                    578: }
                    579:
                    580: /*
                    581:  * Process a received-frame interrupt.
                    582:  */
                    583: int
                    584: i82596_rint(sc, scbstatus)
                    585:        struct  ie_softc *sc;
                    586:        int     scbstatus;
                    587: {
                    588:        static int timesthru = 1024;
                    589:        register int i, status, off;
                    590:
                    591: #ifdef I82596_DEBUG
                    592:        if (sc->sc_debug & IED_RINT)
                    593:                printf("%s: rint: status %b\n",
                    594:                        sc->sc_dev.dv_xname, scbstatus, IE_ST_BITS);
                    595: #endif
                    596:
                    597:        for (;;) {
                    598:                register int drop = 0;
                    599:
                    600:                i = sc->rfhead;
                    601:                off = IE_RFRAME_STATUS(sc->rframes, i);
                    602:                bus_space_barrier(sc->bt, sc->bh, off, 2,
                    603:                                  BUS_SPACE_BARRIER_READ);
                    604:                status = sc->ie_bus_read16(sc, off);
                    605:
                    606: #ifdef I82596_DEBUG
                    607:                if (sc->sc_debug & IED_RINT)
                    608:                        printf("%s: rint: frame(%d) status %b\n",
                    609:                                sc->sc_dev.dv_xname, i, status, IE_ST_BITS);
                    610: #endif
                    611:                if ((status & IE_FD_COMPLETE) == 0) {
                    612:                        if ((status & IE_FD_OK) != 0) {
                    613:                                printf("%s: rint: weird: ",
                    614:                                        sc->sc_dev.dv_xname);
                    615:                                i82596_rx_errors(sc, i, status);
                    616:                                break;
                    617:                        }
                    618:                        if (--timesthru == 0) {
                    619:                                /* Account the accumulated errors */
                    620:                                i82596_count_errors(sc);
                    621:                                timesthru = 1024;
                    622:                        }
                    623:                        break;
                    624:                } else if ((status & IE_FD_OK) == 0) {
                    625:                        /*
                    626:                         * If the chip is configured to automatically
                    627:                         * discard bad frames, the only reason we can
                    628:                         * get here is an "out-of-resource" condition.
                    629:                         */
                    630:                        i82596_rx_errors(sc, i, status);
                    631:                        drop = 1;
                    632:                }
                    633:
                    634: #ifdef I82596_DEBUG
                    635:                if ((status & IE_FD_BUSY) != 0)
                    636:                        printf("%s: rint: frame(%d) busy; status=%x\n",
                    637:                                sc->sc_dev.dv_xname, i, status, IE_ST_BITS);
                    638: #endif
                    639:
                    640:                /*
                    641:                 * Advance the RFD list, since we're done with
                    642:                 * this descriptor.
                    643:                 */
                    644:
                    645:                /* Clear frame status */
                    646:                sc->ie_bus_write16(sc, off, 0);
                    647:
                    648:                /* Put fence at this frame (the head) */
                    649:                off = IE_RFRAME_LAST(sc->rframes, i);
                    650:                sc->ie_bus_write16(sc, off, IE_FD_EOL|IE_FD_SUSP);
                    651:
                    652:                /* and clear RBD field */
                    653:                off = IE_RFRAME_BUFDESC(sc->rframes, i);
                    654:                sc->ie_bus_write16(sc, off, 0xffff);
                    655:
                    656:                /* Remove fence from current tail */
                    657:                off = IE_RFRAME_LAST(sc->rframes, sc->rftail);
                    658:                sc->ie_bus_write16(sc, off, 0);
                    659:
                    660:                if (++sc->rftail == sc->nframes)
                    661:                        sc->rftail = 0;
                    662:                if (++sc->rfhead == sc->nframes)
                    663:                        sc->rfhead = 0;
                    664:
                    665:                /* Pull the frame off the board */
                    666:                if (drop) {
                    667:                        i82596_drop_frames(sc);
                    668:                        if ((status & IE_FD_RNR) != 0)
                    669:                                sc->rnr_expect = 1;
                    670:                        sc->sc_arpcom.ac_if.if_ierrors++;
                    671:                } else if (i82596_readframe(sc, i) != 0)
                    672:                        return (1);
                    673:        }
                    674:
                    675:        if ((scbstatus & IE_ST_RNR) != 0) {
                    676:
                    677:                /*
                    678:                 * Receiver went "Not Ready". We try to figure out
                    679:                 * whether this was an expected event based on past
                    680:                 * frame status values.
                    681:                 */
                    682:
                    683:                if ((scbstatus & IE_RUS_SUSPEND) != 0) {
                    684:                        /*
                    685:                         * We use the "suspend on last frame" flag.
                    686:                         * Send a RU RESUME command in response, since
                    687:                         * we should have dealt with all completed frames
                    688:                         * by now.
                    689:                         */
                    690:                        printf("RINT: SUSPENDED; scbstatus=%b\n",
                    691:                                scbstatus, IE_ST_BITS);
                    692:                        if (i82596_start_cmd(sc, IE_RUC_RESUME, 0, 0, 0) == 0)
                    693:                                return (0);
                    694:                        printf("%s: RU RESUME command timed out\n",
                    695:                                sc->sc_dev.dv_xname);
                    696:                        return (1);     /* Ask for a reset */
                    697:                }
                    698:
                    699:                if (sc->rnr_expect != 0) {
                    700:                        /*
                    701:                         * The RNR condition was announced in the previously
                    702:                         * completed frame.  Assume the receive ring is Ok,
                    703:                         * so restart the receiver without further delay.
                    704:                         */
                    705:                        i82596_start_transceiver(sc);
                    706:                        sc->rnr_expect = 0;
                    707:                        return (0);
                    708:
                    709:                } else if ((scbstatus & IE_RUS_NOSPACE) != 0) {
                    710:                        /*
                    711:                         * We saw no previous IF_FD_RNR flag.
                    712:                         * We check our ring invariants and, if ok,
                    713:                         * just restart the receiver at the current
                    714:                         * point in the ring.
                    715:                         */
                    716:                        if (i82596_chk_rx_ring(sc) != 0)
                    717:                                return (1);
                    718:
                    719:                        i82596_start_transceiver(sc);
                    720:                        sc->sc_arpcom.ac_if.if_ierrors++;
                    721:                        return (0);
                    722:                } else
                    723:                        printf("%s: receiver not ready; scbstatus=%b\n",
                    724:                                sc->sc_dev.dv_xname, scbstatus, IE_ST_BITS);
                    725:
                    726:                sc->sc_arpcom.ac_if.if_ierrors++;
                    727:                return (1);     /* Ask for a reset */
                    728:        }
                    729:
                    730:        return (0);
                    731: }
                    732:
                    733: /*
                    734:  * Process a command-complete interrupt.  These are only generated by the
                    735:  * transmission of frames.  This routine is deceptively simple, since most
                    736:  * of the real work is done by i82596_start().
                    737:  */
                    738: int
                    739: i82596_tint(sc, scbstatus)
                    740:        struct ie_softc *sc;
                    741:        int     scbstatus;
                    742: {
                    743:        register struct ifnet *ifp = &sc->sc_arpcom.ac_if;
                    744:        register int off, status;
                    745:
                    746:        ifp->if_timer = 0;
                    747:        ifp->if_flags &= ~IFF_OACTIVE;
                    748:
                    749: #ifdef I82596_DEBUG
                    750:        if (sc->xmit_busy <= 0) {
                    751:                printf("%s: i82596_tint: WEIRD:"
                    752:                       "xmit_busy=%d, xctail=%d, xchead=%d\n",
                    753:                       sc->sc_dev.dv_xname,
                    754:                       sc->xmit_busy, sc->xctail, sc->xchead);
                    755:                return (0);
                    756:        }
                    757: #endif
                    758:
                    759:        off = IE_CMD_XMIT_STATUS(sc->xmit_cmds, sc->xctail);
                    760:        status = sc->ie_bus_read16(sc, off);
                    761:
                    762: #ifdef I82596_DEBUG
                    763:        if (sc->sc_debug & IED_TINT)
                    764:                printf("%s: tint: SCB status %b; xmit status %b\n",
                    765:                        sc->sc_dev.dv_xname, scbstatus, IE_ST_BITS,
                    766:                        status, IE_XS_BITS);
                    767: #endif
                    768:
                    769:        if ((status & (IE_STAT_COMPL|IE_STAT_BUSY)) == IE_STAT_BUSY) {
                    770:                printf("%s: i82596_tint: command still busy;"
                    771:                       "status=%b; tail=%d\n", sc->sc_dev.dv_xname,
                    772:                       status, IE_XS_BITS, sc->xctail);
                    773:                printf("iestatus = %b\n", scbstatus, IE_ST_BITS);
                    774:        }
                    775:
                    776:        if (status & IE_STAT_OK) {
                    777:                ifp->if_opackets++;
                    778:                ifp->if_collisions += (status & IE_XS_MAXCOLL);
                    779:        } else {
                    780:                ifp->if_oerrors++;
                    781:                /*
                    782:                 * Check SQE and DEFERRED?
                    783:                 * What if more than one bit is set?
                    784:                 */
                    785:                if (status & IE_STAT_ABORT)
                    786:                        printf("%s: send aborted\n", sc->sc_dev.dv_xname);
                    787:                else if (status & IE_XS_NOCARRIER)
                    788:                        printf("%s: no carrier\n", sc->sc_dev.dv_xname);
                    789:                else if (status & IE_XS_LOSTCTS)
                    790:                        printf("%s: lost CTS\n", sc->sc_dev.dv_xname);
                    791:                else if (status & IE_XS_UNDERRUN)
                    792:                        printf("%s: DMA underrun\n", sc->sc_dev.dv_xname);
                    793:                else if (status & IE_XS_EXCMAX) {
                    794:                        printf("%s: too many collisions\n",
                    795:                                sc->sc_dev.dv_xname);
                    796:                        sc->sc_arpcom.ac_if.if_collisions += 16;
                    797:                }
                    798:        }
                    799:
                    800:        /*
                    801:         * If multicast addresses were added or deleted while transmitting,
                    802:         * ie_mc_reset() set the want_mcsetup flag indicating that we
                    803:         * should do it.
                    804:         */
                    805:        if (sc->want_mcsetup) {
                    806:                ie_mc_setup(sc, IE_XBUF_ADDR(sc, sc->xctail));
                    807:                sc->want_mcsetup = 0;
                    808:        }
                    809:
                    810:        /* Done with the buffer. */
                    811:        sc->xmit_busy--;
                    812:        sc->xctail = (sc->xctail + 1) % NTXBUF;
                    813:
                    814:        /* Start the next packet, if any, transmitting. */
                    815:        if (sc->xmit_busy > 0)
                    816:                i82596_xmit(sc);
                    817:
                    818:        i82596_start(ifp);
                    819:        return (0);
                    820: }
                    821:
                    822: /*
                    823:  * Get a range of receive buffer descriptors that represent one packet.
                    824:  */
                    825: int
                    826: i82596_get_rbd_list(sc, start, end, pktlen)
                    827:        struct ie_softc *sc;
                    828:        u_int16_t       *start;
                    829:        u_int16_t       *end;
                    830:        int             *pktlen;
                    831: {
                    832:        int     off, rbbase = sc->rbds;
                    833:        int     rbindex, count = 0;
                    834:        int     plen = 0;
                    835:        int     rbdstatus;
                    836:
                    837:        *start = rbindex = sc->rbhead;
                    838:
                    839:        do {
                    840:                off = IE_RBD_STATUS(rbbase, rbindex);
                    841:                bus_space_barrier(sc->bt, sc->bh, off, 2,
                    842:                                  BUS_SPACE_BARRIER_READ);
                    843:                rbdstatus = sc->ie_bus_read16(sc, off);
                    844:                if ((rbdstatus & IE_RBD_USED) == 0) {
                    845:                        /*
                    846:                         * This means we are somehow out of sync.  So, we
                    847:                         * reset the adapter.
                    848:                         */
                    849: #ifdef I82596_DEBUG
                    850:                        print_rbd(sc, rbindex);
                    851: #endif
                    852:                        log(LOG_ERR,
                    853:                            "%s: receive descriptors out of sync at %d\n",
                    854:                            sc->sc_dev.dv_xname, rbindex);
                    855:                        return (0);
                    856:                }
                    857:                plen += (rbdstatus & IE_RBD_CNTMASK);
                    858:
                    859:                if (++rbindex == sc->nrxbuf)
                    860:                        rbindex = 0;
                    861:
                    862:                ++count;
                    863:        } while ((rbdstatus & IE_RBD_LAST) == 0);
                    864:        *end = rbindex;
                    865:        *pktlen = plen;
                    866:        return (count);
                    867: }
                    868:
                    869:
                    870: /*
                    871:  * Release a range of receive buffer descriptors after we've copied the packet.
                    872:  */
                    873: void
                    874: i82596_release_rbd_list(sc, start, end)
                    875:        struct ie_softc *sc;
                    876:        u_int16_t       start;
                    877:        u_int16_t       end;
                    878: {
                    879:        register int    off, rbbase = sc->rbds;
                    880:        register int    rbindex = start;
                    881:
                    882:        do {
                    883:                /* Clear buffer status */
                    884:                off = IE_RBD_STATUS(rbbase, rbindex);
                    885:                sc->ie_bus_write16(sc, off, 0);
                    886:                if (++rbindex == sc->nrxbuf)
                    887:                        rbindex = 0;
                    888:        } while (rbindex != end);
                    889:
                    890:        /* Mark EOL at new tail */
                    891:        rbindex = ((rbindex == 0) ? sc->nrxbuf : rbindex) - 1;
                    892:        off = IE_RBD_BUFLEN(rbbase, rbindex);
                    893:        sc->ie_bus_write16(sc, off, IE_RBUF_SIZE|IE_RBD_EOL);
                    894:
                    895:        /* Remove EOL from current tail */
                    896:        off = IE_RBD_BUFLEN(rbbase, sc->rbtail);
                    897:        sc->ie_bus_write16(sc, off, IE_RBUF_SIZE);
                    898:
                    899:        /* New head & tail pointer */
                    900: /* hmm, why have both? head is always (tail + 1) % NRXBUF */
                    901:        sc->rbhead = end;
                    902:        sc->rbtail = rbindex;
                    903: }
                    904:
                    905: /*
                    906:  * Drop the packet at the head of the RX buffer ring.
                    907:  * Called if the frame descriptor reports an error on this packet.
                    908:  * Returns 1 if the buffer descriptor ring appears to be corrupt;
                    909:  * and 0 otherwise.
                    910:  */
                    911: int
                    912: i82596_drop_frames(sc)
                    913:        struct ie_softc *sc;
                    914: {
                    915:        u_int16_t bstart, bend;
                    916:        int pktlen;
                    917:
                    918:        if (!i82596_get_rbd_list(sc, &bstart, &bend, &pktlen))
                    919:                return (1);
                    920:        i82596_release_rbd_list(sc, bstart, bend);
                    921:        return (0);
                    922: }
                    923:
                    924: /*
                    925:  * Check the RX frame & buffer descriptor lists for our invariants,
                    926:  * i.e.: EOL bit set iff. it is pointed at by the r*tail pointer.
                    927:  *
                    928:  * Called when the receive unit has stopped unexpectedly.
                    929:  * Returns 1 if an inconsistency is detected; 0 otherwise.
                    930:  *
                    931:  * The Receive Unit is expected to be NOT RUNNING.
                    932:  */
                    933: int
                    934: i82596_chk_rx_ring(sc)
                    935:        struct ie_softc *sc;
                    936: {
                    937:        int n, off, val;
                    938:
                    939:        for (n = 0; n < sc->nrxbuf; n++) {
                    940:                off = IE_RBD_BUFLEN(sc->rbds, n);
                    941:                val = sc->ie_bus_read16(sc, off);
                    942:                if ((n == sc->rbtail) ^ ((val & IE_RBD_EOL) != 0)) {
                    943:                        /* `rbtail' and EOL flag out of sync */
                    944:                        log(LOG_ERR,
                    945:                            "%s: rx buffer descriptors out of sync at %d\n",
                    946:                            sc->sc_dev.dv_xname, n);
                    947:                        return (1);
                    948:                }
                    949:
                    950:                /* Take the opportunity to clear the status fields here ? */
                    951:        }
                    952:
                    953:        for (n = 0; n < sc->nframes; n++) {
                    954:                off = IE_RFRAME_LAST(sc->rframes, n);
                    955:                val = sc->ie_bus_read16(sc, off);
                    956:                if ((n == sc->rftail) ^ ((val & (IE_FD_EOL|IE_FD_SUSP)) != 0)) {
                    957:                        /* `rftail' and EOL flag out of sync */
                    958:                        log(LOG_ERR,
                    959:                            "%s: rx frame list out of sync at %d\n",
                    960:                            sc->sc_dev.dv_xname, n);
                    961:                        return (1);
                    962:                }
                    963:        }
                    964:
                    965:        return (0);
                    966: }
                    967:
                    968: /*
                    969:  * Read data off the interface, and turn it into an mbuf chain.
                    970:  *
                    971:  * This code is DRAMATICALLY different from the previous version; this
                    972:  * version tries to allocate the entire mbuf chain up front, given the
                    973:  * length of the data available.  This enables us to allocate mbuf
                    974:  * clusters in many situations where before we would have had a long
                    975:  * chain of partially-full mbufs.  This should help to speed up the
                    976:  * operation considerably.  (Provided that it works, of course.)
                    977:  */
                    978: static __inline__ struct mbuf *
                    979: i82596_get(struct ie_softc *sc, int head, int totlen)
                    980: {
                    981:        struct mbuf *m, *m0, *newm;
                    982:        int off, len, resid;
                    983:        int thisrboff, thismboff;
                    984:        struct ether_header eh;
                    985:
                    986:        /*
                    987:         * Snarf the Ethernet header.
                    988:         */
                    989:        (sc->memcopyin)(sc, &eh, IE_RBUF_ADDR(sc, head),
                    990:            sizeof(struct ether_header));
                    991:
                    992:        resid = totlen;
                    993:
                    994:        MGETHDR(m0, M_DONTWAIT, MT_DATA);
                    995:        if (m0 == 0)
                    996:                return (0);
                    997:        m0->m_pkthdr.rcvif = &sc->sc_arpcom.ac_if;
                    998:        m0->m_pkthdr.len = totlen;
                    999:        len = MHLEN;
                   1000:        m = m0;
                   1001:
                   1002:        /*
                   1003:         * This loop goes through and allocates mbufs for all the data we will
                   1004:         * be copying in.  It does not actually do the copying yet.
                   1005:         */
                   1006:        while (totlen > 0) {
                   1007:                if (totlen >= MINCLSIZE) {
                   1008:                        MCLGET(m, M_DONTWAIT);
                   1009:                        if ((m->m_flags & M_EXT) == 0)
                   1010:                                goto bad;
                   1011:                        len = MCLBYTES;
                   1012:                }
                   1013:
                   1014:                if (m == m0) {
                   1015:                        caddr_t newdata = (caddr_t)
                   1016:                            ALIGN(m->m_data + sizeof(struct ether_header)) -
                   1017:                            sizeof(struct ether_header);
                   1018:                        len -= newdata - m->m_data;
                   1019:                        m->m_data = newdata;
                   1020:                }
                   1021:
                   1022:                m->m_len = len = min(totlen, len);
                   1023:
                   1024:                totlen -= len;
                   1025:                if (totlen > 0) {
                   1026:                        MGET(newm, M_DONTWAIT, MT_DATA);
                   1027:                        if (newm == 0)
                   1028:                                goto bad;
                   1029:                        len = MLEN;
                   1030:                        m = m->m_next = newm;
                   1031:                }
                   1032:        }
                   1033:
                   1034:        m = m0;
                   1035:        thismboff = 0;
                   1036:
                   1037:        /*
                   1038:         * Copy the Ethernet header into the mbuf chain.
                   1039:         */
                   1040:        bcopy(&eh, mtod(m, caddr_t), sizeof(struct ether_header));
                   1041:        thismboff = sizeof(struct ether_header);
                   1042:        thisrboff = sizeof(struct ether_header);
                   1043:        resid -= sizeof(struct ether_header);
                   1044:
                   1045:        /*
                   1046:         * Now we take the mbuf chain (hopefully only one mbuf most of the
                   1047:         * time) and stuff the data into it.  There are no possible failures
                   1048:         * at or after this point.
                   1049:         */
                   1050:        while (resid > 0) {
                   1051:                int thisrblen = IE_RBUF_SIZE - thisrboff,
                   1052:                    thismblen = m->m_len - thismboff;
                   1053:                len = min(thisrblen, thismblen);
                   1054:
                   1055:                off = IE_RBUF_ADDR(sc,head) + thisrboff;
                   1056:                (sc->memcopyin)(sc, mtod(m, caddr_t) + thismboff, off, len);
                   1057:                resid -= len;
                   1058:
                   1059:                if (len == thismblen) {
                   1060:                        m = m->m_next;
                   1061:                        thismboff = 0;
                   1062:                } else
                   1063:                        thismboff += len;
                   1064:
                   1065:                if (len == thisrblen) {
                   1066:                        if (++head == sc->nrxbuf)
                   1067:                                head = 0;
                   1068:                        thisrboff = 0;
                   1069:                } else
                   1070:                        thisrboff += len;
                   1071:        }
                   1072:
                   1073:        /*
                   1074:         * Unless something changed strangely while we were doing the copy,
                   1075:         * we have now copied everything in from the shared memory.
                   1076:         * This means that we are done.
                   1077:         */
                   1078:        return (m0);
                   1079:
                   1080: bad:
                   1081:        m_freem(m0);
                   1082:        return (NULL);
                   1083: }
                   1084:
                   1085: /*
                   1086:  * Read frame NUM from unit UNIT (pre-cached as IE).
                   1087:  *
                   1088:  * This routine reads the RFD at NUM, and copies in the buffers from the list
                   1089:  * of RBD, then rotates the RBD list so that the receiver doesn't start
                   1090:  * complaining.  Trailers are DROPPED---there's no point in wasting time
                   1091:  * on confusing code to deal with them.  Hopefully, this machine will
                   1092:  * never ARP for trailers anyway.
                   1093:  */
                   1094: int
                   1095: i82596_readframe(sc, num)
                   1096:        struct ie_softc *sc;
                   1097:        int num;                /* frame number to read */
                   1098: {
                   1099:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
                   1100:        struct mbuf *m;
                   1101:        u_int16_t bstart, bend;
                   1102:        int pktlen;
                   1103:
                   1104:        if (i82596_get_rbd_list(sc, &bstart, &bend, &pktlen) == 0) {
                   1105:                ifp->if_ierrors++;
                   1106:                return (1);
                   1107:        }
                   1108:
                   1109:        m = i82596_get(sc, bstart, pktlen);
                   1110:        i82596_release_rbd_list(sc, bstart, bend);
                   1111:
                   1112:        if (m == 0) {
                   1113:                sc->sc_arpcom.ac_if.if_ierrors++;
                   1114:                return (0);
                   1115:        }
                   1116:
                   1117: #ifdef I82596_DEBUG
                   1118:        if (sc->sc_debug & IED_READFRAME) {
                   1119:                struct ether_header *eh = mtod(m, struct ether_header *);
                   1120:
                   1121:                printf("%s: frame from ether %s type 0x%x len %d\n",
                   1122:                    sc->sc_dev.dv_xname, ether_sprintf(eh->ether_shost),
                   1123:                    (u_int)eh->ether_type, pktlen);
                   1124:        }
                   1125: #endif
                   1126:
                   1127: #if NBPFILTER > 0
                   1128:        /* Check for a BPF filter; if so, hand it up. */
                   1129:        if (ifp->if_bpf)
                   1130:                bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
                   1131: #endif /* NBPFILTER > 0 */
                   1132:
                   1133:        /*
                   1134:         * Finally pass this packet up to higher layers.
                   1135:         */
                   1136:        ether_input_mbuf(ifp, m);
                   1137:        ifp->if_ipackets++;
                   1138:        return (0);
                   1139: }
                   1140:
                   1141:
                   1142: /*
                   1143:  * Setup all necessary artifacts for an XMIT command, and then pass the XMIT
                   1144:  * command to the chip to be executed.
                   1145:  */
                   1146: void
                   1147: i82596_xmit(sc)
                   1148:        struct ie_softc *sc;
                   1149: {
                   1150:        int off, cur, prev;
                   1151:
                   1152:        cur = sc->xctail;
                   1153:
                   1154: #ifdef I82596_DEBUG
                   1155:        if (sc->sc_debug & IED_XMIT)
                   1156:                printf("%s: xmit buffer %d\n", sc->sc_dev.dv_xname, cur);
                   1157: #endif
                   1158:
                   1159:        /*
                   1160:         * Setup the transmit command.
                   1161:         */
                   1162:        sc->ie_bus_write16(sc, IE_CMD_XMIT_DESC(sc->xmit_cmds, cur),
                   1163:                               IE_XBD_ADDR(sc->xbds, cur));
                   1164:
                   1165:        sc->ie_bus_write16(sc, IE_CMD_XMIT_STATUS(sc->xmit_cmds, cur), 0);
                   1166:
                   1167:        if (sc->do_xmitnopchain) {
                   1168:                /*
                   1169:                 * Gate this XMIT command to the following NOP
                   1170:                 */
                   1171:                sc->ie_bus_write16(sc, IE_CMD_XMIT_LINK(sc->xmit_cmds, cur),
                   1172:                                       IE_CMD_NOP_ADDR(sc->nop_cmds, cur));
                   1173:                sc->ie_bus_write16(sc, IE_CMD_XMIT_CMD(sc->xmit_cmds, cur),
                   1174:                                       IE_CMD_XMIT | IE_CMD_INTR);
                   1175:
                   1176:                /*
                   1177:                 * Loopback at following NOP
                   1178:                 */
                   1179:                sc->ie_bus_write16(sc, IE_CMD_NOP_STATUS(sc->nop_cmds, cur), 0);
                   1180:                sc->ie_bus_write16(sc, IE_CMD_NOP_LINK(sc->nop_cmds, cur),
                   1181:                                       IE_CMD_NOP_ADDR(sc->nop_cmds, cur));
                   1182:
                   1183:                /*
                   1184:                 * Gate preceding NOP to this XMIT command
                   1185:                 */
                   1186:                prev = (cur + NTXBUF - 1) % NTXBUF;
                   1187:                sc->ie_bus_write16(sc, IE_CMD_NOP_STATUS(sc->nop_cmds, prev), 0);
                   1188:                sc->ie_bus_write16(sc, IE_CMD_NOP_LINK(sc->nop_cmds, prev),
                   1189:                                       IE_CMD_XMIT_ADDR(sc->xmit_cmds, cur));
                   1190:
                   1191:                off = IE_SCB_STATUS(sc->scb);
                   1192:                bus_space_barrier(sc->bt, sc->bh, off, 2,
                   1193:                                  BUS_SPACE_BARRIER_READ);
                   1194:                if ((sc->ie_bus_read16(sc, off) & IE_CUS_ACTIVE) == 0) {
                   1195:                        printf("i82596_xmit: CU not active\n");
                   1196:                        i82596_start_transceiver(sc);
                   1197:                }
                   1198:        } else {
                   1199:                sc->ie_bus_write16(sc, IE_CMD_XMIT_LINK(sc->xmit_cmds,cur),
                   1200:                                       0xffff);
                   1201:
                   1202:                sc->ie_bus_write16(sc, IE_CMD_XMIT_CMD(sc->xmit_cmds, cur),
                   1203:                                       IE_CMD_XMIT | IE_CMD_INTR | IE_CMD_LAST);
                   1204:
                   1205:                off = IE_SCB_CMDLST(sc->scb);
                   1206:                sc->ie_bus_write16(sc, off, IE_CMD_XMIT_ADDR(sc->xmit_cmds, cur));
                   1207:                bus_space_barrier(sc->bt, sc->bh, off, 2,
                   1208:                                  BUS_SPACE_BARRIER_WRITE);
                   1209:
                   1210:                if (i82596_start_cmd(sc, IE_CUC_START, 0, 0, 1)) {
                   1211: #ifdef I82596_DEBUG
                   1212:                        if (sc->sc_debug & IED_XMIT)
                   1213:                                printf("%s: i82596_xmit: "
                   1214:                                    "start xmit command timed out\n",
                   1215:                                       sc->sc_dev.dv_xname);
                   1216: #endif
                   1217:                }
                   1218:        }
                   1219:
                   1220:        sc->sc_arpcom.ac_if.if_timer = 5;
                   1221: }
                   1222:
                   1223:
                   1224: /*
                   1225:  * Start transmission on an interface.
                   1226:  */
                   1227: void
                   1228: i82596_start(ifp)
                   1229:        struct ifnet *ifp;
                   1230: {
                   1231:        struct ie_softc *sc = ifp->if_softc;
                   1232:        struct mbuf *m0, *m;
                   1233:        int     buffer, head, xbase;
                   1234:        u_short len;
                   1235:
                   1236: #ifdef I82596_DEBUG
                   1237:        if (sc->sc_debug & IED_ENQ)
                   1238:                printf("i82596_start(%p)\n", ifp);
                   1239: #endif
                   1240:
                   1241:        if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
                   1242:                return;
                   1243:
                   1244:        for (;;) {
                   1245:                if (sc->xmit_busy == NTXBUF) {
                   1246:                        ifp->if_flags |= IFF_OACTIVE;
                   1247:                        break;
                   1248:                }
                   1249:
                   1250:                IFQ_DEQUEUE(&ifp->if_snd, m0);
                   1251:                if (m0 == 0)
                   1252:                        break;
                   1253:
                   1254:                /* We need to use m->m_pkthdr.len, so require the header */
                   1255:                if ((m0->m_flags & M_PKTHDR) == 0)
                   1256:                        panic("i82596_start: no header mbuf");
                   1257:
                   1258: #if NBPFILTER > 0
                   1259:                /* Tap off here if there is a BPF listener. */
                   1260:                if (ifp->if_bpf)
                   1261:                        bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
                   1262: #endif
                   1263:
                   1264:                if (m0->m_pkthdr.len > IE_TBUF_SIZE)
                   1265:                        printf("%s: tbuf overflow\n", sc->sc_dev.dv_xname);
                   1266:
                   1267:                head = sc->xchead;
                   1268:                sc->xchead = (head + 1) % NTXBUF;
                   1269:                buffer = IE_XBUF_ADDR(sc, head);
                   1270:
                   1271: #ifdef I82596_DEBUG
                   1272:                if (sc->sc_debug & IED_ENQ)
                   1273:                        printf("%s: fill buffer %d offset %x",
                   1274:                            sc->sc_dev.dv_xname, head, buffer);
                   1275: #endif
                   1276:
                   1277:                for (m = m0; m != 0; m = m->m_next) {
                   1278: #ifdef I82596_DEBUG
                   1279:                        if (sc->sc_debug & IED_ENQ) {
                   1280:                                u_int8_t *e, *p = mtod(m, u_int8_t *);
                   1281:                                static int i;
                   1282:                                if (m == m0)
                   1283:                                        i = 0;
                   1284:                                for (e = p + m->m_len; p < e; i++, p += 2) {
                   1285:                                        if (!(i % 8))
                   1286:                                                printf("\n%s:",
                   1287:                                                    sc->sc_dev.dv_xname);
                   1288:                                        printf(" %02x%02x", p[0], p[1]);
                   1289:                                }
                   1290:                        }
                   1291: #endif
                   1292:                        (sc->memcopyout)(sc, mtod(m,caddr_t), buffer, m->m_len);
                   1293:                        buffer += m->m_len;
                   1294:                }
                   1295:
                   1296:                len = m0->m_pkthdr.len;
                   1297:                if (len < ETHER_MIN_LEN - ETHER_CRC_LEN) {
                   1298:                        (sc->memcopyout)(sc, padbuf, buffer,
                   1299:                            ETHER_MIN_LEN - ETHER_CRC_LEN - len);
                   1300:                        buffer += ETHER_MIN_LEN - ETHER_CRC_LEN - len;
                   1301:                        len = ETHER_MIN_LEN - ETHER_CRC_LEN;
                   1302:                }
                   1303:
                   1304: #ifdef I82596_DEBUG
                   1305:                if (sc->sc_debug & IED_ENQ)
                   1306:                        printf("\n");
                   1307: #endif
                   1308:
                   1309:                m_freem(m0);
                   1310:
                   1311:                /*
                   1312:                 * Setup the transmit buffer descriptor here, while we
                   1313:                 * know the packet's length.
                   1314:                 */
                   1315:                xbase = sc->xbds;
                   1316:                sc->ie_bus_write16(sc, IE_XBD_FLAGS(xbase, head),
                   1317:                                       len | IE_TBD_EOL);
                   1318:                sc->ie_bus_write16(sc, IE_XBD_NEXT(xbase, head), 0xffff);
                   1319:                sc->ie_bus_write24(sc, IE_XBD_BUF(xbase, head),
                   1320:                                       sc->sc_maddr + IE_XBUF_ADDR(sc, head));
                   1321:
                   1322:                /* Start the first packet transmitting. */
                   1323:                if (sc->xmit_busy++ == 0)
                   1324:                        i82596_xmit(sc);
                   1325:        }
                   1326: }
                   1327:
                   1328: /*
                   1329:  * Probe IE's ram setup   [ Move all this into MD front-end!? ]
                   1330:  * Use only if SCP and ISCP represent offsets into shared ram space.
                   1331:  */
                   1332: int
                   1333: i82596_proberam(sc)
                   1334:        struct ie_softc *sc;
                   1335: {
                   1336:        int result, off;
                   1337:
                   1338:        /* Put in 16-bit mode */
                   1339:        off = IE_SCP_BUS_USE(sc->scp);
                   1340:        (sc->ie_bus_write16)(sc, off, 0);
                   1341:        bus_space_barrier(sc->bt, sc->bh, off, 2, BUS_SPACE_BARRIER_WRITE);
                   1342:
                   1343:        /* Set the ISCP `busy' bit */
                   1344:        off = IE_ISCP_BUSY(sc->iscp);
                   1345:        (sc->ie_bus_write16)(sc, off, 1);
                   1346:        bus_space_barrier(sc->bt, sc->bh, off, 2, BUS_SPACE_BARRIER_WRITE);
                   1347:
                   1348:        if (sc->hwreset)
                   1349:                (sc->hwreset)(sc, IE_CHIP_PROBE);
                   1350:
                   1351:        (sc->chan_attn) (sc);
                   1352:
                   1353:        DELAY(100);             /* wait a while... */
                   1354:
                   1355:        /* Read back the ISCP `busy' bit; it should be clear by now */
                   1356:        off = IE_ISCP_BUSY(sc->iscp);
                   1357:        bus_space_barrier(sc->bt, sc->bh, off, 1, BUS_SPACE_BARRIER_READ);
                   1358:        result = (sc->ie_bus_read16)(sc, off) == 0;
                   1359:
                   1360:        /* Acknowledge any interrupts we may have caused. */
                   1361:        ie_ack(sc, IE_ST_WHENCE);
                   1362:
                   1363:        return (result);
                   1364: }
                   1365:
                   1366: void
                   1367: i82596_reset(sc, hard)
                   1368:        struct ie_softc *sc;
                   1369:        int hard;
                   1370: {
                   1371:        int s = splnet();
                   1372:
                   1373: #ifdef I82596_DEBUG
                   1374:        if (hard)
                   1375:                printf("%s: reset\n", sc->sc_dev.dv_xname);
                   1376: #endif
                   1377:
                   1378:        /* Clear OACTIVE in case we're called from watchdog (frozen xmit). */
                   1379:        sc->sc_arpcom.ac_if.if_timer = 0;
                   1380:        sc->sc_arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
                   1381:
                   1382:        /*
                   1383:         * Stop i82596 dead in its tracks.
                   1384:         */
                   1385:        if (i82596_start_cmd(sc, IE_RUC_ABORT | IE_CUC_ABORT, 0, 0, 0)) {
                   1386: #ifdef I82596_DEBUG
                   1387:                printf("%s: abort commands timed out\n", sc->sc_dev.dv_xname);
                   1388: #endif
                   1389:        }
                   1390:
                   1391:        /*
                   1392:         * This can really slow down the i82596_reset() on some cards, but it's
                   1393:         * necessary to unwedge other ones (eg, the Sun VME ones) from certain
                   1394:         * lockups.
                   1395:         */
                   1396:        if (hard && sc->hwreset)
                   1397:                (sc->hwreset)(sc, IE_CARD_RESET);
                   1398:
                   1399:        DELAY(100);
                   1400:        ie_ack(sc, IE_ST_WHENCE);
                   1401:
                   1402:        if ((sc->sc_arpcom.ac_if.if_flags & IFF_UP) != 0) {
                   1403:                int retries=0;  /* XXX - find out why init sometimes fails */
                   1404:                while (retries++ < 2)
                   1405:                        if (i82596_init(sc) == 1)
                   1406:                                break;
                   1407:        }
                   1408:
                   1409:        splx(s);
                   1410: }
                   1411:
                   1412: void
                   1413: i82596_simple_command(sc, cmd, cmdbuf)
                   1414:        struct ie_softc *sc;
                   1415:        int cmd;
                   1416:        int cmdbuf;
                   1417: {
                   1418:        /* Setup a simple command */
                   1419:        sc->ie_bus_write16(sc, IE_CMD_COMMON_STATUS(cmdbuf), 0);
                   1420:        sc->ie_bus_write16(sc, IE_CMD_COMMON_CMD(cmdbuf), cmd | IE_CMD_LAST);
                   1421:        sc->ie_bus_write16(sc, IE_CMD_COMMON_LINK(cmdbuf), 0xffff);
                   1422:
                   1423:        /* Assign the command buffer to the SCB command list */
                   1424:        sc->ie_bus_write16(sc, IE_SCB_CMDLST(sc->scb), cmdbuf);
                   1425: }
                   1426:
                   1427: /*
                   1428:  * Run the time-domain reflectometer.
                   1429:  */
                   1430: void
                   1431: ie_run_tdr(sc, cmd)
                   1432:        struct ie_softc *sc;
                   1433:        int cmd;
                   1434: {
                   1435:        int result, clocks;
                   1436:
                   1437:        i82596_simple_command(sc, IE_CMD_TDR, cmd);
                   1438:        (sc->ie_bus_write16)(sc, IE_CMD_TDR_TIME(cmd), 0);
                   1439:
                   1440:        if (i82596_start_cmd(sc, IE_CUC_START, cmd, IE_STAT_COMPL, 0) ||
                   1441:            !(sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmd)) & IE_STAT_OK))
                   1442:                result = 0x10000; /* XXX */
                   1443:        else
                   1444:                result = sc->ie_bus_read16(sc, IE_CMD_TDR_TIME(cmd));
                   1445:
                   1446:        /* Squash any pending interrupts */
                   1447:        ie_ack(sc, IE_ST_WHENCE);
                   1448:
                   1449:        if (result & IE_TDR_SUCCESS)
                   1450:                return;
                   1451:
                   1452:        clocks = result & IE_TDR_TIME;
                   1453:        if (result & 0x10000)
                   1454:                printf("%s: TDR command failed\n", sc->sc_dev.dv_xname);
                   1455:        else if (result & IE_TDR_XCVR)
                   1456:                printf("%s: transceiver problem\n", sc->sc_dev.dv_xname);
                   1457:        else if (result & IE_TDR_OPEN)
                   1458:                printf("%s: TDR detected an open %d clock%s away\n",
                   1459:                    sc->sc_dev.dv_xname, clocks, clocks == 1? "":"s");
                   1460:        else if (result & IE_TDR_SHORT)
                   1461:                printf("%s: TDR detected a short %d clock%s away\n",
                   1462:                    sc->sc_dev.dv_xname, clocks, clocks == 1? "":"s");
                   1463:        else
                   1464:                printf("%s: TDR returned unknown status 0x%x\n",
                   1465:                    sc->sc_dev.dv_xname, result);
                   1466: }
                   1467:
                   1468: /*
                   1469:  * i82596_setup_bufs: set up the buffers
                   1470:  *
                   1471:  * We have a block of KVA at sc->buf_area which is of size sc->buf_area_sz.
                   1472:  * this is to be used for the buffers.  The chip indexs its control data
                   1473:  * structures with 16 bit offsets, and it indexes actual buffers with
                   1474:  * 24 bit addresses.   So we should allocate control buffers first so that
                   1475:  * we don't overflow the 16 bit offset field.   The number of transmit
                   1476:  * buffers is fixed at compile time.
                   1477:  *
                   1478:  */
                   1479: void
                   1480: i82596_setup_bufs(sc)
                   1481:        struct ie_softc *sc;
                   1482: {
                   1483:        int n, r, ptr = sc->buf_area;   /* memory pool */
                   1484:        int cl = 32;
                   1485:
                   1486:        /*
                   1487:         * step 0: zero memory and figure out how many recv buffers and
                   1488:         * frames we can have.
                   1489:         */
                   1490:        ptr = (ptr + cl - 1) & ~(cl - 1); /* set alignment and stick with it */
                   1491:
                   1492:        /*
                   1493:         *  step 1: lay out data structures in the shared-memory area
                   1494:         */
                   1495:
                   1496:        /* The no-op commands; used if "nop-chaining" is in effect */
                   1497:        ptr += cl;
                   1498:        sc->nop_cmds = ptr - 2;
                   1499:        ptr += NTXBUF * 32;
                   1500:
                   1501:        /* The transmit commands */
                   1502:        ptr += cl;
                   1503:        sc->xmit_cmds = ptr - 2;
                   1504:        ptr += NTXBUF * 32;
                   1505:
                   1506:        /* The transmit buffers descriptors */
                   1507:        ptr += cl;
                   1508:        sc->xbds = ptr - 2;
                   1509:        ptr += NTXBUF * 32;
                   1510:
                   1511:        /* The transmit buffers */
                   1512:        sc->xbufs = ptr;
                   1513:        ptr += NTXBUF * IE_TBUF_SIZE;
                   1514:
                   1515:        ptr = (ptr + cl - 1) & ~(cl - 1);       /* re-align.. just in case */
                   1516:
                   1517:        /* Compute free space for RECV stuff */
                   1518:        n = sc->buf_area_sz - (ptr - sc->buf_area);
                   1519:
                   1520:        /* Compute size of one RECV frame */
                   1521:        r = 64 + ((32 + IE_RBUF_SIZE) * B_PER_F);
                   1522:
                   1523:        sc->nframes = n / r;
                   1524:
                   1525:        if (sc->nframes <= 8)
                   1526:                panic("ie: bogus buffer calc");
                   1527:
                   1528:        sc->nrxbuf = sc->nframes * B_PER_F;
                   1529:
                   1530:        /* The receive frame descriptors */
                   1531:        ptr += cl;
                   1532:        sc->rframes = ptr - 2;
                   1533:        ptr += sc->nframes * 64;
                   1534:
                   1535:        /* The receive buffer descriptors */
                   1536:        ptr += cl;
                   1537:        sc->rbds = ptr - 2;
                   1538:        ptr += sc->nrxbuf * 32;
                   1539:
                   1540:        /* The receive buffers */
                   1541:        sc->rbufs = ptr;
                   1542:        ptr += sc->nrxbuf * IE_RBUF_SIZE;
                   1543:
                   1544: #ifdef I82596_DEBUG
                   1545:        printf("%s: %d frames %d bufs\n", sc->sc_dev.dv_xname, sc->nframes,
                   1546:                sc->nrxbuf);
                   1547: #endif
                   1548:
                   1549:        /*
                   1550:         * step 2: link together the recv frames and set EOL on last one
                   1551:         */
                   1552:        for (n = 0; n < sc->nframes; n++) {
                   1553:                int m = (n == sc->nframes - 1) ? 0 : n + 1;
                   1554:
                   1555:                /* Clear status */
                   1556:                sc->ie_bus_write16(sc, IE_RFRAME_STATUS(sc->rframes,n), 0);
                   1557:
                   1558:                /* RBD link = NULL */
                   1559:                sc->ie_bus_write16(sc, IE_RFRAME_BUFDESC(sc->rframes,n),
                   1560:                                       0xffff);
                   1561:
                   1562:                /* Make a circular list */
                   1563:                sc->ie_bus_write16(sc, IE_RFRAME_NEXT(sc->rframes,n),
                   1564:                                       IE_RFRAME_ADDR(sc->rframes,m));
                   1565:
                   1566:                /* Mark last as EOL */
                   1567:                sc->ie_bus_write16(sc, IE_RFRAME_LAST(sc->rframes,n),
                   1568:                                       ((m==0)? (IE_FD_EOL|IE_FD_SUSP) : 0));
                   1569:        }
                   1570:
                   1571:        /*
                   1572:         * step 3: link the RBDs and set EOL on last one
                   1573:         */
                   1574:        for (n = 0; n < sc->nrxbuf; n++) {
                   1575:                int m = (n == sc->nrxbuf - 1) ? 0 : n + 1;
                   1576:
                   1577:                /* Clear status */
                   1578:                sc->ie_bus_write16(sc, IE_RBD_STATUS(sc->rbds,n), 0);
                   1579:
                   1580:                /* Make a circular list */
                   1581:                sc->ie_bus_write16(sc, IE_RBD_NEXT(sc->rbds,n),
                   1582:                                       IE_RBD_ADDR(sc->rbds,m));
                   1583:
                   1584:                /* Link to data buffers */
                   1585:                sc->ie_bus_write24(sc, IE_RBD_BUFADDR(sc->rbds, n),
                   1586:                                       sc->sc_maddr + IE_RBUF_ADDR(sc, n));
                   1587:                sc->ie_bus_write16(sc, IE_RBD_BUFLEN(sc->rbds,n),
                   1588:                                       IE_RBUF_SIZE | ((m==0)?IE_RBD_EOL:0));
                   1589:        }
                   1590:
                   1591:        /*
                   1592:         * step 4: all xmit no-op commands loopback onto themselves
                   1593:         */
                   1594:        for (n = 0; n < NTXBUF; n++) {
                   1595:                (sc->ie_bus_write16)(sc, IE_CMD_NOP_STATUS(sc->nop_cmds, n), 0);
                   1596:
                   1597:                (sc->ie_bus_write16)(sc, IE_CMD_NOP_CMD(sc->nop_cmds, n),
                   1598:                                         IE_CMD_NOP);
                   1599:
                   1600:                (sc->ie_bus_write16)(sc, IE_CMD_NOP_LINK(sc->nop_cmds, n),
                   1601:                                         IE_CMD_NOP_ADDR(sc->nop_cmds, n));
                   1602:        }
                   1603:
                   1604:
                   1605:        /*
                   1606:         * step 6: set the head and tail pointers on receive to keep track of
                   1607:         * the order in which RFDs and RBDs are used.
                   1608:         */
                   1609:
                   1610:        /* Pointers to last packet sent and next available transmit buffer. */
                   1611:        sc->xchead = sc->xctail = 0;
                   1612:
                   1613:        /* Clear transmit-busy flag and set number of free transmit buffers. */
                   1614:        sc->xmit_busy = 0;
                   1615:
                   1616:        /*
                   1617:         * Pointers to first and last receive frame.
                   1618:         * The RFD pointed to by rftail is the only one that has EOL set.
                   1619:         */
                   1620:        sc->rfhead = 0;
                   1621:        sc->rftail = sc->nframes - 1;
                   1622:
                   1623:        /*
                   1624:         * Pointers to first and last receive descriptor buffer.
                   1625:         * The RBD pointed to by rbtail is the only one that has EOL set.
                   1626:         */
                   1627:        sc->rbhead = 0;
                   1628:        sc->rbtail = sc->nrxbuf - 1;
                   1629:
                   1630: /* link in recv frames * and buffer into the scb. */
                   1631: #ifdef I82596_DEBUG
                   1632:        printf("%s: reserved %d bytes\n",
                   1633:                sc->sc_dev.dv_xname, ptr - sc->buf_area);
                   1634: #endif
                   1635: }
                   1636:
                   1637: int
                   1638: ie_cfg_setup(sc, cmd, promiscuous, manchester)
                   1639:        struct ie_softc *sc;
                   1640:        int cmd;
                   1641:        int promiscuous, manchester;
                   1642: {
                   1643:        int cmdresult, status;
                   1644:
                   1645:        i82596_simple_command(sc, IE_CMD_CONFIG, cmd);
                   1646:        bus_space_write_1(sc->bt, sc->bh, IE_CMD_CFG_CNT(cmd), 0x0c);
                   1647:        bus_space_write_1(sc->bt, sc->bh, IE_CMD_CFG_FIFO(cmd), 8);
                   1648:        bus_space_write_1(sc->bt, sc->bh, IE_CMD_CFG_SAVEBAD(cmd), 0x40);
                   1649:        bus_space_write_1(sc->bt, sc->bh, IE_CMD_CFG_ADDRLEN(cmd), 0x2e);
                   1650:        bus_space_write_1(sc->bt, sc->bh, IE_CMD_CFG_PRIORITY(cmd), 0);
                   1651:        bus_space_write_1(sc->bt, sc->bh, IE_CMD_CFG_IFS(cmd), 0x60);
                   1652:        bus_space_write_1(sc->bt, sc->bh, IE_CMD_CFG_SLOT_LOW(cmd), 0);
                   1653:        bus_space_write_1(sc->bt, sc->bh, IE_CMD_CFG_SLOT_HIGH(cmd), 0xf2);
                   1654:        bus_space_write_1(sc->bt, sc->bh, IE_CMD_CFG_PROMISC(cmd),
                   1655:                                          !!promiscuous | manchester << 2);
                   1656:        bus_space_write_1(sc->bt, sc->bh, IE_CMD_CFG_CRSCDT(cmd), 0);
                   1657:        bus_space_write_1(sc->bt, sc->bh, IE_CMD_CFG_MINLEN(cmd), 64);
                   1658:        bus_space_write_1(sc->bt, sc->bh, IE_CMD_CFG_JUNK(cmd), 0xff);
                   1659:        bus_space_barrier(sc->bt, sc->bh, cmd, IE_CMD_CFG_SZ,
                   1660:                          BUS_SPACE_BARRIER_WRITE);
                   1661:
                   1662:        cmdresult = i82596_start_cmd(sc, IE_CUC_START, cmd, IE_STAT_COMPL, 0);
                   1663:        status = sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmd));
                   1664:        if (cmdresult != 0) {
                   1665:                printf("%s: configure command timed out; status %b\n",
                   1666:                        sc->sc_dev.dv_xname, status, IE_STAT_BITS);
                   1667:                return (0);
                   1668:        }
                   1669:        if ((status & IE_STAT_OK) == 0) {
                   1670:                printf("%s: configure command failed; status %b\n",
                   1671:                        sc->sc_dev.dv_xname, status, IE_STAT_BITS);
                   1672:                return (0);
                   1673:        }
                   1674:
                   1675:        /* Squash any pending interrupts */
                   1676:        ie_ack(sc, IE_ST_WHENCE);
                   1677:        return (1);
                   1678: }
                   1679:
                   1680: int
                   1681: ie_ia_setup(sc, cmdbuf)
                   1682:        struct ie_softc *sc;
                   1683:        int cmdbuf;
                   1684: {
                   1685:        int cmdresult, status;
                   1686:
                   1687:        i82596_simple_command(sc, IE_CMD_IASETUP, cmdbuf);
                   1688:
                   1689:        (sc->memcopyout)(sc, sc->sc_arpcom.ac_enaddr,
                   1690:                         IE_CMD_IAS_EADDR(cmdbuf), ETHER_ADDR_LEN);
                   1691:
                   1692:        cmdresult = i82596_start_cmd(sc, IE_CUC_START, cmdbuf, IE_STAT_COMPL, 0);
                   1693:        status = sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmdbuf));
                   1694:        if (cmdresult != 0) {
                   1695:                printf("%s: individual address command timed out; status %b\n",
                   1696:                        sc->sc_dev.dv_xname, status, IE_STAT_BITS);
                   1697:                return (0);
                   1698:        }
                   1699:        if ((status & IE_STAT_OK) == 0) {
                   1700:                printf("%s: individual address command failed; status %b\n",
                   1701:                        sc->sc_dev.dv_xname, status, IE_STAT_BITS);
                   1702:                return (0);
                   1703:        }
                   1704:
                   1705:        /* Squash any pending interrupts */
                   1706:        ie_ack(sc, IE_ST_WHENCE);
                   1707:        return (1);
                   1708: }
                   1709:
                   1710: /*
                   1711:  * Run the multicast setup command.
                   1712:  * Called at splnet().
                   1713:  */
                   1714: int
                   1715: ie_mc_setup(sc, cmdbuf)
                   1716:        struct ie_softc *sc;
                   1717:        int cmdbuf;
                   1718: {
                   1719:        int cmdresult, status;
                   1720:
                   1721:        if (sc->mcast_count == 0)
                   1722:                return (1);
                   1723:
                   1724:        i82596_simple_command(sc, IE_CMD_MCAST, cmdbuf);
                   1725:
                   1726:        (sc->memcopyout)(sc, (caddr_t)sc->mcast_addrs,
                   1727:                         IE_CMD_MCAST_MADDR(cmdbuf),
                   1728:                         sc->mcast_count * ETHER_ADDR_LEN);
                   1729:
                   1730:        sc->ie_bus_write16(sc, IE_CMD_MCAST_BYTES(cmdbuf),
                   1731:                               sc->mcast_count * ETHER_ADDR_LEN);
                   1732:
                   1733:        /* Start the command */
                   1734:        cmdresult = i82596_start_cmd(sc, IE_CUC_START, cmdbuf, IE_STAT_COMPL, 0);
                   1735:        status = sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmdbuf));
                   1736:        if (cmdresult != 0) {
                   1737:                printf("%s: multicast setup command timed out; status %b\n",
                   1738:                        sc->sc_dev.dv_xname, status, IE_STAT_BITS);
                   1739:                return (0);
                   1740:        }
                   1741:        if ((status & IE_STAT_OK) == 0) {
                   1742:                printf("%s: multicast setup command failed; status %b\n",
                   1743:                        sc->sc_dev.dv_xname, status, IE_STAT_BITS);
                   1744:                return (0);
                   1745:        }
                   1746:
                   1747:        /* Squash any pending interrupts */
                   1748:        ie_ack(sc, IE_ST_WHENCE);
                   1749:        return (1);
                   1750: }
                   1751:
                   1752: /*
                   1753:  * This routine takes the environment generated by check_ie_present() and adds
                   1754:  * to it all the other structures we need to operate the adapter.  This
                   1755:  * includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands, starting
                   1756:  * the receiver unit, and clearing interrupts.
                   1757:  *
                   1758:  * THIS ROUTINE MUST BE CALLED AT splnet() OR HIGHER.
                   1759:  */
                   1760: int
                   1761: i82596_init(sc)
                   1762:        struct ie_softc *sc;
                   1763: {
                   1764:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
                   1765:        int cmd;
                   1766:
                   1767:        sc->async_cmd_inprogress = 0;
                   1768:
                   1769:        cmd = sc->buf_area;
                   1770:
                   1771:        /*
                   1772:         * Send the configure command first.
                   1773:         */
                   1774:        if (ie_cfg_setup(sc, cmd, sc->promisc, 0) == 0)
                   1775:                return (0);
                   1776:
                   1777:        /*
                   1778:         * Send the Individual Address Setup command.
                   1779:         */
                   1780:        if (ie_ia_setup(sc, cmd) == 0)
                   1781:                return (0);
                   1782:
                   1783:        /*
                   1784:         * Run the time-domain reflectometer.
                   1785:         */
                   1786:        ie_run_tdr(sc, cmd);
                   1787:
                   1788:        /*
                   1789:         * Set the multi-cast filter, if any
                   1790:         */
                   1791:        if (ie_mc_setup(sc, cmd) == 0)
                   1792:                return (0);
                   1793:
                   1794:        /*
                   1795:         * Acknowledge any interrupts we have generated thus far.
                   1796:         */
                   1797:        ie_ack(sc, IE_ST_WHENCE);
                   1798:
                   1799:        /*
                   1800:         * Set up the transmit and recv buffers.
                   1801:         */
                   1802:        i82596_setup_bufs(sc);
                   1803:
                   1804:        if (sc->hwinit)
                   1805:                (sc->hwinit)(sc);
                   1806:
                   1807:        ifp->if_flags |= IFF_RUNNING;
                   1808:        ifp->if_flags &= ~IFF_OACTIVE;
                   1809:
                   1810:        if (NTXBUF < 2)
                   1811:                sc->do_xmitnopchain = 0;
                   1812:
                   1813:        i82596_start_transceiver(sc);
                   1814:        return (1);
                   1815: }
                   1816:
                   1817: /*
                   1818:  * Start the RU and possibly the CU unit
                   1819:  */
                   1820: void
                   1821: i82596_start_transceiver(sc)
                   1822:        struct ie_softc *sc;
                   1823: {
                   1824:
                   1825:        /*
                   1826:         * Start RU at current position in frame & RBD lists.
                   1827:         */
                   1828:        sc->ie_bus_write16(sc, IE_RFRAME_BUFDESC(sc->rframes,sc->rfhead),
                   1829:                               IE_RBD_ADDR(sc->rbds, sc->rbhead));
                   1830:
                   1831:        sc->ie_bus_write16(sc, IE_SCB_RCVLST(sc->scb),
                   1832:                               IE_RFRAME_ADDR(sc->rframes,sc->rfhead));
                   1833:
                   1834:        if (sc->do_xmitnopchain) {
                   1835:                /* Stop transmit command chain */
                   1836:                if (i82596_start_cmd(sc, IE_CUC_SUSPEND|IE_RUC_SUSPEND, 0, 0, 0))
                   1837:                        printf("%s: CU/RU stop command timed out\n",
                   1838:                                sc->sc_dev.dv_xname);
                   1839:
                   1840:                /* Start the receiver & transmitter chain */
                   1841:                /* sc->scb->ie_command_list =
                   1842:                        IEADDR(sc->nop_cmds[(sc->xctail+NTXBUF-1) % NTXBUF]);*/
                   1843:                sc->ie_bus_write16(sc, IE_SCB_CMDLST(sc->scb),
                   1844:                                   IE_CMD_NOP_ADDR(
                   1845:                                        sc->nop_cmds,
                   1846:                                        (sc->xctail + NTXBUF - 1) % NTXBUF));
                   1847:
                   1848:                if (i82596_start_cmd(sc, IE_CUC_START|IE_RUC_START, 0, 0, 0))
                   1849:                        printf("%s: CU/RU command timed out\n",
                   1850:                                sc->sc_dev.dv_xname);
                   1851:        } else {
                   1852:                if (i82596_start_cmd(sc, IE_RUC_START, 0, 0, 0))
                   1853:                        printf("%s: RU command timed out\n",
                   1854:                                sc->sc_dev.dv_xname);
                   1855:        }
                   1856: }
                   1857:
                   1858: void
                   1859: i82596_stop(sc)
                   1860:        struct ie_softc *sc;
                   1861: {
                   1862:
                   1863:        if (i82596_start_cmd(sc, IE_RUC_SUSPEND | IE_CUC_SUSPEND, 0, 0, 0))
                   1864:                printf("%s: i82596_stop: disable commands timed out\n",
                   1865:                        sc->sc_dev.dv_xname);
                   1866: }
                   1867:
                   1868: int
                   1869: i82596_ioctl(ifp, cmd, data)
                   1870:        register struct ifnet *ifp;
                   1871:        u_long cmd;
                   1872:        caddr_t data;
                   1873: {
                   1874:        struct ie_softc *sc = ifp->if_softc;
                   1875:        struct ifaddr *ifa = (struct ifaddr *)data;
                   1876:        struct ifreq *ifr = (struct ifreq *)data;
                   1877:        int s, error = 0;
                   1878:
                   1879:        s = splnet();
                   1880:
                   1881:        if ((error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data)) > 0) {
                   1882:                splx(s);
                   1883:                return error;
                   1884:        }
                   1885:
                   1886:        switch(cmd) {
                   1887:
                   1888:        case SIOCSIFADDR:
                   1889:                ifp->if_flags |= IFF_UP;
                   1890:
                   1891:                switch(ifa->ifa_addr->sa_family) {
                   1892: #ifdef INET
                   1893:                case AF_INET:
                   1894:                        i82596_init(sc);
                   1895:                        arp_ifinit(&sc->sc_arpcom, ifa);
                   1896:                        break;
                   1897: #endif
                   1898:                default:
                   1899:                        i82596_init(sc);
                   1900:                        break;
                   1901:                }
                   1902:                break;
                   1903:
                   1904:        case SIOCSIFFLAGS:
                   1905:                sc->promisc = ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
                   1906:                if ((ifp->if_flags & IFF_UP) == 0 &&
                   1907:                    (ifp->if_flags & IFF_RUNNING) != 0) {
                   1908:                        /*
                   1909:                         * If interface is marked down and it is running, then
                   1910:                         * stop it.
                   1911:                         */
                   1912:                        i82596_stop(sc);
                   1913:                        ifp->if_flags &= ~IFF_RUNNING;
                   1914:                } else if ((ifp->if_flags & IFF_UP) != 0 &&
                   1915:                           (ifp->if_flags & IFF_RUNNING) == 0) {
                   1916:                        /*
                   1917:                         * If interface is marked up and it is stopped, then
                   1918:                         * start it.
                   1919:                         */
                   1920:                        i82596_init(sc);
                   1921:                } else {
                   1922:                        /*
                   1923:                         * Reset the interface to pick up changes in any other
                   1924:                         * flags that affect hardware registers.
                   1925:                         */
                   1926:                        i82596_stop(sc);
                   1927:                        i82596_init(sc);
                   1928:                }
                   1929: #ifdef I82596_DEBUG
                   1930:                if (ifp->if_flags & IFF_DEBUG)
                   1931:                        sc->sc_debug = IED_ALL;
                   1932:                else
                   1933:                        sc->sc_debug = 0;
                   1934: #endif
                   1935:                break;
                   1936:
                   1937:        case SIOCADDMULTI:
                   1938:        case SIOCDELMULTI:
                   1939:                error = (cmd == SIOCADDMULTI) ?
                   1940:                    ether_addmulti(ifr, &sc->sc_arpcom):
                   1941:                    ether_delmulti(ifr, &sc->sc_arpcom);
                   1942:
                   1943:                if (error == ENETRESET) {
                   1944:                        /*
                   1945:                         * Multicast list has changed; set the hardware filter
                   1946:                         * accordingly.
                   1947:                         */
                   1948:                        if (ifp->if_flags & IFF_RUNNING)
                   1949:                                ie_mc_reset(sc);
                   1950:                        error = 0;
                   1951:                }
                   1952:                break;
                   1953:
                   1954:         case SIOCGIFMEDIA:
                   1955:         case SIOCSIFMEDIA:
                   1956:                 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
                   1957:                 break;
                   1958:
                   1959:        default:
                   1960:                error = EINVAL;
                   1961:        }
                   1962:        splx(s);
                   1963:        return (error);
                   1964: }
                   1965:
                   1966: void
                   1967: ie_mc_reset(sc)
                   1968:        struct ie_softc *sc;
                   1969: {
                   1970:        struct ether_multi *enm;
                   1971:        struct ether_multistep step;
                   1972:        int size;
                   1973:
                   1974:        /*
                   1975:         * Step through the list of addresses.
                   1976:         */
                   1977: again:
                   1978:        size = 0;
                   1979:        sc->mcast_count = 0;
                   1980:        ETHER_FIRST_MULTI(step, &sc->sc_arpcom, enm);
                   1981:        while (enm) {
                   1982:                size += 6;
                   1983:                if (sc->mcast_count >= IE_MAXMCAST ||
                   1984:                    bcmp(enm->enm_addrlo, enm->enm_addrhi, 6) != 0) {
                   1985:                        sc->sc_arpcom.ac_if.if_flags |= IFF_ALLMULTI;
                   1986:                        i82596_ioctl(&sc->sc_arpcom.ac_if,
                   1987:                                     SIOCSIFFLAGS, (void *)0);
                   1988:                        return;
                   1989:                }
                   1990:                ETHER_NEXT_MULTI(step, enm);
                   1991:        }
                   1992:
                   1993:        if (size > sc->mcast_addrs_size) {
                   1994:                /* Need to allocate more space */
                   1995:                if (sc->mcast_addrs_size)
                   1996:                        free(sc->mcast_addrs, M_IFMADDR);
                   1997:                sc->mcast_addrs = (char *)
                   1998:                        malloc(size, M_IFMADDR, M_WAITOK);
                   1999:                sc->mcast_addrs_size = size;
                   2000:        }
                   2001:
                   2002:        /*
                   2003:         * We've got the space; now copy the addresses
                   2004:         */
                   2005:        ETHER_FIRST_MULTI(step, &sc->sc_arpcom, enm);
                   2006:        while (enm) {
                   2007:                if (sc->mcast_count >= IE_MAXMCAST)
                   2008:                        goto again; /* Just in case */
                   2009:
                   2010:                bcopy(enm->enm_addrlo, &sc->mcast_addrs[sc->mcast_count], 6);
                   2011:                sc->mcast_count++;
                   2012:                ETHER_NEXT_MULTI(step, enm);
                   2013:        }
                   2014:        sc->want_mcsetup = 1;
                   2015: }
                   2016:
                   2017: /*
                   2018:  * Media change callback.
                   2019:  */
                   2020: int
                   2021: i82596_mediachange(ifp)
                   2022:         struct ifnet *ifp;
                   2023: {
                   2024:         struct ie_softc *sc = ifp->if_softc;
                   2025:
                   2026:         if (sc->sc_mediachange)
                   2027:                 return ((*sc->sc_mediachange)(sc));
                   2028:         return (EINVAL);
                   2029: }
                   2030:
                   2031: /*
                   2032:  * Media status callback.
                   2033:  */
                   2034: void
                   2035: i82596_mediastatus(ifp, ifmr)
                   2036:         struct ifnet *ifp;
                   2037:         struct ifmediareq *ifmr;
                   2038: {
                   2039:         struct ie_softc *sc = ifp->if_softc;
                   2040:
                   2041:         if (sc->sc_mediastatus)
                   2042:                 (*sc->sc_mediastatus)(sc, ifmr);
                   2043: }
                   2044:
                   2045: #ifdef I82596_DEBUG
                   2046: void
                   2047: print_rbd(sc, n)
                   2048:        struct ie_softc *sc;
                   2049:        int n;
                   2050: {
                   2051:
                   2052:        printf("RBD at %08x:\n  status %b, next %04x, buffer %lx\n"
                   2053:                "length/EOL %04x\n", IE_RBD_ADDR(sc->rbds,n),
                   2054:                sc->ie_bus_read16(sc, IE_RBD_STATUS(sc->rbds,n)), IE_STAT_BITS,
                   2055:                sc->ie_bus_read16(sc, IE_RBD_NEXT(sc->rbds,n)),
                   2056:                (u_long)0,/*bus_space_read_4(sc->bt, sc->bh, IE_RBD_BUFADDR(sc->rbds,n)),-* XXX */
                   2057:                sc->ie_bus_read16(sc, IE_RBD_BUFLEN(sc->rbds,n)));
                   2058: }
                   2059: #endif

CVSweb