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

Cache object: 4169af9c01c58a6aee2ecf6cfda3c025


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