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

Cache object: 582ca31ee8731edb92c7c38ca119ff11


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