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/qbus/if_de.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: if_de.c,v 1.36 2021/08/01 15:29:30 andvar Exp $        */
    2 
    3 /*
    4  * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
    5  * All rights reserved.
    6  *
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. Neither the name of the University nor the names of its contributors
   17  *    may be used to endorse or promote products derived from this software
   18  *    without specific prior written permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   30  * SUCH DAMAGE.
   31  *
   32  *      @(#)if_de.c     7.12 (Berkeley) 12/16/90
   33  */
   34 
   35 /*
   36  * Copyright (c) 2000 Ludd, University of Lule}, Sweden.
   37  * All rights reserved.
   38  *
   39  *
   40  * Redistribution and use in source and binary forms, with or without
   41  * modification, are permitted provided that the following conditions
   42  * are met:
   43  * 1. Redistributions of source code must retain the above copyright
   44  *    notice, this list of conditions and the following disclaimer.
   45  * 2. Redistributions in binary form must reproduce the above copyright
   46  *    notice, this list of conditions and the following disclaimer in the
   47  *    documentation and/or other materials provided with the distribution.
   48  *
   49  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   50  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   51  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   52  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   53  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   54  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   55  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   56  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   57  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   58  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   59  * SUCH DAMAGE.
   60  */
   61 
   62 /*
   63  * DEC DEUNA interface
   64  *
   65  *      Lou Salkind
   66  *      New York University
   67  *
   68  *      Rewritten by Ragge 30 April 2000 to match new world.
   69  *
   70  * TODO:
   71  *      timeout routine (get statistics)
   72  */
   73 
   74 #include <sys/cdefs.h>
   75 __KERNEL_RCSID(0, "$NetBSD: if_de.c,v 1.36 2021/08/01 15:29:30 andvar Exp $");
   76 
   77 #include "opt_inet.h"
   78 
   79 #include <sys/param.h>
   80 #include <sys/systm.h>
   81 #include <sys/mbuf.h>
   82 #include <sys/buf.h>
   83 #include <sys/protosw.h>
   84 #include <sys/socket.h>
   85 #include <sys/ioctl.h>
   86 #include <sys/errno.h>
   87 #include <sys/syslog.h>
   88 #include <sys/device.h>
   89 
   90 #include <net/if.h>
   91 #include <net/if_ether.h>
   92 #include <net/if_dl.h>
   93 #include <net/bpf.h>
   94 
   95 #ifdef INET
   96 #include <netinet/in.h>
   97 #include <netinet/if_inarp.h>
   98 #endif
   99 
  100 #include <sys/bus.h>
  101 
  102 #include <dev/qbus/ubavar.h>
  103 #include <dev/qbus/if_dereg.h>
  104 #include <dev/qbus/if_uba.h>
  105 
  106 #include "ioconf.h"
  107 
  108 /*
  109  * Be careful with transmit/receive buffers, each entry steals 4 map
  110  * registers, and there is only 496 on one unibus...
  111  */
  112 #define NRCV    7       /* number of receive buffers (must be > 1) */
  113 #define NXMT    3       /* number of transmit buffers */
  114 
  115 /*
  116  * Structure containing the elements that must be in DMA-safe memory.
  117  */
  118 struct  de_cdata {
  119         /* the following structures are always mapped in */
  120         struct  de_pcbb dc_pcbb;        /* port control block */
  121         struct  de_ring dc_xrent[NXMT]; /* transmit ring entrys */
  122         struct  de_ring dc_rrent[NRCV]; /* receive ring entrys */
  123         struct  de_udbbuf dc_udbbuf;    /* UNIBUS data buffer */
  124         /* end mapped area */
  125 };
  126 
  127 /*
  128  * Ethernet software status per interface.
  129  *
  130  * Each interface is referenced by a network interface structure,
  131  * ds_if, which the routing code uses to locate the interface.
  132  * This structure contains the output queue for the interface, its address, ...
  133  * We also have, for each interface, a UBA interface structure, which
  134  * contains information about the UNIBUS resources held by the interface:
  135  * map registers, buffered data paths, etc.  Information is cached in this
  136  * structure for use by the if_uba.c routines in running the interface
  137  * efficiently.
  138  */
  139 struct  de_softc {
  140         device_t sc_dev;                /* Configuration common part */
  141         struct uba_softc *sc_uh;        /* our parent */
  142         struct evcnt sc_intrcnt;        /* Interrupt counting */
  143         struct ethercom sc_ec;          /* Ethernet common part */
  144 #define sc_if   sc_ec.ec_if             /* network-visible interface */
  145         bus_space_tag_t sc_iot;
  146         bus_addr_t sc_ioh;
  147         bus_dma_tag_t sc_dmat;
  148         int sc_flags;
  149 #define DSF_MAPPED      1
  150         struct ubinfo sc_ui;
  151         struct de_cdata *sc_dedata;     /* Control structure */
  152         struct de_cdata *sc_pdedata;    /* Bus-mapped control structure */
  153         struct ifubinfo sc_ifuba;       /* UNIBUS resources */
  154         struct ifrw sc_ifr[NRCV];       /* UNIBUS receive buffer maps */
  155         struct ifxmt sc_ifw[NXMT];      /* UNIBUS receive buffer maps */
  156 
  157         int sc_xindex;                  /* UNA index into transmit chain */
  158         int sc_rindex;                  /* UNA index into receive chain */
  159         int sc_xfree;                   /* index for next transmit buffer */
  160         int sc_nxmit;                   /* # of transmits in progress */
  161         void *sc_sh;                    /* shutdownhook cookie */
  162 };
  163 
  164 static  int dematch(device_t, cfdata_t, void *);
  165 static  void deattach(device_t, device_t, void *);
  166 static  void dewait(struct de_softc *, const char *);
  167 static  int deinit(struct ifnet *);
  168 static  int deioctl(struct ifnet *, u_long, void *);
  169 static  void dereset(device_t);
  170 static  void destop(struct ifnet *, int);
  171 static  void destart(struct ifnet *);
  172 static  void derecv(struct de_softc *);
  173 static  void deintr(void *);
  174 static  void deshutdown(void *);
  175 
  176 CFATTACH_DECL_NEW(de, sizeof(struct de_softc),
  177     dematch, deattach, NULL, NULL);
  178 
  179 #define DE_WCSR(csr, val) \
  180         bus_space_write_2(sc->sc_iot, sc->sc_ioh, csr, val)
  181 #define DE_WLOW(val) \
  182         bus_space_write_1(sc->sc_iot, sc->sc_ioh, DE_PCSR0, val)
  183 #define DE_WHIGH(val) \
  184         bus_space_write_1(sc->sc_iot, sc->sc_ioh, DE_PCSR0 + 1, val)
  185 #define DE_RCSR(csr) \
  186         bus_space_read_2(sc->sc_iot, sc->sc_ioh, csr)
  187 
  188 #define LOWORD(x)       ((int)(x) & 0xffff)
  189 #define HIWORD(x)       (((int)(x) >> 16) & 0x3)
  190 /*
  191  * Interface exists: make available by filling in network interface
  192  * record.  System will initialize the interface when it is ready
  193  * to accept packets.  We get the ethernet address here.
  194  */
  195 void
  196 deattach(device_t parent, device_t self, void *aux)
  197 {
  198         struct uba_attach_args *ua = aux;
  199         struct de_softc *sc = device_private(self);
  200         struct ifnet *ifp = &sc->sc_if;
  201         u_int8_t myaddr[ETHER_ADDR_LEN];
  202         int csr1, error;
  203         const char *c;
  204 
  205         sc->sc_dev = self;
  206         sc->sc_uh = device_private(parent);
  207         sc->sc_iot = ua->ua_iot;
  208         sc->sc_ioh = ua->ua_ioh;
  209         sc->sc_dmat = ua->ua_dmat;
  210 
  211         /*
  212          * What kind of a board is this?
  213          * The error bits 4-6 in pcsr1 are a device id as long as
  214          * the high byte is zero.
  215          */
  216         csr1 = DE_RCSR(DE_PCSR1);
  217         if (csr1 & 0xff60)
  218                 c = "broken";
  219         else if (csr1 & 0x10)
  220                 c = "delua";
  221         else
  222                 c = "deuna";
  223 
  224         /*
  225          * Reset the board and temporarily map
  226          * the pcbb buffer onto the Unibus.
  227          */
  228         DE_WCSR(DE_PCSR0, 0);           /* reset INTE */
  229         DELAY(100);
  230         DE_WCSR(DE_PCSR0, PCSR0_RSET);
  231         dewait(sc, "reset");
  232 
  233         sc->sc_ui.ui_size = sizeof(struct de_cdata);
  234         if ((error = ubmemalloc(sc->sc_uh, &sc->sc_ui, 0)))
  235                 return printf(": failed ubmemalloc(), error = %d\n", error);
  236         sc->sc_dedata = (struct de_cdata *)sc->sc_ui.ui_vaddr;
  237 
  238         /*
  239          * Tell the DEUNA about our PCB
  240          */
  241         DE_WCSR(DE_PCSR2, LOWORD(sc->sc_ui.ui_baddr));
  242         DE_WCSR(DE_PCSR3, HIWORD(sc->sc_ui.ui_baddr));
  243         DE_WLOW(CMD_GETPCBB);
  244         dewait(sc, "pcbb");
  245 
  246         sc->sc_dedata->dc_pcbb.pcbb0 = FC_RDPHYAD;
  247         DE_WLOW(CMD_GETCMD);
  248         dewait(sc, "read addr ");
  249 
  250         memcpy(myaddr, (void *)&sc->sc_dedata->dc_pcbb.pcbb2, sizeof (myaddr));
  251         printf(": %s, hardware address %s\n", c, ether_sprintf(myaddr));
  252 
  253         uba_intr_establish(ua->ua_icookie, ua->ua_cvec, deintr, sc,
  254             &sc->sc_intrcnt);
  255         uba_reset_establish(dereset, sc->sc_dev);
  256         evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, ua->ua_evcnt,
  257             device_xname(sc->sc_dev), "intr");
  258 
  259         strcpy(ifp->if_xname, device_xname(sc->sc_dev));
  260         ifp->if_softc = sc;
  261         ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI;
  262         ifp->if_ioctl = deioctl;
  263         ifp->if_start = destart;
  264         ifp->if_init = deinit;
  265         ifp->if_stop = destop;
  266         IFQ_SET_READY(&ifp->if_snd);
  267 
  268         if_attach(ifp);
  269         ether_ifattach(ifp, myaddr);
  270         ubmemfree(sc->sc_uh, &sc->sc_ui);
  271 
  272         sc->sc_sh = shutdownhook_establish(deshutdown, sc);
  273 }
  274 
  275 void
  276 destop(struct ifnet *ifp, int a)
  277 {
  278         struct de_softc *sc = ifp->if_softc;
  279 
  280         DE_WLOW(0);
  281         DELAY(5000);
  282         DE_WLOW(PCSR0_RSET);
  283 }
  284 
  285 
  286 /*
  287  * Reset of interface after UNIBUS reset.
  288  */
  289 void
  290 dereset(device_t dev)
  291 {
  292         struct de_softc *sc = (void *)dev;
  293 
  294         sc->sc_if.if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
  295         sc->sc_flags &= ~DSF_MAPPED;
  296         sc->sc_pdedata = NULL;  /* All mappings lost */
  297         DE_WCSR(DE_PCSR0, PCSR0_RSET);
  298         dewait(sc, "reset");
  299         deinit(&sc->sc_if);
  300 }
  301 
  302 /*
  303  * Initialization of interface; clear recorded pending
  304  * operations, and reinitialize UNIBUS usage.
  305  */
  306 int
  307 deinit(struct ifnet *ifp)
  308 {
  309         struct de_softc *sc = ifp->if_softc;
  310         struct de_cdata *dc, *pdc;
  311         struct ifrw *ifrw;
  312         struct ifxmt *ifxp;
  313         struct de_ring *rp;
  314         int s, error;
  315 
  316         if (ifp->if_flags & IFF_RUNNING)
  317                 return 0;
  318         if ((sc->sc_flags & DSF_MAPPED) == 0) {
  319                 if (if_ubaminit(&sc->sc_ifuba, sc->sc_uh, MCLBYTES,
  320                                 sc->sc_ifr, NRCV, sc->sc_ifw, NXMT)) {
  321                         aprint_error_dev(sc->sc_dev, " can't initialize\n");
  322                         ifp->if_flags &= ~IFF_UP;
  323                         return 0;
  324                 }
  325                 sc->sc_ui.ui_size = sizeof(struct de_cdata);
  326                 if ((error = ubmemalloc(sc->sc_uh, &sc->sc_ui, 0))) {
  327                         aprint_error(": unable to ubmemalloc(), error = %d\n",
  328                             error);
  329                         return 0;
  330                 }
  331                 sc->sc_pdedata = (struct de_cdata *)sc->sc_ui.ui_baddr;
  332                 sc->sc_dedata = (struct de_cdata *)sc->sc_ui.ui_vaddr;
  333                 sc->sc_flags |= DSF_MAPPED;
  334         }
  335 
  336         /*
  337          * Tell the DEUNA about our PCB
  338          */
  339         DE_WCSR(DE_PCSR2, LOWORD(sc->sc_pdedata));
  340         DE_WCSR(DE_PCSR3, HIWORD(sc->sc_pdedata));
  341         DE_WLOW(0);             /* reset INTE */
  342         DELAY(500);
  343         DE_WLOW(CMD_GETPCBB);
  344         dewait(sc, "pcbb");
  345 
  346         dc = sc->sc_dedata;
  347         pdc = sc->sc_pdedata;
  348         /* set the transmit and receive ring header addresses */
  349         dc->dc_pcbb.pcbb0 = FC_WTRING;
  350         dc->dc_pcbb.pcbb2 = LOWORD(&pdc->dc_udbbuf);
  351         dc->dc_pcbb.pcbb4 = HIWORD(&pdc->dc_udbbuf);
  352 
  353         dc->dc_udbbuf.b_tdrbl = LOWORD(&pdc->dc_xrent[0]);
  354         dc->dc_udbbuf.b_tdrbh = HIWORD(&pdc->dc_xrent[0]);
  355         dc->dc_udbbuf.b_telen = sizeof (struct de_ring) / sizeof(u_int16_t);
  356         dc->dc_udbbuf.b_trlen = NXMT;
  357         dc->dc_udbbuf.b_rdrbl = LOWORD(&pdc->dc_rrent[0]);
  358         dc->dc_udbbuf.b_rdrbh = HIWORD(&pdc->dc_rrent[0]);
  359         dc->dc_udbbuf.b_relen = sizeof (struct de_ring) / sizeof(u_int16_t);
  360         dc->dc_udbbuf.b_rrlen = NRCV;
  361 
  362         DE_WLOW(CMD_GETCMD);
  363         dewait(sc, "wtring");
  364 
  365         sc->sc_dedata->dc_pcbb.pcbb0 = FC_WTMODE;
  366         sc->sc_dedata->dc_pcbb.pcbb2 = MOD_TPAD|MOD_HDX|MOD_DRDC|MOD_ENAL;
  367         DE_WLOW(CMD_GETCMD);
  368         dewait(sc, "wtmode");
  369 
  370         /* set up the receive and transmit ring entries */
  371         ifxp = &sc->sc_ifw[0];
  372         for (rp = &dc->dc_xrent[0]; rp < &dc->dc_xrent[NXMT]; rp++) {
  373                 rp->r_segbl = LOWORD(ifxp->ifw_info);
  374                 rp->r_segbh = HIWORD(ifxp->ifw_info);
  375                 rp->r_flags = 0;
  376                 ifxp++;
  377         }
  378         ifrw = &sc->sc_ifr[0];
  379         for (rp = &dc->dc_rrent[0]; rp < &dc->dc_rrent[NRCV]; rp++) {
  380                 rp->r_slen = MCLBYTES - 2;
  381                 rp->r_segbl = LOWORD(ifrw->ifrw_info);
  382                 rp->r_segbh = HIWORD(ifrw->ifrw_info);
  383                 rp->r_flags = RFLG_OWN;
  384                 ifrw++;
  385         }
  386 
  387         /* start up the board (rah rah) */
  388         s = splnet();
  389         sc->sc_rindex = sc->sc_xindex = sc->sc_xfree = sc->sc_nxmit = 0;
  390         sc->sc_if.if_flags |= IFF_RUNNING;
  391         DE_WLOW(PCSR0_INTE);                    /* avoid interlock */
  392         destart(&sc->sc_if);            /* queue output packets */
  393         DE_WLOW(CMD_START|PCSR0_INTE);
  394         splx(s);
  395         return 0;
  396 }
  397 
  398 /*
  399  * Setup output on interface.
  400  * Get another datagram to send off of the interface queue,
  401  * and map it to the interface before starting the output.
  402  * Must be called from ipl >= our interrupt level.
  403  */
  404 void
  405 destart(struct ifnet *ifp)
  406 {
  407         struct de_softc *sc = ifp->if_softc;
  408         struct de_cdata *dc;
  409         struct de_ring *rp;
  410         struct mbuf *m;
  411         int nxmit, len;
  412 
  413         /*
  414          * the following test is necessary, since
  415          * the code is not reentrant and we have
  416          * multiple transmission buffers.
  417          */
  418         if (sc->sc_if.if_flags & IFF_OACTIVE)
  419                 return;
  420         dc = sc->sc_dedata;
  421         for (nxmit = sc->sc_nxmit; nxmit < NXMT; nxmit++) {
  422                 IFQ_DEQUEUE(&ifp->if_snd, m);
  423                 if (m == 0)
  424                         break;
  425 
  426                 rp = &dc->dc_xrent[sc->sc_xfree];
  427                 if (rp->r_flags & XFLG_OWN)
  428                         panic("deuna xmit in progress");
  429                 bpf_mtap(ifp, m, BPF_D_OUT);
  430 
  431                 len = if_ubaput(&sc->sc_ifuba, &sc->sc_ifw[sc->sc_xfree], m);
  432                 rp->r_slen = len;
  433                 rp->r_tdrerr = 0;
  434                 rp->r_flags = XFLG_STP|XFLG_ENP|XFLG_OWN;
  435 
  436                 sc->sc_xfree++;
  437                 if (sc->sc_xfree == NXMT)
  438                         sc->sc_xfree = 0;
  439         }
  440         if (sc->sc_nxmit != nxmit) {
  441                 sc->sc_nxmit = nxmit;
  442                 if (ifp->if_flags & IFF_RUNNING)
  443                         DE_WLOW(PCSR0_INTE|CMD_PDMD);
  444         }
  445 }
  446 
  447 /*
  448  * Command done interrupt.
  449  */
  450 void
  451 deintr(void *arg)
  452 {
  453         struct ifxmt *ifxp;
  454         struct de_cdata *dc;
  455         struct de_softc *sc = arg;
  456         struct de_ring *rp;
  457         short csr0;
  458 
  459         /* save flags right away - clear out interrupt bits */
  460         csr0 = DE_RCSR(DE_PCSR0);
  461         DE_WHIGH(csr0 >> 8);
  462 
  463 
  464         sc->sc_if.if_flags |= IFF_OACTIVE;      /* prevent entering destart */
  465         /*
  466          * if receive, put receive buffer on mbuf
  467          * and hang the request again
  468          */
  469         derecv(sc);
  470 
  471         /*
  472          * Poll transmit ring and check status.
  473          * Be careful about loopback requests.
  474          * Then free buffer space and check for
  475          * more transmit requests.
  476          */
  477         dc = sc->sc_dedata;
  478         for ( ; sc->sc_nxmit > 0; sc->sc_nxmit--) {
  479                 rp = &dc->dc_xrent[sc->sc_xindex];
  480                 if (rp->r_flags & XFLG_OWN)
  481                         break;
  482 
  483                 if_statinc(&sc->sc_if, if_opackets);
  484                 ifxp = &sc->sc_ifw[sc->sc_xindex];
  485                 /* check for unusual conditions */
  486                 if (rp->r_flags & (XFLG_ERRS|XFLG_MTCH|XFLG_ONE|XFLG_MORE)) {
  487                         if (rp->r_flags & XFLG_ERRS) {
  488                                 /* output error */
  489                                 if_statinc(&sc->sc_if, if_oerrors);
  490                         } else if (rp->r_flags & XFLG_ONE) {
  491                                 /* one collision */
  492                                 if_statinc(&sc->sc_if, if_collisions);
  493                         } else if (rp->r_flags & XFLG_MORE) {
  494                                 /* more than one collision (guess...) */
  495                                 if_statadd(&sc->sc_if, if_collisions, 2);
  496                         }
  497                 }
  498                 if_ubaend(&sc->sc_ifuba, ifxp);
  499                 /* check if next transmit buffer also finished */
  500                 sc->sc_xindex++;
  501                 if (sc->sc_xindex == NXMT)
  502                         sc->sc_xindex = 0;
  503         }
  504         sc->sc_if.if_flags &= ~IFF_OACTIVE;
  505         destart(&sc->sc_if);
  506 
  507         if (csr0 & PCSR0_RCBI) {
  508                 DE_WLOW(PCSR0_INTE|CMD_PDMD);
  509         }
  510 }
  511 
  512 /*
  513  * Ethernet interface receiver interface.
  514  * If input error just drop packet.
  515  * Otherwise purge input buffered data path and examine
  516  * packet to determine type.  If can't determine length
  517  * from type, then have to drop packet.  Otherwise decapsulate
  518  * packet based on type and pass to type specific higher-level
  519  * input routine.
  520  */
  521 void
  522 derecv(struct de_softc *sc)
  523 {
  524         struct ifnet *ifp = &sc->sc_if;
  525         struct de_ring *rp;
  526         struct de_cdata *dc;
  527         struct mbuf *m;
  528         int len;
  529 
  530         dc = sc->sc_dedata;
  531         rp = &dc->dc_rrent[sc->sc_rindex];
  532         while ((rp->r_flags & RFLG_OWN) == 0) {
  533                 len = (rp->r_lenerr&RERR_MLEN) - ETHER_CRC_LEN;
  534                 /* check for errors */
  535                 if ((rp->r_flags & (RFLG_ERRS|RFLG_FRAM|RFLG_OFLO|RFLG_CRC)) ||
  536                     (rp->r_lenerr & (RERR_BUFL|RERR_UBTO))) {
  537                         if_statinc(&sc->sc_if, if_ierrors);
  538                         goto next;
  539                 }
  540                 m = if_ubaget(&sc->sc_ifuba, &sc->sc_ifr[sc->sc_rindex],
  541                     ifp, len);
  542                 if (m == 0) {
  543                         if_statinc(&sc->sc_if, if_ierrors);
  544                         goto next;
  545                 }
  546 
  547                 if_percpuq_enqueue(ifp->if_percpuq, m);
  548 
  549                 /* hang the receive buffer again */
  550 next:           rp->r_lenerr = 0;
  551                 rp->r_flags = RFLG_OWN;
  552 
  553                 /* check next receive buffer */
  554                 sc->sc_rindex++;
  555                 if (sc->sc_rindex == NRCV)
  556                         sc->sc_rindex = 0;
  557                 rp = &dc->dc_rrent[sc->sc_rindex];
  558         }
  559 }
  560 
  561 /*
  562  * Process an ioctl request.
  563  */
  564 int
  565 deioctl(struct ifnet *ifp, u_long cmd, void *data)
  566 {
  567         int s, error = 0;
  568 
  569         s = splnet();
  570 
  571         error = ether_ioctl(ifp, cmd, data);
  572         if (error == ENETRESET)
  573                 error = 0;
  574 
  575         splx(s);
  576         return (error);
  577 }
  578 
  579 /*
  580  * Await completion of the named function
  581  * and check for errors.
  582  */
  583 void
  584 dewait(struct de_softc *sc, const char *fn)
  585 {
  586         int csr0, csr1;
  587 
  588         while ((DE_RCSR(DE_PCSR0) & PCSR0_INTR) == 0)
  589                 ;
  590         csr0 = DE_RCSR(DE_PCSR0);
  591         DE_WHIGH(csr0 >> 8);
  592         if (csr0 & PCSR0_PCEI) {
  593                 char bits0[64];
  594                 char bits1[64];
  595                 csr1 = DE_RCSR(DE_PCSR1);
  596                 snprintb(bits0, sizeof(bits0), PCSR0_BITS, csr0);
  597                 snprintb(bits1, sizeof(bits1), PCSR1_BITS, csr1);
  598                 aprint_error_dev(sc->sc_dev, "%s failed, csr0=%s csr1=%s\n",
  599                     fn, bits0, bits1);
  600         }
  601 }
  602 
  603 int
  604 dematch(device_t parent, cfdata_t cf, void *aux)
  605 {
  606         struct uba_attach_args *ua = aux;
  607         struct de_softc ssc;
  608         struct de_softc *sc = &ssc;
  609         int i;
  610 
  611         sc->sc_iot = ua->ua_iot;
  612         sc->sc_ioh = ua->ua_ioh;
  613         /*
  614          * Make sure self-test is finished before we screw with the board.
  615          * Self-test on a DELUA can take 15 seconds (argh).
  616          */
  617         for (i = 0;
  618             (i < 160) &&
  619             (DE_RCSR(DE_PCSR0) & PCSR0_FATI) == 0 &&
  620             (DE_RCSR(DE_PCSR1) & PCSR1_STMASK) == STAT_RESET;
  621             ++i)
  622                 DELAY(50000);
  623         if (((DE_RCSR(DE_PCSR0) & PCSR0_FATI) != 0) ||
  624             (((DE_RCSR(DE_PCSR1) & PCSR1_STMASK) != STAT_READY) &&
  625             ((DE_RCSR(DE_PCSR1) & PCSR1_STMASK) != STAT_RUN)))
  626                 return(0);
  627 
  628         DE_WCSR(DE_PCSR0, 0);
  629         DELAY(5000);
  630         DE_WCSR(DE_PCSR0, PCSR0_RSET);
  631         while ((DE_RCSR(DE_PCSR0) & PCSR0_INTR) == 0)
  632                 ;
  633         /* make board interrupt by executing a GETPCBB command */
  634         DE_WCSR(DE_PCSR0, PCSR0_INTE);
  635         DE_WCSR(DE_PCSR2, 0);
  636         DE_WCSR(DE_PCSR3, 0);
  637         DE_WCSR(DE_PCSR0, PCSR0_INTE|CMD_GETPCBB);
  638         DELAY(50000);
  639 
  640         return 1;
  641 }
  642 
  643 void
  644 deshutdown(void *arg)
  645 {
  646         struct de_softc *sc = arg;
  647 
  648         DE_WCSR(DE_PCSR0, 0);
  649         DELAY(1000);
  650         DE_WCSR(DE_PCSR0, PCSR0_RSET);
  651         dewait(sc, "shutdown");
  652 }

Cache object: 8cbb52822d5088ed0d9d9438f63b25ec


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