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/dp8390.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: dp8390.c,v 1.52 2003/01/15 22:20:05 bouyer Exp $       */
    2 
    3 /*
    4  * Device driver for National Semiconductor DS8390/WD83C690 based ethernet
    5  * adapters.
    6  *
    7  * Copyright (c) 1994, 1995 Charles M. Hannum.  All rights reserved.
    8  *
    9  * Copyright (C) 1993, David Greenman.  This software may be used, modified,
   10  * copied, distributed, and sold, in both source and binary form provided that
   11  * the above copyright and these terms are retained.  Under no circumstances is
   12  * the author responsible for the proper functioning of this software, nor does
   13  * the author assume any responsibility for damages incurred with its use.
   14  */
   15 
   16 #include <sys/cdefs.h>
   17 __KERNEL_RCSID(0, "$NetBSD: dp8390.c,v 1.52 2003/01/15 22:20:05 bouyer Exp $");
   18 
   19 #include "opt_ipkdb.h"
   20 #include "opt_inet.h"
   21 #include "opt_ns.h"
   22 #include "bpfilter.h"
   23 #include "rnd.h"
   24 
   25 #include <sys/param.h>
   26 #include <sys/systm.h>
   27 #include <sys/device.h>
   28 #include <sys/errno.h>
   29 #include <sys/ioctl.h>
   30 #include <sys/mbuf.h>
   31 #include <sys/socket.h>
   32 #include <sys/syslog.h>
   33 
   34 #if NRND > 0
   35 #include <sys/rnd.h>
   36 #endif
   37 
   38 #include <net/if.h>
   39 #include <net/if_dl.h>
   40 #include <net/if_types.h>
   41 #include <net/if_media.h>
   42 #include <net/if_ether.h>
   43 
   44 #ifdef INET
   45 #include <netinet/in.h>
   46 #include <netinet/in_systm.h>
   47 #include <netinet/in_var.h>
   48 #include <netinet/ip.h>
   49 #include <netinet/if_inarp.h>
   50 #endif
   51 
   52 #ifdef NS
   53 #include <netns/ns.h>
   54 #include <netns/ns_if.h>
   55 #endif
   56 
   57 #if NBPFILTER > 0
   58 #include <net/bpf.h>
   59 #include <net/bpfdesc.h>
   60 #endif
   61 
   62 #include <machine/bus.h>
   63 
   64 #ifdef IPKDB_DP8390
   65 #include <ipkdb/ipkdb.h>
   66 #endif
   67 
   68 #include <dev/ic/dp8390reg.h>
   69 #include <dev/ic/dp8390var.h>
   70 
   71 #ifdef DEBUG
   72 #define __inline__      /* XXX for debugging porpoises */
   73 int     dp8390_debug = 0;
   74 #endif
   75 
   76 static __inline__ void  dp8390_xmit __P((struct dp8390_softc *));
   77 
   78 static __inline__ void  dp8390_read_hdr __P((struct dp8390_softc *,
   79                             int, struct dp8390_ring *));
   80 static __inline__ int   dp8390_ring_copy __P((struct dp8390_softc *,
   81                             int, caddr_t, u_short));
   82 static __inline__ int   dp8390_write_mbuf __P((struct dp8390_softc *,
   83                             struct mbuf *, int));
   84 
   85 static int              dp8390_test_mem __P((struct dp8390_softc *));
   86 
   87 /*
   88  * Standard media init routine for the dp8390.
   89  */
   90 void
   91 dp8390_media_init(struct dp8390_softc *sc)
   92 {
   93 
   94         ifmedia_init(&sc->sc_media, 0, dp8390_mediachange, dp8390_mediastatus);
   95         ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
   96         ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL);
   97 }
   98 
   99 /*
  100  * Do bus-independent setup.
  101  */
  102 int
  103 dp8390_config(sc)
  104         struct dp8390_softc *sc;
  105 {
  106         struct ifnet *ifp = &sc->sc_ec.ec_if;
  107         int rv;
  108 
  109         rv = 1;
  110 
  111         if (!sc->test_mem)
  112                 sc->test_mem = dp8390_test_mem;
  113 
  114         /* Allocate one xmit buffer if < 16k, two buffers otherwise. */
  115         if ((sc->mem_size < 16384) ||
  116             (sc->sc_flags & DP8390_NO_MULTI_BUFFERING))
  117                 sc->txb_cnt = 1;
  118         else if (sc->mem_size < 8192 * 3)
  119                 sc->txb_cnt = 2;
  120         else
  121                 sc->txb_cnt = 3;
  122 
  123         sc->tx_page_start = sc->mem_start >> ED_PAGE_SHIFT;
  124         sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE;
  125         sc->rec_page_stop = sc->tx_page_start + (sc->mem_size >> ED_PAGE_SHIFT);
  126         sc->mem_ring = sc->mem_start + (sc->rec_page_start << ED_PAGE_SHIFT);
  127         sc->mem_end = sc->mem_start + sc->mem_size;
  128 
  129         /* Now zero memory and verify that it is clear. */
  130         if ((*sc->test_mem)(sc))
  131                 goto out;
  132 
  133         /* Set interface to stopped condition (reset). */
  134         dp8390_stop(sc);
  135 
  136         /* Initialize ifnet structure. */
  137         strcpy(ifp->if_xname, sc->sc_dev.dv_xname);
  138         ifp->if_softc = sc;
  139         ifp->if_start = dp8390_start;
  140         ifp->if_ioctl = dp8390_ioctl;
  141         if (!ifp->if_watchdog)
  142                 ifp->if_watchdog = dp8390_watchdog;
  143         ifp->if_flags =
  144             IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
  145         IFQ_SET_READY(&ifp->if_snd);
  146 
  147         /* Print additional info when attached. */
  148         printf("%s: Ethernet address %s\n", sc->sc_dev.dv_xname,
  149             ether_sprintf(sc->sc_enaddr));
  150 
  151         /* Initialize media goo. */
  152         (*sc->sc_media_init)(sc);
  153 
  154         /*
  155          * We can support 802.1Q VLAN-sized frames.
  156          */
  157         sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_MTU;
  158 
  159         /* Attach the interface. */
  160         if_attach(ifp);
  161         ether_ifattach(ifp, sc->sc_enaddr);
  162 
  163 #if NRND > 0
  164         rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname,
  165             RND_TYPE_NET, 0);
  166 #endif
  167 
  168         /* The attach is successful. */
  169         sc->sc_flags |= DP8390_ATTACHED;
  170 
  171         rv = 0;
  172 out:
  173         return (rv);
  174 }
  175 
  176 /*
  177  * Media change callback.
  178  */
  179 int
  180 dp8390_mediachange(ifp)
  181         struct ifnet *ifp;
  182 {
  183         struct dp8390_softc *sc = ifp->if_softc;
  184 
  185         if (sc->sc_mediachange)
  186                 return ((*sc->sc_mediachange)(sc));
  187         return (0);
  188 }
  189 
  190 /*
  191  * Media status callback.
  192  */
  193 void
  194 dp8390_mediastatus(ifp, ifmr)
  195         struct ifnet *ifp;
  196         struct ifmediareq *ifmr;
  197 {
  198         struct dp8390_softc *sc = ifp->if_softc;
  199 
  200         if (sc->sc_enabled == 0) {
  201                 ifmr->ifm_active = IFM_ETHER | IFM_NONE;
  202                 ifmr->ifm_status = 0;
  203                 return;
  204         }
  205 
  206         if (sc->sc_mediastatus)
  207                 (*sc->sc_mediastatus)(sc, ifmr);
  208 }
  209 
  210 /*
  211  * Reset interface.
  212  */
  213 void
  214 dp8390_reset(sc)
  215         struct dp8390_softc *sc;
  216 {
  217         int     s;
  218 
  219         s = splnet();
  220         dp8390_stop(sc);
  221         dp8390_init(sc);
  222         splx(s);
  223 }
  224 
  225 /*
  226  * Take interface offline.
  227  */
  228 void
  229 dp8390_stop(sc)
  230         struct dp8390_softc *sc;
  231 {
  232         bus_space_tag_t regt = sc->sc_regt;
  233         bus_space_handle_t regh = sc->sc_regh;
  234         int n = 5000;
  235 
  236         /* Stop everything on the interface, and select page 0 registers. */
  237         NIC_BARRIER(regt, regh);
  238         NIC_PUT(regt, regh, ED_P0_CR,
  239             sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STP);
  240         NIC_BARRIER(regt, regh);
  241 
  242         /*
  243          * Wait for interface to enter stopped state, but limit # of checks to
  244          * 'n' (about 5ms).  It shouldn't even take 5us on modern DS8390's, but
  245          * just in case it's an old one.
  246          */
  247         while (((NIC_GET(regt, regh,
  248             ED_P0_ISR) & ED_ISR_RST) == 0) && --n)
  249                 DELAY(1);
  250 
  251         if (sc->stop_card != NULL)
  252                 (*sc->stop_card)(sc);
  253 }
  254 
  255 /*
  256  * Device timeout/watchdog routine.  Entered if the device neglects to generate
  257  * an interrupt after a transmit has been started on it.
  258  */
  259 
  260 void
  261 dp8390_watchdog(ifp)
  262         struct ifnet *ifp;
  263 {
  264         struct dp8390_softc *sc = ifp->if_softc;
  265 
  266         log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
  267         ++sc->sc_ec.ec_if.if_oerrors;
  268 
  269         dp8390_reset(sc);
  270 }
  271 
  272 /*
  273  * Initialize device.
  274  */
  275 void
  276 dp8390_init(sc)
  277         struct dp8390_softc *sc;
  278 {
  279         bus_space_tag_t regt = sc->sc_regt;
  280         bus_space_handle_t regh = sc->sc_regh;
  281         struct ifnet *ifp = &sc->sc_ec.ec_if;
  282         u_int8_t mcaf[8];
  283         int i;
  284 
  285         /*
  286          * Initialize the NIC in the exact order outlined in the NS manual.
  287          * This init procedure is "mandatory"...don't change what or when
  288          * things happen.
  289          */
  290 
  291         /* Reset transmitter flags. */
  292         ifp->if_timer = 0;
  293 
  294         sc->txb_inuse = 0;
  295         sc->txb_new = 0;
  296         sc->txb_next_tx = 0;
  297 
  298         /* Set interface for page 0, remote DMA complete, stopped. */
  299         NIC_BARRIER(regt, regh);
  300         NIC_PUT(regt, regh, ED_P0_CR,
  301             sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STP);
  302         NIC_BARRIER(regt, regh);
  303 
  304         if (sc->dcr_reg & ED_DCR_LS) {
  305                 NIC_PUT(regt, regh, ED_P0_DCR, sc->dcr_reg);
  306         } else {
  307                 /*
  308                  * Set FIFO threshold to 8, No auto-init Remote DMA, byte
  309                  * order=80x86, byte-wide DMA xfers,
  310                  */
  311                 NIC_PUT(regt, regh, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
  312         }
  313 
  314         /* Clear remote byte count registers. */
  315         NIC_PUT(regt, regh, ED_P0_RBCR0, 0);
  316         NIC_PUT(regt, regh, ED_P0_RBCR1, 0);
  317 
  318         /* Tell RCR to do nothing for now. */
  319         NIC_PUT(regt, regh, ED_P0_RCR, ED_RCR_MON | sc->rcr_proto);
  320 
  321         /* Place NIC in internal loopback mode. */
  322         NIC_PUT(regt, regh, ED_P0_TCR, ED_TCR_LB0);
  323 
  324         /* Set lower bits of byte addressable framing to 0. */
  325         if (sc->is790)
  326                 NIC_PUT(regt, regh, 0x09, 0);
  327 
  328         /* Initialize receive buffer ring. */
  329         NIC_PUT(regt, regh, ED_P0_BNRY, sc->rec_page_start);
  330         NIC_PUT(regt, regh, ED_P0_PSTART, sc->rec_page_start);
  331         NIC_PUT(regt, regh, ED_P0_PSTOP, sc->rec_page_stop);
  332 
  333         /*
  334          * Enable the following interrupts: receive/transmit complete,
  335          * receive/transmit error, and Receiver OverWrite.
  336          *
  337          * Counter overflow and Remote DMA complete are *not* enabled.
  338          */
  339         NIC_PUT(regt, regh, ED_P0_IMR,
  340             ED_IMR_PRXE | ED_IMR_PTXE | ED_IMR_RXEE | ED_IMR_TXEE |
  341             ED_IMR_OVWE);
  342 
  343         /*
  344          * Clear all interrupts.  A '1' in each bit position clears the
  345          * corresponding flag.
  346          */
  347         NIC_PUT(regt, regh, ED_P0_ISR, 0xff);
  348 
  349         /* Program command register for page 1. */
  350         NIC_BARRIER(regt, regh);
  351         NIC_PUT(regt, regh, ED_P0_CR,
  352             sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STP);
  353         NIC_BARRIER(regt, regh);
  354 
  355         /* Copy out our station address. */
  356         for (i = 0; i < ETHER_ADDR_LEN; ++i)
  357                 NIC_PUT(regt, regh, ED_P1_PAR0 + i,
  358                     LLADDR(ifp->if_sadl)[i]);
  359 
  360         /* Set multicast filter on chip. */
  361         dp8390_getmcaf(&sc->sc_ec, mcaf);
  362         for (i = 0; i < 8; i++)
  363                 NIC_PUT(regt, regh, ED_P1_MAR0 + i, mcaf[i]);
  364 
  365         /*
  366          * Set current page pointer to one page after the boundary pointer, as
  367          * recommended in the National manual.
  368          */
  369         sc->next_packet = sc->rec_page_start + 1;
  370         NIC_PUT(regt, regh, ED_P1_CURR, sc->next_packet);
  371 
  372         /* Program command register for page 0. */
  373         NIC_BARRIER(regt, regh);
  374         NIC_PUT(regt, regh, ED_P1_CR,
  375             sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STP);
  376         NIC_BARRIER(regt, regh);
  377 
  378         /* Accept broadcast and multicast packets by default. */
  379         i = ED_RCR_AB | ED_RCR_AM | sc->rcr_proto;
  380         if (ifp->if_flags & IFF_PROMISC) {
  381                 /*
  382                  * Set promiscuous mode.  Multicast filter was set earlier so
  383                  * that we should receive all multicast packets.
  384                  */
  385                 i |= ED_RCR_PRO | ED_RCR_AR | ED_RCR_SEP;
  386         }
  387         NIC_PUT(regt, regh, ED_P0_RCR, i);
  388 
  389         /* Take interface out of loopback. */
  390         NIC_PUT(regt, regh, ED_P0_TCR, 0);
  391 
  392         /* Do any card-specific initialization, if applicable. */
  393         if (sc->init_card)
  394                 (*sc->init_card)(sc);
  395 
  396         /* Fire up the interface. */
  397         NIC_BARRIER(regt, regh);
  398         NIC_PUT(regt, regh, ED_P0_CR,
  399             sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
  400 
  401         /* Set 'running' flag, and clear output active flag. */
  402         ifp->if_flags |= IFF_RUNNING;
  403         ifp->if_flags &= ~IFF_OACTIVE;
  404 
  405         /* ...and attempt to start output. */
  406         dp8390_start(ifp);
  407 }
  408 
  409 /*
  410  * This routine actually starts the transmission on the interface.
  411  */
  412 static __inline__ void
  413 dp8390_xmit(sc)
  414         struct dp8390_softc *sc;
  415 {
  416         bus_space_tag_t regt = sc->sc_regt;
  417         bus_space_handle_t regh = sc->sc_regh;
  418         struct ifnet *ifp = &sc->sc_ec.ec_if;
  419         u_short len;
  420 
  421 #ifdef DIAGNOSTIC
  422         if ((sc->txb_next_tx + sc->txb_inuse) % sc->txb_cnt != sc->txb_new)
  423                 panic("dp8390_xmit: desync, next_tx=%d inuse=%d cnt=%d new=%d",
  424                     sc->txb_next_tx, sc->txb_inuse, sc->txb_cnt, sc->txb_new);
  425 
  426         if (sc->txb_inuse == 0)
  427                 panic("dp8390_xmit: no packets to xmit");
  428 #endif
  429 
  430         len = sc->txb_len[sc->txb_next_tx];
  431 
  432         /* Set NIC for page 0 register access. */
  433         NIC_BARRIER(regt, regh);
  434         NIC_PUT(regt, regh, ED_P0_CR,
  435             sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
  436         NIC_BARRIER(regt, regh);
  437 
  438         /* Set TX buffer start page. */
  439         NIC_PUT(regt, regh, ED_P0_TPSR, sc->tx_page_start +
  440             sc->txb_next_tx * ED_TXBUF_SIZE);
  441 
  442         /* Set TX length. */
  443         NIC_PUT(regt, regh, ED_P0_TBCR0, len);
  444         NIC_PUT(regt, regh, ED_P0_TBCR1, len >> 8);
  445 
  446         /* Set page 0, remote DMA complete, transmit packet, and *start*. */
  447         NIC_BARRIER(regt, regh);
  448         NIC_PUT(regt, regh, ED_P0_CR,
  449             sc->cr_proto | ED_CR_PAGE_0 | ED_CR_TXP | ED_CR_STA);
  450 
  451         /* Point to next transmit buffer slot and wrap if necessary. */
  452         if (++sc->txb_next_tx == sc->txb_cnt)
  453                 sc->txb_next_tx = 0;
  454 
  455         /* Set a timer just in case we never hear from the board again. */
  456         ifp->if_timer = 2;
  457 }
  458 
  459 /*
  460  * Start output on interface.
  461  * We make two assumptions here:
  462  *  1) that the current priority is set to splnet _before_ this code
  463  *     is called *and* is returned to the appropriate priority after
  464  *     return
  465  *  2) that the IFF_OACTIVE flag is checked before this code is called
  466  *     (i.e. that the output part of the interface is idle)
  467  */
  468 void
  469 dp8390_start(ifp)
  470         struct ifnet *ifp;
  471 {
  472         struct dp8390_softc *sc = ifp->if_softc;
  473         struct mbuf *m0;
  474         int buffer;
  475         int len;
  476 
  477         if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
  478                 return;
  479 
  480 outloop:
  481         /* See if there is room to put another packet in the buffer. */
  482         if (sc->txb_inuse == sc->txb_cnt) {
  483                 /* No room.  Indicate this to the outside world and exit. */
  484                 ifp->if_flags |= IFF_OACTIVE;
  485                 return;
  486         }
  487         IFQ_DEQUEUE(&ifp->if_snd, m0);
  488         if (m0 == 0)
  489                 return;
  490 
  491         /* We need to use m->m_pkthdr.len, so require the header */
  492         if ((m0->m_flags & M_PKTHDR) == 0)
  493                 panic("dp8390_start: no header mbuf");
  494 
  495 #if NBPFILTER > 0
  496         /* Tap off here if there is a BPF listener. */
  497         if (ifp->if_bpf)
  498                 bpf_mtap(ifp->if_bpf, m0);
  499 #endif
  500 
  501         /* txb_new points to next open buffer slot. */
  502         buffer = sc->mem_start +
  503             ((sc->txb_new * ED_TXBUF_SIZE) << ED_PAGE_SHIFT);
  504 
  505         if (sc->write_mbuf)
  506                 len = (*sc->write_mbuf)(sc, m0, buffer);
  507         else
  508                 len = dp8390_write_mbuf(sc, m0, buffer);
  509 
  510         m_freem(m0);
  511         sc->txb_len[sc->txb_new] = len;
  512 
  513         /* Point to next buffer slot and wrap if necessary. */
  514         if (++sc->txb_new == sc->txb_cnt)
  515                 sc->txb_new = 0;
  516 
  517         /* Start the first packet transmitting. */
  518         if (sc->txb_inuse++ == 0)
  519                 dp8390_xmit(sc);
  520 
  521         /* Loop back to the top to possibly buffer more packets. */
  522         goto outloop;
  523 }
  524 
  525 /*
  526  * Ethernet interface receiver interrupt.
  527  */
  528 void
  529 dp8390_rint(sc)
  530         struct dp8390_softc *sc;
  531 {
  532         bus_space_tag_t regt = sc->sc_regt;
  533         bus_space_handle_t regh = sc->sc_regh;
  534         struct dp8390_ring packet_hdr;
  535         int packet_ptr;
  536         u_short len;
  537         u_char boundary, current;
  538         u_char nlen;
  539 
  540 loop:
  541         /* Set NIC to page 1 registers to get 'current' pointer. */
  542         NIC_BARRIER(regt, regh);
  543         NIC_PUT(regt, regh, ED_P0_CR,
  544             sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STA);
  545         NIC_BARRIER(regt, regh);
  546 
  547         /*
  548          * 'sc->next_packet' is the logical beginning of the ring-buffer - i.e.
  549          * it points to where new data has been buffered.  The 'CURR' (current)
  550          * register points to the logical end of the ring-buffer - i.e. it
  551          * points to where additional new data will be added.  We loop here
  552          * until the logical beginning equals the logical end (or in other
  553          * words, until the ring-buffer is empty).
  554          */
  555         current = NIC_GET(regt, regh, ED_P1_CURR);
  556         if (sc->next_packet == current)
  557                 return;
  558 
  559         /* Set NIC to page 0 registers to update boundary register. */
  560         NIC_BARRIER(regt, regh);
  561         NIC_PUT(regt, regh, ED_P1_CR,
  562             sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
  563         NIC_BARRIER(regt, regh);
  564 
  565         do {
  566                 /* Get pointer to this buffer's header structure. */
  567                 packet_ptr = sc->mem_ring +
  568                     ((sc->next_packet - sc->rec_page_start) << ED_PAGE_SHIFT);
  569 
  570                 if (sc->read_hdr)
  571                         (*sc->read_hdr)(sc, packet_ptr, &packet_hdr);
  572                 else
  573                         dp8390_read_hdr(sc, packet_ptr, &packet_hdr);
  574                 len = packet_hdr.count;
  575 
  576                 /*
  577                  * Try do deal with old, buggy chips that sometimes duplicate
  578                  * the low byte of the length into the high byte.  We do this
  579                  * by simply ignoring the high byte of the length and always
  580                  * recalculating it.
  581                  *
  582                  * NOTE: sc->next_packet is pointing at the current packet.
  583                  */
  584                 if (packet_hdr.next_packet >= sc->next_packet)
  585                         nlen = (packet_hdr.next_packet - sc->next_packet);
  586                 else
  587                         nlen = ((packet_hdr.next_packet - sc->rec_page_start) +
  588                             (sc->rec_page_stop - sc->next_packet));
  589                 --nlen;
  590                 if ((len & ED_PAGE_MASK) + sizeof(packet_hdr) > ED_PAGE_SIZE)
  591                         --nlen;
  592                 len = (len & ED_PAGE_MASK) | (nlen << ED_PAGE_SHIFT);
  593 #ifdef DIAGNOSTIC
  594                 if (len != packet_hdr.count) {
  595                         printf("%s: length does not match "
  596                             "next packet pointer\n", sc->sc_dev.dv_xname);
  597                         printf("%s: len %04x nlen %04x start %02x "
  598                             "first %02x curr %02x next %02x stop %02x\n",
  599                             sc->sc_dev.dv_xname, packet_hdr.count, len,
  600                             sc->rec_page_start, sc->next_packet, current,
  601                             packet_hdr.next_packet, sc->rec_page_stop);
  602                 }
  603 #endif
  604 
  605                 /*
  606                  * Be fairly liberal about what we allow as a "reasonable"
  607                  * length so that a [crufty] packet will make it to BPF (and
  608                  * can thus be analyzed).  Note that all that is really
  609                  * important is that we have a length that will fit into one
  610                  * mbuf cluster or less; the upper layer protocols can then
  611                  * figure out the length from their own length field(s).
  612                  */
  613                 if (len <= MCLBYTES &&
  614                     packet_hdr.next_packet >= sc->rec_page_start &&
  615                     packet_hdr.next_packet < sc->rec_page_stop) {
  616                         /* Go get packet. */
  617                         dp8390_read(sc,
  618                             packet_ptr + sizeof(struct dp8390_ring),
  619                             len - sizeof(struct dp8390_ring));
  620                         ++sc->sc_ec.ec_if.if_ipackets;
  621                 } else {
  622                         /* Really BAD.  The ring pointers are corrupted. */
  623                         log(LOG_ERR, "%s: NIC memory corrupt - "
  624                             "invalid packet length %d\n",
  625                             sc->sc_dev.dv_xname, len);
  626                         ++sc->sc_ec.ec_if.if_ierrors;
  627                         dp8390_reset(sc);
  628                         return;
  629                 }
  630 
  631                 /* Update next packet pointer. */
  632                 sc->next_packet = packet_hdr.next_packet;
  633 
  634                 /*
  635                  * Update NIC boundary pointer - being careful to keep it one
  636                  * buffer behind (as recommended by NS databook).
  637                  */
  638                 boundary = sc->next_packet - 1;
  639                 if (boundary < sc->rec_page_start)
  640                         boundary = sc->rec_page_stop - 1;
  641                 NIC_PUT(regt, regh, ED_P0_BNRY, boundary);
  642         } while (sc->next_packet != current);
  643 
  644         goto loop;
  645 }
  646 
  647 /* Ethernet interface interrupt processor. */
  648 int
  649 dp8390_intr(arg)
  650         void *arg;
  651 {
  652         struct dp8390_softc *sc = (struct dp8390_softc *)arg;
  653         bus_space_tag_t regt = sc->sc_regt;
  654         bus_space_handle_t regh = sc->sc_regh;
  655         struct ifnet *ifp = &sc->sc_ec.ec_if;
  656         u_char isr;
  657 #if NRND > 0
  658         u_char rndisr;
  659 #endif
  660 
  661         if (sc->sc_enabled == 0 ||
  662             (sc->sc_dev.dv_flags & DVF_ACTIVE) == 0)
  663                 return (0);
  664 
  665         /* Set NIC to page 0 registers. */
  666         NIC_BARRIER(regt, regh);
  667         NIC_PUT(regt, regh, ED_P0_CR,
  668             sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
  669         NIC_BARRIER(regt, regh);
  670 
  671         isr = NIC_GET(regt, regh, ED_P0_ISR);
  672         if (!isr)
  673                 return (0);
  674 
  675 #if NRND > 0
  676         rndisr = isr;
  677 #endif
  678 
  679         /* Loop until there are no more new interrupts. */
  680         for (;;) {
  681                 /*
  682                  * Reset all the bits that we are 'acknowledging' by writing a
  683                  * '1' to each bit position that was set.
  684                  * (Writing a '1' *clears* the bit.)
  685                  */
  686                 NIC_PUT(regt, regh, ED_P0_ISR, isr);
  687 
  688                 /* Work around for AX88190 bug */
  689                 if ((sc->sc_flags & DP8390_DO_AX88190_WORKAROUND) != 0)
  690                         while ((NIC_GET(regt, regh, ED_P0_ISR) & isr) != 0) {
  691                                 NIC_PUT(regt, regh, ED_P0_ISR, 0);
  692                                 NIC_PUT(regt, regh, ED_P0_ISR, isr);
  693                         }
  694 
  695                 /*
  696                  * Handle transmitter interrupts.  Handle these first because
  697                  * the receiver will reset the board under some conditions.
  698                  *
  699                  * If the chip was reset while a packet was transmitting, it
  700                  * may still deliver a TX interrupt.  In this case, just ignore
  701                  * the interrupt.
  702                  */
  703                 if (isr & (ED_ISR_PTX | ED_ISR_TXE) &&
  704                     sc->txb_inuse != 0) {
  705                         u_char collisions =
  706                             NIC_GET(regt, regh, ED_P0_NCR) & 0x0f;
  707 
  708                         /*
  709                          * Check for transmit error.  If a TX completed with an
  710                          * error, we end up throwing the packet away.  Really
  711                          * the only error that is possible is excessive
  712                          * collisions, and in this case it is best to allow the
  713                          * automatic mechanisms of TCP to backoff the flow.  Of
  714                          * course, with UDP we're screwed, but this is expected
  715                          * when a network is heavily loaded.
  716                          */
  717                         if (isr & ED_ISR_TXE) {
  718                                 /*
  719                                  * Excessive collisions (16).
  720                                  */
  721                                 if ((NIC_GET(regt, regh, ED_P0_TSR)
  722                                     & ED_TSR_ABT) && (collisions == 0)) {
  723                                         /*
  724                                          * When collisions total 16, the P0_NCR
  725                                          * will indicate 0, and the TSR_ABT is
  726                                          * set.
  727                                          */
  728                                         collisions = 16;
  729                                 }
  730 
  731                                 /* Update output errors counter. */
  732                                 ++ifp->if_oerrors;
  733                         } else {
  734                                 /*
  735                                  * Throw away the non-error status bits.
  736                                  *
  737                                  * XXX
  738                                  * It may be useful to detect loss of carrier
  739                                  * and late collisions here.
  740                                  */
  741                                 (void)NIC_GET(regt, regh, ED_P0_TSR);
  742 
  743                                 /*
  744                                  * Update total number of successfully
  745                                  * transmitted packets.
  746                                  */
  747                                 ++ifp->if_opackets;
  748                         }
  749 
  750                         /* Clear watchdog timer. */
  751                         ifp->if_timer = 0;
  752                         ifp->if_flags &= ~IFF_OACTIVE;
  753 
  754                         /*
  755                          * Add in total number of collisions on last
  756                          * transmission.
  757                          */
  758                         ifp->if_collisions += collisions;
  759 
  760                         /*
  761                          * Decrement buffer in-use count if not zero (can only
  762                          * be zero if a transmitter interrupt occurred while not
  763                          * actually transmitting).
  764                          * If data is ready to transmit, start it transmitting,
  765                          * otherwise defer until after handling receiver.
  766                          */
  767                         if (--sc->txb_inuse != 0)
  768                                 dp8390_xmit(sc);
  769                 }
  770 
  771                 /* Handle receiver interrupts. */
  772                 if (isr & (ED_ISR_PRX | ED_ISR_RXE | ED_ISR_OVW)) {
  773                         /*
  774                          * Overwrite warning.  In order to make sure that a
  775                          * lockup of the local DMA hasn't occurred, we reset
  776                          * and re-init the NIC.  The NSC manual suggests only a
  777                          * partial reset/re-init is necessary - but some chips
  778                          * seem to want more.  The DMA lockup has been seen
  779                          * only with early rev chips - Methinks this bug was
  780                          * fixed in later revs.  -DG
  781                          */
  782                         if (isr & ED_ISR_OVW) {
  783                                 ++ifp->if_ierrors;
  784 #ifdef DIAGNOSTIC
  785                                 log(LOG_WARNING, "%s: warning - receiver "
  786                                     "ring buffer overrun\n",
  787                                     sc->sc_dev.dv_xname);
  788 #endif
  789                                 /* Stop/reset/re-init NIC. */
  790                                 dp8390_reset(sc);
  791                         } else {
  792                                 /*
  793                                  * Receiver Error.  One or more of: CRC error,
  794                                  * frame alignment error FIFO overrun, or
  795                                  * missed packet.
  796                                  */
  797                                 if (isr & ED_ISR_RXE) {
  798                                         ++ifp->if_ierrors;
  799 #ifdef DEBUG
  800                                         if (dp8390_debug) {
  801                                                 printf("%s: receive error %x\n",
  802                                                     sc->sc_dev.dv_xname,
  803                                                     NIC_GET(regt, regh,
  804                                                         ED_P0_RSR));
  805                                         }
  806 #endif
  807                                 }
  808 
  809                                 /*
  810                                  * Go get the packet(s)
  811                                  * XXX - Doing this on an error is dubious
  812                                  * because there shouldn't be any data to get
  813                                  * (we've configured the interface to not
  814                                  * accept packets with errors).
  815                                  */
  816                                 if (sc->recv_int)
  817                                         (*sc->recv_int)(sc);
  818                                 else
  819                                         dp8390_rint(sc);
  820                         }
  821                 }
  822 
  823                 /*
  824                  * If it looks like the transmitter can take more data, attempt
  825                  * to start output on the interface.  This is done after
  826                  * handling the receiver to give the receiver priority.
  827                  */
  828                 dp8390_start(ifp);
  829 
  830                 /*
  831                  * Return NIC CR to standard state: page 0, remote DMA
  832                  * complete, start (toggling the TXP bit off, even if was just
  833                  * set in the transmit routine, is *okay* - it is 'edge'
  834                  * triggered from low to high).
  835                  */
  836                 NIC_BARRIER(regt, regh);
  837                 NIC_PUT(regt, regh, ED_P0_CR,
  838                     sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
  839                 NIC_BARRIER(regt, regh);
  840 
  841                 /*
  842                  * If the Network Talley Counters overflow, read them to reset
  843                  * them.  It appears that old 8390's won't clear the ISR flag
  844                  * otherwise - resulting in an infinite loop.
  845                  */
  846                 if (isr & ED_ISR_CNT) {
  847                         (void)NIC_GET(regt, regh, ED_P0_CNTR0);
  848                         (void)NIC_GET(regt, regh, ED_P0_CNTR1);
  849                         (void)NIC_GET(regt, regh, ED_P0_CNTR2);
  850                 }
  851 
  852                 isr = NIC_GET(regt, regh, ED_P0_ISR);
  853                 if (!isr)
  854                         goto out;
  855         }
  856 
  857  out:
  858 #if NRND > 0
  859         rnd_add_uint32(&sc->rnd_source, rndisr);
  860 #endif
  861         return (1);
  862 }
  863 
  864 /*
  865  * Process an ioctl request.  This code needs some work - it looks pretty ugly.
  866  */
  867 int
  868 dp8390_ioctl(ifp, cmd, data)
  869         struct ifnet *ifp;
  870         u_long cmd;
  871         caddr_t data;
  872 {
  873         struct dp8390_softc *sc = ifp->if_softc;
  874         struct ifaddr *ifa = (struct ifaddr *) data;
  875         struct ifreq *ifr = (struct ifreq *) data;
  876         int s, error = 0;
  877 
  878         s = splnet();
  879 
  880         switch (cmd) {
  881 
  882         case SIOCSIFADDR:
  883                 if ((error = dp8390_enable(sc)) != 0)
  884                         break;
  885                 ifp->if_flags |= IFF_UP;
  886 
  887                 switch (ifa->ifa_addr->sa_family) {
  888 #ifdef INET
  889                 case AF_INET:
  890                         dp8390_init(sc);
  891                         arp_ifinit(ifp, ifa);
  892                         break;
  893 #endif
  894 #ifdef NS
  895                         /* XXX - This code is probably wrong. */
  896                 case AF_NS:
  897                     {
  898                         struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
  899 
  900                         if (ns_nullhost(*ina))
  901                                 ina->x_host =
  902                                     *(union ns_host *)LLADDR(ifp->if_sadl);
  903                         else
  904                                 memcpy(LLADDR(ifp->if_sadl),
  905                                     ina->x_host.c_host, ETHER_ADDR_LEN);
  906                         /* Set new address. */
  907                         dp8390_init(sc);
  908                         break;
  909                     }
  910 #endif
  911                 default:
  912                         dp8390_init(sc);
  913                         break;
  914                 }
  915                 break;
  916 
  917         case SIOCSIFFLAGS:
  918                 if ((ifp->if_flags & IFF_UP) == 0 &&
  919                     (ifp->if_flags & IFF_RUNNING) != 0) {
  920                         /*
  921                          * If interface is marked down and it is running, then
  922                          * stop it.
  923                          */
  924                         dp8390_stop(sc);
  925                         ifp->if_flags &= ~IFF_RUNNING;
  926                         dp8390_disable(sc);
  927                 } else if ((ifp->if_flags & IFF_UP) != 0 &&
  928                     (ifp->if_flags & IFF_RUNNING) == 0) {
  929                         /*
  930                          * If interface is marked up and it is stopped, then
  931                          * start it.
  932                          */
  933                         if ((error = dp8390_enable(sc)) != 0)
  934                                 break;
  935                         dp8390_init(sc);
  936                 } else if ((ifp->if_flags & IFF_UP) != 0) {
  937                         /*
  938                          * Reset the interface to pick up changes in any other
  939                          * flags that affect hardware registers.
  940                          */
  941                         dp8390_stop(sc);
  942                         dp8390_init(sc);
  943                 }
  944                 break;
  945 
  946         case SIOCADDMULTI:
  947         case SIOCDELMULTI:
  948                 if (sc->sc_enabled == 0) {
  949                         error = EIO;
  950                         break;
  951                 }
  952 
  953                 /* Update our multicast list. */
  954                 error = (cmd == SIOCADDMULTI) ?
  955                     ether_addmulti(ifr, &sc->sc_ec) :
  956                     ether_delmulti(ifr, &sc->sc_ec);
  957 
  958                 if (error == ENETRESET) {
  959                         /*
  960                          * Multicast list has changed; set the hardware filter
  961                          * accordingly.
  962                          */
  963                         dp8390_stop(sc);        /* XXX for ds_setmcaf? */
  964                         dp8390_init(sc);
  965                         error = 0;
  966                 }
  967                 break;
  968 
  969         case SIOCGIFMEDIA:
  970         case SIOCSIFMEDIA:
  971                 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
  972                 break;
  973 
  974         default:
  975                 error = EINVAL;
  976                 break;
  977         }
  978 
  979         splx(s);
  980         return (error);
  981 }
  982 
  983 /*
  984  * Retrieve packet from buffer memory and send to the next level up via
  985  * ether_input().  If there is a BPF listener, give a copy to BPF, too.
  986  */
  987 void
  988 dp8390_read(sc, buf, len)
  989         struct dp8390_softc *sc;
  990         int buf;
  991         u_short len;
  992 {
  993         struct ifnet *ifp = &sc->sc_ec.ec_if;
  994         struct mbuf *m;
  995 
  996         /* Pull packet off interface. */
  997         m = dp8390_get(sc, buf, len);
  998         if (m == 0) {
  999                 ifp->if_ierrors++;
 1000                 return;
 1001         }
 1002 
 1003         ifp->if_ipackets++;
 1004 
 1005 #if NBPFILTER > 0
 1006         /*
 1007          * Check if there's a BPF listener on this interface.
 1008          * If so, hand off the raw packet to bpf.
 1009          */
 1010         if (ifp->if_bpf)
 1011                 bpf_mtap(ifp->if_bpf, m);
 1012 #endif
 1013 
 1014         (*ifp->if_input)(ifp, m);
 1015 }
 1016 
 1017 
 1018 /*
 1019  * Supporting routines.
 1020  */
 1021 
 1022 /*
 1023  * Compute the multicast address filter from the list of multicast addresses we
 1024  * need to listen to.
 1025  */
 1026 void
 1027 dp8390_getmcaf(ec, af)
 1028         struct ethercom *ec;
 1029         u_int8_t *af;
 1030 {
 1031         struct ifnet *ifp = &ec->ec_if;
 1032         struct ether_multi *enm;
 1033         u_int32_t crc;
 1034         int i;
 1035         struct ether_multistep step;
 1036 
 1037         /*
 1038          * Set up multicast address filter by passing all multicast addresses
 1039          * through a crc generator, and then using the high order 6 bits as an
 1040          * index into the 64 bit logical address filter.  The high order bit
 1041          * selects the word, while the rest of the bits select the bit within
 1042          * the word.
 1043          */
 1044 
 1045         if (ifp->if_flags & IFF_PROMISC) {
 1046                 ifp->if_flags |= IFF_ALLMULTI;
 1047                 for (i = 0; i < 8; i++)
 1048                         af[i] = 0xff;
 1049                 return;
 1050         }
 1051         for (i = 0; i < 8; i++)
 1052                 af[i] = 0;
 1053         ETHER_FIRST_MULTI(step, ec, enm);
 1054         while (enm != NULL) {
 1055                 if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
 1056                     sizeof(enm->enm_addrlo)) != 0) {
 1057                         /*
 1058                          * We must listen to a range of multicast addresses.
 1059                          * For now, just accept all multicasts, rather than
 1060                          * trying to set only those filter bits needed to match
 1061                          * the range.  (At this time, the only use of address
 1062                          * ranges is for IP multicast routing, for which the
 1063                          * range is big enough to require all bits set.)
 1064                          */
 1065                         ifp->if_flags |= IFF_ALLMULTI;
 1066                         for (i = 0; i < 8; i++)
 1067                                 af[i] = 0xff;
 1068                         return;
 1069                 }
 1070 
 1071                 crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN);
 1072 
 1073                 /* Just want the 6 most significant bits. */
 1074                 crc >>= 26;
 1075 
 1076                 /* Turn on the corresponding bit in the filter. */
 1077                 af[crc >> 3] |= 1 << (crc & 0x7);
 1078 
 1079                 ETHER_NEXT_MULTI(step, enm);
 1080         }
 1081         ifp->if_flags &= ~IFF_ALLMULTI;
 1082 }
 1083 
 1084 /*
 1085  * Copy data from receive buffer to a new mbuf chain allocating mbufs
 1086  * as needed.  Return pointer to first mbuf in chain.
 1087  * sc = dp8390 info (softc)
 1088  * src = pointer in dp8390 ring buffer
 1089  * total_len = amount of data to copy
 1090  */
 1091 struct mbuf *
 1092 dp8390_get(sc, src, total_len)
 1093         struct dp8390_softc *sc;
 1094         int src;
 1095         u_short total_len;
 1096 {
 1097         struct ifnet *ifp = &sc->sc_ec.ec_if;
 1098         struct mbuf *m, *m0, *newm;
 1099         u_short len;
 1100 
 1101         MGETHDR(m0, M_DONTWAIT, MT_DATA);
 1102         if (m0 == 0)
 1103                 return (0);
 1104         m0->m_pkthdr.rcvif = ifp;
 1105         m0->m_pkthdr.len = total_len;
 1106         len = MHLEN;
 1107         m = m0;
 1108 
 1109         while (total_len > 0) {
 1110                 if (total_len >= MINCLSIZE) {
 1111                         MCLGET(m, M_DONTWAIT);
 1112                         if ((m->m_flags & M_EXT) == 0)
 1113                                 goto bad;
 1114                         len = MCLBYTES;
 1115                 }
 1116 
 1117                 /*
 1118                  * Make sure the data after the Ethernet header is aligned.
 1119                  */
 1120                 if (m == m0) {
 1121                         caddr_t newdata = (caddr_t)
 1122                             ALIGN(m->m_data + sizeof(struct ether_header)) -
 1123                             sizeof(struct ether_header);
 1124                         len -= newdata - m->m_data;
 1125                         m->m_data = newdata;
 1126                 }
 1127 
 1128                 m->m_len = len = min(total_len, len);
 1129                 if (sc->ring_copy)
 1130                         src = (*sc->ring_copy)(sc, src, mtod(m, caddr_t), len);
 1131                 else
 1132                         src = dp8390_ring_copy(sc, src, mtod(m, caddr_t), len);
 1133 
 1134                 total_len -= len;
 1135                 if (total_len > 0) {
 1136                         MGET(newm, M_DONTWAIT, MT_DATA);
 1137                         if (newm == 0)
 1138                                 goto bad;
 1139                         len = MLEN;
 1140                         m = m->m_next = newm;
 1141                 }
 1142         }
 1143 
 1144         return (m0);
 1145 
 1146 bad:
 1147         m_freem(m0);
 1148         return (0);
 1149 }
 1150 
 1151 
 1152 /*
 1153  * Default driver support functions.
 1154  *
 1155  * NOTE: all support functions assume 8-bit shared memory.
 1156  */
 1157 /*
 1158  * Zero NIC buffer memory and verify that it is clear.
 1159  */
 1160 static int
 1161 dp8390_test_mem(sc)
 1162         struct dp8390_softc *sc;
 1163 {
 1164         bus_space_tag_t buft = sc->sc_buft;
 1165         bus_space_handle_t bufh = sc->sc_bufh;
 1166         int i;
 1167 
 1168         bus_space_set_region_1(buft, bufh, sc->mem_start, 0, sc->mem_size);
 1169 
 1170         for (i = 0; i < sc->mem_size; ++i) {
 1171                 if (bus_space_read_1(buft, bufh, sc->mem_start + i)) {
 1172                         printf(": failed to clear NIC buffer at offset %x - "
 1173                             "check configuration\n", (sc->mem_start + i));
 1174                         return 1;
 1175                 }
 1176         }
 1177 
 1178         return 0;
 1179 }
 1180 
 1181 /*
 1182  * Read a packet header from the ring, given the source offset.
 1183  */
 1184 static __inline__ void
 1185 dp8390_read_hdr(sc, src, hdrp)
 1186         struct dp8390_softc *sc;
 1187         int src;
 1188         struct dp8390_ring *hdrp;
 1189 {
 1190         bus_space_tag_t buft = sc->sc_buft;
 1191         bus_space_handle_t bufh = sc->sc_bufh;
 1192 
 1193         /*
 1194          * The byte count includes a 4 byte header that was added by
 1195          * the NIC.
 1196          */
 1197         hdrp->rsr = bus_space_read_1(buft, bufh, src);
 1198         hdrp->next_packet = bus_space_read_1(buft, bufh, src + 1);
 1199         hdrp->count = bus_space_read_1(buft, bufh, src + 2) |
 1200             (bus_space_read_1(buft, bufh, src + 3) << 8);
 1201 }
 1202 
 1203 /*
 1204  * Copy `amount' bytes from a packet in the ring buffer to a linear
 1205  * destination buffer, given a source offset and destination address.
 1206  * Takes into account ring-wrap.
 1207  */
 1208 static __inline__ int
 1209 dp8390_ring_copy(sc, src, dst, amount)
 1210         struct dp8390_softc *sc;
 1211         int src;
 1212         caddr_t dst;
 1213         u_short amount;
 1214 {
 1215         bus_space_tag_t buft = sc->sc_buft;
 1216         bus_space_handle_t bufh = sc->sc_bufh;
 1217         u_short tmp_amount;
 1218 
 1219         /* Does copy wrap to lower addr in ring buffer? */
 1220         if (src + amount > sc->mem_end) {
 1221                 tmp_amount = sc->mem_end - src;
 1222 
 1223                 /* Copy amount up to end of NIC memory. */
 1224                 bus_space_read_region_1(buft, bufh, src, dst, tmp_amount);
 1225 
 1226                 amount -= tmp_amount;
 1227                 src = sc->mem_ring;
 1228                 dst += tmp_amount;
 1229         }
 1230         bus_space_read_region_1(buft, bufh, src, dst, amount);
 1231 
 1232         return (src + amount);
 1233 }
 1234 
 1235 /*
 1236  * Copy a packet from an mbuf to the transmit buffer on the card.
 1237  *
 1238  * Currently uses an extra buffer/extra memory copy, unless the whole
 1239  * packet fits in one mbuf.
 1240  */
 1241 static __inline__ int
 1242 dp8390_write_mbuf(sc, m, buf)
 1243         struct dp8390_softc *sc;
 1244         struct mbuf *m;
 1245         int buf;
 1246 {
 1247         bus_space_tag_t buft = sc->sc_buft;
 1248         bus_space_handle_t bufh = sc->sc_bufh;
 1249         u_char *data;
 1250         int len, totlen = 0;
 1251 
 1252         for (; m ; m = m->m_next) {
 1253                 data = mtod(m, u_char *);
 1254                 len = m->m_len;
 1255                 if (len > 0) {
 1256                         bus_space_write_region_1(buft, bufh, buf, data, len);
 1257                         totlen += len;
 1258                         buf += len;
 1259                 }
 1260         }
 1261         if (totlen < ETHER_MIN_LEN - ETHER_CRC_LEN) {
 1262                 bus_space_set_region_1(buft, bufh, buf, 0,
 1263                     ETHER_MIN_LEN - ETHER_CRC_LEN - totlen);
 1264                 totlen = ETHER_MIN_LEN - ETHER_CRC_LEN;
 1265         }
 1266         return (totlen);
 1267 }
 1268 
 1269 /*
 1270  * Enable power on the interface.
 1271  */
 1272 int
 1273 dp8390_enable(sc)
 1274         struct dp8390_softc *sc;
 1275 {
 1276 
 1277         if (sc->sc_enabled == 0 && sc->sc_enable != NULL) {
 1278                 if ((*sc->sc_enable)(sc) != 0) {
 1279                         printf("%s: device enable failed\n",
 1280                             sc->sc_dev.dv_xname);
 1281                         return (EIO);
 1282                 }
 1283         }
 1284 
 1285         sc->sc_enabled = 1;
 1286         return (0);
 1287 }
 1288 
 1289 /*
 1290  * Disable power on the interface.
 1291  */
 1292 void
 1293 dp8390_disable(sc)
 1294         struct dp8390_softc *sc;
 1295 {
 1296 
 1297         if (sc->sc_enabled != 0 && sc->sc_disable != NULL) {
 1298                 (*sc->sc_disable)(sc);
 1299                 sc->sc_enabled = 0;
 1300         }
 1301 }
 1302 
 1303 int
 1304 dp8390_activate(self, act)
 1305         struct device *self;
 1306         enum devact act;
 1307 {
 1308         struct dp8390_softc *sc = (struct dp8390_softc *)self;
 1309         int rv = 0, s;
 1310 
 1311         s = splnet();
 1312         switch (act) {
 1313         case DVACT_ACTIVATE:
 1314                 rv = EOPNOTSUPP;
 1315                 break;
 1316 
 1317         case DVACT_DEACTIVATE:
 1318                 if_deactivate(&sc->sc_ec.ec_if);
 1319                 break;
 1320         }
 1321         splx(s);
 1322         return (rv);
 1323 }
 1324 
 1325 int
 1326 dp8390_detach(sc, flags)
 1327         struct dp8390_softc *sc;
 1328         int flags;
 1329 {
 1330         struct ifnet *ifp = &sc->sc_ec.ec_if;
 1331 
 1332         /* Succeed now if there's no work to do. */
 1333         if ((sc->sc_flags & DP8390_ATTACHED) == 0)
 1334                 return (0);
 1335 
 1336         /* dp8390_disable() checks sc->sc_enabled */
 1337         dp8390_disable(sc);
 1338 
 1339         if (sc->sc_media_fini != NULL)
 1340                 (*sc->sc_media_fini)(sc);
 1341 
 1342         /* Delete all remaining media. */
 1343         ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY);
 1344 
 1345 #if NRND > 0
 1346         rnd_detach_source(&sc->rnd_source);
 1347 #endif
 1348         ether_ifdetach(ifp);
 1349         if_detach(ifp);
 1350 
 1351         return (0);
 1352 }
 1353 
 1354 #ifdef IPKDB_DP8390
 1355 static void dp8390_ipkdb_hwinit __P((struct ipkdb_if *));
 1356 static void dp8390_ipkdb_init __P((struct ipkdb_if *));
 1357 static void dp8390_ipkdb_leave __P((struct ipkdb_if *));
 1358 static int dp8390_ipkdb_rcv __P((struct ipkdb_if *, u_char *, int));
 1359 static void dp8390_ipkdb_send __P((struct ipkdb_if *, u_char *, int));
 1360 
 1361 /*
 1362  * This is essentially similar to dp8390_config above.
 1363  */
 1364 int
 1365 dp8390_ipkdb_attach(kip)
 1366         struct ipkdb_if *kip;
 1367 {
 1368         struct dp8390_softc *sc = kip->port;
 1369 
 1370         if (sc->mem_size < 8192 * 2)
 1371                 sc->txb_cnt = 1;
 1372         else if (sc->mem_size < 8192 * 3)
 1373                 sc->txb_cnt = 2;
 1374         else
 1375                 sc->txb_cnt = 3;
 1376 
 1377         sc->tx_page_start = sc->mem_start >> ED_PAGE_SHIFT;
 1378         sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE;
 1379         sc->rec_page_stop = sc->tx_page_start + (sc->mem_size >> ED_PAGE_SHIFT);
 1380         sc->mem_ring = sc->mem_start + (sc->rec_page_start << ED_PAGE_SHIFT);
 1381         sc->mem_end = sc->mem_start + sc->mem_size;
 1382 
 1383         dp8390_stop(sc);
 1384 
 1385         kip->start = dp8390_ipkdb_init;
 1386         kip->leave = dp8390_ipkdb_leave;
 1387         kip->receive = dp8390_ipkdb_rcv;
 1388         kip->send = dp8390_ipkdb_send;
 1389 
 1390         return 0;
 1391 }
 1392 
 1393 /*
 1394  * Similar to dp8390_init above.
 1395  */
 1396 static void
 1397 dp8390_ipkdb_hwinit(kip)
 1398         struct ipkdb_if *kip;
 1399 {
 1400         struct dp8390_softc *sc = kip->port;
 1401         struct ifnet *ifp = &sc->sc_ec.ec_if;
 1402         bus_space_tag_t regt = sc->sc_regt;
 1403         bus_space_handle_t regh = sc->sc_regh;
 1404         int i;
 1405 
 1406         sc->txb_inuse = 0;
 1407         sc->txb_new = 0;
 1408         sc->txb_next_tx = 0;
 1409         dp8390_stop(sc);
 1410 
 1411         if (sc->dcr_reg & ED_DCR_LS)
 1412                 NIC_PUT(regt, regh, ED_P0_DCR, sc->dcr_reg);
 1413         else
 1414                 NIC_PUT(regt, regh, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
 1415         NIC_PUT(regt, regh, ED_P0_RBCR0, 0);
 1416         NIC_PUT(regt, regh, ED_P0_RBCR1, 0);
 1417         NIC_PUT(regt, regh, ED_P0_RCR, ED_RCR_MON | sc->rcr_proto);
 1418         NIC_PUT(regt, regh, ED_P0_TCR, ED_TCR_LB0);
 1419         if (sc->is790)
 1420                 NIC_PUT(regt, regh, 0x09, 0);
 1421         NIC_PUT(regt, regh, ED_P0_BNRY, sc->rec_page_start);
 1422         NIC_PUT(regt, regh, ED_P0_PSTART, sc->rec_page_start);
 1423         NIC_PUT(regt, regh, ED_P0_PSTOP, sc->rec_page_stop);
 1424         NIC_PUT(regt, regh, ED_P0_IMR, 0);
 1425         NIC_BARRIER(regt, regh);
 1426         NIC_PUT(regt, regh, ED_P0_ISR, 0xff);
 1427 
 1428         NIC_BARRIER(regt, regh);
 1429         NIC_PUT(regt, regh, ED_P0_CR,
 1430                 sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STP);
 1431         NIC_BARRIER(regt, regh);
 1432 
 1433         for (i = 0; i < sizeof kip->myenetaddr; i++)
 1434                 NIC_PUT(regt, regh, ED_P1_PAR0 + i, kip->myenetaddr[i]);
 1435         /* multicast filter? */
 1436 
 1437         sc->next_packet = sc->rec_page_start + 1;
 1438         NIC_PUT(regt, regh, ED_P1_CURR, sc->next_packet);
 1439 
 1440         NIC_BARRIER(regt, regh);
 1441         NIC_PUT(regt, regh, ED_P1_CR,
 1442                 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STP);
 1443         NIC_BARRIER(regt, regh);
 1444 
 1445         /* promiscuous mode? */
 1446         NIC_PUT(regt, regh, ED_P0_RCR, ED_RCR_AB | ED_RCR_AM | sc->rcr_proto);
 1447         NIC_PUT(regt, regh, ED_P0_TCR, 0);
 1448 
 1449         /* card-specific initialization? */
 1450 
 1451         NIC_BARRIER(regt, regh);
 1452         NIC_PUT(regt, regh, ED_P0_CR,
 1453                 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
 1454 
 1455         ifp->if_flags &= ~IFF_OACTIVE;
 1456 }
 1457 
 1458 static void
 1459 dp8390_ipkdb_init(kip)
 1460         struct ipkdb_if *kip;
 1461 {
 1462         struct dp8390_softc *sc = kip->port;
 1463         bus_space_tag_t regt = sc->sc_regt;
 1464         bus_space_handle_t regh = sc->sc_regh;
 1465         u_char cmd;
 1466 
 1467         cmd = NIC_GET(regt, regh, ED_P0_CR) & ~(ED_CR_PAGE_3 | ED_CR_STA);
 1468 
 1469         /* Select page 0 */
 1470         NIC_BARRIER(regt, regh);
 1471         NIC_PUT(regt, regh, ED_P0_CR, cmd | ED_CR_PAGE_0 | ED_CR_STP);
 1472         NIC_BARRIER(regt, regh);
 1473 
 1474         /* If not started, init chip */
 1475         if (cmd & ED_CR_STP)
 1476                 dp8390_ipkdb_hwinit(kip);
 1477 
 1478         /* If output active, wait for packets to drain */
 1479         while (sc->txb_inuse) {
 1480                 while (!(cmd = (NIC_GET(regt, regh, ED_P0_ISR)
 1481                                 & (ED_ISR_PTX | ED_ISR_TXE))))
 1482                         DELAY(1);
 1483                 NIC_PUT(regt, regh, ED_P0_ISR, cmd);
 1484                 if (--sc->txb_inuse)
 1485                         dp8390_xmit(sc);
 1486         }
 1487 }
 1488 
 1489 static void
 1490 dp8390_ipkdb_leave(kip)
 1491         struct ipkdb_if *kip;
 1492 {
 1493         struct dp8390_softc *sc = kip->port;
 1494         struct ifnet *ifp = &sc->sc_ec.ec_if;
 1495 
 1496         ifp->if_timer = 0;
 1497 }
 1498 
 1499 /*
 1500  * Similar to dp8390_intr above.
 1501  */
 1502 static int
 1503 dp8390_ipkdb_rcv(kip, buf, poll)
 1504         struct ipkdb_if *kip;
 1505         u_char *buf;
 1506         int poll;
 1507 {
 1508         struct dp8390_softc *sc = kip->port;
 1509         bus_space_tag_t regt = sc->sc_regt;
 1510         bus_space_handle_t regh = sc->sc_regh;
 1511         u_char bnry, current, isr;
 1512         int len, nlen, packet_ptr;
 1513         struct dp8390_ring packet_hdr;
 1514 
 1515         /* Switch to page 0. */
 1516         NIC_BARRIER(regt, regh);
 1517         NIC_PUT(regt, regh, ED_P0_CR,
 1518                 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
 1519         NIC_BARRIER(regt, regh);
 1520 
 1521         while (1) {
 1522                 isr = NIC_GET(regt, regh, ED_P0_ISR);
 1523                 NIC_PUT(regt, regh, ED_P0_ISR, isr);
 1524 
 1525                 if (isr & (ED_ISR_PRX | ED_ISR_TXE)) {
 1526                         NIC_GET(regt, regh, ED_P0_NCR);
 1527                         NIC_GET(regt, regh, ED_P0_TSR);
 1528                 }
 1529 
 1530                 if (isr & ED_ISR_OVW) {
 1531                         dp8390_ipkdb_hwinit(kip);
 1532                         continue;
 1533                 }
 1534 
 1535                 if (isr & ED_ISR_CNT) {
 1536                         NIC_GET(regt, regh, ED_P0_CNTR0);
 1537                         NIC_GET(regt, regh, ED_P0_CNTR1);
 1538                         NIC_GET(regt, regh, ED_P0_CNTR2);
 1539                 }
 1540 
 1541                 /* Similar to dp8390_rint above. */
 1542                 NIC_BARRIER(regt, regh);
 1543                 NIC_PUT(regt, regh, ED_P0_CR,
 1544                         sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STA);
 1545                 NIC_BARRIER(regt, regh);
 1546 
 1547                 current = NIC_GET(regt, regh, ED_P1_CURR);
 1548 
 1549                 NIC_BARRIER(regt, regh);
 1550                 NIC_PUT(regt, regh, ED_P1_CR,
 1551                         sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
 1552                 NIC_BARRIER(regt, regh);
 1553 
 1554                 if (sc->next_packet == current) {
 1555                         if (poll)
 1556                                 return 0;
 1557                         continue;
 1558                 }
 1559 
 1560                 packet_ptr = sc->mem_ring
 1561                         + ((sc->next_packet - sc->rec_page_start) << ED_PAGE_SHIFT);
 1562                 sc->read_hdr(sc, packet_ptr, &packet_hdr);
 1563                 len = packet_hdr.count;
 1564                 nlen = packet_hdr.next_packet - sc->next_packet;
 1565                 if (nlen < 0)
 1566                         nlen += sc->rec_page_stop - sc->rec_page_start;
 1567                 nlen--;
 1568                 if ((len & ED_PAGE_MASK) + sizeof(packet_hdr) > ED_PAGE_SIZE)
 1569                         nlen--;
 1570                 len = (len & ED_PAGE_MASK) | (nlen << ED_PAGE_SHIFT);
 1571                 len -= sizeof(packet_hdr);
 1572 
 1573                 if (len <= ETHERMTU
 1574                     && packet_hdr.next_packet >= sc->rec_page_start
 1575                     && packet_hdr.next_packet < sc->rec_page_stop) {
 1576                         sc->ring_copy(sc, packet_ptr + sizeof(packet_hdr),
 1577                                 buf, len);
 1578                         sc->next_packet = packet_hdr.next_packet;
 1579                         bnry = sc->next_packet - 1;
 1580                         if (bnry < sc->rec_page_start)
 1581                                 bnry = sc->rec_page_stop - 1;
 1582                         NIC_PUT(regt, regh, ED_P0_BNRY, bnry);
 1583                         return len;
 1584                 }
 1585 
 1586                 dp8390_ipkdb_hwinit(kip);
 1587         }
 1588 }
 1589 
 1590 static void
 1591 dp8390_ipkdb_send(kip, buf, l)
 1592         struct ipkdb_if *kip;
 1593         u_char *buf;
 1594         int l;
 1595 {
 1596         struct dp8390_softc *sc = kip->port;
 1597         bus_space_tag_t regt = sc->sc_regt;
 1598         bus_space_handle_t regh = sc->sc_regh;
 1599         struct mbuf mb;
 1600 
 1601         mb.m_next = NULL;
 1602         mb.m_pkthdr.len = mb.m_len = l;
 1603         mtod(&mb, u_char *) = buf;
 1604         mb.m_flags = M_EXT | M_PKTHDR;
 1605         mb.m_type = MT_DATA;
 1606 
 1607         l = sc->write_mbuf(sc, &mb,
 1608             sc->mem_start + ((sc->txb_new * ED_TXBUF_SIZE) << ED_PAGE_SHIFT));
 1609         sc->txb_len[sc->txb_new] = max(l, ETHER_MIN_LEN - ETHER_CRC_LEN);
 1610 
 1611         if (++sc->txb_new == sc->txb_cnt)
 1612                 sc->txb_new = 0;
 1613 
 1614         sc->txb_inuse++;
 1615         dp8390_xmit(sc);
 1616 
 1617         while (!(NIC_GET(regt, regh, ED_P0_ISR) & (ED_ISR_PTX | ED_ISR_TXE)))
 1618                 DELAY(1);
 1619 
 1620         sc->txb_inuse--;
 1621 }
 1622 #endif

Cache object: 30c1dffcd73de58944a5e459ed001b8d


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