The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ic/i82586.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 98997f636ecaab7691fb5f40c37fd5f3


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.