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.43 2008/04/08 12:07:27 cegger 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.43 2008/04/08 12:07:27 cegger 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 <sys/bus.h>
   94 #include <sys/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, void *);
  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                         aprint_normal("\n");
  193                         aprint_error_dev(&sc->sc_dev, "Cannot determine data bus width\n");
  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             device_xname(&sc->sc_dev), 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                         aprint_error_dev(&sc->sc_dev, "can't allocate pad buffer\n");
  255                         return;
  256                 }
  257         }
  258 
  259         /* Initialise ifnet structure. */
  260 
  261         strlcpy(ifp->if_xname, device_xname(&sc->sc_dev), IFNAMSIZ);
  262         ifp->if_softc = sc;
  263         ifp->if_start = ea_start;
  264         ifp->if_ioctl = ea_ioctl;
  265         ifp->if_init = ea_init;
  266         ifp->if_stop = ea_stop;
  267         ifp->if_watchdog = ea_watchdog;
  268         ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST | IFF_NOTRAILERS;
  269         if (sc->sc_variant == SEEQ_8004)
  270                 ifp->if_flags |= IFF_SIMPLEX;
  271         IFQ_SET_READY(&ifp->if_snd);
  272 
  273         /* Initialize media goo. */
  274         ifmedia_init(&sc->sc_media, 0, ea_mediachange, ea_mediastatus);
  275         if (media != NULL) {
  276                 int i;
  277 
  278                 for (i = 0; i < nmedia; i++)
  279                         ifmedia_add(&sc->sc_media, media[i], 0, NULL);
  280                 ifmedia_set(&sc->sc_media, defmedia);
  281         } else {
  282                 ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
  283                 ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL);
  284         }
  285 
  286         /* We can support 802.1Q VLAN-sized frames. */
  287         sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;
  288 
  289         /* Now we can attach the interface. */
  290 
  291         if_attach(ifp);
  292         ether_ifattach(ifp, myaddr);
  293 
  294         printf("\n");
  295 
  296 #if NRND > 0
  297         /* After \n because it can print a line of its own. */
  298         rnd_attach_source(&sc->rnd_source, device_xname(&sc->sc_dev),
  299             RND_TYPE_NET, 0);
  300 #endif
  301 }
  302 
  303 /*
  304  * Media change callback.
  305  */
  306 static int
  307 ea_mediachange(struct ifnet *ifp)
  308 {
  309         struct seeq8005_softc *sc = ifp->if_softc;
  310 
  311         if (sc->sc_mediachange)
  312                 return ((*sc->sc_mediachange)(sc));
  313         return (EINVAL);
  314 }
  315 
  316 /*
  317  * Media status callback.
  318  */
  319 static void
  320 ea_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
  321 {
  322         struct seeq8005_softc *sc = ifp->if_softc;
  323 
  324         if (sc->sc_enabled == 0) {
  325                 ifmr->ifm_active = IFM_ETHER | IFM_NONE;
  326                 ifmr->ifm_status = 0;
  327                 return;
  328         }
  329 
  330         if (sc->sc_mediastatus)
  331                 (*sc->sc_mediastatus)(sc, ifmr);
  332 }
  333 
  334 /*
  335  * Test the RAM on the ethernet card.
  336  */
  337 
  338 void
  339 ea_ramtest(struct seeq8005_softc *sc)
  340 {
  341         bus_space_tag_t iot = sc->sc_iot;
  342         bus_space_handle_t ioh = sc->sc_ioh;
  343         int loop;
  344         u_int sum = 0;
  345 
  346         /*
  347          * Test the buffer memory on the board.
  348          * Write simple pattens to it and read them back.
  349          */
  350 
  351         /* Set up the whole buffer RAM for writing */
  352 
  353         ea_select_buffer(sc, SEEQ_BUFCODE_TX_EAP);
  354         SEEQ_WRITE16(sc, iot, ioh, SEEQ_BUFWIN, (SEEQ_MAX_BUFFER_SIZE >> 8) - 1);
  355         SEEQ_WRITE16(sc, iot, ioh, SEEQ_TX_PTR, 0x0000);
  356         SEEQ_WRITE16(sc, iot, ioh, SEEQ_RX_PTR, SEEQ_MAX_BUFFER_SIZE - 2);
  357 
  358 #define SEEQ_RAMTEST_LOOP(value)                                                \
  359 do {                                                                    \
  360         /* Set the write start address and write a pattern */           \
  361         ea_writebuf(sc, NULL, 0x0000, 0);                               \
  362         for (loop = 0; loop < SEEQ_MAX_BUFFER_SIZE; loop += 2)          \
  363                 SEEQ_WRITE16(sc, iot, ioh, SEEQ_BUFWIN, (value));       \
  364                                                                         \
  365         /* Set the read start address and verify the pattern */         \
  366         ea_readbuf(sc, NULL, 0x0000, 0);                                \
  367         for (loop = 0; loop < SEEQ_MAX_BUFFER_SIZE; loop += 2)          \
  368                 if (SEEQ_READ16(sc, iot, ioh, SEEQ_BUFWIN) != (value)) \
  369                         ++sum;                                          \
  370 } while (/*CONSTCOND*/0)
  371 
  372         SEEQ_RAMTEST_LOOP(loop);
  373         SEEQ_RAMTEST_LOOP(loop ^ (SEEQ_MAX_BUFFER_SIZE - 1));
  374         SEEQ_RAMTEST_LOOP(0xaa55);
  375         SEEQ_RAMTEST_LOOP(0x55aa);
  376 
  377         /* Report */
  378 
  379         if (sum > 0)
  380                 aprint_error_dev(&sc->sc_dev, "buffer RAM failed self test, %d faults\n", sum);
  381 }
  382 
  383 
  384 /*
  385  * Stop the tx interface.
  386  *
  387  * Returns 0 if the tx was already stopped or 1 if it was active
  388  */
  389 
  390 static int
  391 ea_stoptx(struct seeq8005_softc *sc)
  392 {
  393         bus_space_tag_t iot = sc->sc_iot;
  394         bus_space_handle_t ioh = sc->sc_ioh;
  395         int timeout;
  396         int status;
  397 
  398         DPRINTF(SEEQ_DEBUG_TX, ("ea_stoptx()\n"));
  399 
  400         sc->sc_enabled = 0;
  401 
  402         status = SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS);
  403         if (!(status & SEEQ_STATUS_TX_ON))
  404                 return 0;
  405 
  406         /* Stop any tx and wait for confirmation */
  407         SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND,
  408                           sc->sc_command | SEEQ_CMD_TX_OFF);
  409 
  410         timeout = 20000;
  411         do {
  412                 status = SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS);
  413                 delay(1);
  414         } while ((status & SEEQ_STATUS_TX_ON) && --timeout > 0);
  415         if (timeout == 0)
  416                 log(LOG_ERR, "%s: timeout waiting for tx termination\n",
  417                     device_xname(&sc->sc_dev));
  418 
  419         /* Clear any pending tx interrupt */
  420         SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND,
  421                    sc->sc_command | SEEQ_CMD_TX_INTACK);
  422         return 1;
  423 }
  424 
  425 
  426 /*
  427  * Stop the rx interface.
  428  *
  429  * Returns 0 if the tx was already stopped or 1 if it was active
  430  */
  431 
  432 static int
  433 ea_stoprx(struct seeq8005_softc *sc)
  434 {
  435         bus_space_tag_t iot = sc->sc_iot;
  436         bus_space_handle_t ioh = sc->sc_ioh;
  437         int timeout;
  438         int status;
  439 
  440         DPRINTF(SEEQ_DEBUG_RX, ("ea_stoprx()\n"));
  441 
  442         status = SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS);
  443         if (!(status & SEEQ_STATUS_RX_ON))
  444                 return 0;
  445 
  446         /* Stop any rx and wait for confirmation */
  447 
  448         SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND,
  449                           sc->sc_command | SEEQ_CMD_RX_OFF);
  450 
  451         timeout = 20000;
  452         do {
  453                 status = SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS);
  454         } while ((status & SEEQ_STATUS_RX_ON) && --timeout > 0);
  455         if (timeout == 0)
  456                 log(LOG_ERR, "%s: timeout waiting for rx termination\n",
  457                     device_xname(&sc->sc_dev));
  458 
  459         /* Clear any pending rx interrupt */
  460 
  461         SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND,
  462                    sc->sc_command | SEEQ_CMD_RX_INTACK);
  463         return 1;
  464 }
  465 
  466 
  467 /*
  468  * Stop interface.
  469  * Stop all IO and shut the interface down
  470  */
  471 
  472 /* ARGSUSED */
  473 static void
  474 ea_stop(struct ifnet *ifp, int disable)
  475 {
  476         struct seeq8005_softc *sc = ifp->if_softc;
  477         bus_space_tag_t iot = sc->sc_iot;
  478         bus_space_handle_t ioh = sc->sc_ioh;
  479 
  480         DPRINTF(SEEQ_DEBUG_MISC, ("ea_stop()\n"));
  481 
  482         /* Stop all IO */
  483         ea_stoptx(sc);
  484         ea_stoprx(sc);
  485 
  486         /* Disable rx and tx interrupts */
  487         sc->sc_command &= (SEEQ_CMD_RX_INTEN | SEEQ_CMD_TX_INTEN);
  488 
  489         /* Clear any pending interrupts */
  490         SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND,
  491                           sc->sc_command | SEEQ_CMD_RX_INTACK |
  492                           SEEQ_CMD_TX_INTACK | SEEQ_CMD_DMA_INTACK |
  493                           SEEQ_CMD_BW_INTACK);
  494 
  495         if (sc->sc_variant == SEEQ_8004) {
  496                 /* Put the chip to sleep */
  497                 ea_select_buffer(sc, SEEQ_BUFCODE_CONFIG3);
  498                 SEEQ_WRITE16(sc, iot, ioh, SEEQ_BUFWIN,
  499                     sc->sc_config3 | SEEQ_CFG3_SLEEP);
  500         }
  501 
  502         /* Cancel any watchdog timer */
  503         sc->sc_ethercom.ec_if.if_timer = 0;
  504 }
  505 
  506 
  507 /*
  508  * Reset the chip
  509  * Following this the software registers are reset
  510  */
  511 
  512 static void
  513 ea_chipreset(struct seeq8005_softc *sc)
  514 {
  515         bus_space_tag_t iot = sc->sc_iot;
  516         bus_space_handle_t ioh = sc->sc_ioh;
  517 
  518         DPRINTF(SEEQ_DEBUG_MISC, ("ea_chipreset()\n"));
  519 
  520         /* Reset the controller. Min of 4us delay here */
  521 
  522         /*
  523          * This can be called before we know whether the chip is in 8- or
  524          * 16-bit mode, so we do a reset in both modes.  The 16-bit reset is
  525          * harmless in 8-bit mode, so we do that second.
  526          */
  527 
  528         /* In 16-bit mode, this will munge the PreamSelect bit. */
  529         bus_space_write_1(iot, ioh, SEEQ_CONFIG2 + 1, SEEQ_CFG2_RESET >> 8);
  530         delay(4);
  531         /* In 8-bit mode, this will zero the bottom half of config reg 2. */
  532         bus_space_write_2(iot, ioh, SEEQ_CONFIG2, SEEQ_CFG2_RESET);
  533         delay(4);
  534 
  535         sc->sc_command = 0;
  536         sc->sc_config1 = 0;
  537         sc->sc_config2 = 0;
  538         sc->sc_config3 = 0;
  539 }
  540 
  541 
  542 /*
  543  * If the DMA FIFO's in write mode, wait for it to empty.  Needed when
  544  * switching the FIFO from write to read.  We also use it when changing
  545  * the address for writes.
  546  */
  547 static void
  548 ea_await_fifo_empty(struct seeq8005_softc *sc)
  549 {
  550         bus_space_tag_t iot = sc->sc_iot;
  551         bus_space_handle_t ioh = sc->sc_ioh;
  552         int timeout;
  553 
  554         timeout = 20000;
  555         if ((SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS) &
  556              SEEQ_STATUS_FIFO_DIR) != 0)
  557                 return; /* FIFO is reading anyway. */
  558         while (--timeout > 0)
  559                 if (SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS) &
  560                     SEEQ_STATUS_FIFO_EMPTY)
  561                         return;
  562         log(LOG_ERR, "%s: DMA FIFO failed to empty\n", device_xname(&sc->sc_dev));
  563 }
  564 
  565 /*
  566  * Wait for the DMA FIFO to fill before reading from it.
  567  */
  568 static void
  569 ea_await_fifo_full(struct seeq8005_softc *sc)
  570 {
  571         bus_space_tag_t iot = sc->sc_iot;
  572         bus_space_handle_t ioh = sc->sc_ioh;
  573         int timeout;
  574 
  575         timeout = 20000;
  576         while (--timeout > 0)
  577                 if (SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS) &
  578                     SEEQ_STATUS_FIFO_FULL)
  579                         return;
  580         log(LOG_ERR, "%s: DMA FIFO failed to fill\n", device_xname(&sc->sc_dev));
  581 }
  582 
  583 /*
  584  * write to the buffer memory on the interface
  585  *
  586  * The buffer address is set to ADDR.
  587  * If len != 0 then data is copied from the address starting at buf
  588  * to the interface buffer.
  589  * BUF must be usable as a u_int16_t *.
  590  * If LEN is odd, it must be safe to overwrite one extra byte.
  591  */
  592 
  593 static void
  594 ea_writebuf(struct seeq8005_softc *sc, u_char *buf, int addr, size_t len)
  595 {
  596         bus_space_tag_t iot = sc->sc_iot;
  597         bus_space_handle_t ioh = sc->sc_ioh;
  598 
  599         DPRINTF(SEEQ_DEBUG_MISC, ("writebuf: st=%04x\n",
  600             SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS)));
  601 
  602 #ifdef DIAGNOSTIC
  603         if (__predict_false(!ALIGNED_POINTER(buf, u_int16_t)))
  604                 panic("%s: unaligned writebuf", device_xname(&sc->sc_dev));
  605         if (__predict_false(addr >= SEEQ_MAX_BUFFER_SIZE))
  606                 panic("%s: writebuf out of range", device_xname(&sc->sc_dev));
  607 #endif
  608 
  609         if (addr != -1) {
  610                 ea_await_fifo_empty(sc);
  611 
  612                 ea_select_buffer(sc, SEEQ_BUFCODE_LOCAL_MEM);
  613                 SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND,
  614                     sc->sc_command | SEEQ_CMD_FIFO_WRITE);
  615                 SEEQ_WRITE16(sc, iot, ioh, SEEQ_DMA_ADDR, addr);
  616         }
  617 
  618         if (len > 0) {
  619                 if (sc->sc_flags & SF_8BIT)
  620                         bus_space_write_multi_1(iot, ioh, SEEQ_BUFWIN,
  621                             (u_int8_t *)buf, len);
  622                 else
  623                         bus_space_write_multi_2(iot, ioh, SEEQ_BUFWIN,
  624                             /* LINTED: alignment checked above */
  625                             (u_int16_t *)buf, len / 2);
  626         }
  627         if (!(sc->sc_flags & SF_8BIT) && len % 2) {
  628                 /* Write the last byte */
  629                 bus_space_write_2(iot, ioh, SEEQ_BUFWIN, buf[len - 1]);
  630         }
  631         /* Leave FIFO to empty in the background */
  632 }
  633 
  634 
  635 /*
  636  * read from the buffer memory on the interface
  637  *
  638  * The buffer address is set to ADDR.
  639  * If len != 0 then data is copied from the interface buffer to the
  640  * address starting at buf.
  641  * BUF must be usable as a u_int16_t *.
  642  * If LEN is odd, it must be safe to overwrite one extra byte.
  643  */
  644 
  645 static void
  646 ea_readbuf(struct seeq8005_softc *sc, u_char *buf, int addr, size_t len)
  647 {
  648         bus_space_tag_t iot = sc->sc_iot;
  649         bus_space_handle_t ioh = sc->sc_ioh;
  650         int runup;
  651 
  652         DPRINTF(SEEQ_DEBUG_MISC, ("readbuf: st=%04x addr=%04x len=%d\n",
  653             SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS), addr, len));
  654 
  655 #ifdef DIAGNOSTIC
  656         if (__predict_false(!ALIGNED_POINTER(buf, u_int16_t)))
  657                 panic("%s: unaligned readbuf", device_xname(&sc->sc_dev));
  658         if (__predict_false(addr >= SEEQ_MAX_BUFFER_SIZE))
  659                 panic("%s: readbuf out of range", device_xname(&sc->sc_dev));
  660 #endif
  661 
  662         if (addr != -1) {
  663                 /*
  664                  * SEEQ 80C04 bug:
  665                  * Starting reading from certain addresses seems to cause
  666                  * us to get bogus results, so we avoid them.
  667                  */
  668                 runup = 0;
  669                 if (sc->sc_variant == SEEQ_8004 &&
  670                     ((addr & 0x00ff) == 0x00ea ||
  671                      (addr & 0x00ff) == 0x00ee ||
  672                      (addr & 0x00ff) == 0x00f0))
  673                         runup = (addr & 0x00ff) - 0x00e8;
  674 
  675                 ea_await_fifo_empty(sc);
  676 
  677                 ea_select_buffer(sc, SEEQ_BUFCODE_LOCAL_MEM);
  678 
  679                 /*
  680                  * 80C04 bug workaround.  I found this in the old arm32 "eb"
  681                  * driver.  I've no idea what it does, but it seems to stop
  682                  * the chip mangling data so often.
  683                  */
  684                 SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND,
  685                     sc->sc_command | SEEQ_CMD_FIFO_WRITE);
  686                 ea_await_fifo_empty(sc);
  687 
  688                 SEEQ_WRITE16(sc, iot, ioh, SEEQ_DMA_ADDR, addr - runup);
  689                 SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND,
  690                     sc->sc_command | SEEQ_CMD_FIFO_READ);
  691 
  692                 ea_await_fifo_full(sc);
  693                 while (runup > 0) {
  694                         /* LINTED: Reading a volatile _does_ have an effect */
  695                         (void)SEEQ_READ16(sc, iot, ioh, SEEQ_BUFWIN);
  696                         runup -= 2;
  697                 }
  698         }
  699 
  700         if (len > 0) {
  701                 if (sc->sc_flags & SF_8BIT)
  702                         bus_space_read_multi_1(iot, ioh, SEEQ_BUFWIN,
  703                             (u_int8_t *)buf, len);
  704                 else
  705                         bus_space_read_multi_2(iot, ioh, SEEQ_BUFWIN,
  706                             /* LINTED: pointer alignment checked above */
  707                             (u_int16_t *)buf, len / 2);
  708         }
  709         if (!(sc->sc_flags & SF_8BIT) && len % 2) {
  710                 /* Read the last byte */
  711                 buf[len - 1] = bus_space_read_2(iot, ioh, SEEQ_BUFWIN);
  712         }
  713 }
  714 
  715 static void
  716 ea_select_buffer(struct seeq8005_softc *sc, int bufcode)
  717 {
  718 
  719         SEEQ_WRITE16(sc, sc->sc_iot, sc->sc_ioh, SEEQ_CONFIG1,
  720                           sc->sc_config1 | bufcode);
  721 }
  722 
  723 /* Must be called at splnet */
  724 static void
  725 ea_set_address(struct seeq8005_softc *sc, int which, const u_int8_t *ea)
  726 {
  727         int i;
  728 
  729         ea_select_buffer(sc, SEEQ_BUFCODE_STATION_ADDR0 + which);
  730         for (i = 0; i < ETHER_ADDR_LEN; ++i)
  731                 SEEQ_WRITE16(sc, sc->sc_iot, sc->sc_ioh, SEEQ_BUFWIN,
  732                                   ea[i]);
  733 }
  734 
  735 /*
  736  * Initialize interface.
  737  *
  738  * This should leave the interface in a state for packet reception and
  739  * transmission.
  740  */
  741 
  742 static int
  743 ea_init(struct ifnet *ifp)
  744 {
  745         struct seeq8005_softc *sc = ifp->if_softc;
  746         bus_space_tag_t iot = sc->sc_iot;
  747         bus_space_handle_t ioh = sc->sc_ioh;
  748         int s;
  749 
  750         DPRINTF(SEEQ_DEBUG_MISC, ("ea_init()\n"));
  751 
  752         s = splnet();
  753 
  754         /* First, reset the board. */
  755 
  756         ea_chipreset(sc);
  757 
  758         /* Set up defaults for the registers */
  759 
  760         sc->sc_command = 0;
  761         sc->sc_config1 = 0;
  762 #if BYTE_ORDER == BIG_ENDIAN
  763         sc->sc_config2 = SEEQ_CFG2_BYTESWAP;
  764 #else
  765         sc->sc_config2 = 0;
  766 #endif
  767         sc->sc_config3 = 0;
  768 
  769         SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND, sc->sc_command);
  770         SEEQ_WRITE16(sc, iot, ioh, SEEQ_CONFIG1, sc->sc_config1);
  771         SEEQ_WRITE16(sc, iot, ioh, SEEQ_CONFIG2, sc->sc_config2);
  772         if (sc->sc_variant == SEEQ_8004) {
  773                 ea_select_buffer(sc, SEEQ_BUFCODE_CONFIG3);
  774                 SEEQ_WRITE16(sc, iot, ioh, SEEQ_BUFWIN, sc->sc_config3);
  775         }
  776 
  777         /* Write the station address - the receiver must be off */
  778         ea_set_address(sc, 0, (const u_int8_t *)CLLADDR(ifp->if_sadl));
  779 
  780         /* Split board memory into Rx and Tx. */
  781         ea_select_buffer(sc, SEEQ_BUFCODE_TX_EAP);
  782         SEEQ_WRITE16(sc, iot, ioh, SEEQ_BUFWIN, (sc->sc_tx_bufsize>> 8) - 1);
  783 
  784         if (sc->sc_variant == SEEQ_8004) {
  785                 /* Make the interface IFF_SIMPLEX. */
  786                 sc->sc_config2 |= SEEQ_CFG2_RX_TX_DISABLE;
  787                 /* Enable reception of long packets (for vlan(4)). */
  788                 sc->sc_config2 |= SEEQ_CFG2_PASS_LONGSHORT;
  789         }
  790 
  791         /* Configure rx. */
  792         ea_mc_reset(sc);
  793         if (ifp->if_flags & IFF_PROMISC)
  794                 sc->sc_config1 = SEEQ_CFG1_PROMISCUOUS;
  795         else if ((ifp->if_flags & IFF_ALLMULTI) || sc->sc_variant == SEEQ_8004)
  796                 sc->sc_config1 = SEEQ_CFG1_MULTICAST;
  797         else
  798                 sc->sc_config1 = SEEQ_CFG1_BROADCAST;
  799         sc->sc_config1 |= SEEQ_CFG1_STATION_ADDR0;
  800         SEEQ_WRITE16(sc, iot, ioh, SEEQ_CONFIG1, sc->sc_config1);
  801 
  802         /* Setup the Rx pointers */
  803         sc->sc_rx_ptr = sc->sc_tx_bufsize;
  804 
  805         SEEQ_WRITE16(sc, iot, ioh, SEEQ_RX_PTR, sc->sc_rx_ptr);
  806         SEEQ_WRITE16(sc, iot, ioh, SEEQ_RX_END, sc->sc_rx_ptr >> 8);
  807 
  808 
  809         /* Place a NULL header at the beginning of the receive area */
  810         ea_writebuf(sc, NULL, sc->sc_rx_ptr, 0);
  811 
  812         SEEQ_WRITE16(sc, iot, ioh, SEEQ_BUFWIN, 0x0000);
  813         SEEQ_WRITE16(sc, iot, ioh, SEEQ_BUFWIN, 0x0000);
  814 
  815 
  816         /* Configure TX. */
  817         DPRINTF(SEEQ_DEBUG_MISC, ("Configuring tx...\n"));
  818 
  819         SEEQ_WRITE16(sc, iot, ioh, SEEQ_TX_PTR, 0x0000);
  820 
  821         sc->sc_config2 |= SEEQ_CFG2_OUTPUT;
  822         SEEQ_WRITE16(sc, iot, ioh, SEEQ_CONFIG2, sc->sc_config2);
  823 
  824         /* Reset tx buffer pointers */
  825         sc->sc_tx_cur = 0;
  826         sc->sc_tx_used = 0;
  827         sc->sc_tx_next = 0;
  828 
  829         /* Place a NULL header at the beginning of the transmit area */
  830         ea_writebuf(sc, NULL, 0x0000, 0);
  831 
  832         SEEQ_WRITE16(sc, iot, ioh, SEEQ_BUFWIN, 0x0000);
  833         SEEQ_WRITE16(sc, iot, ioh, SEEQ_BUFWIN, 0x0000);
  834 
  835         sc->sc_command |= SEEQ_CMD_TX_INTEN;
  836         SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND, sc->sc_command);
  837 
  838         /* Turn on Rx */
  839         sc->sc_command |= SEEQ_CMD_RX_INTEN;
  840         SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND,
  841                           sc->sc_command | SEEQ_CMD_RX_ON);
  842 
  843         /* TX_ON gets set by ea_txpacket when there's something to transmit. */
  844 
  845 
  846         /* Set flags appropriately. */
  847         ifp->if_flags |= IFF_RUNNING;
  848         ifp->if_flags &= ~IFF_OACTIVE;
  849         sc->sc_enabled = 1;
  850 
  851         /* And start output. */
  852         ea_start(ifp);
  853 
  854         splx(s);
  855         return 0;
  856 }
  857 
  858 /*
  859  * Start output on interface. Get datagrams from the queue and output them,
  860  * giving the receiver a chance between datagrams. Call only from splnet or
  861  * interrupt level!
  862  */
  863 
  864 static void
  865 ea_start(struct ifnet *ifp)
  866 {
  867         struct seeq8005_softc *sc = ifp->if_softc;
  868         int s;
  869 
  870         s = splnet();
  871         DPRINTF(SEEQ_DEBUG_TX, ("ea_start()...\n"));
  872 
  873         /*
  874          * Don't do anything if output is active.  seeq8005intr() will call
  875          * us (actually eatxpacket()) back when the card's ready for more
  876          * frames.
  877          */
  878         if (ifp->if_flags & IFF_OACTIVE)
  879                 return;
  880 
  881         /* Mark interface as output active */
  882 
  883         ifp->if_flags |= IFF_OACTIVE;
  884 
  885         /* tx packets */
  886 
  887         eatxpacket(sc);
  888         splx(s);
  889 }
  890 
  891 
  892 /*
  893  * Transfer a packet to the interface buffer and start transmission
  894  *
  895  * Called at splnet()
  896  */
  897 
  898 void
  899 eatxpacket(struct seeq8005_softc *sc)
  900 {
  901         bus_space_tag_t iot = sc->sc_iot;
  902         bus_space_handle_t ioh = sc->sc_ioh;
  903         struct mbuf *m0;
  904         struct ifnet *ifp;
  905 
  906         ifp = &sc->sc_ethercom.ec_if;
  907 
  908         /* Dequeue the next packet. */
  909         IFQ_DEQUEUE(&ifp->if_snd, m0);
  910 
  911         /* If there's nothing to send, return. */
  912         if (!m0) {
  913                 ifp->if_flags &= ~IFF_OACTIVE;
  914                 sc->sc_config2 |= SEEQ_CFG2_OUTPUT;
  915                 SEEQ_WRITE16(sc, iot, ioh, SEEQ_CONFIG2, sc->sc_config2);
  916                 DPRINTF(SEEQ_DEBUG_TX, ("tx finished\n"));
  917                 return;
  918         }
  919 
  920 #if NBPFILTER > 0
  921         /* Give the packet to the bpf, if any. */
  922         if (ifp->if_bpf)
  923                 bpf_mtap(ifp->if_bpf, m0);
  924 #endif
  925 
  926         DPRINTF(SEEQ_DEBUG_TX, ("Tx new packet\n"));
  927 
  928         sc->sc_config2 &= ~SEEQ_CFG2_OUTPUT;
  929         SEEQ_WRITE16(sc, iot, ioh, SEEQ_CONFIG2, sc->sc_config2);
  930 
  931         ea_writembuf(sc, m0, 0x0000);
  932         m_freem(m0);
  933 
  934         SEEQ_WRITE16(sc, iot, ioh, SEEQ_TX_PTR, 0x0000);
  935 
  936         /* Now transmit the datagram. */
  937         SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND,
  938                           sc->sc_command | SEEQ_CMD_TX_ON);
  939 
  940         /* Make sure we notice if the chip goes silent on us. */
  941         ifp->if_timer = 5;
  942 
  943         DPRINTF(SEEQ_DEBUG_TX,
  944             ("st=%04x\n", SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS)));
  945         DPRINTF(SEEQ_DEBUG_TX, ("tx: queued\n"));
  946 }
  947 
  948 /*
  949  * Copy a packet from an mbuf to the transmit buffer on the card.
  950  *
  951  * Puts a valid Tx header at the start of the packet, and a null header at
  952  * the end.
  953  */
  954 static int
  955 ea_writembuf(struct seeq8005_softc *sc, struct mbuf *m0, int bufstart)
  956 {
  957         struct mbuf *m;
  958         int len, nextpacket;
  959         u_int8_t hdr[4];
  960 
  961         /*
  962          * Copy the datagram to the packet buffer.
  963          */
  964         len = 0;
  965         for (m = m0; m; m = m->m_next) {
  966                 if (m->m_len == 0)
  967                         continue;
  968                 ea_writebuf(sc, mtod(m, u_char *), bufstart + 4 + len,
  969                     m->m_len);
  970                 len += m->m_len;
  971         }
  972 
  973         if (len < ETHER_MIN_LEN) {
  974                 ea_writebuf(sc, padbuf, bufstart + 4 + len,
  975                     ETHER_MIN_LEN - len);
  976                 len = ETHER_MIN_LEN;
  977         }
  978 
  979         /* Follow it with a NULL packet header */
  980         memset(hdr, 0, 4);
  981         ea_writebuf(sc, hdr, bufstart + 4 + len, 4);
  982         SEEQ_WRITE16(sc, sc->sc_iot, sc->sc_ioh, SEEQ_BUFWIN, 0x0000);
  983         SEEQ_WRITE16(sc, sc->sc_iot, sc->sc_ioh, SEEQ_BUFWIN, 0x0000);
  984 
  985         /* Ok we now have a packet len bytes long in our packet buffer */
  986         DPRINTF(SEEQ_DEBUG_TX, ("ea_writembuf: length=%d\n", len));
  987 
  988         /* Write the packet header */
  989         nextpacket = len + 4;
  990         hdr[0] = (nextpacket >> 8) & 0xff;
  991         hdr[1] = nextpacket & 0xff;
  992         hdr[2] = SEEQ_PKTCMD_TX | SEEQ_PKTCMD_DATA_FOLLOWS |
  993                 SEEQ_TXCMD_XMIT_SUCCESS_INT | SEEQ_TXCMD_COLLISION_INT;
  994         hdr[3] = 0; /* Status byte -- will be update by hardware. */
  995         ea_writebuf(sc, hdr, 0x0000, 4);
  996 
  997         return len;
  998 }
  999 
 1000 /*
 1001  * Ethernet controller interrupt.
 1002  */
 1003 
 1004 int
 1005 seeq8005intr(void *arg)
 1006 {
 1007         struct seeq8005_softc *sc = arg;
 1008         bus_space_tag_t iot = sc->sc_iot;
 1009         bus_space_handle_t ioh = sc->sc_ioh;
 1010         int status, handled;
 1011 
 1012         handled = 0;
 1013 
 1014         /* Get the controller status */
 1015         status = SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS);
 1016 
 1017         /* Tx interrupt ? */
 1018         if (status & SEEQ_STATUS_TX_INT) {
 1019                 handled = 1;
 1020 
 1021                 /* Acknowledge the interrupt */
 1022                 SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND,
 1023                                   sc->sc_command | SEEQ_CMD_TX_INTACK);
 1024 
 1025                 ea_txint(sc);
 1026         }
 1027 
 1028 
 1029         /* Rx interrupt ? */
 1030         if (status & SEEQ_STATUS_RX_INT) {
 1031                 handled = 1;
 1032 
 1033                 /* Acknowledge the interrupt */
 1034                 SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND,
 1035                                   sc->sc_command | SEEQ_CMD_RX_INTACK);
 1036 
 1037                 /* Processes the received packets */
 1038                 ea_rxint(sc);
 1039         }
 1040 
 1041 #if NRND > 0
 1042         if (handled)
 1043                 rnd_add_uint32(&sc->rnd_source, status);
 1044 #endif
 1045         return handled;
 1046 }
 1047 
 1048 static void
 1049 ea_txint(struct seeq8005_softc *sc)
 1050 {
 1051         struct ifnet *ifp = &sc->sc_ethercom.ec_if;
 1052         bus_space_tag_t iot = sc->sc_iot;
 1053         bus_space_handle_t ioh = sc->sc_ioh;
 1054         u_int8_t txhdr[4];
 1055         u_int txstatus;
 1056 
 1057         ea_readbuf(sc, txhdr, 0x0000, 4);
 1058 
 1059         DPRINTF(SEEQ_DEBUG_TX, ("txstatus=%02x %02x %02x %02x\n",
 1060             txhdr[0], txhdr[1], txhdr[2], txhdr[3]));
 1061         txstatus = txhdr[3];
 1062 
 1063         /*
 1064          * If SEEQ_TXSTAT_COLLISION is set then we received at least
 1065          * one collision. On the 8004 we can find out exactly how many
 1066          * collisions occurred.
 1067          *
 1068          * The SEEQ_PKTSTAT_DONE will be set if the transmission has
 1069          * completed.
 1070          *
 1071          * If SEEQ_TXSTAT_COLLISION16 is set then 16 collisions
 1072          * occurred and the packet transmission was aborted.
 1073          * This situation is untested as present.
 1074          *
 1075          * The SEEQ_TXSTAT_BABBLE is untested as it should only be set
 1076          * when we deliberately transmit oversized packets (e.g. for
 1077          * 802.1Q).
 1078          */
 1079         if (txstatus & SEEQ_TXSTAT_COLLISION) {
 1080                 switch (sc->sc_variant) {
 1081                 case SEEQ_8004: {
 1082                         int colls;
 1083 
 1084                         /*
 1085                          * The 8004 contains a 4 bit collision count
 1086                          * in the status register.
 1087                          */
 1088 
 1089                         /* This appears to be broken on 80C04.AE */
 1090 /*                      ifp->if_collisions +=
 1091                             (txstatus >> SEEQ_TXSTAT_COLLISIONS_SHIFT)
 1092                             & SEEQ_TXSTAT_COLLISION_MASK;*/
 1093 
 1094                         /* Use the TX Collision register */
 1095                         ea_select_buffer(sc, SEEQ_BUFCODE_TX_COLLS);
 1096                         colls = bus_space_read_1(iot, ioh, SEEQ_BUFWIN);
 1097                         ifp->if_collisions += colls;
 1098                         break;
 1099                 }
 1100                 case SEEQ_8005:
 1101                         /* We known there was at least 1 collision */
 1102                         ifp->if_collisions++;
 1103                         break;
 1104                 }
 1105         } else if (txstatus & SEEQ_TXSTAT_COLLISION16) {
 1106                 printf("seeq_intr: col16 %x\n", txstatus);
 1107                 ifp->if_collisions += 16;
 1108                 ifp->if_oerrors++;
 1109         }
 1110 
 1111         /* Have we completed transmission on the packet ? */
 1112         if (txstatus & SEEQ_PKTSTAT_DONE) {
 1113                 /* Clear watchdog timer. */
 1114                 ifp->if_timer = 0;
 1115                 ifp->if_flags &= ~IFF_OACTIVE;
 1116 
 1117                 /* Update stats */
 1118                 ifp->if_opackets++;
 1119 
 1120                 /* Tx next packet */
 1121 
 1122                 eatxpacket(sc);
 1123         }
 1124 }
 1125 
 1126 void
 1127 ea_rxint(struct seeq8005_softc *sc)
 1128 {
 1129         bus_space_tag_t iot = sc->sc_iot;
 1130         bus_space_handle_t ioh = sc->sc_ioh;
 1131         u_int addr;
 1132         int len;
 1133         int ctrl;
 1134         int ptr;
 1135         int status;
 1136         u_int8_t rxhdr[4];
 1137         struct ifnet *ifp;
 1138 
 1139         ifp = &sc->sc_ethercom.ec_if;
 1140 
 1141 
 1142         /* We start from the last rx pointer position */
 1143         addr = sc->sc_rx_ptr;
 1144         sc->sc_config2 &= ~SEEQ_CFG2_OUTPUT;
 1145         SEEQ_WRITE16(sc, iot, ioh, SEEQ_CONFIG2, sc->sc_config2);
 1146 
 1147         do {
 1148                 /* Read rx header */
 1149                 ea_readbuf(sc, rxhdr, addr, 4);
 1150 
 1151                 /* Split the packet header */
 1152                 ptr = (rxhdr[0] << 8) | rxhdr[1];
 1153                 ctrl = rxhdr[2];
 1154                 status = rxhdr[3];
 1155 
 1156                 DPRINTF(SEEQ_DEBUG_RX,
 1157                     ("addr=%04x ptr=%04x ctrl=%02x status=%02x\n",
 1158                         addr, ptr, ctrl, status));
 1159 
 1160                 /* Zero packet ptr ? then must be null header so exit */
 1161                 if (ptr == 0) break;
 1162 
 1163                 /* Sanity-check the next-packet pointer and flags. */
 1164                 if (__predict_false(ptr < sc->sc_tx_bufsize ||
 1165                     (ctrl & SEEQ_PKTCMD_TX))) {
 1166                         ++ifp->if_ierrors;
 1167                         log(LOG_ERR,
 1168                             "%s: Rx chain corrupt at %04x (ptr = %04x)\n",
 1169                             device_xname(&sc->sc_dev), addr, ptr);
 1170                         ea_init(ifp);
 1171                         return;
 1172                 }
 1173 
 1174                 /* Get packet length */
 1175                 len = (ptr - addr) - 4;
 1176 
 1177                 if (len < 0)
 1178                         len += sc->sc_rx_bufsize;
 1179                 DPRINTF(SEEQ_DEBUG_RX, ("len=%04x\n", len));
 1180 
 1181                 /* Has the packet rx completed ? if not then exit */
 1182                 if ((status & SEEQ_PKTSTAT_DONE) == 0)
 1183                         break;
 1184 
 1185                 /*
 1186                  * Did we have any errors? then note error and go to
 1187                  * next packet
 1188                  */
 1189                 if (__predict_false(status &
 1190                         (SEEQ_RXSTAT_CRC_ERROR | SEEQ_RXSTAT_DRIBBLE_ERROR |
 1191                          SEEQ_RXSTAT_SHORT_FRAME))) {
 1192                         ++ifp->if_ierrors;
 1193                         log(LOG_WARNING,
 1194                             "%s: rx packet error at %04x (err=%02x)\n",
 1195                             device_xname(&sc->sc_dev), addr, status & 0x0f);
 1196                         /* XXX shouldn't need to reset if it's genuine. */
 1197                         ea_init(ifp);
 1198                         return;
 1199                 }
 1200                 /*
 1201                  * Is the packet too big?  We allow slightly oversize packets
 1202                  * for vlan(4) and tcpdump purposes, but the rest of the world
 1203                  * wants incoming packets in a single mbuf cluster.
 1204                  */
 1205                 if (__predict_false(len > MCLBYTES)) {
 1206                         ++ifp->if_ierrors;
 1207                         log(LOG_ERR,
 1208                             "%s: rx packet size error at %04x (len=%d)\n",
 1209                             device_xname(&sc->sc_dev), addr, len);
 1210                         sc->sc_config2 |= SEEQ_CFG2_OUTPUT;
 1211                         SEEQ_WRITE16(sc, iot, ioh, SEEQ_CONFIG2,
 1212                                           sc->sc_config2);
 1213                         ea_init(ifp);
 1214                         return;
 1215                 }
 1216 
 1217                 ifp->if_ipackets++;
 1218                 /* Pass data up to upper levels. */
 1219                 ea_read(sc, addr + 4, len);
 1220 
 1221                 addr = ptr;
 1222         } while (len != 0);
 1223 
 1224         sc->sc_config2 |= SEEQ_CFG2_OUTPUT;
 1225         SEEQ_WRITE16(sc, iot, ioh, SEEQ_CONFIG2, sc->sc_config2);
 1226 
 1227         DPRINTF(SEEQ_DEBUG_RX, ("new rx ptr=%04x\n", addr));
 1228 
 1229         /* Store new rx pointer */
 1230         sc->sc_rx_ptr = addr;
 1231         SEEQ_WRITE16(sc, iot, ioh, SEEQ_RX_END, sc->sc_rx_ptr >> 8);
 1232 
 1233         /* Make sure the receiver is on */
 1234         SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND,
 1235                           sc->sc_command | SEEQ_CMD_RX_ON);
 1236 }
 1237 
 1238 
 1239 /*
 1240  * Pass a packet up to the higher levels.
 1241  */
 1242 
 1243 static void
 1244 ea_read(struct seeq8005_softc *sc, int addr, int len)
 1245 {
 1246         struct mbuf *m;
 1247         struct ifnet *ifp;
 1248 
 1249         ifp = &sc->sc_ethercom.ec_if;
 1250 
 1251         /* Pull packet off interface. */
 1252         m = ea_get(sc, addr, len, ifp);
 1253         if (m == 0)
 1254                 return;
 1255 
 1256 #if NBPFILTER > 0
 1257         /*
 1258          * Check if there's a BPF listener on this interface.
 1259          * If so, hand off the raw packet to bpf.
 1260          */
 1261         if (ifp->if_bpf)
 1262                 bpf_mtap(ifp->if_bpf, m);
 1263 #endif
 1264 
 1265         (*ifp->if_input)(ifp, m);
 1266 }
 1267 
 1268 /*
 1269  * Pull read data off a interface.  Len is length of data, with local net
 1270  * header stripped.  We copy the data into mbufs.  When full cluster sized
 1271  * units are present we copy into clusters.
 1272  */
 1273 
 1274 struct mbuf *
 1275 ea_get(struct seeq8005_softc *sc, int addr, int totlen, struct ifnet *ifp)
 1276 {
 1277         struct mbuf *top, **mp, *m;
 1278         int len;
 1279         u_int cp, epkt;
 1280 
 1281         cp = addr;
 1282         epkt = cp + totlen;
 1283 
 1284         MGETHDR(m, M_DONTWAIT, MT_DATA);
 1285         if (m == 0)
 1286                 return 0;
 1287         m->m_pkthdr.rcvif = ifp;
 1288         m->m_pkthdr.len = totlen;
 1289         m->m_len = MHLEN;
 1290         top = 0;
 1291         mp = &top;
 1292 
 1293         while (totlen > 0) {
 1294                 if (top) {
 1295                         MGET(m, M_DONTWAIT, MT_DATA);
 1296                         if (m == 0) {
 1297                                 m_freem(top);
 1298                                 return 0;
 1299                         }
 1300                         m->m_len = MLEN;
 1301                 }
 1302                 len = min(totlen, epkt - cp);
 1303                 if (len >= MINCLSIZE) {
 1304                         MCLGET(m, M_DONTWAIT);
 1305                         if (m->m_flags & M_EXT)
 1306                                 m->m_len = len = min(len, MCLBYTES);
 1307                         else
 1308                                 len = m->m_len;
 1309                 } else {
 1310                         /*
 1311                          * Place initial small packet/header at end of mbuf.
 1312                          */
 1313                         if (len < m->m_len) {
 1314                                 if (top == 0 && len + max_linkhdr <= m->m_len)
 1315                                         m->m_data += max_linkhdr;
 1316                                 m->m_len = len;
 1317                         } else
 1318                                 len = m->m_len;
 1319                 }
 1320                 if (top == 0) {
 1321                         /* Make sure the payload is aligned */
 1322                         char *newdata = (char *)
 1323                             ALIGN((char*)m->m_data + 
 1324                                 sizeof(struct ether_header)) -
 1325                             sizeof(struct ether_header);
 1326                         len -= newdata - m->m_data;
 1327                         m->m_len = len;
 1328                         m->m_data = newdata;
 1329                 }
 1330                 ea_readbuf(sc, mtod(m, u_char *),
 1331                     cp < SEEQ_MAX_BUFFER_SIZE ? cp : cp - sc->sc_rx_bufsize,
 1332                     len);
 1333                 cp += len;
 1334                 *mp = m;
 1335                 mp = &m->m_next;
 1336                 totlen -= len;
 1337                 if (cp == epkt)
 1338                         cp = addr;
 1339         }
 1340 
 1341         return top;
 1342 }
 1343 
 1344 /*
 1345  * Process an ioctl request.  Mostly boilerplate.
 1346  */
 1347 static int
 1348 ea_ioctl(struct ifnet *ifp, u_long cmd, void *data)
 1349 {
 1350         struct seeq8005_softc *sc = ifp->if_softc;
 1351         int s, error = 0;
 1352 
 1353         s = splnet();
 1354         switch (cmd) {
 1355 
 1356         default:
 1357                 error = ether_ioctl(ifp, cmd, data);
 1358                 if (error == ENETRESET) {
 1359                         /*
 1360                          * Multicast list has changed; set the hardware filter
 1361                          * accordingly.
 1362                          */
 1363                         if (ifp->if_flags & IFF_RUNNING)
 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             device_xname(&sc->sc_dev),
 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: b59d801c4af853cf764991d1aa3edc46


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