root/dev/ic/dp8390.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dp8390_media_init
  2. dp8390_config
  3. dp8390_mediachange
  4. dp8390_mediastatus
  5. dp8390_reset
  6. dp8390_stop
  7. dp8390_watchdog
  8. dp8390_init
  9. dp8390_xmit
  10. dp8390_start
  11. dp8390_rint
  12. dp8390_intr
  13. dp8390_ioctl
  14. dp8390_read
  15. dp8390_getmcaf
  16. dp8390_get
  17. dp8390_test_mem
  18. dp8390_read_hdr
  19. dp8390_ring_copy
  20. dp8390_write_mbuf
  21. dp8390_enable
  22. dp8390_disable
  23. dp8390_detach

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

/* [<][>][^][v][top][bottom][index][help] */