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

Cache object: 7307c7d74459fe71d7d0155b6e410cbf


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