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/am7990.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: am7990.c,v 1.67 2005/02/27 00:27:00 perry Exp $        */
    2 
    3 /*-
    4  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
    9  * Simulation Facility, NASA Ames Research Center.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  * 3. All advertising materials mentioning features or use of this software
   20  *    must display the following acknowledgement:
   21  *      This product includes software developed by the NetBSD
   22  *      Foundation, Inc. and its contributors.
   23  * 4. Neither the name of The NetBSD Foundation nor the names of its
   24  *    contributors may be used to endorse or promote products derived
   25  *    from this software without specific prior written permission.
   26  *
   27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   37  * POSSIBILITY OF SUCH DAMAGE.
   38  */
   39 
   40 /*-
   41  * Copyright (c) 1992, 1993
   42  *      The Regents of the University of California.  All rights reserved.
   43  *
   44  * This code is derived from software contributed to Berkeley by
   45  * Ralph Campbell and Rick Macklem.
   46  *
   47  * Redistribution and use in source and binary forms, with or without
   48  * modification, are permitted provided that the following conditions
   49  * are met:
   50  * 1. Redistributions of source code must retain the above copyright
   51  *    notice, this list of conditions and the following disclaimer.
   52  * 2. Redistributions in binary form must reproduce the above copyright
   53  *    notice, this list of conditions and the following disclaimer in the
   54  *    documentation and/or other materials provided with the distribution.
   55  * 3. Neither the name of the University nor the names of its contributors
   56  *    may be used to endorse or promote products derived from this software
   57  *    without specific prior written permission.
   58  *
   59  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   60  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   61  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   62  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   63  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   64  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   65  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   66  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   67  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   68  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   69  * SUCH DAMAGE.
   70  *
   71  *      @(#)if_le.c     8.2 (Berkeley) 11/16/93
   72  */
   73 
   74 #include <sys/cdefs.h>
   75 __KERNEL_RCSID(0, "$NetBSD: am7990.c,v 1.67 2005/02/27 00:27:00 perry Exp $");
   76 
   77 #include "bpfilter.h"
   78 #include "rnd.h"
   79 
   80 #include <sys/param.h>
   81 #include <sys/systm.h>
   82 #include <sys/mbuf.h>
   83 #include <sys/syslog.h>
   84 #include <sys/socket.h>
   85 #include <sys/device.h>
   86 #include <sys/malloc.h>
   87 #include <sys/ioctl.h>
   88 #include <sys/errno.h>
   89 #if NRND > 0
   90 #include <sys/rnd.h>
   91 #endif
   92 
   93 #include <net/if.h>
   94 #include <net/if_dl.h>
   95 #include <net/if_ether.h>
   96 #include <net/if_media.h>
   97 
   98 #if NBPFILTER > 0
   99 #include <net/bpf.h>
  100 #include <net/bpfdesc.h>
  101 #endif
  102 
  103 #include <dev/ic/lancereg.h>
  104 #include <dev/ic/lancevar.h>
  105 #include <dev/ic/am7990reg.h>
  106 #include <dev/ic/am7990var.h>
  107 
  108 static void     am7990_meminit(struct lance_softc *);
  109 static void     am7990_start(struct ifnet *);
  110 
  111 #if defined(_KERNEL_OPT)
  112 #include "opt_ddb.h"
  113 #endif
  114 
  115 #ifdef LEDEBUG
  116 static void     am7990_recv_print(struct lance_softc *, int);
  117 static void     am7990_xmit_print(struct lance_softc *, int);
  118 #endif
  119 
  120 #define ifp     (&sc->sc_ethercom.ec_if)
  121 
  122 void
  123 am7990_config(struct am7990_softc *sc)
  124 {
  125         int mem, i;
  126 
  127         sc->lsc.sc_meminit = am7990_meminit;
  128         sc->lsc.sc_start = am7990_start;
  129 
  130         lance_config(&sc->lsc);
  131 
  132         mem = 0;
  133         sc->lsc.sc_initaddr = mem;
  134         mem += sizeof(struct leinit);
  135         sc->lsc.sc_rmdaddr = mem;
  136         mem += sizeof(struct lermd) * sc->lsc.sc_nrbuf;
  137         sc->lsc.sc_tmdaddr = mem;
  138         mem += sizeof(struct letmd) * sc->lsc.sc_ntbuf;
  139         for (i = 0; i < sc->lsc.sc_nrbuf; i++, mem += LEBLEN)
  140                 sc->lsc.sc_rbufaddr[i] = mem;
  141         for (i = 0; i < sc->lsc.sc_ntbuf; i++, mem += LEBLEN)
  142                 sc->lsc.sc_tbufaddr[i] = mem;
  143 #ifdef notyet
  144         if (mem > ...)
  145                 panic(...);
  146 #endif
  147 }
  148 
  149 /*
  150  * Set up the initialization block and the descriptor rings.
  151  */
  152 static void
  153 am7990_meminit(struct lance_softc *sc)
  154 {
  155         u_long a;
  156         int bix;
  157         struct leinit init;
  158         struct lermd rmd;
  159         struct letmd tmd;
  160         u_int8_t *myaddr;
  161 
  162 #if NBPFILTER > 0
  163         if (ifp->if_flags & IFF_PROMISC)
  164                 init.init_mode = LE_MODE_NORMAL | LE_MODE_PROM;
  165         else
  166 #endif
  167                 init.init_mode = LE_MODE_NORMAL;
  168         if (sc->sc_initmodemedia == 1)
  169                 init.init_mode |= LE_MODE_PSEL0;
  170 
  171         /*
  172          * Update our private copy of the Ethernet address.
  173          * We NEED the copy so we can ensure its alignment!
  174          */
  175         memcpy(sc->sc_enaddr, LLADDR(ifp->if_sadl), ETHER_ADDR_LEN);
  176         myaddr = sc->sc_enaddr;
  177 
  178         init.init_padr[0] = (myaddr[1] << 8) | myaddr[0];
  179         init.init_padr[1] = (myaddr[3] << 8) | myaddr[2];
  180         init.init_padr[2] = (myaddr[5] << 8) | myaddr[4];
  181         lance_setladrf(&sc->sc_ethercom, init.init_ladrf);
  182 
  183         sc->sc_last_rd = 0;
  184         sc->sc_first_td = sc->sc_last_td = sc->sc_no_td = 0;
  185 
  186         a = sc->sc_addr + LE_RMDADDR(sc, 0);
  187         init.init_rdra = a;
  188         init.init_rlen = (a >> 16) | ((ffs(sc->sc_nrbuf) - 1) << 13);
  189 
  190         a = sc->sc_addr + LE_TMDADDR(sc, 0);
  191         init.init_tdra = a;
  192         init.init_tlen = (a >> 16) | ((ffs(sc->sc_ntbuf) - 1) << 13);
  193 
  194         (*sc->sc_copytodesc)(sc, &init, LE_INITADDR(sc), sizeof(init));
  195 
  196         /*
  197          * Set up receive ring descriptors.
  198          */
  199         for (bix = 0; bix < sc->sc_nrbuf; bix++) {
  200                 a = sc->sc_addr + LE_RBUFADDR(sc, bix);
  201                 rmd.rmd0 = a;
  202                 rmd.rmd1_hadr = a >> 16;
  203                 rmd.rmd1_bits = LE_R1_OWN;
  204                 rmd.rmd2 = -LEBLEN | LE_XMD2_ONES;
  205                 rmd.rmd3 = 0;
  206                 (*sc->sc_copytodesc)(sc, &rmd, LE_RMDADDR(sc, bix),
  207                     sizeof(rmd));
  208         }
  209 
  210         /*
  211          * Set up transmit ring descriptors.
  212          */
  213         for (bix = 0; bix < sc->sc_ntbuf; bix++) {
  214                 a = sc->sc_addr + LE_TBUFADDR(sc, bix);
  215                 tmd.tmd0 = a;
  216                 tmd.tmd1_hadr = a >> 16;
  217                 tmd.tmd1_bits = 0;
  218                 tmd.tmd2 = 0 | LE_XMD2_ONES;
  219                 tmd.tmd3 = 0;
  220                 (*sc->sc_copytodesc)(sc, &tmd, LE_TMDADDR(sc, bix),
  221                     sizeof(tmd));
  222         }
  223 }
  224 
  225 static void
  226 am7990_rint(struct lance_softc *sc)
  227 {
  228         int bix;
  229         int rp;
  230         struct lermd rmd;
  231 
  232         bix = sc->sc_last_rd;
  233 
  234         /* Process all buffers with valid data. */
  235         for (;;) {
  236                 rp = LE_RMDADDR(sc, bix);
  237                 (*sc->sc_copyfromdesc)(sc, &rmd, rp, sizeof(rmd));
  238 
  239                 if (rmd.rmd1_bits & LE_R1_OWN)
  240                         break;
  241 
  242                 if (rmd.rmd1_bits & LE_R1_ERR) {
  243                         if (rmd.rmd1_bits & LE_R1_ENP) {
  244 #ifdef LEDEBUG
  245                                 if ((rmd.rmd1_bits & LE_R1_OFLO) == 0) {
  246                                         if (rmd.rmd1_bits & LE_R1_FRAM)
  247                                                 printf("%s: framing error\n",
  248                                                     sc->sc_dev.dv_xname);
  249                                         if (rmd.rmd1_bits & LE_R1_CRC)
  250                                                 printf("%s: crc mismatch\n",
  251                                                     sc->sc_dev.dv_xname);
  252                                 }
  253 #endif
  254                         } else {
  255                                 if (rmd.rmd1_bits & LE_R1_OFLO)
  256                                         printf("%s: overflow\n",
  257                                             sc->sc_dev.dv_xname);
  258                         }
  259                         if (rmd.rmd1_bits & LE_R1_BUFF)
  260                                 printf("%s: receive buffer error\n",
  261                                     sc->sc_dev.dv_xname);
  262                         ifp->if_ierrors++;
  263                 } else if ((rmd.rmd1_bits & (LE_R1_STP | LE_R1_ENP)) !=
  264                     (LE_R1_STP | LE_R1_ENP)) {
  265                         printf("%s: dropping chained buffer\n",
  266                             sc->sc_dev.dv_xname);
  267                         ifp->if_ierrors++;
  268                 } else {
  269 #ifdef LEDEBUG
  270                         if (sc->sc_debug > 1)
  271                                 am7990_recv_print(sc, sc->sc_last_rd);
  272 #endif
  273                         lance_read(sc, LE_RBUFADDR(sc, bix),
  274                                    (int)rmd.rmd3 - 4);
  275                 }
  276 
  277                 rmd.rmd1_bits = LE_R1_OWN;
  278                 rmd.rmd2 = -LEBLEN | LE_XMD2_ONES;
  279                 rmd.rmd3 = 0;
  280                 (*sc->sc_copytodesc)(sc, &rmd, rp, sizeof(rmd));
  281 
  282 #ifdef LEDEBUG
  283                 if (sc->sc_debug)
  284                         printf("sc->sc_last_rd = %x, rmd: "
  285                                "ladr %04x, hadr %02x, flags %02x, "
  286                                "bcnt %04x, mcnt %04x\n",
  287                                 sc->sc_last_rd,
  288                                 rmd.rmd0, rmd.rmd1_hadr, rmd.rmd1_bits,
  289                                 rmd.rmd2, rmd.rmd3);
  290 #endif
  291 
  292                 if (++bix == sc->sc_nrbuf)
  293                         bix = 0;
  294         }
  295 
  296         sc->sc_last_rd = bix;
  297 }
  298 
  299 static void
  300 am7990_tint(struct lance_softc *sc)
  301 {
  302         int bix;
  303         struct letmd tmd;
  304 
  305         bix = sc->sc_first_td;
  306 
  307         for (;;) {
  308                 if (sc->sc_no_td <= 0)
  309                         break;
  310 
  311                 (*sc->sc_copyfromdesc)(sc, &tmd, LE_TMDADDR(sc, bix),
  312                     sizeof(tmd));
  313 
  314 #ifdef LEDEBUG
  315                 if (sc->sc_debug)
  316                         printf("trans tmd: "
  317                             "ladr %04x, hadr %02x, flags %02x, "
  318                             "bcnt %04x, mcnt %04x\n",
  319                             tmd.tmd0, tmd.tmd1_hadr, tmd.tmd1_bits,
  320                             tmd.tmd2, tmd.tmd3);
  321 #endif
  322 
  323                 if (tmd.tmd1_bits & LE_T1_OWN)
  324                         break;
  325 
  326                 ifp->if_flags &= ~IFF_OACTIVE;
  327 
  328                 if (tmd.tmd1_bits & LE_T1_ERR) {
  329                         if (tmd.tmd3 & LE_T3_BUFF)
  330                                 printf("%s: transmit buffer error\n",
  331                                     sc->sc_dev.dv_xname);
  332                         else if (tmd.tmd3 & LE_T3_UFLO)
  333                                 printf("%s: underflow\n", sc->sc_dev.dv_xname);
  334                         if (tmd.tmd3 & (LE_T3_BUFF | LE_T3_UFLO)) {
  335                                 lance_reset(sc);
  336                                 return;
  337                         }
  338                         if (tmd.tmd3 & LE_T3_LCAR) {
  339                                 sc->sc_havecarrier = 0;
  340                                 if (sc->sc_nocarrier)
  341                                         (*sc->sc_nocarrier)(sc);
  342                                 else
  343                                         printf("%s: lost carrier\n",
  344                                             sc->sc_dev.dv_xname);
  345                         }
  346                         if (tmd.tmd3 & LE_T3_LCOL)
  347                                 ifp->if_collisions++;
  348                         if (tmd.tmd3 & LE_T3_RTRY) {
  349 #ifdef LEDEBUG
  350                                 printf("%s: excessive collisions, tdr %d\n",
  351                                     sc->sc_dev.dv_xname,
  352                                     tmd.tmd3 & LE_T3_TDR_MASK);
  353 #endif
  354                                 ifp->if_collisions += 16;
  355                         }
  356                         ifp->if_oerrors++;
  357                 } else {
  358                         if (tmd.tmd1_bits & LE_T1_ONE)
  359                                 ifp->if_collisions++;
  360                         else if (tmd.tmd1_bits & LE_T1_MORE)
  361                                 /* Real number is unknown. */
  362                                 ifp->if_collisions += 2;
  363                         ifp->if_opackets++;
  364                 }
  365 
  366                 if (++bix == sc->sc_ntbuf)
  367                         bix = 0;
  368 
  369                 --sc->sc_no_td;
  370         }
  371 
  372         sc->sc_first_td = bix;
  373 
  374         am7990_start(ifp);
  375 
  376         if (sc->sc_no_td == 0)
  377                 ifp->if_timer = 0;
  378 }
  379 
  380 /*
  381  * Controller interrupt.
  382  */
  383 int
  384 am7990_intr(void *arg)
  385 {
  386         struct lance_softc *sc = arg;
  387         u_int16_t isr;
  388 
  389         isr = (*sc->sc_rdcsr)(sc, LE_CSR0) | sc->sc_saved_csr0;
  390         sc->sc_saved_csr0 = 0;
  391 #if defined(LEDEBUG) && LEDEBUG > 1
  392         if (sc->sc_debug)
  393                 printf("%s: am7990_intr entering with isr=%04x\n",
  394                     sc->sc_dev.dv_xname, isr);
  395 #endif
  396         if ((isr & LE_C0_INTR) == 0)
  397                 return (0);
  398 
  399 #ifdef __vax__
  400         /*
  401          * DEC needs this write order to the registers, don't know
  402          * the results on other arch's.  Ragge 991029
  403          */
  404         isr &= ~LE_C0_INEA;
  405         (*sc->sc_wrcsr)(sc, LE_CSR0, isr);
  406         (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INEA);
  407 #else
  408         (*sc->sc_wrcsr)(sc, LE_CSR0,
  409             isr & (LE_C0_INEA | LE_C0_BABL | LE_C0_MISS | LE_C0_MERR |
  410                    LE_C0_RINT | LE_C0_TINT | LE_C0_IDON));
  411 #endif
  412         if (isr & LE_C0_ERR) {
  413                 if (isr & LE_C0_BABL) {
  414 #ifdef LEDEBUG
  415                         printf("%s: babble\n", sc->sc_dev.dv_xname);
  416 #endif
  417                         ifp->if_oerrors++;
  418                 }
  419 #if 0
  420                 if (isr & LE_C0_CERR) {
  421                         printf("%s: collision error\n", sc->sc_dev.dv_xname);
  422                         ifp->if_collisions++;
  423                 }
  424 #endif
  425                 if (isr & LE_C0_MISS) {
  426 #ifdef LEDEBUG
  427                         printf("%s: missed packet\n", sc->sc_dev.dv_xname);
  428 #endif
  429                         ifp->if_ierrors++;
  430                 }
  431                 if (isr & LE_C0_MERR) {
  432                         printf("%s: memory error\n", sc->sc_dev.dv_xname);
  433                         lance_reset(sc);
  434                         return (1);
  435                 }
  436         }
  437 
  438         if ((isr & LE_C0_RXON) == 0) {
  439                 printf("%s: receiver disabled\n", sc->sc_dev.dv_xname);
  440                 ifp->if_ierrors++;
  441                 lance_reset(sc);
  442                 return (1);
  443         }
  444         if ((isr & LE_C0_TXON) == 0) {
  445                 printf("%s: transmitter disabled\n", sc->sc_dev.dv_xname);
  446                 ifp->if_oerrors++;
  447                 lance_reset(sc);
  448                 return (1);
  449         }
  450 
  451         /*
  452          * Pretend we have carrier; if we don't this will be cleared
  453          * shortly.
  454          */
  455         sc->sc_havecarrier = 1;
  456 
  457         if (isr & LE_C0_RINT)
  458                 am7990_rint(sc);
  459         if (isr & LE_C0_TINT)
  460                 am7990_tint(sc);
  461 
  462 #if NRND > 0
  463         rnd_add_uint32(&sc->rnd_source, isr);
  464 #endif
  465 
  466         return (1);
  467 }
  468 
  469 #undef ifp
  470 
  471 /*
  472  * Setup output on interface.
  473  * Get another datagram to send off of the interface queue, and map it to the
  474  * interface before starting the output.
  475  * Called only at splnet or interrupt level.
  476  */
  477 static void
  478 am7990_start(struct ifnet *ifp)
  479 {
  480         struct lance_softc *sc = ifp->if_softc;
  481         int bix;
  482         struct mbuf *m;
  483         struct letmd tmd;
  484         int rp;
  485         int len;
  486 
  487         if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
  488                 return;
  489 
  490         bix = sc->sc_last_td;
  491 
  492         for (;;) {
  493                 rp = LE_TMDADDR(sc, bix);
  494                 (*sc->sc_copyfromdesc)(sc, &tmd, rp, sizeof(tmd));
  495 
  496                 if (tmd.tmd1_bits & LE_T1_OWN) {
  497                         ifp->if_flags |= IFF_OACTIVE;
  498                         printf("missing buffer, no_td = %d, last_td = %d\n",
  499                             sc->sc_no_td, sc->sc_last_td);
  500                 }
  501 
  502                 IFQ_DEQUEUE(&ifp->if_snd, m);
  503                 if (m == 0)
  504                         break;
  505 
  506 #if NBPFILTER > 0
  507                 /*
  508                  * If BPF is listening on this interface, let it see the packet
  509                  * before we commit it to the wire.
  510                  */
  511                 if (ifp->if_bpf)
  512                         bpf_mtap(ifp->if_bpf, m);
  513 #endif
  514 
  515                 /*
  516                  * Copy the mbuf chain into the transmit buffer.
  517                  */
  518                 len = lance_put(sc, LE_TBUFADDR(sc, bix), m);
  519 
  520 #ifdef LEDEBUG
  521                 if (len > ETHERMTU + sizeof(struct ether_header))
  522                         printf("packet length %d\n", len);
  523 #endif
  524 
  525                 ifp->if_timer = 5;
  526 
  527                 /*
  528                  * Init transmit registers, and set transmit start flag.
  529                  */
  530                 tmd.tmd1_bits = LE_T1_OWN | LE_T1_STP | LE_T1_ENP;
  531                 tmd.tmd2 = -len | LE_XMD2_ONES;
  532                 tmd.tmd3 = 0;
  533 
  534                 (*sc->sc_copytodesc)(sc, &tmd, rp, sizeof(tmd));
  535 
  536 #ifdef LEDEBUG
  537                 if (sc->sc_debug > 1)
  538                         am7990_xmit_print(sc, sc->sc_last_td);
  539 #endif
  540 
  541                 (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INEA | LE_C0_TDMD);
  542 
  543                 if (++bix == sc->sc_ntbuf)
  544                         bix = 0;
  545 
  546                 if (++sc->sc_no_td == sc->sc_ntbuf) {
  547                         ifp->if_flags |= IFF_OACTIVE;
  548                         break;
  549                 }
  550 
  551         }
  552 
  553         sc->sc_last_td = bix;
  554 }
  555 
  556 #ifdef LEDEBUG
  557 static void
  558 am7990_recv_print(struct lance_softc *sc, int no)
  559 {
  560         struct lermd rmd;
  561         u_int16_t len;
  562         struct ether_header eh;
  563 
  564         (*sc->sc_copyfromdesc)(sc, &rmd, LE_RMDADDR(sc, no), sizeof(rmd));
  565         len = rmd.rmd3;
  566         printf("%s: receive buffer %d, len = %d\n", sc->sc_dev.dv_xname, no,
  567             len);
  568         printf("%s: status %04x\n", sc->sc_dev.dv_xname,
  569             (*sc->sc_rdcsr)(sc, LE_CSR0));
  570         printf("%s: ladr %04x, hadr %02x, flags %02x, bcnt %04x, mcnt %04x\n",
  571             sc->sc_dev.dv_xname,
  572             rmd.rmd0, rmd.rmd1_hadr, rmd.rmd1_bits, rmd.rmd2, rmd.rmd3);
  573         if (len >= sizeof(eh)) {
  574                 (*sc->sc_copyfrombuf)(sc, &eh, LE_RBUFADDR(sc, no), sizeof(eh));
  575                 printf("%s: dst %s", sc->sc_dev.dv_xname,
  576                         ether_sprintf(eh.ether_dhost));
  577                 printf(" src %s type %04x\n", ether_sprintf(eh.ether_shost),
  578                         ntohs(eh.ether_type));
  579         }
  580 }
  581 
  582 static void
  583 am7990_xmit_print(struct lance_softc *sc, int no)
  584 {
  585         struct letmd tmd;
  586         u_int16_t len;
  587         struct ether_header eh;
  588 
  589         (*sc->sc_copyfromdesc)(sc, &tmd, LE_TMDADDR(sc, no), sizeof(tmd));
  590         len = -tmd.tmd2;
  591         printf("%s: transmit buffer %d, len = %d\n", sc->sc_dev.dv_xname, no,
  592             len);
  593         printf("%s: status %04x\n", sc->sc_dev.dv_xname,
  594             (*sc->sc_rdcsr)(sc, LE_CSR0));
  595         printf("%s: ladr %04x, hadr %02x, flags %02x, bcnt %04x, mcnt %04x\n",
  596             sc->sc_dev.dv_xname,
  597             tmd.tmd0, tmd.tmd1_hadr, tmd.tmd1_bits, tmd.tmd2, tmd.tmd3);
  598         if (len >= sizeof(eh)) {
  599                 (*sc->sc_copyfrombuf)(sc, &eh, LE_TBUFADDR(sc, no), sizeof(eh));
  600                 printf("%s: dst %s", sc->sc_dev.dv_xname,
  601                         ether_sprintf(eh.ether_dhost));
  602                 printf(" src %s type %04x\n", ether_sprintf(eh.ether_shost),
  603                     ntohs(eh.ether_type));
  604         }
  605 }
  606 #endif /* LEDEBUG */

Cache object: 42048dddd78ef6be5206f0d3a3f2509d


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