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/dp83932.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: dp83932.c,v 1.27 2008/08/23 15:46:47 tsutsui Exp $     */
    2 
    3 /*-
    4  * Copyright (c) 2001 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Jason R. Thorpe.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 /*
   33  * Device driver for the National Semiconductor DP83932
   34  * Systems-Oriented Network Interface Controller (SONIC).
   35  */
   36 
   37 #include <sys/cdefs.h>
   38 __KERNEL_RCSID(0, "$NetBSD: dp83932.c,v 1.27 2008/08/23 15:46:47 tsutsui Exp $");
   39 
   40 #include "bpfilter.h"
   41 
   42 #include <sys/param.h>
   43 #include <sys/systm.h>
   44 #include <sys/mbuf.h>
   45 #include <sys/malloc.h>
   46 #include <sys/kernel.h>
   47 #include <sys/socket.h>
   48 #include <sys/ioctl.h>
   49 #include <sys/errno.h>
   50 #include <sys/device.h>
   51 
   52 #include <uvm/uvm_extern.h>
   53 
   54 #include <net/if.h>
   55 #include <net/if_dl.h>
   56 #include <net/if_ether.h>
   57 
   58 #if NBPFILTER > 0
   59 #include <net/bpf.h>
   60 #endif
   61 
   62 #include <sys/bus.h>
   63 #include <sys/intr.h>
   64 
   65 #include <dev/ic/dp83932reg.h>
   66 #include <dev/ic/dp83932var.h>
   67 
   68 void    sonic_start(struct ifnet *);
   69 void    sonic_watchdog(struct ifnet *);
   70 int     sonic_ioctl(struct ifnet *, u_long, void *);
   71 int     sonic_init(struct ifnet *);
   72 void    sonic_stop(struct ifnet *, int);
   73 
   74 void    sonic_shutdown(void *);
   75 
   76 void    sonic_reset(struct sonic_softc *);
   77 void    sonic_rxdrain(struct sonic_softc *);
   78 int     sonic_add_rxbuf(struct sonic_softc *, int);
   79 void    sonic_set_filter(struct sonic_softc *);
   80 
   81 uint16_t sonic_txintr(struct sonic_softc *);
   82 void    sonic_rxintr(struct sonic_softc *);
   83 
   84 int     sonic_copy_small = 0;
   85 
   86 #define ETHER_PAD_LEN (ETHER_MIN_LEN - ETHER_CRC_LEN)
   87 
   88 /*
   89  * sonic_attach:
   90  *
   91  *      Attach a SONIC interface to the system.
   92  */
   93 void
   94 sonic_attach(struct sonic_softc *sc, const uint8_t *enaddr)
   95 {
   96         struct ifnet *ifp = &sc->sc_ethercom.ec_if;
   97         int i, rseg, error;
   98         bus_dma_segment_t seg;
   99         size_t cdatasize;
  100         uint8_t *nullbuf;
  101 
  102         /*
  103          * Allocate the control data structures, and create and load the
  104          * DMA map for it.
  105          */
  106         if (sc->sc_32bit)
  107                 cdatasize = sizeof(struct sonic_control_data32);
  108         else
  109                 cdatasize = sizeof(struct sonic_control_data16);
  110 
  111         if ((error = bus_dmamem_alloc(sc->sc_dmat, cdatasize + ETHER_PAD_LEN,
  112              PAGE_SIZE, (64 * 1024), &seg, 1, &rseg,
  113              BUS_DMA_NOWAIT)) != 0) {
  114                 aprint_error_dev(sc->sc_dev,
  115                     "unable to allocate control data, error = %d\n", error);
  116                 goto fail_0;
  117         }
  118 
  119         if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
  120             cdatasize + ETHER_PAD_LEN, (void **) &sc->sc_cdata16,
  121             BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
  122                 aprint_error_dev(sc->sc_dev,
  123                     "unable to map control data, error = %d\n", error);
  124                 goto fail_1;
  125         }
  126         nullbuf = (uint8_t *)sc->sc_cdata16 + cdatasize;
  127         memset(nullbuf, 0, ETHER_PAD_LEN);
  128 
  129         if ((error = bus_dmamap_create(sc->sc_dmat,
  130              cdatasize, 1, cdatasize, 0, BUS_DMA_NOWAIT,
  131              &sc->sc_cddmamap)) != 0) {
  132                 aprint_error_dev(sc->sc_dev,
  133                     "unable to create control data DMA map, error = %d\n",
  134                     error);
  135                 goto fail_2;
  136         }
  137 
  138         if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap,
  139              sc->sc_cdata16, cdatasize, NULL, BUS_DMA_NOWAIT)) != 0) {
  140                 aprint_error_dev(sc->sc_dev,
  141                     "unable to load control data DMA map, error = %d\n", error);
  142                 goto fail_3;
  143         }
  144 
  145         /*
  146          * Create the transmit buffer DMA maps.
  147          */
  148         for (i = 0; i < SONIC_NTXDESC; i++) {
  149                 if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
  150                      SONIC_NTXFRAGS, MCLBYTES, 0, BUS_DMA_NOWAIT,
  151                      &sc->sc_txsoft[i].ds_dmamap)) != 0) {
  152                         aprint_error_dev(sc->sc_dev,
  153                             "unable to create tx DMA map %d, error = %d\n",
  154                             i, error);
  155                         goto fail_4;
  156                 }
  157         }
  158 
  159         /*
  160          * Create the receive buffer DMA maps.
  161          */
  162         for (i = 0; i < SONIC_NRXDESC; i++) {
  163                 if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
  164                      MCLBYTES, 0, BUS_DMA_NOWAIT,
  165                      &sc->sc_rxsoft[i].ds_dmamap)) != 0) {
  166                         aprint_error_dev(sc->sc_dev,
  167                             "unable to create rx DMA map %d, error = %d\n",
  168                             i, error);
  169                         goto fail_5;
  170                 }
  171                 sc->sc_rxsoft[i].ds_mbuf = NULL;
  172         }
  173 
  174         /*
  175          * create and map the pad buffer
  176          */
  177         if ((error = bus_dmamap_create(sc->sc_dmat, ETHER_PAD_LEN, 1,
  178             ETHER_PAD_LEN, 0, BUS_DMA_NOWAIT, &sc->sc_nulldmamap)) != 0) {
  179                 aprint_error_dev(sc->sc_dev,
  180                     "unable to create pad buffer DMA map, error = %d\n", error);
  181                 goto fail_5;
  182         }
  183 
  184         if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_nulldmamap,
  185             nullbuf, ETHER_PAD_LEN, NULL, BUS_DMA_NOWAIT)) != 0) {
  186                 aprint_error_dev(sc->sc_dev,
  187                     "unable to load pad buffer DMA map, error = %d\n", error);
  188                 goto fail_6;
  189         }
  190         bus_dmamap_sync(sc->sc_dmat, sc->sc_nulldmamap, 0, ETHER_PAD_LEN,
  191             BUS_DMASYNC_PREWRITE);
  192 
  193         /*
  194          * Reset the chip to a known state.
  195          */
  196         sonic_reset(sc);
  197 
  198         aprint_normal_dev(sc->sc_dev, "Ethernet address %s\n",
  199             ether_sprintf(enaddr));
  200 
  201         strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
  202         ifp->if_softc = sc;
  203         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
  204         ifp->if_ioctl = sonic_ioctl;
  205         ifp->if_start = sonic_start;
  206         ifp->if_watchdog = sonic_watchdog;
  207         ifp->if_init = sonic_init;
  208         ifp->if_stop = sonic_stop;
  209         IFQ_SET_READY(&ifp->if_snd);
  210 
  211         /*
  212          * We can support 802.1Q VLAN-sized frames.
  213          */
  214         sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;
  215 
  216         /*
  217          * Attach the interface.
  218          */
  219         if_attach(ifp);
  220         ether_ifattach(ifp, enaddr);
  221 
  222         /*
  223          * Make sure the interface is shutdown during reboot.
  224          */
  225         sc->sc_sdhook = shutdownhook_establish(sonic_shutdown, sc);
  226         if (sc->sc_sdhook == NULL)
  227                 aprint_error_dev(sc->sc_dev,
  228                     "WARNING: unable to establish shutdown hook\n");
  229         return;
  230 
  231         /*
  232          * Free any resources we've allocated during the failed attach
  233          * attempt.  Do this in reverse order and fall through.
  234          */
  235  fail_6:
  236         bus_dmamap_destroy(sc->sc_dmat, sc->sc_nulldmamap);
  237  fail_5:
  238         for (i = 0; i < SONIC_NRXDESC; i++) {
  239                 if (sc->sc_rxsoft[i].ds_dmamap != NULL)
  240                         bus_dmamap_destroy(sc->sc_dmat,
  241                             sc->sc_rxsoft[i].ds_dmamap);
  242         }
  243  fail_4:
  244         for (i = 0; i < SONIC_NTXDESC; i++) {
  245                 if (sc->sc_txsoft[i].ds_dmamap != NULL)
  246                         bus_dmamap_destroy(sc->sc_dmat,
  247                             sc->sc_txsoft[i].ds_dmamap);
  248         }
  249         bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap);
  250  fail_3:
  251         bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap);
  252  fail_2:
  253         bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_cdata16, cdatasize);
  254  fail_1:
  255         bus_dmamem_free(sc->sc_dmat, &seg, rseg);
  256  fail_0:
  257         return;
  258 }
  259 
  260 /*
  261  * sonic_shutdown:
  262  *
  263  *      Make sure the interface is stopped at reboot.
  264  */
  265 void
  266 sonic_shutdown(void *arg)
  267 {
  268         struct sonic_softc *sc = arg;
  269 
  270         sonic_stop(&sc->sc_ethercom.ec_if, 1);
  271 }
  272 
  273 /*
  274  * sonic_start:         [ifnet interface function]
  275  *
  276  *      Start packet transmission on the interface.
  277  */
  278 void
  279 sonic_start(struct ifnet *ifp)
  280 {
  281         struct sonic_softc *sc = ifp->if_softc;
  282         struct mbuf *m0, *m;
  283         struct sonic_tda16 *tda16;
  284         struct sonic_tda32 *tda32;
  285         struct sonic_descsoft *ds;
  286         bus_dmamap_t dmamap;
  287         int error, olasttx, nexttx, opending, totlen, olseg;
  288         int seg = 0;    /* XXX: gcc */
  289 
  290         if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
  291                 return;
  292 
  293         /*
  294          * Remember the previous txpending and the current "last txdesc
  295          * used" index.
  296          */
  297         opending = sc->sc_txpending;
  298         olasttx = sc->sc_txlast;
  299 
  300         /*
  301          * Loop through the send queue, setting up transmit descriptors
  302          * until we drain the queue, or use up all available transmit
  303          * descriptors.  Leave one at the end for sanity's sake.
  304          */
  305         while (sc->sc_txpending < (SONIC_NTXDESC - 1)) {
  306                 /*
  307                  * Grab a packet off the queue.
  308                  */
  309                 IFQ_POLL(&ifp->if_snd, m0);
  310                 if (m0 == NULL)
  311                         break;
  312                 m = NULL;
  313 
  314                 /*
  315                  * Get the next available transmit descriptor.
  316                  */
  317                 nexttx = SONIC_NEXTTX(sc->sc_txlast);
  318                 ds = &sc->sc_txsoft[nexttx];
  319                 dmamap = ds->ds_dmamap;
  320 
  321                 /*
  322                  * Load the DMA map.  If this fails, the packet either
  323                  * didn't fit in the allotted number of frags, or we were
  324                  * short on resources.  In this case, we'll copy and try
  325                  * again.
  326                  */
  327                 if ((error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0,
  328                     BUS_DMA_WRITE|BUS_DMA_NOWAIT)) != 0 ||
  329                     (m0->m_pkthdr.len < ETHER_PAD_LEN &&
  330                     dmamap->dm_nsegs == SONIC_NTXFRAGS)) {
  331                         if (error == 0)
  332                                 bus_dmamap_unload(sc->sc_dmat, dmamap);
  333                         MGETHDR(m, M_DONTWAIT, MT_DATA);
  334                         if (m == NULL) {
  335                                 printf("%s: unable to allocate Tx mbuf\n",
  336                                     device_xname(sc->sc_dev));
  337                                 break;
  338                         }
  339                         if (m0->m_pkthdr.len > MHLEN) {
  340                                 MCLGET(m, M_DONTWAIT);
  341                                 if ((m->m_flags & M_EXT) == 0) {
  342                                         printf("%s: unable to allocate Tx "
  343                                             "cluster\n",
  344                                             device_xname(sc->sc_dev));
  345                                         m_freem(m);
  346                                         break;
  347                                 }
  348                         }
  349                         m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, void *));
  350                         m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len;
  351                         error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap,
  352                             m, BUS_DMA_WRITE|BUS_DMA_NOWAIT);
  353                         if (error) {
  354                                 printf("%s: unable to load Tx buffer, "
  355                                     "error = %d\n", device_xname(sc->sc_dev),
  356                                     error);
  357                                 m_freem(m);
  358                                 break;
  359                         }
  360                 }
  361                 IFQ_DEQUEUE(&ifp->if_snd, m0);
  362                 if (m != NULL) {
  363                         m_freem(m0);
  364                         m0 = m;
  365                 }
  366 
  367                 /*
  368                  * WE ARE NOW COMMITTED TO TRANSMITTING THE PACKET.
  369                  */
  370 
  371                 /* Sync the DMA map. */
  372                 bus_dmamap_sync(sc->sc_dmat, dmamap, 0, dmamap->dm_mapsize,
  373                     BUS_DMASYNC_PREWRITE);
  374 
  375                 /*
  376                  * Store a pointer to the packet so we can free it later.
  377                  */
  378                 ds->ds_mbuf = m0;
  379 
  380                 /*
  381                  * Initialize the transmit descriptor.
  382                  */
  383                 totlen = 0;
  384                 if (sc->sc_32bit) {
  385                         tda32 = &sc->sc_tda32[nexttx];
  386                         for (seg = 0; seg < dmamap->dm_nsegs; seg++) {
  387                                 tda32->tda_frags[seg].frag_ptr1 =
  388                                     htosonic32(sc,
  389                                     (dmamap->dm_segs[seg].ds_addr >> 16) &
  390                                     0xffff);
  391                                 tda32->tda_frags[seg].frag_ptr0 =
  392                                     htosonic32(sc,
  393                                     dmamap->dm_segs[seg].ds_addr & 0xffff);
  394                                 tda32->tda_frags[seg].frag_size =
  395                                     htosonic32(sc, dmamap->dm_segs[seg].ds_len);
  396                                 totlen += dmamap->dm_segs[seg].ds_len;
  397                         }
  398                         if (totlen < ETHER_PAD_LEN) {
  399                                 tda32->tda_frags[seg].frag_ptr1 =
  400                                     htosonic32(sc,
  401                                     (sc->sc_nulldma >> 16) & 0xffff);
  402                                 tda32->tda_frags[seg].frag_ptr0 =
  403                                     htosonic32(sc, sc->sc_nulldma & 0xffff);
  404                                 tda32->tda_frags[seg].frag_size =
  405                                     htosonic32(sc, ETHER_PAD_LEN - totlen);
  406                                 totlen = ETHER_PAD_LEN;
  407                                 seg++;
  408                         }
  409 
  410                         tda32->tda_status = 0;
  411                         tda32->tda_pktconfig = 0;
  412                         tda32->tda_pktsize = htosonic32(sc, totlen);
  413                         tda32->tda_fragcnt = htosonic32(sc, seg);
  414 
  415                         /* Link it up. */
  416                         tda32->tda_frags[seg].frag_ptr0 =
  417                             htosonic32(sc, SONIC_CDTXADDR32(sc,
  418                             SONIC_NEXTTX(nexttx)) & 0xffff);
  419 
  420                         /* Sync the Tx descriptor. */
  421                         SONIC_CDTXSYNC32(sc, nexttx,
  422                             BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  423                 } else {
  424                         tda16 = &sc->sc_tda16[nexttx];
  425                         for (seg = 0; seg < dmamap->dm_nsegs; seg++) {
  426                                 tda16->tda_frags[seg].frag_ptr1 =
  427                                     htosonic16(sc,
  428                                     (dmamap->dm_segs[seg].ds_addr >> 16) &
  429                                     0xffff);
  430                                 tda16->tda_frags[seg].frag_ptr0 =
  431                                     htosonic16(sc,
  432                                     dmamap->dm_segs[seg].ds_addr & 0xffff);
  433                                 tda16->tda_frags[seg].frag_size =
  434                                     htosonic16(sc, dmamap->dm_segs[seg].ds_len);
  435                                 totlen += dmamap->dm_segs[seg].ds_len;
  436                         }
  437                         if (totlen < ETHER_PAD_LEN) {
  438                                 tda16->tda_frags[seg].frag_ptr1 =
  439                                     htosonic16(sc,
  440                                     (sc->sc_nulldma >> 16) & 0xffff);
  441                                 tda16->tda_frags[seg].frag_ptr0 =
  442                                     htosonic16(sc, sc->sc_nulldma & 0xffff);
  443                                 tda16->tda_frags[seg].frag_size =
  444                                     htosonic16(sc, ETHER_PAD_LEN - totlen);
  445                                 totlen = ETHER_PAD_LEN;
  446                                 seg++;
  447                         }
  448 
  449                         tda16->tda_status = 0;
  450                         tda16->tda_pktconfig = 0;
  451                         tda16->tda_pktsize = htosonic16(sc, totlen);
  452                         tda16->tda_fragcnt = htosonic16(sc, seg);
  453 
  454                         /* Link it up. */
  455                         tda16->tda_frags[seg].frag_ptr0 =
  456                             htosonic16(sc, SONIC_CDTXADDR16(sc,
  457                             SONIC_NEXTTX(nexttx)) & 0xffff);
  458 
  459                         /* Sync the Tx descriptor. */
  460                         SONIC_CDTXSYNC16(sc, nexttx,
  461                             BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  462                 }
  463 
  464                 /* Advance the Tx pointer. */
  465                 sc->sc_txpending++;
  466                 sc->sc_txlast = nexttx;
  467 
  468 #if NBPFILTER > 0
  469                 /*
  470                  * Pass the packet to any BPF listeners.
  471                  */
  472                 if (ifp->if_bpf)
  473                         bpf_mtap(ifp->if_bpf, m0);
  474 #endif
  475         }
  476 
  477         if (sc->sc_txpending == (SONIC_NTXDESC - 1)) {
  478                 /* No more slots left; notify upper layer. */
  479                 ifp->if_flags |= IFF_OACTIVE;
  480         }
  481 
  482         if (sc->sc_txpending != opending) {
  483                 /*
  484                  * We enqueued packets.  If the transmitter was idle,
  485                  * reset the txdirty pointer.
  486                  */
  487                 if (opending == 0)
  488                         sc->sc_txdirty = SONIC_NEXTTX(olasttx);
  489 
  490                 /*
  491                  * Stop the SONIC on the last packet we've set up,
  492                  * and clear end-of-list on the descriptor previous
  493                  * to our new chain.
  494                  *
  495                  * NOTE: our `seg' variable should still be valid!
  496                  */
  497                 if (sc->sc_32bit) {
  498                         olseg =
  499                             sonic32toh(sc, sc->sc_tda32[olasttx].tda_fragcnt);
  500                         sc->sc_tda32[sc->sc_txlast].tda_frags[seg].frag_ptr0 |=
  501                             htosonic32(sc, TDA_LINK_EOL);
  502                         SONIC_CDTXSYNC32(sc, sc->sc_txlast,
  503                             BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  504                         sc->sc_tda32[olasttx].tda_frags[olseg].frag_ptr0 &=
  505                             htosonic32(sc, ~TDA_LINK_EOL);
  506                         SONIC_CDTXSYNC32(sc, olasttx,
  507                             BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  508                 } else {
  509                         olseg =
  510                             sonic16toh(sc, sc->sc_tda16[olasttx].tda_fragcnt);
  511                         sc->sc_tda16[sc->sc_txlast].tda_frags[seg].frag_ptr0 |=
  512                             htosonic16(sc, TDA_LINK_EOL);
  513                         SONIC_CDTXSYNC16(sc, sc->sc_txlast,
  514                             BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  515                         sc->sc_tda16[olasttx].tda_frags[olseg].frag_ptr0 &=
  516                             htosonic16(sc, ~TDA_LINK_EOL);
  517                         SONIC_CDTXSYNC16(sc, olasttx,
  518                             BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  519                 }
  520 
  521                 /* Start the transmitter. */
  522                 CSR_WRITE(sc, SONIC_CR, CR_TXP);
  523 
  524                 /* Set a watchdog timer in case the chip flakes out. */
  525                 ifp->if_timer = 5;
  526         }
  527 }
  528 
  529 /*
  530  * sonic_watchdog:      [ifnet interface function]
  531  *
  532  *      Watchdog timer handler.
  533  */
  534 void
  535 sonic_watchdog(struct ifnet *ifp)
  536 {
  537         struct sonic_softc *sc = ifp->if_softc;
  538 
  539         printf("%s: device timeout\n", device_xname(sc->sc_dev));
  540         ifp->if_oerrors++;
  541 
  542         (void)sonic_init(ifp);
  543 }
  544 
  545 /*
  546  * sonic_ioctl:         [ifnet interface function]
  547  *
  548  *      Handle control requests from the operator.
  549  */
  550 int
  551 sonic_ioctl(struct ifnet *ifp, u_long cmd, void *data)
  552 {
  553         int s, error;
  554 
  555         s = splnet();
  556 
  557         error = ether_ioctl(ifp, cmd, data);
  558         if (error == ENETRESET) {
  559                 /*
  560                  * Multicast list has changed; set the hardware
  561                  * filter accordingly.
  562                  */
  563                 if (ifp->if_flags & IFF_RUNNING)
  564                         (void)sonic_init(ifp);
  565                 error = 0;
  566         }
  567 
  568         splx(s);
  569         return error;
  570 }
  571 
  572 /*
  573  * sonic_intr:
  574  *
  575  *      Interrupt service routine.
  576  */
  577 int
  578 sonic_intr(void *arg)
  579 {
  580         struct sonic_softc *sc = arg;
  581         struct ifnet *ifp = &sc->sc_ethercom.ec_if;
  582         uint16_t isr;
  583         int handled = 0, wantinit;
  584 
  585         for (wantinit = 0; wantinit == 0;) {
  586                 isr = CSR_READ(sc, SONIC_ISR) & sc->sc_imr;
  587                 if (isr == 0)
  588                         break;
  589                 CSR_WRITE(sc, SONIC_ISR, isr);  /* ACK */
  590 
  591                 handled = 1;
  592 
  593                 if (isr & IMR_PRX)
  594                         sonic_rxintr(sc);
  595 
  596                 if (isr & (IMR_PTX|IMR_TXER)) {
  597                         if (sonic_txintr(sc) & TCR_FU) {
  598                                 printf("%s: transmit FIFO underrun\n",
  599                                     device_xname(sc->sc_dev));
  600                                 wantinit = 1;
  601                         }
  602                 }
  603 
  604                 if (isr & (IMR_RFO|IMR_RBA|IMR_RBE|IMR_RDE)) {
  605 #define PRINTERR(bit, str)                                              \
  606                         if (isr & (bit))                                \
  607                                 printf("%s: %s\n",device_xname(sc->sc_dev), str)
  608                         PRINTERR(IMR_RFO, "receive FIFO overrun");
  609                         PRINTERR(IMR_RBA, "receive buffer exceeded");
  610                         PRINTERR(IMR_RBE, "receive buffers exhausted");
  611                         PRINTERR(IMR_RDE, "receive descriptors exhausted");
  612                         wantinit = 1;
  613                 }
  614         }
  615 
  616         if (handled) {
  617                 if (wantinit)
  618                         (void)sonic_init(ifp);
  619                 sonic_start(ifp);
  620         }
  621 
  622         return handled;
  623 }
  624 
  625 /*
  626  * sonic_txintr:
  627  *
  628  *      Helper; handle transmit complete interrupts.
  629  */
  630 uint16_t
  631 sonic_txintr(struct sonic_softc *sc)
  632 {
  633         struct ifnet *ifp = &sc->sc_ethercom.ec_if;
  634         struct sonic_descsoft *ds;
  635         struct sonic_tda32 *tda32;
  636         struct sonic_tda16 *tda16;
  637         uint16_t status, totstat = 0;
  638         int i;
  639 
  640         ifp->if_flags &= ~IFF_OACTIVE;
  641 
  642         for (i = sc->sc_txdirty; sc->sc_txpending != 0;
  643              i = SONIC_NEXTTX(i), sc->sc_txpending--) {
  644                 ds = &sc->sc_txsoft[i];
  645 
  646                 if (sc->sc_32bit) {
  647                         SONIC_CDTXSYNC32(sc, i,
  648                             BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
  649                         tda32 = &sc->sc_tda32[i];
  650                         status = sonic32toh(sc, tda32->tda_status);
  651                         SONIC_CDTXSYNC32(sc, i, BUS_DMASYNC_PREREAD);
  652                 } else {
  653                         SONIC_CDTXSYNC16(sc, i,
  654                             BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
  655                         tda16 = &sc->sc_tda16[i];
  656                         status = sonic16toh(sc, tda16->tda_status);
  657                         SONIC_CDTXSYNC16(sc, i, BUS_DMASYNC_PREREAD);
  658                 }
  659 
  660                 if ((status & ~(TCR_EXDIS|TCR_CRCI|TCR_POWC|TCR_PINT)) == 0)
  661                         break;
  662 
  663                 totstat |= status;
  664 
  665                 bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0,
  666                     ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
  667                 bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap);
  668                 m_freem(ds->ds_mbuf);
  669                 ds->ds_mbuf = NULL;
  670 
  671                 /*
  672                  * Check for errors and collisions.
  673                  */
  674                 if (status & TCR_PTX)
  675                         ifp->if_opackets++;
  676                 else
  677                         ifp->if_oerrors++;
  678                 ifp->if_collisions += TDA_STATUS_NCOL(status);
  679         }
  680 
  681         /* Update the dirty transmit buffer pointer. */
  682         sc->sc_txdirty = i;
  683 
  684         /*
  685          * Cancel the watchdog timer if there are no pending
  686          * transmissions.
  687          */
  688         if (sc->sc_txpending == 0)
  689                 ifp->if_timer = 0;
  690 
  691         return totstat;
  692 }
  693 
  694 /*
  695  * sonic_rxintr:
  696  *
  697  *      Helper; handle receive interrupts.
  698  */
  699 void
  700 sonic_rxintr(struct sonic_softc *sc)
  701 {
  702         struct ifnet *ifp = &sc->sc_ethercom.ec_if;
  703         struct sonic_descsoft *ds;
  704         struct sonic_rda32 *rda32;
  705         struct sonic_rda16 *rda16;
  706         struct mbuf *m;
  707         int i, len;
  708         uint16_t status, bytecount, ptr0, ptr1, seqno;
  709 
  710         for (i = sc->sc_rxptr;; i = SONIC_NEXTRX(i)) {
  711                 ds = &sc->sc_rxsoft[i];
  712 
  713                 if (sc->sc_32bit) {
  714                         SONIC_CDRXSYNC32(sc, i,
  715                             BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
  716                         rda32 = &sc->sc_rda32[i];
  717                         SONIC_CDRXSYNC32(sc, i, BUS_DMASYNC_PREREAD);
  718                         if (rda32->rda_inuse != 0)
  719                                 break;
  720                         status = sonic32toh(sc, rda32->rda_status);
  721                         bytecount = sonic32toh(sc, rda32->rda_bytecount);
  722                         ptr0 = sonic32toh(sc, rda32->rda_pkt_ptr0);
  723                         ptr1 = sonic32toh(sc, rda32->rda_pkt_ptr1);
  724                         seqno = sonic32toh(sc, rda32->rda_seqno);
  725                 } else {
  726                         SONIC_CDRXSYNC16(sc, i,
  727                             BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
  728                         rda16 = &sc->sc_rda16[i];
  729                         SONIC_CDRXSYNC16(sc, i, BUS_DMASYNC_PREREAD);
  730                         if (rda16->rda_inuse != 0)
  731                                 break;
  732                         status = sonic16toh(sc, rda16->rda_status);
  733                         bytecount = sonic16toh(sc, rda16->rda_bytecount);
  734                         ptr0 = sonic16toh(sc, rda16->rda_pkt_ptr0);
  735                         ptr1 = sonic16toh(sc, rda16->rda_pkt_ptr1);
  736                         seqno = sonic16toh(sc, rda16->rda_seqno);
  737                 }
  738 
  739                 /*
  740                  * Make absolutely sure this is the only packet
  741                  * in this receive buffer.  Our entire Rx buffer
  742                  * management scheme depends on this, and if the
  743                  * SONIC didn't follow our rule, it means we've
  744                  * misconfigured it.
  745                  */
  746                 KASSERT(status & RCR_LPKT);
  747 
  748                 /*
  749                  * Make sure the packet arrived OK.  If an error occurred,
  750                  * update stats and reset the descriptor.  The buffer will
  751                  * be reused the next time the descriptor comes up in the
  752                  * ring.
  753                  */
  754                 if ((status & RCR_PRX) == 0) {
  755                         if (status & RCR_FAER)
  756                                 printf("%s: Rx frame alignment error\n",
  757                                     device_xname(sc->sc_dev));
  758                         else if (status & RCR_CRCR)
  759                                 printf("%s: Rx CRC error\n",
  760                                     device_xname(sc->sc_dev));
  761                         ifp->if_ierrors++;
  762                         SONIC_INIT_RXDESC(sc, i);
  763                         continue;
  764                 }
  765 
  766                 bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0,
  767                     ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
  768 
  769                 /*
  770                  * The SONIC includes the CRC with every packet.
  771                  */
  772                 len = bytecount - ETHER_CRC_LEN;
  773 
  774                 /*
  775                  * Ok, if the chip is in 32-bit mode, then receive
  776                  * buffers must be aligned to 32-bit boundaries,
  777                  * which means the payload is misaligned.  In this
  778                  * case, we must allocate a new mbuf, and copy the
  779                  * packet into it, scooted forward 2 bytes to ensure
  780                  * proper alignment.
  781                  *
  782                  * Note, in 16-bit mode, we can configure the SONIC
  783                  * to do what we want, and we have.
  784                  */
  785 #ifndef __NO_STRICT_ALIGNMENT
  786                 if (sc->sc_32bit) {
  787                         MGETHDR(m, M_DONTWAIT, MT_DATA);
  788                         if (m == NULL)
  789                                 goto dropit;
  790                         if (len > (MHLEN - 2)) {
  791                                 MCLGET(m, M_DONTWAIT);
  792                                 if ((m->m_flags & M_EXT) == 0)
  793                                         goto dropit;
  794                         }
  795                         m->m_data += 2;
  796                         /*
  797                          * Note that we use a cluster for incoming frames,
  798                          * so the buffer is virtually contiguous.
  799                          */
  800                         memcpy(mtod(m, void *), mtod(ds->ds_mbuf, void *),
  801                             len);
  802                         SONIC_INIT_RXDESC(sc, i);
  803                         bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0,
  804                             ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
  805                 } else
  806 #endif /* ! __NO_STRICT_ALIGNMENT */
  807                 /*
  808                  * If the packet is small enough to fit in a single
  809                  * header mbuf, allocate one and copy the data into
  810                  * it.  This greatly reduces memory consumption when
  811                  * we receive lots of small packets.
  812                  */
  813                 if (sonic_copy_small != 0 && len <= (MHLEN - 2)) {
  814                         MGETHDR(m, M_DONTWAIT, MT_DATA);
  815                         if (m == NULL)
  816                                 goto dropit;
  817                         m->m_data += 2;
  818                         /*
  819                          * Note that we use a cluster for incoming frames,
  820                          * so the buffer is virtually contiguous.
  821                          */
  822                         memcpy(mtod(m, void *), mtod(ds->ds_mbuf, void *),
  823                             len);
  824                         SONIC_INIT_RXDESC(sc, i);
  825                         bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0,
  826                             ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
  827                 } else {
  828                         m = ds->ds_mbuf;
  829                         if (sonic_add_rxbuf(sc, i) != 0) {
  830  dropit:
  831                                 ifp->if_ierrors++;
  832                                 SONIC_INIT_RXDESC(sc, i);
  833                                 bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0,
  834                                     ds->ds_dmamap->dm_mapsize,
  835                                     BUS_DMASYNC_PREREAD);
  836                                 continue;
  837                         }
  838                 }
  839 
  840                 ifp->if_ipackets++;
  841                 m->m_pkthdr.rcvif = ifp;
  842                 m->m_pkthdr.len = m->m_len = len;
  843 
  844 #if NBPFILTER > 0
  845                 /*
  846                  * Pass this up to any BPF listeners.
  847                  */
  848                 if (ifp->if_bpf)
  849                         bpf_mtap(ifp->if_bpf, m);
  850 #endif /* NBPFILTER > 0 */
  851 
  852                 /* Pass it on. */
  853                 (*ifp->if_input)(ifp, m);
  854         }
  855 
  856         /* Update the receive pointer. */
  857         sc->sc_rxptr = i;
  858         CSR_WRITE(sc, SONIC_RWR, SONIC_CDRRADDR(sc, SONIC_PREVRX(i)));
  859 }
  860 
  861 /*
  862  * sonic_reset:
  863  *
  864  *      Perform a soft reset on the SONIC.
  865  */
  866 void
  867 sonic_reset(struct sonic_softc *sc)
  868 {
  869 
  870         /* stop TX, RX and timer, and ensure RST is clear */
  871         CSR_WRITE(sc, SONIC_CR, CR_STP | CR_RXDIS | CR_HTX);
  872         delay(1000);
  873 
  874         CSR_WRITE(sc, SONIC_CR, CR_RST);
  875         delay(1000);
  876 
  877         /* clear all interrupts */
  878         CSR_WRITE(sc, SONIC_IMR, 0);
  879         CSR_WRITE(sc, SONIC_ISR, IMR_ALL);
  880 
  881         CSR_WRITE(sc, SONIC_CR, 0);
  882         delay(1000);
  883 }
  884 
  885 /*
  886  * sonic_init:          [ifnet interface function]
  887  *
  888  *      Initialize the interface.  Must be called at splnet().
  889  */
  890 int
  891 sonic_init(struct ifnet *ifp)
  892 {
  893         struct sonic_softc *sc = ifp->if_softc;
  894         struct sonic_descsoft *ds;
  895         int i, error = 0;
  896         uint16_t reg;
  897 
  898         /*
  899          * Cancel any pending I/O.
  900          */
  901         sonic_stop(ifp, 0);
  902 
  903         /*
  904          * Reset the SONIC to a known state.
  905          */
  906         sonic_reset(sc);
  907 
  908         /*
  909          * Bring the SONIC into reset state, and program the DCR.
  910          *
  911          * Note: We don't bother optimizing the transmit and receive
  912          * thresholds, here. TFT/RFT values should be set in MD attachments.
  913          */
  914         reg = sc->sc_dcr;
  915         if (sc->sc_32bit)
  916                 reg |= DCR_DW;
  917         CSR_WRITE(sc, SONIC_CR, CR_RST);
  918         CSR_WRITE(sc, SONIC_DCR, reg);
  919         CSR_WRITE(sc, SONIC_DCR2, sc->sc_dcr2);
  920         CSR_WRITE(sc, SONIC_CR, 0);
  921 
  922         /*
  923          * Initialize the transmit descriptors.
  924          */
  925         if (sc->sc_32bit) {
  926                 for (i = 0; i < SONIC_NTXDESC; i++) {
  927                         memset(&sc->sc_tda32[i], 0, sizeof(struct sonic_tda32));
  928                         SONIC_CDTXSYNC32(sc, i,
  929                             BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  930                 }
  931         } else {
  932                 for (i = 0; i < SONIC_NTXDESC; i++) {
  933                         memset(&sc->sc_tda16[i], 0, sizeof(struct sonic_tda16));
  934                         SONIC_CDTXSYNC16(sc, i,
  935                             BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  936                 }
  937         }
  938         sc->sc_txpending = 0;
  939         sc->sc_txdirty = 0;
  940         sc->sc_txlast = SONIC_NTXDESC - 1;
  941 
  942         /*
  943          * Initialize the receive descriptor ring.
  944          */
  945         for (i = 0; i < SONIC_NRXDESC; i++) {
  946                 ds = &sc->sc_rxsoft[i];
  947                 if (ds->ds_mbuf == NULL) {
  948                         if ((error = sonic_add_rxbuf(sc, i)) != 0) {
  949                                 printf("%s: unable to allocate or map Rx "
  950                                     "buffer %d, error = %d\n",
  951                                     device_xname(sc->sc_dev), i, error);
  952                                 /*
  953                                  * XXX Should attempt to run with fewer receive
  954                                  * XXX buffers instead of just failing.
  955                                  */
  956                                 sonic_rxdrain(sc);
  957                                 goto out;
  958                         }
  959                 } else
  960                         SONIC_INIT_RXDESC(sc, i);
  961         }
  962         sc->sc_rxptr = 0;
  963 
  964         /* Give the transmit ring to the SONIC. */
  965         CSR_WRITE(sc, SONIC_UTDAR, (SONIC_CDTXADDR(sc, 0) >> 16) & 0xffff);
  966         CSR_WRITE(sc, SONIC_CTDAR, SONIC_CDTXADDR(sc, 0) & 0xffff);
  967 
  968         /* Give the receive descriptor ring to the SONIC. */
  969         CSR_WRITE(sc, SONIC_URDAR, (SONIC_CDRXADDR(sc, 0) >> 16) & 0xffff);
  970         CSR_WRITE(sc, SONIC_CRDAR, SONIC_CDRXADDR(sc, 0) & 0xffff);
  971 
  972         /* Give the receive buffer ring to the SONIC. */
  973         CSR_WRITE(sc, SONIC_URRAR, (SONIC_CDRRADDR(sc, 0) >> 16) & 0xffff);
  974         CSR_WRITE(sc, SONIC_RSAR, SONIC_CDRRADDR(sc, 0) & 0xffff);
  975         if (sc->sc_32bit)
  976                 CSR_WRITE(sc, SONIC_REAR,
  977                     (SONIC_CDRRADDR(sc, SONIC_NRXDESC - 1) +
  978                     sizeof(struct sonic_rra32)) & 0xffff);
  979         else
  980                 CSR_WRITE(sc, SONIC_REAR,
  981                     (SONIC_CDRRADDR(sc, SONIC_NRXDESC - 1) +
  982                     sizeof(struct sonic_rra16)) & 0xffff);
  983         CSR_WRITE(sc, SONIC_RRR, SONIC_CDRRADDR(sc, 0) & 0xffff);
  984         CSR_WRITE(sc, SONIC_RWR, SONIC_CDRRADDR(sc, SONIC_NRXDESC - 1));
  985 
  986         /*
  987          * Set the End-Of-Buffer counter such that only one packet
  988          * will be placed into each buffer we provide.  Note we are
  989          * following the recommendation of section 3.4.4 of the manual
  990          * here, and have "lengthened" the receive buffers accordingly.
  991          */
  992         if (sc->sc_32bit)
  993                 CSR_WRITE(sc, SONIC_EOBC, (ETHER_MAX_LEN + 2) / 2);
  994         else
  995                 CSR_WRITE(sc, SONIC_EOBC, (ETHER_MAX_LEN / 2));
  996 
  997         /* Reset the receive sequence counter. */
  998         CSR_WRITE(sc, SONIC_RSC, 0);
  999 
 1000         /* Clear the tally registers. */
 1001         CSR_WRITE(sc, SONIC_CRCETC, 0xffff);
 1002         CSR_WRITE(sc, SONIC_FAET, 0xffff);
 1003         CSR_WRITE(sc, SONIC_MPT, 0xffff);
 1004 
 1005         /* Set the receive filter. */
 1006         sonic_set_filter(sc);
 1007 
 1008         /*
 1009          * Set the interrupt mask register.
 1010          */
 1011         sc->sc_imr = IMR_RFO | IMR_RBA | IMR_RBE | IMR_RDE |
 1012             IMR_TXER | IMR_PTX | IMR_PRX;
 1013         CSR_WRITE(sc, SONIC_IMR, sc->sc_imr);
 1014 
 1015         /*
 1016          * Start the receive process in motion.  Note, we don't
 1017          * start the transmit process until we actually try to
 1018          * transmit packets.
 1019          */
 1020         CSR_WRITE(sc, SONIC_CR, CR_RXEN | CR_RRRA);
 1021 
 1022         /*
 1023          * ...all done!
 1024          */
 1025         ifp->if_flags |= IFF_RUNNING;
 1026         ifp->if_flags &= ~IFF_OACTIVE;
 1027 
 1028  out:
 1029         if (error)
 1030                 printf("%s: interface not running\n", device_xname(sc->sc_dev));
 1031         return error;
 1032 }
 1033 
 1034 /*
 1035  * sonic_rxdrain:
 1036  *
 1037  *      Drain the receive queue.
 1038  */
 1039 void
 1040 sonic_rxdrain(struct sonic_softc *sc)
 1041 {
 1042         struct sonic_descsoft *ds;
 1043         int i;
 1044 
 1045         for (i = 0; i < SONIC_NRXDESC; i++) {
 1046                 ds = &sc->sc_rxsoft[i];
 1047                 if (ds->ds_mbuf != NULL) {
 1048                         bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap);
 1049                         m_freem(ds->ds_mbuf);
 1050                         ds->ds_mbuf = NULL;
 1051                 }
 1052         }
 1053 }
 1054 
 1055 /*
 1056  * sonic_stop:          [ifnet interface function]
 1057  *
 1058  *      Stop transmission on the interface.
 1059  */
 1060 void
 1061 sonic_stop(struct ifnet *ifp, int disable)
 1062 {
 1063         struct sonic_softc *sc = ifp->if_softc;
 1064         struct sonic_descsoft *ds;
 1065         int i;
 1066 
 1067         /*
 1068          * Disable interrupts.
 1069          */
 1070         CSR_WRITE(sc, SONIC_IMR, 0);
 1071 
 1072         /*
 1073          * Stop the transmitter, receiver, and timer.
 1074          */
 1075         CSR_WRITE(sc, SONIC_CR, CR_HTX|CR_RXDIS|CR_STP);
 1076         for (i = 0; i < 1000; i++) {
 1077                 if ((CSR_READ(sc, SONIC_CR) & (CR_TXP|CR_RXEN|CR_ST)) == 0)
 1078                         break;
 1079                 delay(2);
 1080         }
 1081         if ((CSR_READ(sc, SONIC_CR) & (CR_TXP|CR_RXEN|CR_ST)) != 0)
 1082                 printf("%s: SONIC failed to stop\n", device_xname(sc->sc_dev));
 1083 
 1084         /*
 1085          * Release any queued transmit buffers.
 1086          */
 1087         for (i = 0; i < SONIC_NTXDESC; i++) {
 1088                 ds = &sc->sc_txsoft[i];
 1089                 if (ds->ds_mbuf != NULL) {
 1090                         bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap);
 1091                         m_freem(ds->ds_mbuf);
 1092                         ds->ds_mbuf = NULL;
 1093                 }
 1094         }
 1095 
 1096         /*
 1097          * Mark the interface down and cancel the watchdog timer.
 1098          */
 1099         ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
 1100         ifp->if_timer = 0;
 1101 
 1102         if (disable)
 1103                 sonic_rxdrain(sc);
 1104 }
 1105 
 1106 /*
 1107  * sonic_add_rxbuf:
 1108  *
 1109  *      Add a receive buffer to the indicated descriptor.
 1110  */
 1111 int
 1112 sonic_add_rxbuf(struct sonic_softc *sc, int idx)
 1113 {
 1114         struct sonic_descsoft *ds = &sc->sc_rxsoft[idx];
 1115         struct mbuf *m;
 1116         int error;
 1117 
 1118         MGETHDR(m, M_DONTWAIT, MT_DATA);
 1119         if (m == NULL)
 1120                 return ENOBUFS;
 1121 
 1122         MCLGET(m, M_DONTWAIT);
 1123         if ((m->m_flags & M_EXT) == 0) {
 1124                 m_freem(m);
 1125                 return ENOBUFS;
 1126         }
 1127 
 1128         if (ds->ds_mbuf != NULL)
 1129                 bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap);
 1130 
 1131         ds->ds_mbuf = m;
 1132 
 1133         error = bus_dmamap_load(sc->sc_dmat, ds->ds_dmamap,
 1134             m->m_ext.ext_buf, m->m_ext.ext_size, NULL,
 1135             BUS_DMA_READ|BUS_DMA_NOWAIT);
 1136         if (error) {
 1137                 printf("%s: can't load rx DMA map %d, error = %d\n",
 1138                     device_xname(sc->sc_dev), idx, error);
 1139                 panic("sonic_add_rxbuf");       /* XXX */
 1140         }
 1141 
 1142         bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0,
 1143             ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
 1144 
 1145         SONIC_INIT_RXDESC(sc, idx);
 1146 
 1147         return 0;
 1148 }
 1149 
 1150 static void
 1151 sonic_set_camentry(struct sonic_softc *sc, int entry, const uint8_t *enaddr)
 1152 {
 1153 
 1154         if (sc->sc_32bit) {
 1155                 struct sonic_cda32 *cda = &sc->sc_cda32[entry];
 1156 
 1157                 cda->cda_entry = htosonic32(sc, entry);
 1158                 cda->cda_addr0 = htosonic32(sc, enaddr[0] | (enaddr[1] << 8));
 1159                 cda->cda_addr1 = htosonic32(sc, enaddr[2] | (enaddr[3] << 8));
 1160                 cda->cda_addr2 = htosonic32(sc, enaddr[4] | (enaddr[5] << 8));
 1161         } else {
 1162                 struct sonic_cda16 *cda = &sc->sc_cda16[entry];
 1163 
 1164                 cda->cda_entry = htosonic16(sc, entry);
 1165                 cda->cda_addr0 = htosonic16(sc, enaddr[0] | (enaddr[1] << 8));
 1166                 cda->cda_addr1 = htosonic16(sc, enaddr[2] | (enaddr[3] << 8));
 1167                 cda->cda_addr2 = htosonic16(sc, enaddr[4] | (enaddr[5] << 8));
 1168         }
 1169 }
 1170 
 1171 /*
 1172  * sonic_set_filter:
 1173  *
 1174  *      Set the SONIC receive filter.
 1175  */
 1176 void
 1177 sonic_set_filter(struct sonic_softc *sc)
 1178 {
 1179         struct ethercom *ec = &sc->sc_ethercom;
 1180         struct ifnet *ifp = &sc->sc_ethercom.ec_if;
 1181         struct ether_multi *enm;
 1182         struct ether_multistep step;
 1183         int i, entry = 0;
 1184         uint16_t camvalid = 0;
 1185         uint16_t rcr = 0;
 1186 
 1187         if (ifp->if_flags & IFF_BROADCAST)
 1188                 rcr |= RCR_BRD;
 1189 
 1190         if (ifp->if_flags & IFF_PROMISC) {
 1191                 rcr |= RCR_PRO;
 1192                 goto allmulti;
 1193         }
 1194 
 1195         /* Put our station address in the first CAM slot. */
 1196         sonic_set_camentry(sc, entry, CLLADDR(ifp->if_sadl));
 1197         camvalid |= (1U << entry);
 1198         entry++;
 1199 
 1200         /* Add the multicast addresses to the CAM. */
 1201         ETHER_FIRST_MULTI(step, ec, enm);
 1202         while (enm != NULL) {
 1203                 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
 1204                         /*
 1205                          * We must listen to a range of multicast addresses.
 1206                          * The only way to do this on the SONIC is to enable
 1207                          * reception of all multicast packets.
 1208                          */
 1209                         goto allmulti;
 1210                 }
 1211 
 1212                 if (entry == SONIC_NCAMENT) {
 1213                         /*
 1214                          * Out of CAM slots.  Have to enable reception
 1215                          * of all multicast addresses.
 1216                          */
 1217                         goto allmulti;
 1218                 }
 1219 
 1220                 sonic_set_camentry(sc, entry, enm->enm_addrlo);
 1221                 camvalid |= (1U << entry);
 1222                 entry++;
 1223 
 1224                 ETHER_NEXT_MULTI(step, enm);
 1225         }
 1226 
 1227         ifp->if_flags &= ~IFF_ALLMULTI;
 1228         goto setit;
 1229 
 1230  allmulti:
 1231         /* Use only the first CAM slot (station address). */
 1232         camvalid = 0x0001;
 1233         entry = 1;
 1234         rcr |= RCR_AMC;
 1235 
 1236  setit:
 1237         /* set mask for the CAM Enable register */
 1238         if (sc->sc_32bit) {
 1239                 if (entry == SONIC_NCAMENT)
 1240                         sc->sc_cdaenable32 = htosonic32(sc, camvalid);
 1241                 else
 1242                         sc->sc_cda32[entry].cda_entry =
 1243                             htosonic32(sc, camvalid);
 1244         } else {
 1245                 if (entry == SONIC_NCAMENT)
 1246                         sc->sc_cdaenable16 = htosonic16(sc, camvalid);
 1247                 else
 1248                         sc->sc_cda16[entry].cda_entry =
 1249                             htosonic16(sc, camvalid);
 1250         }
 1251 
 1252         /* Load the CAM. */
 1253         SONIC_CDCAMSYNC(sc, BUS_DMASYNC_PREWRITE);
 1254         CSR_WRITE(sc, SONIC_CDP, SONIC_CDCAMADDR(sc) & 0xffff);
 1255         CSR_WRITE(sc, SONIC_CDC, entry);
 1256         CSR_WRITE(sc, SONIC_CR, CR_LCAM);
 1257         for (i = 0; i < 10000; i++) {
 1258                 if ((CSR_READ(sc, SONIC_CR) & CR_LCAM) == 0)
 1259                         break;
 1260                 delay(2);
 1261         }
 1262         if (CSR_READ(sc, SONIC_CR) & CR_LCAM)
 1263                 printf("%s: CAM load failed\n", device_xname(sc->sc_dev));
 1264         SONIC_CDCAMSYNC(sc, BUS_DMASYNC_POSTWRITE);
 1265 
 1266         /* Set the receive control register. */
 1267         CSR_WRITE(sc, SONIC_RCR, rcr);
 1268 }

Cache object: 47533e8e7298d92c686cf6a29767fba5


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