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

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: sgec.c,v 1.27.24.2 2007/05/07 03:23:57 snj Exp $ */
    2 /*
    3  * Copyright (c) 1999 Ludd, University of Lule}, Sweden. All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 3. All advertising materials mentioning features or use of this software
   14  *    must display the following acknowledgement:
   15  *      This product includes software developed at Ludd, University of
   16  *      Lule}, Sweden and its contributors.
   17  * 4. The name of the author may not be used to endorse or promote products
   18  *    derived from this software without specific prior written permission
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 /*
   33  * Driver for the SGEC (Second Generation Ethernet Controller), sitting
   34  * on for example the VAX 4000/300 (KA670).
   35  *
   36  * The SGEC looks like a mixture of the DEQNA and the TULIP. Fun toy.
   37  *
   38  * Even though the chip is capable to use virtual addresses (read the
   39  * System Page Table directly) this driver doesn't do so, and there
   40  * is no benefit in doing it either in NetBSD of today.
   41  *
   42  * Things that is still to do:
   43  *      Collect statistics.
   44  *      Use imperfect filtering when many multicast addresses.
   45  */
   46 
   47 #include <sys/cdefs.h>
   48 __KERNEL_RCSID(0, "$NetBSD: sgec.c,v 1.27.24.2 2007/05/07 03:23:57 snj Exp $");
   49 
   50 #include "opt_inet.h"
   51 #include "bpfilter.h"
   52 
   53 #include <sys/param.h>
   54 #include <sys/mbuf.h>
   55 #include <sys/socket.h>
   56 #include <sys/device.h>
   57 #include <sys/systm.h>
   58 #include <sys/sockio.h>
   59 
   60 #include <uvm/uvm_extern.h>
   61 
   62 #include <net/if.h>
   63 #include <net/if_ether.h>
   64 #include <net/if_dl.h>
   65 
   66 #include <netinet/in.h>
   67 #include <netinet/if_inarp.h>
   68 
   69 #if NBPFILTER > 0
   70 #include <net/bpf.h>
   71 #include <net/bpfdesc.h>
   72 #endif
   73 
   74 #include <machine/bus.h>
   75 
   76 #include <dev/ic/sgecreg.h>
   77 #include <dev/ic/sgecvar.h>
   78 
   79 static  void    zeinit(struct ze_softc *);
   80 static  void    zestart(struct ifnet *);
   81 static  int     zeioctl(struct ifnet *, u_long, caddr_t);
   82 static  int     ze_add_rxbuf(struct ze_softc *, int);
   83 static  void    ze_setup(struct ze_softc *);
   84 static  void    zetimeout(struct ifnet *);
   85 static  int     zereset(struct ze_softc *);
   86 
   87 #define ZE_WCSR(csr, val) \
   88         bus_space_write_4(sc->sc_iot, sc->sc_ioh, csr, val)
   89 #define ZE_RCSR(csr) \
   90         bus_space_read_4(sc->sc_iot, sc->sc_ioh, csr)
   91 
   92 /*
   93  * Interface exists: make available by filling in network interface
   94  * record.  System will initialize the interface when it is ready
   95  * to accept packets.
   96  */
   97 void
   98 sgec_attach(sc)
   99         struct ze_softc *sc;
  100 {
  101         struct  ifnet *ifp = (struct ifnet *)&sc->sc_if;
  102         struct  ze_tdes *tp;
  103         struct  ze_rdes *rp;
  104         bus_dma_segment_t seg;
  105         int i, rseg, error;
  106 
  107         /*
  108          * Allocate DMA safe memory for descriptors and setup memory.
  109          */
  110         if ((error = bus_dmamem_alloc(sc->sc_dmat,
  111             sizeof(struct ze_cdata), PAGE_SIZE, 0, &seg, 1, &rseg,
  112             BUS_DMA_NOWAIT)) != 0) {
  113                 printf(": unable to allocate control data, error = %d\n",
  114                     error);
  115                 goto fail_0;
  116         }
  117 
  118         if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
  119             sizeof(struct ze_cdata), (caddr_t *)&sc->sc_zedata,
  120             BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
  121                 printf(": unable to map control data, error = %d\n", error);
  122                 goto fail_1;
  123         }
  124 
  125         if ((error = bus_dmamap_create(sc->sc_dmat,
  126             sizeof(struct ze_cdata), 1,
  127             sizeof(struct ze_cdata), 0, BUS_DMA_NOWAIT,
  128             &sc->sc_cmap)) != 0) {
  129                 printf(": unable to create control data DMA map, error = %d\n",
  130                     error);
  131                 goto fail_2;
  132         }
  133 
  134         if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cmap,
  135             sc->sc_zedata, sizeof(struct ze_cdata), NULL,
  136             BUS_DMA_NOWAIT)) != 0) {
  137                 printf(": unable to load control data DMA map, error = %d\n",
  138                     error);
  139                 goto fail_3;
  140         }
  141 
  142         /*
  143          * Zero the newly allocated memory.
  144          */
  145         memset(sc->sc_zedata, 0, sizeof(struct ze_cdata));
  146         /*
  147          * Create the transmit descriptor DMA maps.
  148          */
  149         for (i = 0; i < TXDESCS; i++) {
  150                 if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
  151                     TXDESCS - 1, MCLBYTES, 0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW,
  152                     &sc->sc_xmtmap[i]))) {
  153                         printf(": unable to create tx DMA map %d, error = %d\n",
  154                             i, error);
  155                         goto fail_4;
  156                 }
  157         }
  158 
  159         /*
  160          * Create receive buffer DMA maps.
  161          */
  162         for (i = 0; i < RXDESCS; i++) {
  163                 if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
  164                     MCLBYTES, 0, BUS_DMA_NOWAIT,
  165                     &sc->sc_rcvmap[i]))) {
  166                         printf(": unable to create rx DMA map %d, error = %d\n",
  167                             i, error);
  168                         goto fail_5;
  169                 }
  170         }
  171         /*
  172          * Pre-allocate the receive buffers.
  173          */
  174         for (i = 0; i < RXDESCS; i++) {
  175                 if ((error = ze_add_rxbuf(sc, i)) != 0) {
  176                         printf(": unable to allocate or map rx buffer %d\n,"
  177                             " error = %d\n", i, error);
  178                         goto fail_6;
  179                 }
  180         }
  181 
  182         /* For vmstat -i
  183          */
  184         evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL,
  185             sc->sc_dev.dv_xname, "intr");
  186         evcnt_attach_dynamic(&sc->sc_rxintrcnt, EVCNT_TYPE_INTR,
  187             &sc->sc_intrcnt, sc->sc_dev.dv_xname, "rx intr");
  188         evcnt_attach_dynamic(&sc->sc_txintrcnt, EVCNT_TYPE_INTR,
  189             &sc->sc_intrcnt, sc->sc_dev.dv_xname, "tx intr");
  190         evcnt_attach_dynamic(&sc->sc_txdraincnt, EVCNT_TYPE_INTR,
  191             &sc->sc_intrcnt, sc->sc_dev.dv_xname, "tx drain");
  192         evcnt_attach_dynamic(&sc->sc_nobufintrcnt, EVCNT_TYPE_INTR,
  193             &sc->sc_intrcnt, sc->sc_dev.dv_xname, "nobuf intr");
  194         evcnt_attach_dynamic(&sc->sc_nointrcnt, EVCNT_TYPE_INTR,
  195             &sc->sc_intrcnt, sc->sc_dev.dv_xname, "no intr");
  196 
  197         /*
  198          * Create ring loops of the buffer chains.
  199          * This is only done once.
  200          */
  201         sc->sc_pzedata = (struct ze_cdata *)sc->sc_cmap->dm_segs[0].ds_addr;
  202 
  203         rp = sc->sc_zedata->zc_recv;
  204         rp[RXDESCS].ze_framelen = ZE_FRAMELEN_OW;
  205         rp[RXDESCS].ze_rdes1 = ZE_RDES1_CA;
  206         rp[RXDESCS].ze_bufaddr = (char *)sc->sc_pzedata->zc_recv;
  207 
  208         tp = sc->sc_zedata->zc_xmit;
  209         tp[TXDESCS].ze_tdr = ZE_TDR_OW;
  210         tp[TXDESCS].ze_tdes1 = ZE_TDES1_CA;
  211         tp[TXDESCS].ze_bufaddr = (char *)sc->sc_pzedata->zc_xmit;
  212 
  213         if (zereset(sc))
  214                 return;
  215 
  216         strcpy(ifp->if_xname, sc->sc_dev.dv_xname);
  217         ifp->if_softc = sc;
  218         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
  219         ifp->if_start = zestart;
  220         ifp->if_ioctl = zeioctl;
  221         ifp->if_watchdog = zetimeout;
  222         IFQ_SET_READY(&ifp->if_snd);
  223 
  224         /*
  225          * Attach the interface.
  226          */
  227         if_attach(ifp);
  228         ether_ifattach(ifp, sc->sc_enaddr);
  229 
  230         printf("\n%s: hardware address %s\n", sc->sc_dev.dv_xname,
  231             ether_sprintf(sc->sc_enaddr));
  232         return;
  233 
  234         /*
  235          * Free any resources we've allocated during the failed attach
  236          * attempt.  Do this in reverse order and fall through.
  237          */
  238  fail_6:
  239         for (i = 0; i < RXDESCS; i++) {
  240                 if (sc->sc_rxmbuf[i] != NULL) {
  241                         bus_dmamap_unload(sc->sc_dmat, sc->sc_xmtmap[i]);
  242                         m_freem(sc->sc_rxmbuf[i]);
  243                 }
  244         }
  245  fail_5:
  246         for (i = 0; i < RXDESCS; i++) {
  247                 if (sc->sc_xmtmap[i] != NULL)
  248                         bus_dmamap_destroy(sc->sc_dmat, sc->sc_xmtmap[i]);
  249         }
  250  fail_4:
  251         for (i = 0; i < TXDESCS; i++) {
  252                 if (sc->sc_rcvmap[i] != NULL)
  253                         bus_dmamap_destroy(sc->sc_dmat, sc->sc_rcvmap[i]);
  254         }
  255         bus_dmamap_unload(sc->sc_dmat, sc->sc_cmap);
  256  fail_3:
  257         bus_dmamap_destroy(sc->sc_dmat, sc->sc_cmap);
  258  fail_2:
  259         bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_zedata,
  260             sizeof(struct ze_cdata));
  261  fail_1:
  262         bus_dmamem_free(sc->sc_dmat, &seg, rseg);
  263  fail_0:
  264         return;
  265 }
  266 
  267 /*
  268  * Initialization of interface.
  269  */
  270 void
  271 zeinit(sc)
  272         struct ze_softc *sc;
  273 {
  274         struct ifnet *ifp = (struct ifnet *)&sc->sc_if;
  275         struct ze_cdata *zc = sc->sc_zedata;
  276         int i;
  277 
  278         /*
  279          * Reset the interface.
  280          */
  281         if (zereset(sc))
  282                 return;
  283 
  284         sc->sc_nexttx = sc->sc_inq = sc->sc_lastack = sc->sc_txcnt = 0;
  285         /*
  286          * Release and init transmit descriptors.
  287          */
  288         for (i = 0; i < TXDESCS; i++) {
  289                 if (sc->sc_xmtmap[i]->dm_nsegs > 0)
  290                         bus_dmamap_unload(sc->sc_dmat, sc->sc_xmtmap[i]);
  291                 if (sc->sc_txmbuf[i]) {
  292                         m_freem(sc->sc_txmbuf[i]);
  293                         sc->sc_txmbuf[i] = 0;
  294                 }
  295                 zc->zc_xmit[i].ze_tdr = 0; /* Clear valid bit */
  296         }
  297 
  298 
  299         /*
  300          * Init receive descriptors.
  301          */
  302         for (i = 0; i < RXDESCS; i++)
  303                 zc->zc_recv[i].ze_framelen = ZE_FRAMELEN_OW;
  304         sc->sc_nextrx = 0;
  305 
  306         ZE_WCSR(ZE_CSR6, ZE_NICSR6_IE|ZE_NICSR6_BL_8|ZE_NICSR6_ST|
  307             ZE_NICSR6_SR|ZE_NICSR6_DC);
  308 
  309         ifp->if_flags |= IFF_RUNNING;
  310         ifp->if_flags &= ~IFF_OACTIVE;
  311 
  312         /*
  313          * Send a setup frame.
  314          * This will start the transmit machinery as well.
  315          */
  316         ze_setup(sc);
  317 
  318 }
  319 
  320 /*
  321  * Start output on interface.
  322  */
  323 void
  324 zestart(ifp)
  325         struct ifnet *ifp;
  326 {
  327         struct ze_softc *sc = ifp->if_softc;
  328         struct ze_cdata *zc = sc->sc_zedata;
  329         paddr_t buffer;
  330         struct mbuf *m;
  331         int nexttx, starttx;
  332         int len, i, totlen, error;
  333         int old_inq = sc->sc_inq;
  334         uint16_t orword, tdr;
  335         bus_dmamap_t map;
  336 
  337         while (sc->sc_inq < (TXDESCS - 1)) {
  338 
  339                 if (sc->sc_setup) {
  340                         ze_setup(sc);
  341                         continue;
  342                 }
  343                 nexttx = sc->sc_nexttx;
  344                 IFQ_POLL(&sc->sc_if.if_snd, m);
  345                 if (m == 0)
  346                         goto out;
  347                 /*
  348                  * Count number of mbufs in chain.
  349                  * Always do DMA directly from mbufs, therefore the transmit
  350                  * ring is really big.
  351                  */
  352                 map = sc->sc_xmtmap[nexttx];
  353                 error = bus_dmamap_load_mbuf(sc->sc_dmat, map, m,
  354                     BUS_DMA_WRITE);
  355                 if (error) {
  356                         printf("zestart: load_mbuf failed: %d", error);
  357                         goto out;
  358                 }
  359 
  360                 if (map->dm_nsegs >= TXDESCS)
  361                         panic("zestart"); /* XXX */
  362 
  363                 if ((map->dm_nsegs + sc->sc_inq) >= (TXDESCS - 1)) {
  364                         bus_dmamap_unload(sc->sc_dmat, map);
  365                         ifp->if_flags |= IFF_OACTIVE;
  366                         goto out;
  367                 }
  368 
  369                 /*
  370                  * m now points to a mbuf chain that can be loaded.
  371                  * Loop around and set it.
  372                  */
  373                 totlen = 0;
  374                 orword = ZE_TDES1_FS;
  375                 starttx = nexttx;
  376                 for (i = 0; i < map->dm_nsegs; i++) {
  377                         buffer = map->dm_segs[i].ds_addr;
  378                         len = map->dm_segs[i].ds_len;
  379 
  380                         KASSERT(len > 0);
  381 
  382                         totlen += len;
  383                         /* Word alignment calc */
  384                         if (totlen == m->m_pkthdr.len) {
  385                                 sc->sc_txcnt += map->dm_nsegs;
  386                                 if (sc->sc_txcnt >= TXDESCS * 3 / 4) {
  387                                         orword |= ZE_TDES1_IC;
  388                                         sc->sc_txcnt = 0;
  389                                 }
  390                                 orword |= ZE_TDES1_LS;
  391                                 sc->sc_txmbuf[nexttx] = m;
  392                         }
  393                         zc->zc_xmit[nexttx].ze_bufsize = len;
  394                         zc->zc_xmit[nexttx].ze_bufaddr = (char *)buffer;
  395                         zc->zc_xmit[nexttx].ze_tdes1 = orword;
  396                         zc->zc_xmit[nexttx].ze_tdr = tdr;
  397 
  398                         if (++nexttx == TXDESCS)
  399                                 nexttx = 0;
  400                         orword = 0;
  401                         tdr = ZE_TDR_OW;
  402                 }
  403 
  404                 sc->sc_inq += map->dm_nsegs;
  405 
  406                 IFQ_DEQUEUE(&ifp->if_snd, m);
  407 #ifdef DIAGNOSTIC
  408                 if (totlen != m->m_pkthdr.len)
  409                         panic("zestart: len fault");
  410 #endif
  411                 /*
  412                  * Turn ownership of the packet over to the device.
  413                  */
  414                 zc->zc_xmit[starttx].ze_tdr = ZE_TDR_OW;
  415 
  416                 /*
  417                  * Kick off the transmit logic, if it is stopped.
  418                  */
  419                 if ((ZE_RCSR(ZE_CSR5) & ZE_NICSR5_TS) != ZE_NICSR5_TS_RUN)
  420                         ZE_WCSR(ZE_CSR1, -1);
  421                 sc->sc_nexttx = nexttx;
  422         }
  423         if (sc->sc_inq == (TXDESCS - 1))
  424                 ifp->if_flags |= IFF_OACTIVE;
  425 
  426 out:    if (old_inq < sc->sc_inq)
  427                 ifp->if_timer = 5; /* If transmit logic dies */
  428 }
  429 
  430 int
  431 sgec_intr(sc)
  432         struct ze_softc *sc;
  433 {
  434         struct ze_cdata *zc = sc->sc_zedata;
  435         struct ifnet *ifp = &sc->sc_if;
  436         struct mbuf *m;
  437         int csr, len;
  438 
  439         csr = ZE_RCSR(ZE_CSR5);
  440         if ((csr & ZE_NICSR5_IS) == 0) { /* Wasn't we */
  441                 sc->sc_nointrcnt.ev_count++;
  442                 return 0;
  443         }
  444         ZE_WCSR(ZE_CSR5, csr);
  445 
  446         if (csr & ZE_NICSR5_RU)
  447                 sc->sc_nobufintrcnt.ev_count++;
  448 
  449         if (csr & ZE_NICSR5_RI) {
  450                 sc->sc_rxintrcnt.ev_count++;
  451                 while ((zc->zc_recv[sc->sc_nextrx].ze_framelen &
  452                     ZE_FRAMELEN_OW) == 0) {
  453 
  454                         ifp->if_ipackets++;
  455                         m = sc->sc_rxmbuf[sc->sc_nextrx];
  456                         len = zc->zc_recv[sc->sc_nextrx].ze_framelen;
  457                         ze_add_rxbuf(sc, sc->sc_nextrx);
  458                         if (++sc->sc_nextrx == RXDESCS)
  459                                 sc->sc_nextrx = 0;
  460                         if (len < ETHER_MIN_LEN) {
  461                                 ifp->if_ierrors++;
  462                                 m_freem(m);
  463                         } else {
  464                                 m->m_pkthdr.rcvif = ifp;
  465                                 m->m_pkthdr.len = m->m_len =
  466                                     len - ETHER_CRC_LEN;
  467 #if NBPFILTER > 0
  468                                 if (ifp->if_bpf)
  469                                         bpf_mtap(ifp->if_bpf, m);
  470 #endif
  471                                 (*ifp->if_input)(ifp, m);
  472                         }
  473                 }
  474         }
  475 
  476         if (csr & ZE_NICSR5_TI)
  477                 sc->sc_txintrcnt.ev_count++;
  478         if (sc->sc_lastack != sc->sc_nexttx) {
  479                 int lastack;
  480                 for (lastack = sc->sc_lastack; lastack != sc->sc_nexttx; ) {
  481                         bus_dmamap_t map;
  482                         int nlastack;
  483 
  484                         if ((zc->zc_xmit[lastack].ze_tdr & ZE_TDR_OW) != 0)
  485                                 break;
  486 
  487                         if ((zc->zc_xmit[lastack].ze_tdes1 & ZE_TDES1_DT) ==
  488                             ZE_TDES1_DT_SETUP) {
  489                                 if (++lastack == TXDESCS)
  490                                         lastack = 0;
  491                                 sc->sc_inq--;
  492                                 continue;
  493                         }
  494 
  495                         KASSERT(zc->zc_xmit[lastack].ze_tdes1 & ZE_TDES1_FS);
  496                         map = sc->sc_xmtmap[lastack];
  497                         KASSERT(map->dm_nsegs > 0);
  498                         nlastack = (lastack + map->dm_nsegs - 1) % TXDESCS;
  499                         if (zc->zc_xmit[nlastack].ze_tdr & ZE_TDR_OW)
  500                                 break;
  501                         lastack = nlastack;
  502                         if (sc->sc_txcnt > map->dm_nsegs)
  503                             sc->sc_txcnt -= map->dm_nsegs;
  504                         else
  505                             sc->sc_txcnt = 0;
  506                         sc->sc_inq -= map->dm_nsegs;
  507                         KASSERT(zc->zc_xmit[lastack].ze_tdes1 & ZE_TDES1_LS);
  508                         ifp->if_opackets++;
  509                         bus_dmamap_unload(sc->sc_dmat, map);
  510                         KASSERT(sc->sc_txmbuf[lastack]);
  511 #if NBPFILTER > 0
  512                         if (ifp->if_bpf)
  513                                 bpf_mtap(ifp->if_bpf, sc->sc_txmbuf[lastack]);
  514 #endif
  515                         m_freem(sc->sc_txmbuf[lastack]);
  516                         sc->sc_txmbuf[lastack] = 0;
  517                         if (++lastack == TXDESCS)
  518                                 lastack = 0;
  519                 }
  520                 if (lastack != sc->sc_lastack) {
  521                         sc->sc_txdraincnt.ev_count++;
  522                         sc->sc_lastack = lastack;
  523                         if (sc->sc_inq == 0)
  524                                 ifp->if_timer = 0;
  525                         ifp->if_flags &= ~IFF_OACTIVE;
  526                         zestart(ifp); /* Put in more in queue */
  527                 }
  528         }
  529         return 1;
  530 }
  531 
  532 /*
  533  * Process an ioctl request.
  534  */
  535 int
  536 zeioctl(ifp, cmd, data)
  537         struct ifnet *ifp;
  538         u_long cmd;
  539         caddr_t data;
  540 {
  541         struct ze_softc *sc = ifp->if_softc;
  542         struct ifreq *ifr = (struct ifreq *)data;
  543         struct ifaddr *ifa = (struct ifaddr *)data;
  544         int s = splnet(), error = 0;
  545 
  546         switch (cmd) {
  547 
  548         case SIOCSIFADDR:
  549                 ifp->if_flags |= IFF_UP;
  550                 switch(ifa->ifa_addr->sa_family) {
  551 #ifdef INET
  552                 case AF_INET:
  553                         zeinit(sc);
  554                         arp_ifinit(ifp, ifa);
  555                         break;
  556 #endif
  557                 }
  558                 break;
  559 
  560         case SIOCSIFFLAGS:
  561                 if ((ifp->if_flags & IFF_UP) == 0 &&
  562                     (ifp->if_flags & IFF_RUNNING) != 0) {
  563                         /*
  564                          * If interface is marked down and it is running,
  565                          * stop it. (by disabling receive mechanism).
  566                          */
  567                         ZE_WCSR(ZE_CSR6, ZE_RCSR(ZE_CSR6) &
  568                             ~(ZE_NICSR6_ST|ZE_NICSR6_SR));
  569                         ifp->if_flags &= ~IFF_RUNNING;
  570                 } else if ((ifp->if_flags & IFF_UP) != 0 &&
  571                            (ifp->if_flags & IFF_RUNNING) == 0) {
  572                         /*
  573                          * If interface it marked up and it is stopped, then
  574                          * start it.
  575                          */
  576                         zeinit(sc);
  577                 } else if ((ifp->if_flags & IFF_UP) != 0) {
  578                         /*
  579                          * Send a new setup packet to match any new changes.
  580                          * (Like IFF_PROMISC etc)
  581                          */
  582                         ze_setup(sc);
  583                 }
  584                 break;
  585 
  586         case SIOCADDMULTI:
  587         case SIOCDELMULTI:
  588                 /*
  589                  * Update our multicast list.
  590                  */
  591                 error = (cmd == SIOCADDMULTI) ?
  592                         ether_addmulti(ifr, &sc->sc_ec):
  593                         ether_delmulti(ifr, &sc->sc_ec);
  594 
  595                 if (error == ENETRESET) {
  596                         /*
  597                          * Multicast list has changed; set the hardware filter
  598                          * accordingly.
  599                          */
  600                         if (ifp->if_flags & IFF_RUNNING)
  601                                 ze_setup(sc);
  602                         error = 0;
  603                 }
  604                 break;
  605 
  606         default:
  607                 error = EINVAL;
  608 
  609         }
  610         splx(s);
  611         return (error);
  612 }
  613 
  614 /*
  615  * Add a receive buffer to the indicated descriptor.
  616  */
  617 int
  618 ze_add_rxbuf(sc, i)
  619         struct ze_softc *sc;
  620         int i;
  621 {
  622         struct mbuf *m;
  623         struct ze_rdes *rp;
  624         int error;
  625 
  626         MGETHDR(m, M_DONTWAIT, MT_DATA);
  627         if (m == NULL)
  628                 return (ENOBUFS);
  629 
  630         MCLAIM(m, &sc->sc_ec.ec_rx_mowner);
  631         MCLGET(m, M_DONTWAIT);
  632         if ((m->m_flags & M_EXT) == 0) {
  633                 m_freem(m);
  634                 return (ENOBUFS);
  635         }
  636 
  637         if (sc->sc_rxmbuf[i] != NULL)
  638                 bus_dmamap_unload(sc->sc_dmat, sc->sc_rcvmap[i]);
  639 
  640         error = bus_dmamap_load(sc->sc_dmat, sc->sc_rcvmap[i],
  641             m->m_ext.ext_buf, m->m_ext.ext_size, NULL,
  642             BUS_DMA_READ|BUS_DMA_NOWAIT);
  643         if (error)
  644                 panic("%s: can't load rx DMA map %d, error = %d",
  645                     sc->sc_dev.dv_xname, i, error);
  646         sc->sc_rxmbuf[i] = m;
  647 
  648         bus_dmamap_sync(sc->sc_dmat, sc->sc_rcvmap[i], 0,
  649             sc->sc_rcvmap[i]->dm_mapsize, BUS_DMASYNC_PREREAD);
  650 
  651         /*
  652          * We know that the mbuf cluster is page aligned. Also, be sure
  653          * that the IP header will be longword aligned.
  654          */
  655         m->m_data += 2;
  656         rp = &sc->sc_zedata->zc_recv[i];
  657         rp->ze_bufsize = (m->m_ext.ext_size - 2);
  658         rp->ze_bufaddr = (char *)sc->sc_rcvmap[i]->dm_segs[0].ds_addr + 2;
  659         rp->ze_framelen = ZE_FRAMELEN_OW;
  660 
  661         return (0);
  662 }
  663 
  664 /*
  665  * Create a setup packet and put in queue for sending.
  666  */
  667 void
  668 ze_setup(sc)
  669         struct ze_softc *sc;
  670 {
  671         struct ether_multi *enm;
  672         struct ether_multistep step;
  673         struct ze_cdata *zc = sc->sc_zedata;
  674         struct ifnet *ifp = &sc->sc_if;
  675         u_int8_t *enaddr = LLADDR(ifp->if_sadl);
  676         int j, idx, reg;
  677 
  678         if (sc->sc_inq == (TXDESCS - 1)) {
  679                 sc->sc_setup = 1;
  680                 return;
  681         }
  682         sc->sc_setup = 0;
  683         /*
  684          * Init the setup packet with valid info.
  685          */
  686         memset(zc->zc_setup, 0xff, sizeof(zc->zc_setup)); /* Broadcast */
  687         memcpy(zc->zc_setup, enaddr, ETHER_ADDR_LEN);
  688 
  689         /*
  690          * Multicast handling. The SGEC can handle up to 16 direct
  691          * ethernet addresses.
  692          */
  693         j = 16;
  694         ifp->if_flags &= ~IFF_ALLMULTI;
  695         ETHER_FIRST_MULTI(step, &sc->sc_ec, enm);
  696         while (enm != NULL) {
  697                 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 6)) {
  698                         ifp->if_flags |= IFF_ALLMULTI;
  699                         break;
  700                 }
  701                 memcpy(&zc->zc_setup[j], enm->enm_addrlo, ETHER_ADDR_LEN);
  702                 j += 8;
  703                 ETHER_NEXT_MULTI(step, enm);
  704                 if ((enm != NULL)&& (j == 128)) {
  705                         ifp->if_flags |= IFF_ALLMULTI;
  706                         break;
  707                 }
  708         }
  709 
  710         /*
  711          * ALLMULTI implies PROMISC in this driver.
  712          */
  713         if (ifp->if_flags & IFF_ALLMULTI)
  714                 ifp->if_flags |= IFF_PROMISC;
  715         else if (ifp->if_pcount == 0)
  716                 ifp->if_flags &= ~IFF_PROMISC;
  717 
  718         /*
  719          * Fiddle with the receive logic.
  720          */
  721         reg = ZE_RCSR(ZE_CSR6);
  722         DELAY(10);
  723         ZE_WCSR(ZE_CSR6, reg & ~ZE_NICSR6_SR); /* Stop rx */
  724         reg &= ~ZE_NICSR6_AF;
  725         if (ifp->if_flags & IFF_PROMISC)
  726                 reg |= ZE_NICSR6_AF_PROM;
  727         else if (ifp->if_flags & IFF_ALLMULTI)
  728                 reg |= ZE_NICSR6_AF_ALLM;
  729         DELAY(10);
  730         ZE_WCSR(ZE_CSR6, reg);
  731         /*
  732          * Only send a setup packet if needed.
  733          */
  734         if ((ifp->if_flags & (IFF_PROMISC|IFF_ALLMULTI)) == 0) {
  735                 idx = sc->sc_nexttx;
  736                 zc->zc_xmit[idx].ze_tdes1 = ZE_TDES1_DT_SETUP;
  737                 zc->zc_xmit[idx].ze_bufsize = 128;
  738                 zc->zc_xmit[idx].ze_bufaddr = sc->sc_pzedata->zc_setup;
  739                 zc->zc_xmit[idx].ze_tdr = ZE_TDR_OW;
  740 
  741                 if ((ZE_RCSR(ZE_CSR5) & ZE_NICSR5_TS) != ZE_NICSR5_TS_RUN)
  742                         ZE_WCSR(ZE_CSR1, -1);
  743 
  744                 sc->sc_inq++;
  745                 if (++sc->sc_nexttx == TXDESCS)
  746                         sc->sc_nexttx = 0;
  747         }
  748 }
  749 
  750 /*
  751  * Check for dead transmit logic.
  752  */
  753 void
  754 zetimeout(ifp)
  755         struct ifnet *ifp;
  756 {
  757         struct ze_softc *sc = ifp->if_softc;
  758 
  759         if (sc->sc_inq == 0)
  760                 return;
  761 
  762         printf("%s: xmit logic died, resetting...\n", sc->sc_dev.dv_xname);
  763         /*
  764          * Do a reset of interface, to get it going again.
  765          * Will it work by just restart the transmit logic?
  766          */
  767         zeinit(sc);
  768 }
  769 
  770 /*
  771  * Reset chip:
  772  * Set/reset the reset flag.
  773  *  Write interrupt vector.
  774  *  Write ring buffer addresses.
  775  *  Write SBR.
  776  */
  777 int
  778 zereset(sc)
  779         struct ze_softc *sc;
  780 {
  781         int reg, i;
  782 
  783         ZE_WCSR(ZE_CSR6, ZE_NICSR6_RE);
  784         DELAY(50000);
  785         if (ZE_RCSR(ZE_CSR6) & ZE_NICSR5_SF) {
  786                 printf("%s: selftest failed\n", sc->sc_dev.dv_xname);
  787                 return 1;
  788         }
  789 
  790         /*
  791          * Get the vector that were set at match time, and remember it.
  792          * WHICH VECTOR TO USE? Take one unused. XXX
  793          * Funny way to set vector described in the programmers manual.
  794          */
  795         reg = ZE_NICSR0_IPL14 | sc->sc_intvec | 0x1fff0003; /* SYNC/ASYNC??? */
  796         i = 10;
  797         do {
  798                 if (i-- == 0) {
  799                         printf("Failing SGEC CSR0 init\n");
  800                         return 1;
  801                 }
  802                 ZE_WCSR(ZE_CSR0, reg);
  803         } while (ZE_RCSR(ZE_CSR0) != reg);
  804 
  805         ZE_WCSR(ZE_CSR3, (vaddr_t)sc->sc_pzedata->zc_recv);
  806         ZE_WCSR(ZE_CSR4, (vaddr_t)sc->sc_pzedata->zc_xmit);
  807         return 0;
  808 }

Cache object: 15b5fca3781b2f172feffc9d3aa0475a


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