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

Cache object: 576622f249731781d811b4b0eba67e21


[ 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.