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.55 2005/02/04 02:10:36 perry 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.55 2005/02/04 02:10:36 perry 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(struct dp8390_softc *);
   77 
   78 static __inline__ void  dp8390_read_hdr(struct dp8390_softc *,
   79                             int, struct dp8390_ring *);
   80 static __inline__ int   dp8390_ring_copy(struct dp8390_softc *,
   81                             int, caddr_t, u_short);
   82 static __inline__ int   dp8390_write_mbuf(struct dp8390_softc *,
   83                             struct mbuf *, int);
   84 
   85 static int              dp8390_test_mem(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                 } else {
  621                         /* Really BAD.  The ring pointers are corrupted. */
  622                         log(LOG_ERR, "%s: NIC memory corrupt - "
  623                             "invalid packet length %d\n",
  624                             sc->sc_dev.dv_xname, len);
  625                         ++sc->sc_ec.ec_if.if_ierrors;
  626                         dp8390_reset(sc);
  627                         return;
  628                 }
  629 
  630                 /* Update next packet pointer. */
  631                 sc->next_packet = packet_hdr.next_packet;
  632 
  633                 /*
  634                  * Update NIC boundary pointer - being careful to keep it one
  635                  * buffer behind (as recommended by NS databook).
  636                  */
  637                 boundary = sc->next_packet - 1;
  638                 if (boundary < sc->rec_page_start)
  639                         boundary = sc->rec_page_stop - 1;
  640                 NIC_PUT(regt, regh, ED_P0_BNRY, boundary);
  641         } while (sc->next_packet != current);
  642 
  643         goto loop;
  644 }
  645 
  646 /* Ethernet interface interrupt processor. */
  647 int
  648 dp8390_intr(arg)
  649         void *arg;
  650 {
  651         struct dp8390_softc *sc = (struct dp8390_softc *)arg;
  652         bus_space_tag_t regt = sc->sc_regt;
  653         bus_space_handle_t regh = sc->sc_regh;
  654         struct ifnet *ifp = &sc->sc_ec.ec_if;
  655         u_char isr;
  656 #if NRND > 0
  657         u_char rndisr;
  658 #endif
  659 
  660         if (sc->sc_enabled == 0 ||
  661             (sc->sc_dev.dv_flags & DVF_ACTIVE) == 0)
  662                 return (0);
  663 
  664         /* Set NIC to page 0 registers. */
  665         NIC_BARRIER(regt, regh);
  666         NIC_PUT(regt, regh, ED_P0_CR,
  667             sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
  668         NIC_BARRIER(regt, regh);
  669 
  670         isr = NIC_GET(regt, regh, ED_P0_ISR);
  671         if (!isr)
  672                 return (0);
  673 
  674 #if NRND > 0
  675         rndisr = isr;
  676 #endif
  677 
  678         /* Loop until there are no more new interrupts. */
  679         for (;;) {
  680                 /*
  681                  * Reset all the bits that we are 'acknowledging' by writing a
  682                  * '1' to each bit position that was set.
  683                  * (Writing a '1' *clears* the bit.)
  684                  */
  685                 NIC_PUT(regt, regh, ED_P0_ISR, isr);
  686 
  687                 /* Work around for AX88190 bug */
  688                 if ((sc->sc_flags & DP8390_DO_AX88190_WORKAROUND) != 0)
  689                         while ((NIC_GET(regt, regh, ED_P0_ISR) & isr) != 0) {
  690                                 NIC_PUT(regt, regh, ED_P0_ISR, 0);
  691                                 NIC_PUT(regt, regh, ED_P0_ISR, isr);
  692                         }
  693 
  694                 /*
  695                  * Handle transmitter interrupts.  Handle these first because
  696                  * the receiver will reset the board under some conditions.
  697                  *
  698                  * If the chip was reset while a packet was transmitting, it
  699                  * may still deliver a TX interrupt.  In this case, just ignore
  700                  * the interrupt.
  701                  */
  702                 if (isr & (ED_ISR_PTX | ED_ISR_TXE) &&
  703                     sc->txb_inuse != 0) {
  704                         u_char collisions =
  705                             NIC_GET(regt, regh, ED_P0_NCR) & 0x0f;
  706 
  707                         /*
  708                          * Check for transmit error.  If a TX completed with an
  709                          * error, we end up throwing the packet away.  Really
  710                          * the only error that is possible is excessive
  711                          * collisions, and in this case it is best to allow the
  712                          * automatic mechanisms of TCP to backoff the flow.  Of
  713                          * course, with UDP we're screwed, but this is expected
  714                          * when a network is heavily loaded.
  715                          */
  716                         if (isr & ED_ISR_TXE) {
  717                                 /*
  718                                  * Excessive collisions (16).
  719                                  */
  720                                 if ((NIC_GET(regt, regh, ED_P0_TSR)
  721                                     & ED_TSR_ABT) && (collisions == 0)) {
  722                                         /*
  723                                          * When collisions total 16, the P0_NCR
  724                                          * will indicate 0, and the TSR_ABT is
  725                                          * set.
  726                                          */
  727                                         collisions = 16;
  728                                 }
  729 
  730                                 /* Update output errors counter. */
  731                                 ++ifp->if_oerrors;
  732                         } else {
  733                                 /*
  734                                  * Throw away the non-error status bits.
  735                                  *
  736                                  * XXX
  737                                  * It may be useful to detect loss of carrier
  738                                  * and late collisions here.
  739                                  */
  740                                 (void)NIC_GET(regt, regh, ED_P0_TSR);
  741 
  742                                 /*
  743                                  * Update total number of successfully
  744                                  * transmitted packets.
  745                                  */
  746                                 ++ifp->if_opackets;
  747                         }
  748 
  749                         /* Clear watchdog timer. */
  750                         ifp->if_timer = 0;
  751                         ifp->if_flags &= ~IFF_OACTIVE;
  752 
  753                         /*
  754                          * Add in total number of collisions on last
  755                          * transmission.
  756                          */
  757                         ifp->if_collisions += collisions;
  758 
  759                         /*
  760                          * Decrement buffer in-use count if not zero (can only
  761                          * be zero if a transmitter interrupt occurred while not
  762                          * actually transmitting).
  763                          * If data is ready to transmit, start it transmitting,
  764                          * otherwise defer until after handling receiver.
  765                          */
  766                         if (--sc->txb_inuse != 0)
  767                                 dp8390_xmit(sc);
  768                 }
  769 
  770                 /* Handle receiver interrupts. */
  771                 if (isr & (ED_ISR_PRX | ED_ISR_RXE | ED_ISR_OVW)) {
  772                         /*
  773                          * Overwrite warning.  In order to make sure that a
  774                          * lockup of the local DMA hasn't occurred, we reset
  775                          * and re-init the NIC.  The NSC manual suggests only a
  776                          * partial reset/re-init is necessary - but some chips
  777                          * seem to want more.  The DMA lockup has been seen
  778                          * only with early rev chips - Methinks this bug was
  779                          * fixed in later revs.  -DG
  780                          */
  781                         if (isr & ED_ISR_OVW) {
  782                                 ++ifp->if_ierrors;
  783 #ifdef DIAGNOSTIC
  784                                 log(LOG_WARNING, "%s: warning - receiver "
  785                                     "ring buffer overrun\n",
  786                                     sc->sc_dev.dv_xname);
  787 #endif
  788                                 /* Stop/reset/re-init NIC. */
  789                                 dp8390_reset(sc);
  790                         } else {
  791                                 /*
  792                                  * Receiver Error.  One or more of: CRC error,
  793                                  * frame alignment error FIFO overrun, or
  794                                  * missed packet.
  795                                  */
  796                                 if (isr & ED_ISR_RXE) {
  797                                         ++ifp->if_ierrors;
  798 #ifdef DEBUG
  799                                         if (dp8390_debug) {
  800                                                 printf("%s: receive error %x\n",
  801                                                     sc->sc_dev.dv_xname,
  802                                                     NIC_GET(regt, regh,
  803                                                         ED_P0_RSR));
  804                                         }
  805 #endif
  806                                 }
  807 
  808                                 /*
  809                                  * Go get the packet(s)
  810                                  * XXX - Doing this on an error is dubious
  811                                  * because there shouldn't be any data to get
  812                                  * (we've configured the interface to not
  813                                  * accept packets with errors).
  814                                  */
  815                                 if (sc->recv_int)
  816                                         (*sc->recv_int)(sc);
  817                                 else
  818                                         dp8390_rint(sc);
  819                         }
  820                 }
  821 
  822                 /*
  823                  * If it looks like the transmitter can take more data, attempt
  824                  * to start output on the interface.  This is done after
  825                  * handling the receiver to give the receiver priority.
  826                  */
  827                 dp8390_start(ifp);
  828 
  829                 /*
  830                  * Return NIC CR to standard state: page 0, remote DMA
  831                  * complete, start (toggling the TXP bit off, even if was just
  832                  * set in the transmit routine, is *okay* - it is 'edge'
  833                  * triggered from low to high).
  834                  */
  835                 NIC_BARRIER(regt, regh);
  836                 NIC_PUT(regt, regh, ED_P0_CR,
  837                     sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
  838                 NIC_BARRIER(regt, regh);
  839 
  840                 /*
  841                  * If the Network Talley Counters overflow, read them to reset
  842                  * them.  It appears that old 8390's won't clear the ISR flag
  843                  * otherwise - resulting in an infinite loop.
  844                  */
  845                 if (isr & ED_ISR_CNT) {
  846                         (void)NIC_GET(regt, regh, ED_P0_CNTR0);
  847                         (void)NIC_GET(regt, regh, ED_P0_CNTR1);
  848                         (void)NIC_GET(regt, regh, ED_P0_CNTR2);
  849                 }
  850 
  851                 isr = NIC_GET(regt, regh, ED_P0_ISR);
  852                 if (!isr)
  853                         goto out;
  854         }
  855 
  856  out:
  857 #if NRND > 0
  858         rnd_add_uint32(&sc->rnd_source, rndisr);
  859 #endif
  860         return (1);
  861 }
  862 
  863 /*
  864  * Process an ioctl request.  This code needs some work - it looks pretty ugly.
  865  */
  866 int
  867 dp8390_ioctl(ifp, cmd, data)
  868         struct ifnet *ifp;
  869         u_long cmd;
  870         caddr_t data;
  871 {
  872         struct dp8390_softc *sc = ifp->if_softc;
  873         struct ifaddr *ifa = (struct ifaddr *) data;
  874         struct ifreq *ifr = (struct ifreq *) data;
  875         int s, error = 0;
  876 
  877         s = splnet();
  878 
  879         switch (cmd) {
  880 
  881         case SIOCSIFADDR:
  882                 if ((error = dp8390_enable(sc)) != 0)
  883                         break;
  884                 ifp->if_flags |= IFF_UP;
  885 
  886                 switch (ifa->ifa_addr->sa_family) {
  887 #ifdef INET
  888                 case AF_INET:
  889                         dp8390_init(sc);
  890                         arp_ifinit(ifp, ifa);
  891                         break;
  892 #endif
  893 #ifdef NS
  894                         /* XXX - This code is probably wrong. */
  895                 case AF_NS:
  896                     {
  897                         struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
  898 
  899                         if (ns_nullhost(*ina))
  900                                 ina->x_host =
  901                                     *(union ns_host *)LLADDR(ifp->if_sadl);
  902                         else
  903                                 memcpy(LLADDR(ifp->if_sadl),
  904                                     ina->x_host.c_host, ETHER_ADDR_LEN);
  905                         /* Set new address. */
  906                         dp8390_init(sc);
  907                         break;
  908                     }
  909 #endif
  910                 default:
  911                         dp8390_init(sc);
  912                         break;
  913                 }
  914                 break;
  915 
  916         case SIOCSIFFLAGS:
  917                 if ((ifp->if_flags & IFF_UP) == 0 &&
  918                     (ifp->if_flags & IFF_RUNNING) != 0) {
  919                         /*
  920                          * If interface is marked down and it is running, then
  921                          * stop it.
  922                          */
  923                         dp8390_stop(sc);
  924                         ifp->if_flags &= ~IFF_RUNNING;
  925                         dp8390_disable(sc);
  926                 } else if ((ifp->if_flags & IFF_UP) != 0 &&
  927                     (ifp->if_flags & IFF_RUNNING) == 0) {
  928                         /*
  929                          * If interface is marked up and it is stopped, then
  930                          * start it.
  931                          */
  932                         if ((error = dp8390_enable(sc)) != 0)
  933                                 break;
  934                         dp8390_init(sc);
  935                 } else if ((ifp->if_flags & IFF_UP) != 0) {
  936                         /*
  937                          * Reset the interface to pick up changes in any other
  938                          * flags that affect hardware registers.
  939                          */
  940                         dp8390_stop(sc);
  941                         dp8390_init(sc);
  942                 }
  943                 break;
  944 
  945         case SIOCADDMULTI:
  946         case SIOCDELMULTI:
  947                 if (sc->sc_enabled == 0) {
  948                         error = EIO;
  949                         break;
  950                 }
  951 
  952                 /* Update our multicast list. */
  953                 error = (cmd == SIOCADDMULTI) ?
  954                     ether_addmulti(ifr, &sc->sc_ec) :
  955                     ether_delmulti(ifr, &sc->sc_ec);
  956 
  957                 if (error == ENETRESET) {
  958                         /*
  959                          * Multicast list has changed; set the hardware filter
  960                          * accordingly.
  961                          */
  962                         if (ifp->if_flags & IFF_RUNNING) {
  963                                 dp8390_stop(sc); /* XXX for ds_setmcaf? */
  964                                 dp8390_init(sc);
  965                         }
  966                         error = 0;
  967                 }
  968                 break;
  969 
  970         case SIOCGIFMEDIA:
  971         case SIOCSIFMEDIA:
  972                 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
  973                 break;
  974 
  975         default:
  976                 error = EINVAL;
  977                 break;
  978         }
  979 
  980         splx(s);
  981         return (error);
  982 }
  983 
  984 /*
  985  * Retrieve packet from buffer memory and send to the next level up via
  986  * ether_input().  If there is a BPF listener, give a copy to BPF, too.
  987  */
  988 void
  989 dp8390_read(sc, buf, len)
  990         struct dp8390_softc *sc;
  991         int buf;
  992         u_short len;
  993 {
  994         struct ifnet *ifp = &sc->sc_ec.ec_if;
  995         struct mbuf *m;
  996 
  997         /* Pull packet off interface. */
  998         m = dp8390_get(sc, buf, len);
  999         if (m == 0) {
 1000                 ifp->if_ierrors++;
 1001                 return;
 1002         }
 1003 
 1004         ifp->if_ipackets++;
 1005 
 1006 #if NBPFILTER > 0
 1007         /*
 1008          * Check if there's a BPF listener on this interface.
 1009          * If so, hand off the raw packet to bpf.
 1010          */
 1011         if (ifp->if_bpf)
 1012                 bpf_mtap(ifp->if_bpf, m);
 1013 #endif
 1014 
 1015         (*ifp->if_input)(ifp, m);
 1016 }
 1017 
 1018 
 1019 /*
 1020  * Supporting routines.
 1021  */
 1022 
 1023 /*
 1024  * Compute the multicast address filter from the list of multicast addresses we
 1025  * need to listen to.
 1026  */
 1027 void
 1028 dp8390_getmcaf(ec, af)
 1029         struct ethercom *ec;
 1030         u_int8_t *af;
 1031 {
 1032         struct ifnet *ifp = &ec->ec_if;
 1033         struct ether_multi *enm;
 1034         u_int32_t crc;
 1035         int i;
 1036         struct ether_multistep step;
 1037 
 1038         /*
 1039          * Set up multicast address filter by passing all multicast addresses
 1040          * through a crc generator, and then using the high order 6 bits as an
 1041          * index into the 64 bit logical address filter.  The high order bit
 1042          * selects the word, while the rest of the bits select the bit within
 1043          * the word.
 1044          */
 1045 
 1046         if (ifp->if_flags & IFF_PROMISC) {
 1047                 ifp->if_flags |= IFF_ALLMULTI;
 1048                 for (i = 0; i < 8; i++)
 1049                         af[i] = 0xff;
 1050                 return;
 1051         }
 1052         for (i = 0; i < 8; i++)
 1053                 af[i] = 0;
 1054         ETHER_FIRST_MULTI(step, ec, enm);
 1055         while (enm != NULL) {
 1056                 if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
 1057                     sizeof(enm->enm_addrlo)) != 0) {
 1058                         /*
 1059                          * We must listen to a range of multicast addresses.
 1060                          * For now, just accept all multicasts, rather than
 1061                          * trying to set only those filter bits needed to match
 1062                          * the range.  (At this time, the only use of address
 1063                          * ranges is for IP multicast routing, for which the
 1064                          * range is big enough to require all bits set.)
 1065                          */
 1066                         ifp->if_flags |= IFF_ALLMULTI;
 1067                         for (i = 0; i < 8; i++)
 1068                                 af[i] = 0xff;
 1069                         return;
 1070                 }
 1071 
 1072                 crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN);
 1073 
 1074                 /* Just want the 6 most significant bits. */
 1075                 crc >>= 26;
 1076 
 1077                 /* Turn on the corresponding bit in the filter. */
 1078                 af[crc >> 3] |= 1 << (crc & 0x7);
 1079 
 1080                 ETHER_NEXT_MULTI(step, enm);
 1081         }
 1082         ifp->if_flags &= ~IFF_ALLMULTI;
 1083 }
 1084 
 1085 /*
 1086  * Copy data from receive buffer to a new mbuf chain allocating mbufs
 1087  * as needed.  Return pointer to first mbuf in chain.
 1088  * sc = dp8390 info (softc)
 1089  * src = pointer in dp8390 ring buffer
 1090  * total_len = amount of data to copy
 1091  */
 1092 struct mbuf *
 1093 dp8390_get(sc, src, total_len)
 1094         struct dp8390_softc *sc;
 1095         int src;
 1096         u_short total_len;
 1097 {
 1098         struct ifnet *ifp = &sc->sc_ec.ec_if;
 1099         struct mbuf *m, *m0, *newm;
 1100         u_short len;
 1101 
 1102         MGETHDR(m0, M_DONTWAIT, MT_DATA);
 1103         if (m0 == 0)
 1104                 return (0);
 1105         m0->m_pkthdr.rcvif = ifp;
 1106         m0->m_pkthdr.len = total_len;
 1107         len = MHLEN;
 1108         m = m0;
 1109 
 1110         while (total_len > 0) {
 1111                 if (total_len >= MINCLSIZE) {
 1112                         MCLGET(m, M_DONTWAIT);
 1113                         if ((m->m_flags & M_EXT) == 0)
 1114                                 goto bad;
 1115                         len = MCLBYTES;
 1116                 }
 1117 
 1118                 /*
 1119                  * Make sure the data after the Ethernet header is aligned.
 1120                  */
 1121                 if (m == m0) {
 1122                         caddr_t newdata = (caddr_t)
 1123                             ALIGN(m->m_data + sizeof(struct ether_header)) -
 1124                             sizeof(struct ether_header);
 1125                         len -= newdata - m->m_data;
 1126                         m->m_data = newdata;
 1127                 }
 1128 
 1129                 m->m_len = len = min(total_len, len);
 1130                 if (sc->ring_copy)
 1131                         src = (*sc->ring_copy)(sc, src, mtod(m, caddr_t), len);
 1132                 else
 1133                         src = dp8390_ring_copy(sc, src, mtod(m, caddr_t), len);
 1134 
 1135                 total_len -= len;
 1136                 if (total_len > 0) {
 1137                         MGET(newm, M_DONTWAIT, MT_DATA);
 1138                         if (newm == 0)
 1139                                 goto bad;
 1140                         len = MLEN;
 1141                         m = m->m_next = newm;
 1142                 }
 1143         }
 1144 
 1145         return (m0);
 1146 
 1147 bad:
 1148         m_freem(m0);
 1149         return (0);
 1150 }
 1151 
 1152 
 1153 /*
 1154  * Default driver support functions.
 1155  *
 1156  * NOTE: all support functions assume 8-bit shared memory.
 1157  */
 1158 /*
 1159  * Zero NIC buffer memory and verify that it is clear.
 1160  */
 1161 static int
 1162 dp8390_test_mem(sc)
 1163         struct dp8390_softc *sc;
 1164 {
 1165         bus_space_tag_t buft = sc->sc_buft;
 1166         bus_space_handle_t bufh = sc->sc_bufh;
 1167         int i;
 1168 
 1169         bus_space_set_region_1(buft, bufh, sc->mem_start, 0, sc->mem_size);
 1170 
 1171         for (i = 0; i < sc->mem_size; ++i) {
 1172                 if (bus_space_read_1(buft, bufh, sc->mem_start + i)) {
 1173                         printf(": failed to clear NIC buffer at offset %x - "
 1174                             "check configuration\n", (sc->mem_start + i));
 1175                         return 1;
 1176                 }
 1177         }
 1178 
 1179         return 0;
 1180 }
 1181 
 1182 /*
 1183  * Read a packet header from the ring, given the source offset.
 1184  */
 1185 static __inline__ void
 1186 dp8390_read_hdr(sc, src, hdrp)
 1187         struct dp8390_softc *sc;
 1188         int src;
 1189         struct dp8390_ring *hdrp;
 1190 {
 1191         bus_space_tag_t buft = sc->sc_buft;
 1192         bus_space_handle_t bufh = sc->sc_bufh;
 1193 
 1194         /*
 1195          * The byte count includes a 4 byte header that was added by
 1196          * the NIC.
 1197          */
 1198         hdrp->rsr = bus_space_read_1(buft, bufh, src);
 1199         hdrp->next_packet = bus_space_read_1(buft, bufh, src + 1);
 1200         hdrp->count = bus_space_read_1(buft, bufh, src + 2) |
 1201             (bus_space_read_1(buft, bufh, src + 3) << 8);
 1202 }
 1203 
 1204 /*
 1205  * Copy `amount' bytes from a packet in the ring buffer to a linear
 1206  * destination buffer, given a source offset and destination address.
 1207  * Takes into account ring-wrap.
 1208  */
 1209 static __inline__ int
 1210 dp8390_ring_copy(sc, src, dst, amount)
 1211         struct dp8390_softc *sc;
 1212         int src;
 1213         caddr_t dst;
 1214         u_short amount;
 1215 {
 1216         bus_space_tag_t buft = sc->sc_buft;
 1217         bus_space_handle_t bufh = sc->sc_bufh;
 1218         u_short tmp_amount;
 1219 
 1220         /* Does copy wrap to lower addr in ring buffer? */
 1221         if (src + amount > sc->mem_end) {
 1222                 tmp_amount = sc->mem_end - src;
 1223 
 1224                 /* Copy amount up to end of NIC memory. */
 1225                 bus_space_read_region_1(buft, bufh, src, dst, tmp_amount);
 1226 
 1227                 amount -= tmp_amount;
 1228                 src = sc->mem_ring;
 1229                 dst += tmp_amount;
 1230         }
 1231         bus_space_read_region_1(buft, bufh, src, dst, amount);
 1232 
 1233         return (src + amount);
 1234 }
 1235 
 1236 /*
 1237  * Copy a packet from an mbuf to the transmit buffer on the card.
 1238  *
 1239  * Currently uses an extra buffer/extra memory copy, unless the whole
 1240  * packet fits in one mbuf.
 1241  */
 1242 static __inline__ int
 1243 dp8390_write_mbuf(sc, m, buf)
 1244         struct dp8390_softc *sc;
 1245         struct mbuf *m;
 1246         int buf;
 1247 {
 1248         bus_space_tag_t buft = sc->sc_buft;
 1249         bus_space_handle_t bufh = sc->sc_bufh;
 1250         u_char *data;
 1251         int len, totlen = 0;
 1252 
 1253         for (; m ; m = m->m_next) {
 1254                 data = mtod(m, u_char *);
 1255                 len = m->m_len;
 1256                 if (len > 0) {
 1257                         bus_space_write_region_1(buft, bufh, buf, data, len);
 1258                         totlen += len;
 1259                         buf += len;
 1260                 }
 1261         }
 1262         if (totlen < ETHER_MIN_LEN - ETHER_CRC_LEN) {
 1263                 bus_space_set_region_1(buft, bufh, buf, 0,
 1264                     ETHER_MIN_LEN - ETHER_CRC_LEN - totlen);
 1265                 totlen = ETHER_MIN_LEN - ETHER_CRC_LEN;
 1266         }
 1267         return (totlen);
 1268 }
 1269 
 1270 /*
 1271  * Enable power on the interface.
 1272  */
 1273 int
 1274 dp8390_enable(sc)
 1275         struct dp8390_softc *sc;
 1276 {
 1277 
 1278         if (sc->sc_enabled == 0 && sc->sc_enable != NULL) {
 1279                 if ((*sc->sc_enable)(sc) != 0) {
 1280                         printf("%s: device enable failed\n",
 1281                             sc->sc_dev.dv_xname);
 1282                         return (EIO);
 1283                 }
 1284         }
 1285 
 1286         sc->sc_enabled = 1;
 1287         return (0);
 1288 }
 1289 
 1290 /*
 1291  * Disable power on the interface.
 1292  */
 1293 void
 1294 dp8390_disable(sc)
 1295         struct dp8390_softc *sc;
 1296 {
 1297 
 1298         if (sc->sc_enabled != 0 && sc->sc_disable != NULL) {
 1299                 (*sc->sc_disable)(sc);
 1300                 sc->sc_enabled = 0;
 1301         }
 1302 }
 1303 
 1304 int
 1305 dp8390_activate(self, act)
 1306         struct device *self;
 1307         enum devact act;
 1308 {
 1309         struct dp8390_softc *sc = (struct dp8390_softc *)self;
 1310         int rv = 0, s;
 1311 
 1312         s = splnet();
 1313         switch (act) {
 1314         case DVACT_ACTIVATE:
 1315                 rv = EOPNOTSUPP;
 1316                 break;
 1317 
 1318         case DVACT_DEACTIVATE:
 1319                 if_deactivate(&sc->sc_ec.ec_if);
 1320                 break;
 1321         }
 1322         splx(s);
 1323         return (rv);
 1324 }
 1325 
 1326 int
 1327 dp8390_detach(sc, flags)
 1328         struct dp8390_softc *sc;
 1329         int flags;
 1330 {
 1331         struct ifnet *ifp = &sc->sc_ec.ec_if;
 1332 
 1333         /* Succeed now if there's no work to do. */
 1334         if ((sc->sc_flags & DP8390_ATTACHED) == 0)
 1335                 return (0);
 1336 
 1337         /* dp8390_disable() checks sc->sc_enabled */
 1338         dp8390_disable(sc);
 1339 
 1340         if (sc->sc_media_fini != NULL)
 1341                 (*sc->sc_media_fini)(sc);
 1342 
 1343         /* Delete all remaining media. */
 1344         ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY);
 1345 
 1346 #if NRND > 0
 1347         rnd_detach_source(&sc->rnd_source);
 1348 #endif
 1349         ether_ifdetach(ifp);
 1350         if_detach(ifp);
 1351 
 1352         return (0);
 1353 }
 1354 
 1355 #ifdef IPKDB_DP8390
 1356 static void dp8390_ipkdb_hwinit(struct ipkdb_if *);
 1357 static void dp8390_ipkdb_init(struct ipkdb_if *);
 1358 static void dp8390_ipkdb_leave(struct ipkdb_if *);
 1359 static int dp8390_ipkdb_rcv(struct ipkdb_if *, u_char *, int);
 1360 static void dp8390_ipkdb_send(struct ipkdb_if *, u_char *, int);
 1361 
 1362 /*
 1363  * This is essentially similar to dp8390_config above.
 1364  */
 1365 int
 1366 dp8390_ipkdb_attach(kip)
 1367         struct ipkdb_if *kip;
 1368 {
 1369         struct dp8390_softc *sc = kip->port;
 1370 
 1371         if (sc->mem_size < 8192 * 2)
 1372                 sc->txb_cnt = 1;
 1373         else if (sc->mem_size < 8192 * 3)
 1374                 sc->txb_cnt = 2;
 1375         else
 1376                 sc->txb_cnt = 3;
 1377 
 1378         sc->tx_page_start = sc->mem_start >> ED_PAGE_SHIFT;
 1379         sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE;
 1380         sc->rec_page_stop = sc->tx_page_start + (sc->mem_size >> ED_PAGE_SHIFT);
 1381         sc->mem_ring = sc->mem_start + (sc->rec_page_start << ED_PAGE_SHIFT);
 1382         sc->mem_end = sc->mem_start + sc->mem_size;
 1383 
 1384         dp8390_stop(sc);
 1385 
 1386         kip->start = dp8390_ipkdb_init;
 1387         kip->leave = dp8390_ipkdb_leave;
 1388         kip->receive = dp8390_ipkdb_rcv;
 1389         kip->send = dp8390_ipkdb_send;
 1390 
 1391         return 0;
 1392 }
 1393 
 1394 /*
 1395  * Similar to dp8390_init above.
 1396  */
 1397 static void
 1398 dp8390_ipkdb_hwinit(kip)
 1399         struct ipkdb_if *kip;
 1400 {
 1401         struct dp8390_softc *sc = kip->port;
 1402         struct ifnet *ifp = &sc->sc_ec.ec_if;
 1403         bus_space_tag_t regt = sc->sc_regt;
 1404         bus_space_handle_t regh = sc->sc_regh;
 1405         int i;
 1406 
 1407         sc->txb_inuse = 0;
 1408         sc->txb_new = 0;
 1409         sc->txb_next_tx = 0;
 1410         dp8390_stop(sc);
 1411 
 1412         if (sc->dcr_reg & ED_DCR_LS)
 1413                 NIC_PUT(regt, regh, ED_P0_DCR, sc->dcr_reg);
 1414         else
 1415                 NIC_PUT(regt, regh, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
 1416         NIC_PUT(regt, regh, ED_P0_RBCR0, 0);
 1417         NIC_PUT(regt, regh, ED_P0_RBCR1, 0);
 1418         NIC_PUT(regt, regh, ED_P0_RCR, ED_RCR_MON | sc->rcr_proto);
 1419         NIC_PUT(regt, regh, ED_P0_TCR, ED_TCR_LB0);
 1420         if (sc->is790)
 1421                 NIC_PUT(regt, regh, 0x09, 0);
 1422         NIC_PUT(regt, regh, ED_P0_BNRY, sc->rec_page_start);
 1423         NIC_PUT(regt, regh, ED_P0_PSTART, sc->rec_page_start);
 1424         NIC_PUT(regt, regh, ED_P0_PSTOP, sc->rec_page_stop);
 1425         NIC_PUT(regt, regh, ED_P0_IMR, 0);
 1426         NIC_BARRIER(regt, regh);
 1427         NIC_PUT(regt, regh, ED_P0_ISR, 0xff);
 1428 
 1429         NIC_BARRIER(regt, regh);
 1430         NIC_PUT(regt, regh, ED_P0_CR,
 1431                 sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STP);
 1432         NIC_BARRIER(regt, regh);
 1433 
 1434         for (i = 0; i < sizeof kip->myenetaddr; i++)
 1435                 NIC_PUT(regt, regh, ED_P1_PAR0 + i, kip->myenetaddr[i]);
 1436         /* multicast filter? */
 1437 
 1438         sc->next_packet = sc->rec_page_start + 1;
 1439         NIC_PUT(regt, regh, ED_P1_CURR, sc->next_packet);
 1440 
 1441         NIC_BARRIER(regt, regh);
 1442         NIC_PUT(regt, regh, ED_P1_CR,
 1443                 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STP);
 1444         NIC_BARRIER(regt, regh);
 1445 
 1446         /* promiscuous mode? */
 1447         NIC_PUT(regt, regh, ED_P0_RCR, ED_RCR_AB | ED_RCR_AM | sc->rcr_proto);
 1448         NIC_PUT(regt, regh, ED_P0_TCR, 0);
 1449 
 1450         /* card-specific initialization? */
 1451 
 1452         NIC_BARRIER(regt, regh);
 1453         NIC_PUT(regt, regh, ED_P0_CR,
 1454                 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
 1455 
 1456         ifp->if_flags &= ~IFF_OACTIVE;
 1457 }
 1458 
 1459 static void
 1460 dp8390_ipkdb_init(kip)
 1461         struct ipkdb_if *kip;
 1462 {
 1463         struct dp8390_softc *sc = kip->port;
 1464         bus_space_tag_t regt = sc->sc_regt;
 1465         bus_space_handle_t regh = sc->sc_regh;
 1466         u_char cmd;
 1467 
 1468         cmd = NIC_GET(regt, regh, ED_P0_CR) & ~(ED_CR_PAGE_3 | ED_CR_STA);
 1469 
 1470         /* Select page 0 */
 1471         NIC_BARRIER(regt, regh);
 1472         NIC_PUT(regt, regh, ED_P0_CR, cmd | ED_CR_PAGE_0 | ED_CR_STP);
 1473         NIC_BARRIER(regt, regh);
 1474 
 1475         /* If not started, init chip */
 1476         if (cmd & ED_CR_STP)
 1477                 dp8390_ipkdb_hwinit(kip);
 1478 
 1479         /* If output active, wait for packets to drain */
 1480         while (sc->txb_inuse) {
 1481                 while (!(cmd = (NIC_GET(regt, regh, ED_P0_ISR)
 1482                                 & (ED_ISR_PTX | ED_ISR_TXE))))
 1483                         DELAY(1);
 1484                 NIC_PUT(regt, regh, ED_P0_ISR, cmd);
 1485                 if (--sc->txb_inuse)
 1486                         dp8390_xmit(sc);
 1487         }
 1488 }
 1489 
 1490 static void
 1491 dp8390_ipkdb_leave(kip)
 1492         struct ipkdb_if *kip;
 1493 {
 1494         struct dp8390_softc *sc = kip->port;
 1495         struct ifnet *ifp = &sc->sc_ec.ec_if;
 1496 
 1497         ifp->if_timer = 0;
 1498 }
 1499 
 1500 /*
 1501  * Similar to dp8390_intr above.
 1502  */
 1503 static int
 1504 dp8390_ipkdb_rcv(kip, buf, poll)
 1505         struct ipkdb_if *kip;
 1506         u_char *buf;
 1507         int poll;
 1508 {
 1509         struct dp8390_softc *sc = kip->port;
 1510         bus_space_tag_t regt = sc->sc_regt;
 1511         bus_space_handle_t regh = sc->sc_regh;
 1512         u_char bnry, current, isr;
 1513         int len, nlen, packet_ptr;
 1514         struct dp8390_ring packet_hdr;
 1515 
 1516         /* Switch to page 0. */
 1517         NIC_BARRIER(regt, regh);
 1518         NIC_PUT(regt, regh, ED_P0_CR,
 1519                 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
 1520         NIC_BARRIER(regt, regh);
 1521 
 1522         while (1) {
 1523                 isr = NIC_GET(regt, regh, ED_P0_ISR);
 1524                 NIC_PUT(regt, regh, ED_P0_ISR, isr);
 1525 
 1526                 if (isr & (ED_ISR_PRX | ED_ISR_TXE)) {
 1527                         NIC_GET(regt, regh, ED_P0_NCR);
 1528                         NIC_GET(regt, regh, ED_P0_TSR);
 1529                 }
 1530 
 1531                 if (isr & ED_ISR_OVW) {
 1532                         dp8390_ipkdb_hwinit(kip);
 1533                         continue;
 1534                 }
 1535 
 1536                 if (isr & ED_ISR_CNT) {
 1537                         NIC_GET(regt, regh, ED_P0_CNTR0);
 1538                         NIC_GET(regt, regh, ED_P0_CNTR1);
 1539                         NIC_GET(regt, regh, ED_P0_CNTR2);
 1540                 }
 1541 
 1542                 /* Similar to dp8390_rint above. */
 1543                 NIC_BARRIER(regt, regh);
 1544                 NIC_PUT(regt, regh, ED_P0_CR,
 1545                         sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STA);
 1546                 NIC_BARRIER(regt, regh);
 1547 
 1548                 current = NIC_GET(regt, regh, ED_P1_CURR);
 1549 
 1550                 NIC_BARRIER(regt, regh);
 1551                 NIC_PUT(regt, regh, ED_P1_CR,
 1552                         sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
 1553                 NIC_BARRIER(regt, regh);
 1554 
 1555                 if (sc->next_packet == current) {
 1556                         if (poll)
 1557                                 return 0;
 1558                         continue;
 1559                 }
 1560 
 1561                 packet_ptr = sc->mem_ring
 1562                         + ((sc->next_packet - sc->rec_page_start) << ED_PAGE_SHIFT);
 1563                 sc->read_hdr(sc, packet_ptr, &packet_hdr);
 1564                 len = packet_hdr.count;
 1565                 nlen = packet_hdr.next_packet - sc->next_packet;
 1566                 if (nlen < 0)
 1567                         nlen += sc->rec_page_stop - sc->rec_page_start;
 1568                 nlen--;
 1569                 if ((len & ED_PAGE_MASK) + sizeof(packet_hdr) > ED_PAGE_SIZE)
 1570                         nlen--;
 1571                 len = (len & ED_PAGE_MASK) | (nlen << ED_PAGE_SHIFT);
 1572                 len -= sizeof(packet_hdr);
 1573 
 1574                 if (len <= ETHERMTU
 1575                     && packet_hdr.next_packet >= sc->rec_page_start
 1576                     && packet_hdr.next_packet < sc->rec_page_stop) {
 1577                         sc->ring_copy(sc, packet_ptr + sizeof(packet_hdr),
 1578                                 buf, len);
 1579                         sc->next_packet = packet_hdr.next_packet;
 1580                         bnry = sc->next_packet - 1;
 1581                         if (bnry < sc->rec_page_start)
 1582                                 bnry = sc->rec_page_stop - 1;
 1583                         NIC_PUT(regt, regh, ED_P0_BNRY, bnry);
 1584                         return len;
 1585                 }
 1586 
 1587                 dp8390_ipkdb_hwinit(kip);
 1588         }
 1589 }
 1590 
 1591 static void
 1592 dp8390_ipkdb_send(kip, buf, l)
 1593         struct ipkdb_if *kip;
 1594         u_char *buf;
 1595         int l;
 1596 {
 1597         struct dp8390_softc *sc = kip->port;
 1598         bus_space_tag_t regt = sc->sc_regt;
 1599         bus_space_handle_t regh = sc->sc_regh;
 1600         struct mbuf mb;
 1601 
 1602         mb.m_next = NULL;
 1603         mb.m_pkthdr.len = mb.m_len = l;
 1604         mtod(&mb, u_char *) = buf;
 1605         mb.m_flags = M_EXT | M_PKTHDR;
 1606         mb.m_type = MT_DATA;
 1607 
 1608         l = sc->write_mbuf(sc, &mb,
 1609             sc->mem_start + ((sc->txb_new * ED_TXBUF_SIZE) << ED_PAGE_SHIFT));
 1610         sc->txb_len[sc->txb_new] = max(l, ETHER_MIN_LEN - ETHER_CRC_LEN);
 1611 
 1612         if (++sc->txb_new == sc->txb_cnt)
 1613                 sc->txb_new = 0;
 1614 
 1615         sc->txb_inuse++;
 1616         dp8390_xmit(sc);
 1617 
 1618         while (!(NIC_GET(regt, regh, ED_P0_ISR) & (ED_ISR_PTX | ED_ISR_TXE)))
 1619                 DELAY(1);
 1620 
 1621         sc->txb_inuse--;
 1622 }
 1623 #endif

Cache object: e99e6d643da0610b03d42e066dd5be2c


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