root/dev/ic/i82596.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. i82596_probe
  2. i82596_attach
  3. i82596_watchdog
  4. i82596_cmd_wait
  5. i82596_start_cmd
  6. i82596_count_errors
  7. i82596_rx_errors
  8. i82596_intr
  9. i82596_rint
  10. i82596_tint
  11. i82596_get_rbd_list
  12. i82596_release_rbd_list
  13. i82596_drop_frames
  14. i82596_chk_rx_ring
  15. i82596_get
  16. i82596_readframe
  17. i82596_xmit
  18. i82596_start
  19. i82596_proberam
  20. i82596_reset
  21. i82596_simple_command
  22. ie_run_tdr
  23. i82596_setup_bufs
  24. ie_cfg_setup
  25. ie_ia_setup
  26. ie_mc_setup
  27. i82596_init
  28. i82596_start_transceiver
  29. i82596_stop
  30. i82596_ioctl
  31. ie_mc_reset
  32. i82596_mediachange
  33. i82596_mediastatus
  34. print_rbd

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

/* [<][>][^][v][top][bottom][index][help] */