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

Cache object: 34e78a19ab2bbfd1269aac8d8750a6ff


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