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/seeq8005.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: seeq8005.c,v 1.35 2003/01/15 21:56:06 bouyer Exp $ */
    2 
    3 /*
    4  * Copyright (c) 2000, 2001 Ben Harris
    5  * Copyright (c) 1995-1998 Mark Brinicombe
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. All advertising materials mentioning features or use of this software
   17  *    must display the following acknowledgement:
   18  *      This product includes software developed by Mark Brinicombe
   19  *      for the NetBSD Project.
   20  * 4. The name of the company nor the name of the author may be used to
   21  *    endorse or promote products derived from this software without specific
   22  *    prior written permission.
   23  *
   24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
   25  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
   26  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   27  * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
   28  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   29  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   30  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   34  * SUCH DAMAGE.
   35  */
   36 /*
   37  * seeq8005.c - SEEQ 8005 device driver
   38  */
   39 /*
   40  * This driver currently supports the following chips:
   41  * SEEQ 8005 Advanced Ethernet Data Link Controller
   42  * SEEQ 80C04 Ethernet Data Link Controller
   43  * SEEQ 80C04A AutoDUPLEX CMOS Ethernet Data Link Controller
   44  */
   45 /*
   46  * More information on the 8004 and 8005 AEDLC controllers can be found in
   47  * the SEEQ Technology Inc 1992 Data Comm Devices data book.
   48  *
   49  * This data book may no longer be available as these are rather old chips
   50  * (1991 - 1993)
   51  */
   52 /*
   53  * This driver is based on the arm32 ea(4) driver, hence the names of many
   54  * of the functions.
   55  */
   56 /*
   57  * Bugs/possible improvements:
   58  *      - Does not currently support DMA
   59  *      - Does not transmit multiple packets in one go
   60  *      - Does not support 8-bit busses
   61  */
   62 
   63 #include <sys/cdefs.h>
   64 __KERNEL_RCSID(0, "$NetBSD: seeq8005.c,v 1.35 2003/01/15 21:56:06 bouyer Exp $");
   65 
   66 #include <sys/param.h>
   67 #include <sys/systm.h>
   68 #include <sys/endian.h>
   69 #include <sys/errno.h>
   70 #include <sys/ioctl.h>
   71 #include <sys/mbuf.h>
   72 #include <sys/socket.h>
   73 #include <sys/syslog.h>
   74 #include <sys/device.h>
   75 
   76 #include <net/if.h>
   77 #include <net/if_dl.h>
   78 #include <net/if_types.h>
   79 #include <net/if_ether.h>
   80 #include <net/if_media.h>
   81 
   82 #include "bpfilter.h"
   83 #if NBPFILTER > 0
   84 #include <net/bpf.h>
   85 #include <net/bpfdesc.h>
   86 #endif
   87 
   88 #include "rnd.h"
   89 #if NRND > 0
   90 #include <sys/rnd.h>
   91 #endif
   92 
   93 #include <machine/bus.h>
   94 #include <machine/intr.h>
   95 
   96 #include <dev/ic/seeq8005reg.h>
   97 #include <dev/ic/seeq8005var.h>
   98 
   99 /*#define SEEQ_DEBUG*/
  100 
  101 /* for debugging convenience */
  102 #ifdef SEEQ8005_DEBUG
  103 #define SEEQ_DEBUG_MISC         1
  104 #define SEEQ_DEBUG_TX           2
  105 #define SEEQ_DEBUG_RX           4
  106 #define SEEQ_DEBUG_PKT          8
  107 #define SEEQ_DEBUG_TXINT        16
  108 #define SEEQ_DEBUG_RXINT        32
  109 int seeq8005_debug = 0;
  110 #define DPRINTF(f, x) { if (seeq8005_debug & (f)) printf x; }
  111 #else
  112 #define DPRINTF(f, x)
  113 #endif
  114 
  115 #define SEEQ_TX_BUFFER_SIZE             0x800           /* (> ETHER_MAX_LEN) */
  116 
  117 #define SEEQ_READ16(sc, iot, ioh, reg)                                  \
  118         ((sc)->sc_flags & SF_8BIT ?                                     \
  119             (bus_space_read_1((iot), (ioh), (reg)) |                    \
  120              (bus_space_read_1((iot), (ioh), (reg) + 1) << 8)) :        \
  121             (bus_space_read_2((iot), (ioh), (reg))))
  122 
  123 #define SEEQ_WRITE16(sc, iot, ioh, reg, val) do {                       \
  124         if ((sc)->sc_flags & SF_8BIT) {                                 \
  125                 bus_space_write_1((iot), (ioh), (reg), (val) & 0xff);   \
  126                 bus_space_write_1((iot), (ioh), (reg) + 1, (val) >> 8); \
  127         } else                                                          \
  128                 bus_space_write_2((iot), (ioh), (reg), (val));          \
  129 } while (/*CONSTCOND*/0)
  130 
  131 /*
  132  * prototypes
  133  */
  134 
  135 static int ea_init(struct ifnet *);
  136 static int ea_ioctl(struct ifnet *, u_long, caddr_t);
  137 static void ea_start(struct ifnet *);
  138 static void ea_watchdog(struct ifnet *);
  139 static void ea_chipreset(struct seeq8005_softc *);
  140 static void ea_ramtest(struct seeq8005_softc *);
  141 static int ea_stoptx(struct seeq8005_softc *);
  142 static int ea_stoprx(struct seeq8005_softc *);
  143 static void ea_stop(struct ifnet *, int);
  144 static void ea_await_fifo_empty(struct seeq8005_softc *);
  145 static void ea_await_fifo_full(struct seeq8005_softc *);
  146 static void ea_writebuf(struct seeq8005_softc *, u_char *, int, size_t);
  147 static void ea_readbuf(struct seeq8005_softc *, u_char *, int, size_t);
  148 static void ea_select_buffer(struct seeq8005_softc *, int);
  149 static void ea_set_address(struct seeq8005_softc *, int, const u_int8_t *);
  150 static void ea_read(struct seeq8005_softc *, int, int);
  151 static struct mbuf *ea_get(struct seeq8005_softc *, int, int, struct ifnet *);
  152 static void ea_txint(struct seeq8005_softc *);
  153 static void ea_rxint(struct seeq8005_softc *);
  154 static void eatxpacket(struct seeq8005_softc *);
  155 static int ea_writembuf(struct seeq8005_softc *, struct mbuf *, int);
  156 static void ea_mc_reset(struct seeq8005_softc *);
  157 static void ea_mc_reset_8004(struct seeq8005_softc *);
  158 static void ea_mc_reset_8005(struct seeq8005_softc *);
  159 static int ea_mediachange(struct ifnet *);
  160 static void ea_mediastatus(struct ifnet *, struct ifmediareq *);
  161 
  162 static char* padbuf = NULL;
  163 
  164 
  165 /*
  166  * Attach chip.
  167  */
  168 
  169 void
  170 seeq8005_attach(struct seeq8005_softc *sc, const u_int8_t *myaddr, int *media,
  171     int nmedia, int defmedia)
  172 {
  173         struct ifnet *ifp = &sc->sc_ethercom.ec_if;
  174         bus_space_tag_t iot = sc->sc_iot;
  175         bus_space_handle_t ioh = sc->sc_ioh;
  176         u_int id;
  177 
  178         KASSERT(myaddr != NULL);
  179         printf(" address %s", ether_sprintf(myaddr));
  180 
  181         /* Stop the board. */
  182 
  183         ea_chipreset(sc);
  184 
  185         /* Work out data bus width. */
  186         SEEQ_WRITE16(sc, iot, ioh, SEEQ_RX_PTR, 0x1234);
  187         if (SEEQ_READ16(sc, iot, ioh, SEEQ_RX_PTR) != 0x1234) {
  188                 /* Try 8-bit mode */
  189                 sc->sc_flags |= SF_8BIT;
  190                 SEEQ_WRITE16(sc, iot, ioh, SEEQ_RX_PTR, 0x1234);
  191                 if (SEEQ_READ16(sc, iot, ioh, SEEQ_RX_PTR) != 0x1234) {
  192                         printf("\n%s: Cannot determine data bus width\n",
  193                             sc->sc_dev.dv_xname);
  194                         return;
  195                 }
  196         }
  197 
  198         printf(", %d-bit", sc->sc_flags & SF_8BIT ? 8 : 16);
  199 
  200         /* Get the product ID */
  201         
  202         ea_select_buffer(sc, SEEQ_BUFCODE_PRODUCTID);
  203         id = SEEQ_READ16(sc, sc->sc_iot, sc->sc_ioh, SEEQ_BUFWIN);
  204 
  205         switch (id & SEEQ_PRODUCTID_MASK) {
  206         case SEEQ_PRODUCTID_8004:
  207                 sc->sc_variant = SEEQ_8004;
  208                 switch (id & SEEQ_PRODUCTID_REV_MASK) {
  209                 case SEEQ_PRODUCTID_REV_80C04:
  210                         printf(", SEEQ 80C04\n");
  211                         break;
  212                 case SEEQ_PRODUCTID_REV_80C04A:
  213                         printf(", SEEQ 80C04A\n");
  214                         break;
  215                 default:
  216                         /* Unknown SEEQ 8004 variants */
  217                         printf(", SEEQ 8004 rev %x\n",
  218                             id & SEEQ_PRODUCTID_REV_MASK);
  219                         break;
  220                 }
  221                 break;
  222         default:        /* XXX */
  223                 sc->sc_variant = SEEQ_8005;
  224                 printf(", SEEQ 8005\n");
  225                 break;
  226         }
  227 
  228         /* Both the 8004 and 8005 are designed for 64K Buffer memory */
  229         sc->sc_buffersize = SEEQ_MAX_BUFFER_SIZE;
  230 
  231         /*
  232          * Set up tx and rx buffers.
  233          *
  234          * We use approximately a quarter of the packet memory for TX
  235          * buffers and the rest for RX buffers
  236          */
  237         /* sc->sc_tx_bufs = sc->sc_buffersize / SEEQ_TX_BUFFER_SIZE / 4; */
  238         sc->sc_tx_bufs = 1;
  239         sc->sc_tx_bufsize = sc->sc_tx_bufs * SEEQ_TX_BUFFER_SIZE;
  240         sc->sc_rx_bufsize = sc->sc_buffersize - sc->sc_tx_bufsize;
  241         sc->sc_enabled = 0;
  242 
  243         /* Test the RAM */
  244         ea_ramtest(sc);
  245 
  246         printf("%s: %dKB packet memory, txbuf=%dKB (%d buffers), rxbuf=%dKB",
  247             sc->sc_dev.dv_xname, sc->sc_buffersize >> 10,
  248             sc->sc_tx_bufsize >> 10, sc->sc_tx_bufs, sc->sc_rx_bufsize >> 10); 
  249 
  250         if (padbuf == NULL) {
  251                 padbuf = malloc(ETHER_MIN_LEN - ETHER_CRC_LEN, M_DEVBUF,
  252                     M_ZERO | M_NOWAIT);
  253                 if (padbuf == NULL) {
  254                         printf("%s: can't allocate pad buffer\n",
  255                             sc->sc_dev.dv_xname);
  256                         return;
  257                 }
  258         }
  259 
  260         /* Initialise ifnet structure. */
  261 
  262         strcpy(ifp->if_xname, sc->sc_dev.dv_xname);
  263         ifp->if_softc = sc;
  264         ifp->if_start = ea_start;
  265         ifp->if_ioctl = ea_ioctl;
  266         ifp->if_init = ea_init;
  267         ifp->if_stop = ea_stop;
  268         ifp->if_watchdog = ea_watchdog;
  269         ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST | IFF_NOTRAILERS;
  270         if (sc->sc_variant == SEEQ_8004)
  271                 ifp->if_flags |= IFF_SIMPLEX;
  272         IFQ_SET_READY(&ifp->if_snd);
  273 
  274         /* Initialize media goo. */
  275         ifmedia_init(&sc->sc_media, 0, ea_mediachange, ea_mediastatus);
  276         if (media != NULL) {
  277                 int i;
  278 
  279                 for (i = 0; i < nmedia; i++)
  280                         ifmedia_add(&sc->sc_media, media[i], 0, NULL);
  281                 ifmedia_set(&sc->sc_media, defmedia);
  282         } else {
  283                 ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
  284                 ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL);
  285         }
  286 
  287         /* We can support 802.1Q VLAN-sized frames. */
  288         sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;
  289 
  290         /* Now we can attach the interface. */
  291 
  292         if_attach(ifp);
  293         ether_ifattach(ifp, myaddr);
  294 
  295         printf("\n");
  296 
  297 #if NRND > 0
  298         /* After \n because it can print a line of its own. */
  299         rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname,
  300             RND_TYPE_NET, 0);
  301 #endif
  302 }
  303 
  304 /*
  305  * Media change callback.
  306  */
  307 static int
  308 ea_mediachange(struct ifnet *ifp)
  309 {
  310         struct seeq8005_softc *sc = ifp->if_softc;
  311 
  312         if (sc->sc_mediachange)
  313                 return ((*sc->sc_mediachange)(sc));
  314         return (EINVAL);
  315 }
  316 
  317 /*
  318  * Media status callback.
  319  */
  320 static void
  321 ea_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
  322 {
  323         struct seeq8005_softc *sc = ifp->if_softc;
  324 
  325         if (sc->sc_enabled == 0) {
  326                 ifmr->ifm_active = IFM_ETHER | IFM_NONE;
  327                 ifmr->ifm_status = 0;
  328                 return;
  329         }
  330 
  331         if (sc->sc_mediastatus)
  332                 (*sc->sc_mediastatus)(sc, ifmr);
  333 }
  334 
  335 /*
  336  * Test the RAM on the ethernet card.
  337  */
  338 
  339 void
  340 ea_ramtest(struct seeq8005_softc *sc)
  341 {
  342         bus_space_tag_t iot = sc->sc_iot;
  343         bus_space_handle_t ioh = sc->sc_ioh;
  344         int loop;
  345         u_int sum = 0;
  346 
  347         /*
  348          * Test the buffer memory on the board.
  349          * Write simple pattens to it and read them back.
  350          */
  351 
  352         /* Set up the whole buffer RAM for writing */
  353 
  354         ea_select_buffer(sc, SEEQ_BUFCODE_TX_EAP);
  355         SEEQ_WRITE16(sc, iot, ioh, SEEQ_BUFWIN, (SEEQ_MAX_BUFFER_SIZE >> 8) - 1);
  356         SEEQ_WRITE16(sc, iot, ioh, SEEQ_TX_PTR, 0x0000);
  357         SEEQ_WRITE16(sc, iot, ioh, SEEQ_RX_PTR, SEEQ_MAX_BUFFER_SIZE - 2);
  358 
  359 #define SEEQ_RAMTEST_LOOP(value)                                                \
  360 do {                                                                    \
  361         /* Set the write start address and write a pattern */           \
  362         ea_writebuf(sc, NULL, 0x0000, 0);                               \
  363         for (loop = 0; loop < SEEQ_MAX_BUFFER_SIZE; loop += 2)          \
  364                 SEEQ_WRITE16(sc, iot, ioh, SEEQ_BUFWIN, (value));       \
  365                                                                         \
  366         /* Set the read start address and verify the pattern */         \
  367         ea_readbuf(sc, NULL, 0x0000, 0);                                \
  368         for (loop = 0; loop < SEEQ_MAX_BUFFER_SIZE; loop += 2)          \
  369                 if (SEEQ_READ16(sc, iot, ioh, SEEQ_BUFWIN) != (value)) \
  370                         ++sum;                                          \
  371 } while (/*CONSTCOND*/0)
  372 
  373         SEEQ_RAMTEST_LOOP(loop);
  374         SEEQ_RAMTEST_LOOP(loop ^ (SEEQ_MAX_BUFFER_SIZE - 1));
  375         SEEQ_RAMTEST_LOOP(0xaa55);
  376         SEEQ_RAMTEST_LOOP(0x55aa);
  377 
  378         /* Report */
  379 
  380         if (sum > 0)
  381                 printf("%s: buffer RAM failed self test, %d faults\n",
  382                        sc->sc_dev.dv_xname, sum);
  383 }
  384 
  385 
  386 /*
  387  * Stop the tx interface.
  388  *
  389  * Returns 0 if the tx was already stopped or 1 if it was active
  390  */
  391 
  392 static int
  393 ea_stoptx(struct seeq8005_softc *sc)
  394 {
  395         bus_space_tag_t iot = sc->sc_iot;
  396         bus_space_handle_t ioh = sc->sc_ioh;
  397         int timeout;
  398         int status;
  399 
  400         DPRINTF(SEEQ_DEBUG_TX, ("ea_stoptx()\n"));
  401 
  402         sc->sc_enabled = 0;
  403 
  404         status = SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS);
  405         if (!(status & SEEQ_STATUS_TX_ON))
  406                 return 0;
  407 
  408         /* Stop any tx and wait for confirmation */
  409         SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND,
  410                           sc->sc_command | SEEQ_CMD_TX_OFF);
  411 
  412         timeout = 20000;
  413         do {
  414                 status = SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS);
  415                 delay(1);
  416         } while ((status & SEEQ_STATUS_TX_ON) && --timeout > 0);
  417         if (timeout == 0)
  418                 log(LOG_ERR, "%s: timeout waiting for tx termination\n",
  419                     sc->sc_dev.dv_xname);
  420 
  421         /* Clear any pending tx interrupt */
  422         SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND,
  423                    sc->sc_command | SEEQ_CMD_TX_INTACK);
  424         return 1;
  425 }
  426 
  427 
  428 /*
  429  * Stop the rx interface.
  430  *
  431  * Returns 0 if the tx was already stopped or 1 if it was active
  432  */
  433 
  434 static int
  435 ea_stoprx(struct seeq8005_softc *sc)
  436 {
  437         bus_space_tag_t iot = sc->sc_iot;
  438         bus_space_handle_t ioh = sc->sc_ioh;
  439         int timeout;
  440         int status;
  441 
  442         DPRINTF(SEEQ_DEBUG_RX, ("ea_stoprx()\n"));
  443 
  444         status = SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS);
  445         if (!(status & SEEQ_STATUS_RX_ON))
  446                 return 0;
  447 
  448         /* Stop any rx and wait for confirmation */
  449 
  450         SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND,
  451                           sc->sc_command | SEEQ_CMD_RX_OFF);
  452 
  453         timeout = 20000;
  454         do {
  455                 status = SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS);
  456         } while ((status & SEEQ_STATUS_RX_ON) && --timeout > 0);
  457         if (timeout == 0)
  458                 log(LOG_ERR, "%s: timeout waiting for rx termination\n",
  459                     sc->sc_dev.dv_xname);
  460 
  461         /* Clear any pending rx interrupt */
  462 
  463         SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND,
  464                    sc->sc_command | SEEQ_CMD_RX_INTACK);
  465         return 1;
  466 }
  467 
  468 
  469 /*
  470  * Stop interface.
  471  * Stop all IO and shut the interface down
  472  */
  473 
  474 /* ARGSUSED */
  475 static void
  476 ea_stop(struct ifnet *ifp, int disable)
  477 {
  478         struct seeq8005_softc *sc = ifp->if_softc;
  479         bus_space_tag_t iot = sc->sc_iot;
  480         bus_space_handle_t ioh = sc->sc_ioh;
  481         
  482         DPRINTF(SEEQ_DEBUG_MISC, ("ea_stop()\n"));
  483 
  484         /* Stop all IO */
  485         ea_stoptx(sc);
  486         ea_stoprx(sc);
  487 
  488         /* Disable rx and tx interrupts */
  489         sc->sc_command &= (SEEQ_CMD_RX_INTEN | SEEQ_CMD_TX_INTEN);
  490 
  491         /* Clear any pending interrupts */
  492         SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND,
  493                           sc->sc_command | SEEQ_CMD_RX_INTACK |
  494                           SEEQ_CMD_TX_INTACK | SEEQ_CMD_DMA_INTACK |
  495                           SEEQ_CMD_BW_INTACK);
  496 
  497         if (sc->sc_variant == SEEQ_8004) {
  498                 /* Put the chip to sleep */
  499                 ea_select_buffer(sc, SEEQ_BUFCODE_CONFIG3);
  500                 SEEQ_WRITE16(sc, iot, ioh, SEEQ_BUFWIN,
  501                     sc->sc_config3 | SEEQ_CFG3_SLEEP);
  502         }
  503 
  504         /* Cancel any watchdog timer */
  505         sc->sc_ethercom.ec_if.if_timer = 0;
  506 }
  507 
  508 
  509 /*
  510  * Reset the chip
  511  * Following this the software registers are reset
  512  */
  513 
  514 static void
  515 ea_chipreset(struct seeq8005_softc *sc)
  516 {
  517         bus_space_tag_t iot = sc->sc_iot;
  518         bus_space_handle_t ioh = sc->sc_ioh;
  519 
  520         DPRINTF(SEEQ_DEBUG_MISC, ("ea_chipreset()\n"));
  521 
  522         /* Reset the controller. Min of 4us delay here */
  523 
  524         /*
  525          * This can be called before we know whether the chip is in 8- or
  526          * 16-bit mode, so we do a reset in both modes.  The 16-bit reset is
  527          * harmless in 8-bit mode, so we do that second.
  528          */
  529 
  530         /* In 16-bit mode, this will munge the PreamSelect bit. */
  531         bus_space_write_1(iot, ioh, SEEQ_CONFIG2 + 1, SEEQ_CFG2_RESET >> 8);
  532         delay(4);
  533         /* In 8-bit mode, this will zero the bottom half of config reg 2. */
  534         bus_space_write_2(iot, ioh, SEEQ_CONFIG2, SEEQ_CFG2_RESET);
  535         delay(4);
  536 
  537         sc->sc_command = 0;
  538         sc->sc_config1 = 0;
  539         sc->sc_config2 = 0;
  540         sc->sc_config3 = 0;
  541 }
  542 
  543 
  544 /*
  545  * If the DMA FIFO's in write mode, wait for it to empty.  Needed when
  546  * switching the FIFO from write to read.  We also use it when changing
  547  * the address for writes.
  548  */
  549 static void
  550 ea_await_fifo_empty(struct seeq8005_softc *sc)
  551 {
  552         bus_space_tag_t iot = sc->sc_iot;
  553         bus_space_handle_t ioh = sc->sc_ioh;
  554         int timeout;
  555         
  556         timeout = 20000;
  557         if ((SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS) &
  558              SEEQ_STATUS_FIFO_DIR) != 0)
  559                 return; /* FIFO is reading anyway. */
  560         while (--timeout > 0)
  561                 if (SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS) &
  562                     SEEQ_STATUS_FIFO_EMPTY)
  563                         return;
  564         log(LOG_ERR, "%s: DMA FIFO failed to empty\n", sc->sc_dev.dv_xname);
  565 }
  566 
  567 /*
  568  * Wait for the DMA FIFO to fill before reading from it.
  569  */
  570 static void
  571 ea_await_fifo_full(struct seeq8005_softc *sc)
  572 {
  573         bus_space_tag_t iot = sc->sc_iot;
  574         bus_space_handle_t ioh = sc->sc_ioh;
  575         int timeout;
  576 
  577         timeout = 20000;
  578         while (--timeout > 0)
  579                 if (SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS) &
  580                     SEEQ_STATUS_FIFO_FULL)
  581                         return;
  582         log(LOG_ERR, "%s: DMA FIFO failed to fill\n", sc->sc_dev.dv_xname);
  583 }
  584 
  585 /*
  586  * write to the buffer memory on the interface
  587  *
  588  * The buffer address is set to ADDR.
  589  * If len != 0 then data is copied from the address starting at buf
  590  * to the interface buffer.
  591  * BUF must be usable as a u_int16_t *.
  592  * If LEN is odd, it must be safe to overwrite one extra byte.
  593  */
  594 
  595 static void
  596 ea_writebuf(struct seeq8005_softc *sc, u_char *buf, int addr, size_t len)
  597 {
  598         bus_space_tag_t iot = sc->sc_iot;
  599         bus_space_handle_t ioh = sc->sc_ioh;
  600 
  601         DPRINTF(SEEQ_DEBUG_MISC, ("writebuf: st=%04x\n",
  602             SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS)));
  603 
  604 #ifdef DIAGNOSTIC
  605         if (__predict_false(!ALIGNED_POINTER(buf, u_int16_t)))
  606                 panic("%s: unaligned writebuf", sc->sc_dev.dv_xname);
  607         if (__predict_false(addr >= SEEQ_MAX_BUFFER_SIZE))
  608                 panic("%s: writebuf out of range", sc->sc_dev.dv_xname);
  609 #endif
  610 
  611         if (addr != -1) {
  612                 ea_await_fifo_empty(sc);
  613 
  614                 ea_select_buffer(sc, SEEQ_BUFCODE_LOCAL_MEM);
  615                 SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND,
  616                     sc->sc_command | SEEQ_CMD_FIFO_WRITE);
  617                 SEEQ_WRITE16(sc, iot, ioh, SEEQ_DMA_ADDR, addr);
  618         }
  619 
  620         if (len > 0) {
  621                 if (sc->sc_flags & SF_8BIT)
  622                         bus_space_write_multi_1(iot, ioh, SEEQ_BUFWIN,
  623                             (u_int8_t *)buf, len);
  624                 else
  625                         bus_space_write_multi_2(iot, ioh, SEEQ_BUFWIN,
  626                             /* LINTED: alignment checked above */
  627                             (u_int16_t *)buf, len / 2);
  628         }
  629         if (!(sc->sc_flags & SF_8BIT) && len % 2) {
  630                 /* Write the last byte */
  631                 bus_space_write_2(iot, ioh, SEEQ_BUFWIN, buf[len - 1]);
  632         }
  633         /* Leave FIFO to empty in the background */
  634 }
  635 
  636 
  637 /*
  638  * read from the buffer memory on the interface
  639  *
  640  * The buffer address is set to ADDR.
  641  * If len != 0 then data is copied from the interface buffer to the
  642  * address starting at buf.
  643  * BUF must be usable as a u_int16_t *.
  644  * If LEN is odd, it must be safe to overwrite one extra byte.
  645  */
  646 
  647 static void
  648 ea_readbuf(struct seeq8005_softc *sc, u_char *buf, int addr, size_t len)
  649 {
  650         bus_space_tag_t iot = sc->sc_iot;
  651         bus_space_handle_t ioh = sc->sc_ioh;
  652         int runup;
  653 
  654         DPRINTF(SEEQ_DEBUG_MISC, ("readbuf: st=%04x addr=%04x len=%d\n",
  655             SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS), addr, len));
  656 
  657 #ifdef DIAGNOSTIC
  658         if (__predict_false(!ALIGNED_POINTER(buf, u_int16_t)))
  659                 panic("%s: unaligned readbuf", sc->sc_dev.dv_xname);
  660         if (__predict_false(addr >= SEEQ_MAX_BUFFER_SIZE))
  661                 panic("%s: readbuf out of range", sc->sc_dev.dv_xname);
  662 #endif
  663 
  664         if (addr != -1) {
  665                 /*
  666                  * SEEQ 80C04 bug:
  667                  * Starting reading from certain addresses seems to cause
  668                  * us to get bogus results, so we avoid them.
  669                  */
  670                 runup = 0;
  671                 if (sc->sc_variant == SEEQ_8004 &&
  672                     ((addr & 0x00ff) == 0x00ea ||
  673                      (addr & 0x00ff) == 0x00ee ||
  674                      (addr & 0x00ff) == 0x00f0))
  675                         runup = (addr & 0x00ff) - 0x00e8;
  676 
  677                 ea_await_fifo_empty(sc);
  678 
  679                 ea_select_buffer(sc, SEEQ_BUFCODE_LOCAL_MEM);
  680 
  681                 /*
  682                  * 80C04 bug workaround.  I found this in the old arm32 "eb"
  683                  * driver.  I've no idea what it does, but it seems to stop
  684                  * the chip mangling data so often.
  685                  */
  686                 SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND,
  687                     sc->sc_command | SEEQ_CMD_FIFO_WRITE);
  688                 ea_await_fifo_empty(sc);
  689 
  690                 SEEQ_WRITE16(sc, iot, ioh, SEEQ_DMA_ADDR, addr - runup);
  691                 SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND,
  692                     sc->sc_command | SEEQ_CMD_FIFO_READ);
  693 
  694                 ea_await_fifo_full(sc);
  695                 while (runup > 0) {
  696                         /* LINTED: Reading a volatile _does_ have an effect */
  697                         (void)SEEQ_READ16(sc, iot, ioh, SEEQ_BUFWIN);
  698                         runup -= 2;
  699                 }
  700         }
  701 
  702         if (len > 0) {
  703                 if (sc->sc_flags & SF_8BIT)
  704                         bus_space_read_multi_1(iot, ioh, SEEQ_BUFWIN,
  705                             (u_int8_t *)buf, len);
  706                 else
  707                         bus_space_read_multi_2(iot, ioh, SEEQ_BUFWIN,
  708                             /* LINTED: pointer alignment checked above */
  709                             (u_int16_t *)buf, len / 2);
  710         }
  711         if (!(sc->sc_flags & SF_8BIT) && len % 2) {
  712                 /* Read the last byte */
  713                 buf[len - 1] = bus_space_read_2(iot, ioh, SEEQ_BUFWIN);
  714         }
  715 }
  716 
  717 static void
  718 ea_select_buffer(struct seeq8005_softc *sc, int bufcode)
  719 {
  720 
  721         SEEQ_WRITE16(sc, sc->sc_iot, sc->sc_ioh, SEEQ_CONFIG1,
  722                           sc->sc_config1 | bufcode);
  723 }
  724 
  725 /* Must be called at splnet */
  726 static void
  727 ea_set_address(struct seeq8005_softc *sc, int which, u_int8_t const *ea)
  728 {
  729         int i;
  730 
  731         ea_select_buffer(sc, SEEQ_BUFCODE_STATION_ADDR0 + which);
  732         for (i = 0; i < ETHER_ADDR_LEN; ++i)
  733                 SEEQ_WRITE16(sc, sc->sc_iot, sc->sc_ioh, SEEQ_BUFWIN,
  734                                   ea[i]);
  735 }
  736 
  737 /*
  738  * Initialize interface.
  739  *
  740  * This should leave the interface in a state for packet reception and
  741  * transmission.
  742  */
  743 
  744 static int
  745 ea_init(struct ifnet *ifp)
  746 {
  747         struct seeq8005_softc *sc = ifp->if_softc;
  748         bus_space_tag_t iot = sc->sc_iot;
  749         bus_space_handle_t ioh = sc->sc_ioh;
  750         int s;
  751 
  752         DPRINTF(SEEQ_DEBUG_MISC, ("ea_init()\n"));
  753 
  754         s = splnet();
  755 
  756         /* First, reset the board. */
  757 
  758         ea_chipreset(sc);
  759 
  760         /* Set up defaults for the registers */
  761 
  762         sc->sc_command = 0;
  763         sc->sc_config1 = 0;
  764 #if BYTE_ORDER == BIG_ENDIAN
  765         sc->sc_config2 = SEEQ_CFG2_BYTESWAP;
  766 #else
  767         sc->sc_config2 = 0;
  768 #endif
  769         sc->sc_config3 = 0;
  770 
  771         SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND, sc->sc_command);
  772         SEEQ_WRITE16(sc, iot, ioh, SEEQ_CONFIG1, sc->sc_config1);
  773         SEEQ_WRITE16(sc, iot, ioh, SEEQ_CONFIG2, sc->sc_config2);
  774         if (sc->sc_variant == SEEQ_8004) {
  775                 ea_select_buffer(sc, SEEQ_BUFCODE_CONFIG3);
  776                 SEEQ_WRITE16(sc, iot, ioh, SEEQ_BUFWIN, sc->sc_config3);
  777         }
  778 
  779         /* Write the station address - the receiver must be off */
  780         ea_set_address(sc, 0, (u_int8_t *)LLADDR(ifp->if_sadl));
  781 
  782         /* Split board memory into Rx and Tx. */
  783         ea_select_buffer(sc, SEEQ_BUFCODE_TX_EAP);
  784         SEEQ_WRITE16(sc, iot, ioh, SEEQ_BUFWIN, (sc->sc_tx_bufsize>> 8) - 1);
  785 
  786         if (sc->sc_variant == SEEQ_8004) {
  787                 /* Make the interface IFF_SIMPLEX. */
  788                 sc->sc_config2 |= SEEQ_CFG2_RX_TX_DISABLE;
  789                 /* Enable reception of long packets (for vlan(4)). */
  790                 sc->sc_config2 |= SEEQ_CFG2_PASS_LONGSHORT;
  791         }
  792 
  793         /* Configure rx. */
  794         ea_mc_reset(sc);
  795         if (ifp->if_flags & IFF_PROMISC)
  796                 sc->sc_config1 = SEEQ_CFG1_PROMISCUOUS;
  797         else if ((ifp->if_flags & IFF_ALLMULTI) || sc->sc_variant == SEEQ_8004)
  798                 sc->sc_config1 = SEEQ_CFG1_MULTICAST;
  799         else
  800                 sc->sc_config1 = SEEQ_CFG1_BROADCAST;
  801         sc->sc_config1 |= SEEQ_CFG1_STATION_ADDR0;
  802         SEEQ_WRITE16(sc, iot, ioh, SEEQ_CONFIG1, sc->sc_config1);
  803 
  804         /* Setup the Rx pointers */
  805         sc->sc_rx_ptr = sc->sc_tx_bufsize;
  806 
  807         SEEQ_WRITE16(sc, iot, ioh, SEEQ_RX_PTR, sc->sc_rx_ptr);
  808         SEEQ_WRITE16(sc, iot, ioh, SEEQ_RX_END, sc->sc_rx_ptr >> 8);
  809 
  810 
  811         /* Place a NULL header at the beginning of the receive area */
  812         ea_writebuf(sc, NULL, sc->sc_rx_ptr, 0);
  813                 
  814         SEEQ_WRITE16(sc, iot, ioh, SEEQ_BUFWIN, 0x0000);
  815         SEEQ_WRITE16(sc, iot, ioh, SEEQ_BUFWIN, 0x0000);
  816 
  817 
  818         /* Configure TX. */
  819         DPRINTF(SEEQ_DEBUG_MISC, ("Configuring tx...\n"));
  820 
  821         SEEQ_WRITE16(sc, iot, ioh, SEEQ_TX_PTR, 0x0000);
  822 
  823         sc->sc_config2 |= SEEQ_CFG2_OUTPUT;
  824         SEEQ_WRITE16(sc, iot, ioh, SEEQ_CONFIG2, sc->sc_config2);
  825 
  826         /* Reset tx buffer pointers */
  827         sc->sc_tx_cur = 0;
  828         sc->sc_tx_used = 0;
  829         sc->sc_tx_next = 0;
  830 
  831         /* Place a NULL header at the beginning of the transmit area */
  832         ea_writebuf(sc, NULL, 0x0000, 0);
  833                 
  834         SEEQ_WRITE16(sc, iot, ioh, SEEQ_BUFWIN, 0x0000);
  835         SEEQ_WRITE16(sc, iot, ioh, SEEQ_BUFWIN, 0x0000);
  836 
  837         sc->sc_command |= SEEQ_CMD_TX_INTEN;
  838         SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND, sc->sc_command);
  839 
  840         /* Turn on Rx */
  841         sc->sc_command |= SEEQ_CMD_RX_INTEN;
  842         SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND,
  843                           sc->sc_command | SEEQ_CMD_RX_ON);
  844 
  845         /* TX_ON gets set by ea_txpacket when there's something to transmit. */
  846 
  847 
  848         /* Set flags appropriately. */
  849         ifp->if_flags |= IFF_RUNNING;
  850         ifp->if_flags &= ~IFF_OACTIVE;
  851         sc->sc_enabled = 1;
  852 
  853         /* And start output. */
  854         ea_start(ifp);
  855 
  856         splx(s);
  857         return 0;
  858 }
  859 
  860 /*
  861  * Start output on interface. Get datagrams from the queue and output them,
  862  * giving the receiver a chance between datagrams. Call only from splnet or
  863  * interrupt level!
  864  */
  865 
  866 static void
  867 ea_start(struct ifnet *ifp)
  868 {
  869         struct seeq8005_softc *sc = ifp->if_softc;
  870         int s;
  871 
  872         s = splnet();
  873         DPRINTF(SEEQ_DEBUG_TX, ("ea_start()...\n"));
  874 
  875         /*
  876          * Don't do anything if output is active.  seeq8005intr() will call
  877          * us (actually eatxpacket()) back when the card's ready for more
  878          * frames.
  879          */
  880         if (ifp->if_flags & IFF_OACTIVE)
  881                 return;
  882 
  883         /* Mark interface as output active */
  884         
  885         ifp->if_flags |= IFF_OACTIVE;
  886 
  887         /* tx packets */
  888 
  889         eatxpacket(sc);
  890         splx(s);
  891 }
  892 
  893 
  894 /*
  895  * Transfer a packet to the interface buffer and start transmission
  896  *
  897  * Called at splnet()
  898  */
  899  
  900 void
  901 eatxpacket(struct seeq8005_softc *sc)
  902 {
  903         bus_space_tag_t iot = sc->sc_iot;
  904         bus_space_handle_t ioh = sc->sc_ioh;
  905         struct mbuf *m0;
  906         struct ifnet *ifp;
  907 
  908         ifp = &sc->sc_ethercom.ec_if;
  909 
  910         /* Dequeue the next packet. */
  911         IFQ_DEQUEUE(&ifp->if_snd, m0);
  912 
  913         /* If there's nothing to send, return. */
  914         if (!m0) {
  915                 ifp->if_flags &= ~IFF_OACTIVE;
  916                 sc->sc_config2 |= SEEQ_CFG2_OUTPUT;
  917                 SEEQ_WRITE16(sc, iot, ioh, SEEQ_CONFIG2, sc->sc_config2);
  918                 DPRINTF(SEEQ_DEBUG_TX, ("tx finished\n"));
  919                 return;
  920         }
  921 
  922 #if NBPFILTER > 0
  923         /* Give the packet to the bpf, if any. */
  924         if (ifp->if_bpf)
  925                 bpf_mtap(ifp->if_bpf, m0);
  926 #endif
  927 
  928         DPRINTF(SEEQ_DEBUG_TX, ("Tx new packet\n"));
  929 
  930         sc->sc_config2 &= ~SEEQ_CFG2_OUTPUT;
  931         SEEQ_WRITE16(sc, iot, ioh, SEEQ_CONFIG2, sc->sc_config2);
  932 
  933         ea_writembuf(sc, m0, 0x0000);
  934         m_freem(m0);
  935 
  936         SEEQ_WRITE16(sc, iot, ioh, SEEQ_TX_PTR, 0x0000);
  937 
  938         /* Now transmit the datagram. */
  939         SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND,
  940                           sc->sc_command | SEEQ_CMD_TX_ON);
  941 
  942         /* Make sure we notice if the chip goes silent on us. */
  943         ifp->if_timer = 5;
  944 
  945         DPRINTF(SEEQ_DEBUG_TX,
  946             ("st=%04x\n", SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS)));
  947         DPRINTF(SEEQ_DEBUG_TX, ("tx: queued\n"));
  948 }
  949 
  950 /*
  951  * Copy a packet from an mbuf to the transmit buffer on the card.
  952  *
  953  * Puts a valid Tx header at the start of the packet, and a null header at
  954  * the end.
  955  */
  956 static int
  957 ea_writembuf(struct seeq8005_softc *sc, struct mbuf *m0, int bufstart)
  958 {
  959         struct mbuf *m;
  960         int len, nextpacket;
  961         u_int8_t hdr[4];
  962 
  963         /*
  964          * Copy the datagram to the packet buffer.
  965          */
  966         len = 0;
  967         for (m = m0; m; m = m->m_next) {
  968                 if (m->m_len == 0)
  969                         continue;
  970                 ea_writebuf(sc, mtod(m, u_char *), bufstart + 4 + len,
  971                     m->m_len);
  972                 len += m->m_len;
  973         }
  974 
  975         if (len < ETHER_MIN_LEN) {
  976                 ea_writebuf(sc, padbuf, bufstart + 4 + len,
  977                     ETHER_MIN_LEN - len);
  978                 len = ETHER_MIN_LEN;
  979         }
  980 
  981         /* Follow it with a NULL packet header */
  982         memset(hdr, 0, 4);
  983         ea_writebuf(sc, hdr, bufstart + 4 + len, 4);
  984         SEEQ_WRITE16(sc, sc->sc_iot, sc->sc_ioh, SEEQ_BUFWIN, 0x0000);
  985         SEEQ_WRITE16(sc, sc->sc_iot, sc->sc_ioh, SEEQ_BUFWIN, 0x0000);
  986 
  987         /* Ok we now have a packet len bytes long in our packet buffer */
  988         DPRINTF(SEEQ_DEBUG_TX, ("ea_writembuf: length=%d\n", len));
  989 
  990         /* Write the packet header */
  991         nextpacket = len + 4;
  992         hdr[0] = (nextpacket >> 8) & 0xff;
  993         hdr[1] = nextpacket & 0xff;
  994         hdr[2] = SEEQ_PKTCMD_TX | SEEQ_PKTCMD_DATA_FOLLOWS |
  995                 SEEQ_TXCMD_XMIT_SUCCESS_INT | SEEQ_TXCMD_COLLISION_INT;
  996         hdr[3] = 0; /* Status byte -- will be update by hardware. */
  997         ea_writebuf(sc, hdr, 0x0000, 4);
  998 
  999         return len;
 1000 }
 1001 
 1002 /*
 1003  * Ethernet controller interrupt.
 1004  */
 1005 
 1006 int
 1007 seeq8005intr(void *arg)
 1008 {
 1009         struct seeq8005_softc *sc = arg;
 1010         bus_space_tag_t iot = sc->sc_iot;
 1011         bus_space_handle_t ioh = sc->sc_ioh;
 1012         int status, handled;
 1013 
 1014         handled = 0;
 1015 
 1016         /* Get the controller status */
 1017         status = SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS);
 1018 
 1019         /* Tx interrupt ? */
 1020         if (status & SEEQ_STATUS_TX_INT) {
 1021                 handled = 1;
 1022 
 1023                 /* Acknowledge the interrupt */
 1024                 SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND,
 1025                                   sc->sc_command | SEEQ_CMD_TX_INTACK);
 1026 
 1027                 ea_txint(sc);
 1028         }
 1029 
 1030 
 1031         /* Rx interrupt ? */
 1032         if (status & SEEQ_STATUS_RX_INT) {
 1033                 handled = 1;
 1034 
 1035                 /* Acknowledge the interrupt */
 1036                 SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND,
 1037                                   sc->sc_command | SEEQ_CMD_RX_INTACK);
 1038 
 1039                 /* Processes the received packets */
 1040                 ea_rxint(sc);
 1041         }
 1042 
 1043 #if NRND > 0
 1044         if (handled)
 1045                 rnd_add_uint32(&sc->rnd_source, status);
 1046 #endif
 1047         return handled;
 1048 }
 1049 
 1050 static void
 1051 ea_txint(struct seeq8005_softc *sc)
 1052 {
 1053         struct ifnet *ifp = &sc->sc_ethercom.ec_if;
 1054         bus_space_tag_t iot = sc->sc_iot;
 1055         bus_space_handle_t ioh = sc->sc_ioh;
 1056         u_int8_t txhdr[4];
 1057         u_int txstatus;
 1058 
 1059         ea_readbuf(sc, txhdr, 0x0000, 4);
 1060 
 1061         DPRINTF(SEEQ_DEBUG_TX, ("txstatus=%02x %02x %02x %02x\n",
 1062             txhdr[0], txhdr[1], txhdr[2], txhdr[3]));
 1063         txstatus = txhdr[3];
 1064 
 1065         /*
 1066          * If SEEQ_TXSTAT_COLLISION is set then we received at least
 1067          * one collision. On the 8004 we can find out exactly how many
 1068          * collisions occurred.
 1069          *
 1070          * The SEEQ_PKTSTAT_DONE will be set if the transmission has
 1071          * completed.
 1072          *
 1073          * If SEEQ_TXSTAT_COLLISION16 is set then 16 collisions
 1074          * occurred and the packet transmission was aborted.
 1075          * This situation is untested as present.
 1076          *
 1077          * The SEEQ_TXSTAT_BABBLE is untested as it should only be set
 1078          * when we deliberately transmit oversized packets (e.g. for
 1079          * 802.1Q).
 1080          */
 1081         if (txstatus & SEEQ_TXSTAT_COLLISION) {
 1082                 switch (sc->sc_variant) {
 1083                 case SEEQ_8004: {
 1084                         int colls;
 1085 
 1086                         /*
 1087                          * The 8004 contains a 4 bit collision count
 1088                          * in the status register.
 1089                          */
 1090 
 1091                         /* This appears to be broken on 80C04.AE */
 1092 /*                      ifp->if_collisions +=
 1093                             (txstatus >> SEEQ_TXSTAT_COLLISIONS_SHIFT)
 1094                             & SEEQ_TXSTAT_COLLISION_MASK;*/
 1095                                     
 1096                         /* Use the TX Collision register */
 1097                         ea_select_buffer(sc, SEEQ_BUFCODE_TX_COLLS);
 1098                         colls = bus_space_read_1(iot, ioh, SEEQ_BUFWIN);
 1099                         ifp->if_collisions += colls;
 1100                         break;
 1101                 }
 1102                 case SEEQ_8005:
 1103                         /* We known there was at least 1 collision */
 1104                         ifp->if_collisions++;
 1105                         break;
 1106                 }
 1107         } else if (txstatus & SEEQ_TXSTAT_COLLISION16) {
 1108                 printf("seeq_intr: col16 %x\n", txstatus);
 1109                 ifp->if_collisions += 16;
 1110                 ifp->if_oerrors++;
 1111         }
 1112 
 1113         /* Have we completed transmission on the packet ? */
 1114         if (txstatus & SEEQ_PKTSTAT_DONE) {
 1115                 /* Clear watchdog timer. */
 1116                 ifp->if_timer = 0;
 1117                 ifp->if_flags &= ~IFF_OACTIVE;
 1118 
 1119                 /* Update stats */
 1120                 ifp->if_opackets++;
 1121 
 1122                 /* Tx next packet */
 1123 
 1124                 eatxpacket(sc);
 1125         }
 1126 }
 1127 
 1128 void
 1129 ea_rxint(struct seeq8005_softc *sc)
 1130 {
 1131         bus_space_tag_t iot = sc->sc_iot;
 1132         bus_space_handle_t ioh = sc->sc_ioh;
 1133         u_int addr;
 1134         int len;
 1135         int ctrl;
 1136         int ptr;
 1137         int status;
 1138         u_int8_t rxhdr[4];
 1139         struct ifnet *ifp;
 1140 
 1141         ifp = &sc->sc_ethercom.ec_if;
 1142 
 1143 
 1144         /* We start from the last rx pointer position */
 1145         addr = sc->sc_rx_ptr;
 1146         sc->sc_config2 &= ~SEEQ_CFG2_OUTPUT;
 1147         SEEQ_WRITE16(sc, iot, ioh, SEEQ_CONFIG2, sc->sc_config2);
 1148 
 1149         do {
 1150                 /* Read rx header */
 1151                 ea_readbuf(sc, rxhdr, addr, 4);
 1152                 
 1153                 /* Split the packet header */
 1154                 ptr = (rxhdr[0] << 8) | rxhdr[1];
 1155                 ctrl = rxhdr[2];
 1156                 status = rxhdr[3];
 1157 
 1158                 DPRINTF(SEEQ_DEBUG_RX,
 1159                     ("addr=%04x ptr=%04x ctrl=%02x status=%02x\n",
 1160                         addr, ptr, ctrl, status));
 1161 
 1162                 /* Zero packet ptr ? then must be null header so exit */
 1163                 if (ptr == 0) break;
 1164 
 1165                 /* Sanity-check the next-packet pointer and flags. */
 1166                 if (__predict_false(ptr < sc->sc_tx_bufsize ||
 1167                     (ctrl & SEEQ_PKTCMD_TX))) {
 1168                         ++ifp->if_ierrors;
 1169                         log(LOG_ERR,
 1170                             "%s: Rx chain corrupt at %04x (ptr = %04x)\n",
 1171                             sc->sc_dev.dv_xname, addr, ptr);
 1172                         ea_init(ifp);
 1173                         return;
 1174                 }
 1175 
 1176                 /* Get packet length */
 1177                 len = (ptr - addr) - 4;
 1178 
 1179                 if (len < 0)
 1180                         len += sc->sc_rx_bufsize;
 1181                 DPRINTF(SEEQ_DEBUG_RX, ("len=%04x\n", len));
 1182 
 1183                 /* Has the packet rx completed ? if not then exit */
 1184                 if ((status & SEEQ_PKTSTAT_DONE) == 0)
 1185                         break;
 1186 
 1187                 /*
 1188                  * Did we have any errors? then note error and go to
 1189                  * next packet
 1190                  */
 1191                 if (__predict_false(status &
 1192                         (SEEQ_RXSTAT_CRC_ERROR | SEEQ_RXSTAT_DRIBBLE_ERROR |
 1193                          SEEQ_RXSTAT_SHORT_FRAME))) {
 1194                         ++ifp->if_ierrors;
 1195                         log(LOG_WARNING,
 1196                             "%s: rx packet error at %04x (err=%02x)\n",
 1197                             sc->sc_dev.dv_xname, addr, status & 0x0f);
 1198                         /* XXX shouldn't need to reset if it's genuine. */
 1199                         ea_init(ifp);
 1200                         return;
 1201                 }
 1202                 /*
 1203                  * Is the packet too big?  We allow slightly oversize packets
 1204                  * for vlan(4) and tcpdump purposes, but the rest of the world
 1205                  * wants incoming packets in a single mbuf cluster.
 1206                  */
 1207                 if (__predict_false(len > MCLBYTES)) {
 1208                         ++ifp->if_ierrors;
 1209                         log(LOG_ERR,
 1210                             "%s: rx packet size error at %04x (len=%d)\n",
 1211                             sc->sc_dev.dv_xname, addr, len);
 1212                         sc->sc_config2 |= SEEQ_CFG2_OUTPUT;
 1213                         SEEQ_WRITE16(sc, iot, ioh, SEEQ_CONFIG2,
 1214                                           sc->sc_config2);
 1215                         ea_init(ifp);
 1216                         return;
 1217                 }
 1218 
 1219                 ifp->if_ipackets++;
 1220                 /* Pass data up to upper levels. */
 1221                 ea_read(sc, addr + 4, len);
 1222 
 1223                 addr = ptr;
 1224         } while (len != 0);
 1225 
 1226         sc->sc_config2 |= SEEQ_CFG2_OUTPUT;
 1227         SEEQ_WRITE16(sc, iot, ioh, SEEQ_CONFIG2, sc->sc_config2);
 1228 
 1229         DPRINTF(SEEQ_DEBUG_RX, ("new rx ptr=%04x\n", addr));
 1230 
 1231         /* Store new rx pointer */
 1232         sc->sc_rx_ptr = addr;
 1233         SEEQ_WRITE16(sc, iot, ioh, SEEQ_RX_END, sc->sc_rx_ptr >> 8);
 1234 
 1235         /* Make sure the receiver is on */
 1236         SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND,
 1237                           sc->sc_command | SEEQ_CMD_RX_ON);
 1238 }
 1239 
 1240 
 1241 /*
 1242  * Pass a packet up to the higher levels.
 1243  */
 1244 
 1245 static void
 1246 ea_read(struct seeq8005_softc *sc, int addr, int len)
 1247 {
 1248         struct mbuf *m;
 1249         struct ifnet *ifp;
 1250 
 1251         ifp = &sc->sc_ethercom.ec_if;
 1252 
 1253         /* Pull packet off interface. */
 1254         m = ea_get(sc, addr, len, ifp);
 1255         if (m == 0)
 1256                 return;
 1257 
 1258 #if NBPFILTER > 0
 1259         /*
 1260          * Check if there's a BPF listener on this interface.
 1261          * If so, hand off the raw packet to bpf.
 1262          */
 1263         if (ifp->if_bpf)
 1264                 bpf_mtap(ifp->if_bpf, m);
 1265 #endif
 1266 
 1267         (*ifp->if_input)(ifp, m);
 1268 }
 1269 
 1270 /*
 1271  * Pull read data off a interface.  Len is length of data, with local net
 1272  * header stripped.  We copy the data into mbufs.  When full cluster sized
 1273  * units are present we copy into clusters.
 1274  */
 1275 
 1276 struct mbuf *
 1277 ea_get(struct seeq8005_softc *sc, int addr, int totlen, struct ifnet *ifp)
 1278 {
 1279         struct mbuf *top, **mp, *m;
 1280         int len;
 1281         u_int cp, epkt;
 1282 
 1283         cp = addr;
 1284         epkt = cp + totlen;
 1285 
 1286         MGETHDR(m, M_DONTWAIT, MT_DATA);
 1287         if (m == 0)
 1288                 return 0;
 1289         m->m_pkthdr.rcvif = ifp;
 1290         m->m_pkthdr.len = totlen;
 1291         m->m_len = MHLEN;
 1292         top = 0;
 1293         mp = &top;
 1294 
 1295         while (totlen > 0) {
 1296                 if (top) {
 1297                         MGET(m, M_DONTWAIT, MT_DATA);
 1298                         if (m == 0) {
 1299                                 m_freem(top);
 1300                                 return 0;
 1301                         }
 1302                         m->m_len = MLEN;
 1303                 }
 1304                 len = min(totlen, epkt - cp);
 1305                 if (len >= MINCLSIZE) {
 1306                         MCLGET(m, M_DONTWAIT);
 1307                         if (m->m_flags & M_EXT)
 1308                                 m->m_len = len = min(len, MCLBYTES);
 1309                         else
 1310                                 len = m->m_len;
 1311                 } else {
 1312                         /*
 1313                          * Place initial small packet/header at end of mbuf.
 1314                          */
 1315                         if (len < m->m_len) {
 1316                                 if (top == 0 && len + max_linkhdr <= m->m_len)
 1317                                         m->m_data += max_linkhdr;
 1318                                 m->m_len = len;
 1319                         } else
 1320                                 len = m->m_len;
 1321                 }
 1322                 if (top == 0) {
 1323                         /* Make sure the payload is aligned */
 1324                         caddr_t newdata = (caddr_t)
 1325                             ALIGN(m->m_data + sizeof(struct ether_header)) -
 1326                             sizeof(struct ether_header);
 1327                         len -= newdata - m->m_data;
 1328                         m->m_len = len;
 1329                         m->m_data = newdata;
 1330                 }
 1331                 ea_readbuf(sc, mtod(m, u_char *),
 1332                     cp < SEEQ_MAX_BUFFER_SIZE ? cp : cp - sc->sc_rx_bufsize,
 1333                     len);
 1334                 cp += len;
 1335                 *mp = m;
 1336                 mp = &m->m_next;
 1337                 totlen -= len;
 1338                 if (cp == epkt)
 1339                         cp = addr;
 1340         }
 1341 
 1342         return top;
 1343 }
 1344 
 1345 /*
 1346  * Process an ioctl request.  Mostly boilerplate.
 1347  */
 1348 static int
 1349 ea_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 1350 {
 1351         struct seeq8005_softc *sc = ifp->if_softc;
 1352         int s, error = 0;
 1353 
 1354         s = splnet();
 1355         switch (cmd) {
 1356 
 1357         default:
 1358                 error = ether_ioctl(ifp, cmd, data);
 1359                 if (error == ENETRESET) {
 1360                         /*
 1361                          * Multicast list has changed; set the hardware filter
 1362                          * accordingly.
 1363                          */
 1364                         ea_mc_reset(sc);
 1365                         error = 0;
 1366                 }
 1367                 break;
 1368         }
 1369 
 1370         splx(s);
 1371         return error;
 1372 }
 1373 
 1374 /* Must be called at splnet() */
 1375 
 1376 static void
 1377 ea_mc_reset(struct seeq8005_softc *sc)
 1378 {
 1379 
 1380         switch (sc->sc_variant) {
 1381         case SEEQ_8004:
 1382                 ea_mc_reset_8004(sc);
 1383                 return;
 1384         case SEEQ_8005:
 1385                 ea_mc_reset_8005(sc);
 1386                 return;
 1387         }
 1388 }
 1389 
 1390 static void
 1391 ea_mc_reset_8004(struct seeq8005_softc *sc)
 1392 {
 1393         struct ethercom *ec = &sc->sc_ethercom;
 1394         struct ifnet *ifp = &ec->ec_if;
 1395         struct ether_multi *enm;
 1396         u_int32_t crc;
 1397         int i;
 1398         struct ether_multistep step;
 1399         u_int8_t af[8];
 1400 
 1401         /*
 1402          * Set up multicast address filter by passing all multicast addresses
 1403          * through a crc generator, and then using bits 2 - 7 as an index
 1404          * into the 64 bit logical address filter.  The high order bits
 1405          * selects the word, while the rest of the bits select the bit within
 1406          * the word.
 1407          */
 1408 
 1409         if (ifp->if_flags & IFF_PROMISC) {
 1410                 ifp->if_flags |= IFF_ALLMULTI;
 1411                 for (i = 0; i < 8; i++)
 1412                         af[i] = 0xff;
 1413                 return;
 1414         }
 1415         for (i = 0; i < 8; i++)
 1416                 af[i] = 0;
 1417         ETHER_FIRST_MULTI(step, ec, enm);
 1418         while (enm != NULL) {
 1419                 if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
 1420                     sizeof(enm->enm_addrlo)) != 0) {
 1421                         /*
 1422                          * We must listen to a range of multicast addresses.
 1423                          * For now, just accept all multicasts, rather than
 1424                          * trying to set only those filter bits needed to match
 1425                          * the range.  (At this time, the only use of address
 1426                          * ranges is for IP multicast routing, for which the
 1427                          * range is big enough to require all bits set.)
 1428                          */
 1429                         ifp->if_flags |= IFF_ALLMULTI;
 1430                         for (i = 0; i < 8; i++)
 1431                                 af[i] = 0xff;
 1432                         break;
 1433                 }
 1434 
 1435                 crc = ether_crc32_be(enm->enm_addrlo, sizeof(enm->enm_addrlo));
 1436 
 1437                 /* Just want the 6 most significant bits. */
 1438                 crc = (crc >> 2) & 0x3f;
 1439 
 1440                 /* Turn on the corresponding bit in the filter. */
 1441                 af[crc >> 3] |= 1 << (crc & 0x7);
 1442 
 1443                 ETHER_NEXT_MULTI(step, enm);
 1444         }
 1445         ifp->if_flags &= ~IFF_ALLMULTI;
 1446 
 1447         ea_select_buffer(sc, SEEQ_BUFCODE_MULTICAST);
 1448                 for (i = 0; i < 8; ++i)
 1449                         bus_space_write_1(sc->sc_iot, sc->sc_ioh,
 1450                             SEEQ_BUFWIN, af[i]);
 1451 }
 1452 
 1453 static void
 1454 ea_mc_reset_8005(struct seeq8005_softc *sc)
 1455 {
 1456         struct ether_multi *enm;
 1457         struct ether_multistep step;
 1458         int naddr, maxaddrs;
 1459 
 1460         naddr = 0;
 1461         maxaddrs = 5;
 1462         ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm);
 1463         while (enm != NULL) {
 1464                 /* Have we got space? */
 1465                 if (naddr >= maxaddrs ||
 1466                     memcmp(enm->enm_addrlo, enm->enm_addrhi, 6) != 0) {
 1467                         sc->sc_ethercom.ec_if.if_flags |= IFF_ALLMULTI;
 1468                         ea_ioctl(&sc->sc_ethercom.ec_if, SIOCSIFFLAGS, NULL);
 1469                         return;
 1470                 }
 1471                 ea_set_address(sc, 1 + naddr, enm->enm_addrlo);
 1472                 sc->sc_config1 |= SEEQ_CFG1_STATION_ADDR1 << naddr;
 1473                 naddr++;
 1474                 ETHER_NEXT_MULTI(step, enm);
 1475         }
 1476         for (; naddr < maxaddrs; naddr++)
 1477                 sc->sc_config1 &= ~(SEEQ_CFG1_STATION_ADDR1 << naddr);
 1478         SEEQ_WRITE16(sc, sc->sc_iot, sc->sc_ioh, SEEQ_CONFIG1,
 1479                           sc->sc_config1);
 1480 }
 1481 
 1482 /*
 1483  * Device timeout routine.
 1484  */
 1485 
 1486 static void
 1487 ea_watchdog(struct ifnet *ifp)
 1488 {
 1489         struct seeq8005_softc *sc = ifp->if_softc;
 1490 
 1491         log(LOG_ERR, "%s: lost Tx interrupt (status = 0x%04x)\n",
 1492             sc->sc_dev.dv_xname,
 1493             SEEQ_READ16(sc, sc->sc_iot, sc->sc_ioh, SEEQ_STATUS));
 1494         ifp->if_oerrors++;
 1495 
 1496         /* Kick the interface */
 1497 
 1498         ea_init(ifp);
 1499 
 1500         ifp->if_timer = 0;
 1501 }
 1502 
 1503 /* End of if_ea.c */

Cache object: 082cce54f1ccb5a9ca363dea12f0e1fd


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