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

Cache object: 0566cda6d3e02b9b87f4a476c243b856


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