root/dev/pci/if_wb.c

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

DEFINITIONS

This source file includes following definitions.
  1. wb_eeprom_putbyte
  2. wb_eeprom_getword
  3. wb_read_eeprom
  4. wb_mii_sync
  5. wb_mii_send
  6. wb_mii_readreg
  7. wb_mii_writereg
  8. wb_miibus_readreg
  9. wb_miibus_writereg
  10. wb_miibus_statchg
  11. wb_setmulti
  12. wb_setcfg
  13. wb_reset
  14. wb_fixmedia
  15. wb_probe
  16. wb_attach
  17. wb_list_tx_init
  18. wb_list_rx_init
  19. wb_bfree
  20. wb_newbuf
  21. wb_rxeof
  22. wb_rxeoc
  23. wb_txeof
  24. wb_txeoc
  25. wb_intr
  26. wb_tick
  27. wb_encap
  28. wb_start
  29. wb_init
  30. wb_ifmedia_upd
  31. wb_ifmedia_sts
  32. wb_ioctl
  33. wb_watchdog
  34. wb_stop
  35. wb_shutdown

    1 /*      $OpenBSD: if_wb.c,v 1.38 2007/05/26 00:36:03 krw Exp $  */
    2 
    3 /*
    4  * Copyright (c) 1997, 1998
    5  *      Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. All advertising materials mentioning features or use of this software
   16  *    must display the following acknowledgement:
   17  *      This product includes software developed by Bill Paul.
   18  * 4. Neither the name of the author nor the names of any co-contributors
   19  *    may be used to endorse or promote products derived from this software
   20  *    without specific prior written permission.
   21  *
   22  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
   23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   25  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
   26  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   32  * THE POSSIBILITY OF SUCH DAMAGE.
   33  *
   34  * $FreeBSD: src/sys/pci/if_wb.c,v 1.26 1999/09/25 17:29:02 wpaul Exp $
   35  */
   36 
   37 /*
   38  * Winbond fast ethernet PCI NIC driver
   39  *
   40  * Supports various cheap network adapters based on the Winbond W89C840F
   41  * fast ethernet controller chip. This includes adapters manufactured by
   42  * Winbond itself and some made by Linksys.
   43  *
   44  * Written by Bill Paul <wpaul@ctr.columbia.edu>
   45  * Electrical Engineering Department
   46  * Columbia University, New York City
   47  */
   48 
   49 /*
   50  * The Winbond W89C840F chip is a bus master; in some ways it resembles
   51  * a DEC 'tulip' chip, only not as complicated. Unfortunately, it has
   52  * one major difference which is that while the registers do many of
   53  * the same things as a tulip adapter, the offsets are different: where
   54  * tulip registers are typically spaced 8 bytes apart, the Winbond
   55  * registers are spaced 4 bytes apart. The receiver filter is also
   56  * programmed differently.
   57  * 
   58  * Like the tulip, the Winbond chip uses small descriptors containing
   59  * a status word, a control word and 32-bit areas that can either be used
   60  * to point to two external data blocks, or to point to a single block
   61  * and another descriptor in a linked list. Descriptors can be grouped
   62  * together in blocks to form fixed length rings or can be chained
   63  * together in linked lists. A single packet may be spread out over
   64  * several descriptors if necessary.
   65  *
   66  * For the receive ring, this driver uses a linked list of descriptors,
   67  * each pointing to a single mbuf cluster buffer, which us large enough
   68  * to hold an entire packet. The link list is looped back to created a
   69  * closed ring.
   70  *
   71  * For transmission, the driver creates a linked list of 'super descriptors'
   72  * which each contain several individual descriptors linked together.
   73  * Each 'super descriptor' contains WB_MAXFRAGS descriptors, which we
   74  * abuse as fragment pointers. This allows us to use a buffer management
   75  * scheme very similar to that used in the ThunderLAN and Etherlink XL
   76  * drivers.
   77  *
   78  * Autonegotiation is performed using the external PHY via the MII bus.
   79  * The sample boards I have all use a Davicom PHY.
   80  *
   81  * Note: the author of the Linux driver for the Winbond chip alludes
   82  * to some sort of flaw in the chip's design that seems to mandate some
   83  * drastic workaround which significantly impairs transmit performance.
   84  * I have no idea what he's on about: transmit performance with all
   85  * three of my test boards seems fine.
   86  */
   87 
   88 #include "bpfilter.h"
   89 
   90 #include <sys/param.h>
   91 #include <sys/systm.h>
   92 #include <sys/sockio.h>
   93 #include <sys/mbuf.h>
   94 #include <sys/malloc.h>
   95 #include <sys/kernel.h>
   96 #include <sys/socket.h>
   97 #include <sys/device.h>
   98 #include <sys/queue.h>
   99 #include <sys/timeout.h>
  100 
  101 #include <net/if.h>
  102 #include <net/if_dl.h>
  103 #include <net/if_types.h>
  104 
  105 #ifdef INET
  106 #include <netinet/in.h>
  107 #include <netinet/in_systm.h>
  108 #include <netinet/in_var.h>
  109 #include <netinet/ip.h>
  110 #include <netinet/if_ether.h>
  111 #endif
  112 
  113 #include <net/if_media.h>
  114 
  115 #if NBPFILTER > 0
  116 #include <net/bpf.h>
  117 #endif
  118 
  119 #include <uvm/uvm_extern.h>             /* for vtophys */
  120 #define VTOPHYS(v)      vtophys((vaddr_t)(v))
  121 
  122 #include <dev/mii/mii.h>
  123 #include <dev/mii/miivar.h>
  124 #include <dev/pci/pcireg.h>
  125 #include <dev/pci/pcivar.h>
  126 #include <dev/pci/pcidevs.h>
  127 
  128 #define WB_USEIOSPACE
  129 
  130 /* #define WB_BACKGROUND_AUTONEG */
  131 
  132 #include <dev/pci/if_wbreg.h>
  133 
  134 int wb_probe(struct device *, void *, void *);
  135 void wb_attach(struct device *, struct device *, void *);
  136 
  137 void wb_bfree(caddr_t, u_int, void *);
  138 int wb_newbuf(struct wb_softc *, struct wb_chain_onefrag *,
  139     struct mbuf *);
  140 int wb_encap(struct wb_softc *, struct wb_chain *,
  141     struct mbuf *);
  142 
  143 void wb_rxeof(struct wb_softc *);
  144 void wb_rxeoc(struct wb_softc *);
  145 void wb_txeof(struct wb_softc *);
  146 void wb_txeoc(struct wb_softc *);
  147 int wb_intr(void *);
  148 void wb_tick(void *);
  149 void wb_start(struct ifnet *);
  150 int wb_ioctl(struct ifnet *, u_long, caddr_t);
  151 void wb_init(void *);
  152 void wb_stop(struct wb_softc *);
  153 void wb_watchdog(struct ifnet *);
  154 void wb_shutdown(void *);
  155 int wb_ifmedia_upd(struct ifnet *);
  156 void wb_ifmedia_sts(struct ifnet *, struct ifmediareq *);
  157 
  158 void wb_eeprom_putbyte(struct wb_softc *, int);
  159 void wb_eeprom_getword(struct wb_softc *, int, u_int16_t *);
  160 void wb_read_eeprom(struct wb_softc *, caddr_t, int, int, int);
  161 void wb_mii_sync(struct wb_softc *);
  162 void wb_mii_send(struct wb_softc *, u_int32_t, int);
  163 int wb_mii_readreg(struct wb_softc *, struct wb_mii_frame *);
  164 int wb_mii_writereg(struct wb_softc *, struct wb_mii_frame *);
  165 
  166 void wb_setcfg(struct wb_softc *, u_int32_t);
  167 u_int8_t wb_calchash(caddr_t);
  168 void wb_setmulti(struct wb_softc *);
  169 void wb_reset(struct wb_softc *);
  170 void wb_fixmedia(struct wb_softc *);
  171 int wb_list_rx_init(struct wb_softc *);
  172 int wb_list_tx_init(struct wb_softc *);
  173 
  174 int wb_miibus_readreg(struct device *, int, int);
  175 void wb_miibus_writereg(struct device *, int, int, int);
  176 void wb_miibus_statchg(struct device *);
  177 
  178 #define WB_SETBIT(sc, reg, x)                           \
  179         CSR_WRITE_4(sc, reg,                            \
  180                 CSR_READ_4(sc, reg) | x)
  181 
  182 #define WB_CLRBIT(sc, reg, x)                           \
  183         CSR_WRITE_4(sc, reg,                            \
  184                 CSR_READ_4(sc, reg) & ~x)
  185 
  186 #define SIO_SET(x)                                      \
  187         CSR_WRITE_4(sc, WB_SIO,                         \
  188                 CSR_READ_4(sc, WB_SIO) | x)
  189 
  190 #define SIO_CLR(x)                                      \
  191         CSR_WRITE_4(sc, WB_SIO,                         \
  192                 CSR_READ_4(sc, WB_SIO) & ~x)
  193 
  194 /*
  195  * Send a read command and address to the EEPROM, check for ACK.
  196  */
  197 void wb_eeprom_putbyte(sc, addr)
  198         struct wb_softc         *sc;
  199         int                     addr;
  200 {
  201         int                     d, i;
  202 
  203         d = addr | WB_EECMD_READ;
  204 
  205         /*
  206          * Feed in each bit and strobe the clock.
  207          */
  208         for (i = 0x400; i; i >>= 1) {
  209                 if (d & i) {
  210                         SIO_SET(WB_SIO_EE_DATAIN);
  211                 } else {
  212                         SIO_CLR(WB_SIO_EE_DATAIN);
  213                 }
  214                 DELAY(100);
  215                 SIO_SET(WB_SIO_EE_CLK);
  216                 DELAY(150);
  217                 SIO_CLR(WB_SIO_EE_CLK);
  218                 DELAY(100);
  219         }
  220 
  221         return;
  222 }
  223 
  224 /*
  225  * Read a word of data stored in the EEPROM at address 'addr.'
  226  */
  227 void wb_eeprom_getword(sc, addr, dest)
  228         struct wb_softc         *sc;
  229         int                     addr;
  230         u_int16_t               *dest;
  231 {
  232         int                     i;
  233         u_int16_t               word = 0;
  234 
  235         /* Enter EEPROM access mode. */
  236         CSR_WRITE_4(sc, WB_SIO, WB_SIO_EESEL|WB_SIO_EE_CS);
  237 
  238         /*
  239          * Send address of word we want to read.
  240          */
  241         wb_eeprom_putbyte(sc, addr);
  242 
  243         CSR_WRITE_4(sc, WB_SIO, WB_SIO_EESEL|WB_SIO_EE_CS);
  244 
  245         /*
  246          * Start reading bits from EEPROM.
  247          */
  248         for (i = 0x8000; i; i >>= 1) {
  249                 SIO_SET(WB_SIO_EE_CLK);
  250                 DELAY(100);
  251                 if (CSR_READ_4(sc, WB_SIO) & WB_SIO_EE_DATAOUT)
  252                         word |= i;
  253                 SIO_CLR(WB_SIO_EE_CLK);
  254                 DELAY(100);
  255         }
  256 
  257         /* Turn off EEPROM access mode. */
  258         CSR_WRITE_4(sc, WB_SIO, 0);
  259 
  260         *dest = word;
  261 
  262         return;
  263 }
  264 
  265 /*
  266  * Read a sequence of words from the EEPROM.
  267  */
  268 void wb_read_eeprom(sc, dest, off, cnt, swap)
  269         struct wb_softc         *sc;
  270         caddr_t                 dest;
  271         int                     off;
  272         int                     cnt;
  273         int                     swap;
  274 {
  275         int                     i;
  276         u_int16_t               word = 0, *ptr;
  277 
  278         for (i = 0; i < cnt; i++) {
  279                 wb_eeprom_getword(sc, off + i, &word);
  280                 ptr = (u_int16_t *)(dest + (i * 2));
  281                 if (swap)
  282                         *ptr = ntohs(word);
  283                 else
  284                         *ptr = word;
  285         }
  286 
  287         return;
  288 }
  289 
  290 /*
  291  * Sync the PHYs by setting data bit and strobing the clock 32 times.
  292  */
  293 void wb_mii_sync(sc)
  294         struct wb_softc         *sc;
  295 {
  296         int                     i;
  297 
  298         SIO_SET(WB_SIO_MII_DIR|WB_SIO_MII_DATAIN);
  299 
  300         for (i = 0; i < 32; i++) {
  301                 SIO_SET(WB_SIO_MII_CLK);
  302                 DELAY(1);
  303                 SIO_CLR(WB_SIO_MII_CLK);
  304                 DELAY(1);
  305         }
  306 
  307         return;
  308 }
  309 
  310 /*
  311  * Clock a series of bits through the MII.
  312  */
  313 void wb_mii_send(sc, bits, cnt)
  314         struct wb_softc         *sc;
  315         u_int32_t               bits;
  316         int                     cnt;
  317 {
  318         int                     i;
  319 
  320         SIO_CLR(WB_SIO_MII_CLK);
  321 
  322         for (i = (0x1 << (cnt - 1)); i; i >>= 1) {
  323                 if (bits & i) {
  324                         SIO_SET(WB_SIO_MII_DATAIN);
  325                 } else {
  326                         SIO_CLR(WB_SIO_MII_DATAIN);
  327                 }
  328                 DELAY(1);
  329                 SIO_CLR(WB_SIO_MII_CLK);
  330                 DELAY(1);
  331                 SIO_SET(WB_SIO_MII_CLK);
  332         }
  333 }
  334 
  335 /*
  336  * Read an PHY register through the MII.
  337  */
  338 int wb_mii_readreg(sc, frame)
  339         struct wb_softc         *sc;
  340         struct wb_mii_frame     *frame;
  341         
  342 {
  343         int                     i, ack, s;
  344 
  345         s = splnet();
  346 
  347         /*
  348          * Set up frame for RX.
  349          */
  350         frame->mii_stdelim = WB_MII_STARTDELIM;
  351         frame->mii_opcode = WB_MII_READOP;
  352         frame->mii_turnaround = 0;
  353         frame->mii_data = 0;
  354         
  355         CSR_WRITE_4(sc, WB_SIO, 0);
  356 
  357         /*
  358          * Turn on data xmit.
  359          */
  360         SIO_SET(WB_SIO_MII_DIR);
  361 
  362         wb_mii_sync(sc);
  363 
  364         /*
  365          * Send command/address info.
  366          */
  367         wb_mii_send(sc, frame->mii_stdelim, 2);
  368         wb_mii_send(sc, frame->mii_opcode, 2);
  369         wb_mii_send(sc, frame->mii_phyaddr, 5);
  370         wb_mii_send(sc, frame->mii_regaddr, 5);
  371 
  372         /* Idle bit */
  373         SIO_CLR((WB_SIO_MII_CLK|WB_SIO_MII_DATAIN));
  374         DELAY(1);
  375         SIO_SET(WB_SIO_MII_CLK);
  376         DELAY(1);
  377 
  378         /* Turn off xmit. */
  379         SIO_CLR(WB_SIO_MII_DIR);
  380         /* Check for ack */
  381         SIO_CLR(WB_SIO_MII_CLK);
  382         DELAY(1);
  383         ack = CSR_READ_4(sc, WB_SIO) & WB_SIO_MII_DATAOUT;
  384         SIO_SET(WB_SIO_MII_CLK);
  385         DELAY(1);
  386         SIO_CLR(WB_SIO_MII_CLK);
  387         DELAY(1);
  388         SIO_SET(WB_SIO_MII_CLK);
  389         DELAY(1);
  390 
  391         /*
  392          * Now try reading data bits. If the ack failed, we still
  393          * need to clock through 16 cycles to keep the PHY(s) in sync.
  394          */
  395         if (ack) {
  396                 for(i = 0; i < 16; i++) {
  397                         SIO_CLR(WB_SIO_MII_CLK);
  398                         DELAY(1);
  399                         SIO_SET(WB_SIO_MII_CLK);
  400                         DELAY(1);
  401                 }
  402                 goto fail;
  403         }
  404 
  405         for (i = 0x8000; i; i >>= 1) {
  406                 SIO_CLR(WB_SIO_MII_CLK);
  407                 DELAY(1);
  408                 if (!ack) {
  409                         if (CSR_READ_4(sc, WB_SIO) & WB_SIO_MII_DATAOUT)
  410                                 frame->mii_data |= i;
  411                         DELAY(1);
  412                 }
  413                 SIO_SET(WB_SIO_MII_CLK);
  414                 DELAY(1);
  415         }
  416 
  417 fail:
  418 
  419         SIO_CLR(WB_SIO_MII_CLK);
  420         DELAY(1);
  421         SIO_SET(WB_SIO_MII_CLK);
  422         DELAY(1);
  423 
  424         splx(s);
  425 
  426         if (ack)
  427                 return(1);
  428         return(0);
  429 }
  430 
  431 /*
  432  * Write to a PHY register through the MII.
  433  */
  434 int wb_mii_writereg(sc, frame)
  435         struct wb_softc         *sc;
  436         struct wb_mii_frame     *frame;
  437         
  438 {
  439         int                     s;
  440 
  441         s = splnet();
  442         /*
  443          * Set up frame for TX.
  444          */
  445 
  446         frame->mii_stdelim = WB_MII_STARTDELIM;
  447         frame->mii_opcode = WB_MII_WRITEOP;
  448         frame->mii_turnaround = WB_MII_TURNAROUND;
  449         
  450         /*
  451          * Turn on data output.
  452          */
  453         SIO_SET(WB_SIO_MII_DIR);
  454 
  455         wb_mii_sync(sc);
  456 
  457         wb_mii_send(sc, frame->mii_stdelim, 2);
  458         wb_mii_send(sc, frame->mii_opcode, 2);
  459         wb_mii_send(sc, frame->mii_phyaddr, 5);
  460         wb_mii_send(sc, frame->mii_regaddr, 5);
  461         wb_mii_send(sc, frame->mii_turnaround, 2);
  462         wb_mii_send(sc, frame->mii_data, 16);
  463 
  464         /* Idle bit. */
  465         SIO_SET(WB_SIO_MII_CLK);
  466         DELAY(1);
  467         SIO_CLR(WB_SIO_MII_CLK);
  468         DELAY(1);
  469 
  470         /*
  471          * Turn off xmit.
  472          */
  473         SIO_CLR(WB_SIO_MII_DIR);
  474 
  475         splx(s);
  476 
  477         return(0);
  478 }
  479 
  480 int
  481 wb_miibus_readreg(dev, phy, reg)
  482         struct device *dev;
  483         int phy, reg;
  484 {
  485         struct wb_softc *sc = (struct wb_softc *)dev;
  486         struct wb_mii_frame frame;
  487 
  488         bzero((char *)&frame, sizeof(frame));
  489 
  490         frame.mii_phyaddr = phy;
  491         frame.mii_regaddr = reg;
  492         wb_mii_readreg(sc, &frame);
  493 
  494         return(frame.mii_data);
  495 }
  496 
  497 void
  498 wb_miibus_writereg(dev, phy, reg, data)
  499         struct device *dev;
  500         int phy, reg, data;
  501 {
  502         struct wb_softc *sc = (struct wb_softc *)dev;
  503         struct wb_mii_frame frame;
  504 
  505         bzero((char *)&frame, sizeof(frame));
  506 
  507         frame.mii_phyaddr = phy;
  508         frame.mii_regaddr = reg;
  509         frame.mii_data = data;
  510 
  511         wb_mii_writereg(sc, &frame);
  512 
  513         return;
  514 }
  515 
  516 void
  517 wb_miibus_statchg(dev)
  518         struct device *dev;
  519 {
  520         struct wb_softc *sc = (struct wb_softc *)dev;
  521 
  522         wb_setcfg(sc, sc->sc_mii.mii_media_active);
  523 }
  524 
  525 /*
  526  * Program the 64-bit multicast hash filter.
  527  */
  528 void wb_setmulti(sc)
  529         struct wb_softc         *sc;
  530 {
  531         struct ifnet            *ifp;
  532         int                     h = 0;
  533         u_int32_t               hashes[2] = { 0, 0 };
  534         struct arpcom           *ac = &sc->arpcom;
  535         struct ether_multi      *enm;
  536         struct ether_multistep  step;
  537         u_int32_t               rxfilt;
  538         int                     mcnt = 0;
  539 
  540         ifp = &sc->arpcom.ac_if;
  541 
  542         rxfilt = CSR_READ_4(sc, WB_NETCFG);
  543 
  544 allmulti:
  545         if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
  546                 rxfilt |= WB_NETCFG_RX_MULTI;
  547                 CSR_WRITE_4(sc, WB_NETCFG, rxfilt);
  548                 CSR_WRITE_4(sc, WB_MAR0, 0xFFFFFFFF);
  549                 CSR_WRITE_4(sc, WB_MAR1, 0xFFFFFFFF);
  550                 return;
  551         }
  552 
  553         /* first, zot all the existing hash bits */
  554         CSR_WRITE_4(sc, WB_MAR0, 0);
  555         CSR_WRITE_4(sc, WB_MAR1, 0);
  556 
  557         /* now program new ones */
  558         ETHER_FIRST_MULTI(step, ac, enm);
  559         while (enm != NULL) {
  560                 if (bcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
  561                         ifp->if_flags |= IFF_ALLMULTI;
  562                         goto allmulti;
  563                 }
  564                 h = ~(ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN) >> 26);
  565                 if (h < 32)
  566                         hashes[0] |= (1 << h);
  567                 else
  568                         hashes[1] |= (1 << (h - 32));
  569                 mcnt++;
  570                 ETHER_NEXT_MULTI(step, enm);
  571         }
  572 
  573         if (mcnt)
  574                 rxfilt |= WB_NETCFG_RX_MULTI;
  575         else
  576                 rxfilt &= ~WB_NETCFG_RX_MULTI;
  577 
  578         CSR_WRITE_4(sc, WB_MAR0, hashes[0]);
  579         CSR_WRITE_4(sc, WB_MAR1, hashes[1]);
  580         CSR_WRITE_4(sc, WB_NETCFG, rxfilt);
  581 
  582         return;
  583 }
  584 
  585 /*
  586  * The Winbond manual states that in order to fiddle with the
  587  * 'full-duplex' and '100Mbps' bits in the netconfig register, we
  588  * first have to put the transmit and/or receive logic in the idle state.
  589  */
  590 void
  591 wb_setcfg(sc, media)
  592         struct wb_softc *sc;
  593         u_int32_t media;
  594 {
  595         int                     i, restart = 0;
  596 
  597         if (CSR_READ_4(sc, WB_NETCFG) & (WB_NETCFG_TX_ON|WB_NETCFG_RX_ON)) {
  598                 restart = 1;
  599                 WB_CLRBIT(sc, WB_NETCFG, (WB_NETCFG_TX_ON|WB_NETCFG_RX_ON));
  600 
  601                 for (i = 0; i < WB_TIMEOUT; i++) {
  602                         DELAY(10);
  603                         if ((CSR_READ_4(sc, WB_ISR) & WB_ISR_TX_IDLE) &&
  604                                 (CSR_READ_4(sc, WB_ISR) & WB_ISR_RX_IDLE))
  605                                 break;
  606                 }
  607 
  608                 if (i == WB_TIMEOUT)
  609                         printf("%s: failed to force tx and "
  610                                 "rx to idle state\n", sc->sc_dev.dv_xname);
  611         }
  612 
  613         if (IFM_SUBTYPE(media) == IFM_10_T)
  614                 WB_CLRBIT(sc, WB_NETCFG, WB_NETCFG_100MBPS);
  615         else
  616                 WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_100MBPS);
  617 
  618         if ((media & IFM_GMASK) == IFM_FDX)
  619                 WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_FULLDUPLEX);
  620         else
  621                 WB_CLRBIT(sc, WB_NETCFG, WB_NETCFG_FULLDUPLEX);
  622 
  623         if (restart)
  624                 WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_TX_ON|WB_NETCFG_RX_ON);
  625 
  626         return;
  627 }
  628 
  629 void
  630 wb_reset(sc)
  631         struct wb_softc *sc;
  632 {
  633         int i;
  634         struct mii_data *mii = &sc->sc_mii;
  635 
  636         CSR_WRITE_4(sc, WB_NETCFG, 0);
  637         CSR_WRITE_4(sc, WB_BUSCTL, 0);
  638         CSR_WRITE_4(sc, WB_TXADDR, 0);
  639         CSR_WRITE_4(sc, WB_RXADDR, 0);
  640 
  641         WB_SETBIT(sc, WB_BUSCTL, WB_BUSCTL_RESET);
  642         WB_SETBIT(sc, WB_BUSCTL, WB_BUSCTL_RESET);
  643 
  644         for (i = 0; i < WB_TIMEOUT; i++) {
  645                 DELAY(10);
  646                 if (!(CSR_READ_4(sc, WB_BUSCTL) & WB_BUSCTL_RESET))
  647                         break;
  648         }
  649         if (i == WB_TIMEOUT)
  650                 printf("%s: reset never completed!\n", sc->sc_dev.dv_xname);
  651 
  652         /* Wait a little while for the chip to get its brains in order. */
  653         DELAY(1000);
  654 
  655         if (mii->mii_instance) {
  656                 struct mii_softc *miisc;
  657                 LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
  658                         mii_phy_reset(miisc);
  659         }
  660 }
  661 
  662 void
  663 wb_fixmedia(sc)
  664         struct wb_softc *sc;
  665 {
  666         struct mii_data *mii = &sc->sc_mii;
  667         u_int32_t media;
  668 
  669         if (LIST_FIRST(&mii->mii_phys) == NULL)
  670                 return;
  671 
  672         mii_pollstat(mii);
  673         if (IFM_SUBTYPE(mii->mii_media_active) == IFM_10_T) {
  674                 media = mii->mii_media_active & ~IFM_10_T;
  675                 media |= IFM_100_TX;
  676         } if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX) {
  677                 media = mii->mii_media_active & ~IFM_100_TX;
  678                 media |= IFM_10_T;
  679         } else
  680                 return;
  681 
  682         ifmedia_set(&mii->mii_media, media);
  683 }
  684 
  685 const struct pci_matchid wb_devices[] = {
  686         { PCI_VENDOR_WINBOND, PCI_PRODUCT_WINBOND_W89C840F },
  687         { PCI_VENDOR_COMPEX, PCI_PRODUCT_COMPEX_RL100ATX },
  688 };
  689 
  690 /*
  691  * Probe for a Winbond chip. Check the PCI vendor and device
  692  * IDs against our list and return a device name if we find a match.
  693  */
  694 int
  695 wb_probe(parent, match, aux)
  696         struct device *parent;
  697         void *match, *aux;
  698 {
  699         return (pci_matchbyid((struct pci_attach_args *)aux, wb_devices,
  700             sizeof(wb_devices)/sizeof(wb_devices[0])));
  701 }
  702 
  703 /*
  704  * Attach the interface. Allocate softc structures, do ifmedia
  705  * setup and ethernet/BPF attach.
  706  */
  707 void
  708 wb_attach(parent, self, aux)
  709         struct device *parent, *self;
  710         void *aux;
  711 {
  712         struct wb_softc *sc = (struct wb_softc *)self;
  713         struct pci_attach_args *pa = aux;
  714         pci_chipset_tag_t pc = pa->pa_pc;
  715         pci_intr_handle_t ih;
  716         const char *intrstr = NULL;
  717         struct ifnet *ifp = &sc->arpcom.ac_if;
  718         bus_size_t size;
  719         int rseg;
  720         pcireg_t command;
  721         bus_dma_segment_t seg;
  722         bus_dmamap_t dmamap;
  723         caddr_t kva;
  724 
  725         /*
  726          * Handle power management nonsense.
  727          */
  728 
  729         command = pci_conf_read(pc, pa->pa_tag, WB_PCI_CAPID) & 0x000000FF;
  730         if (command == 0x01) {
  731 
  732                 command = pci_conf_read(pc, pa->pa_tag, WB_PCI_PWRMGMTCTRL);
  733                 if (command & WB_PSTATE_MASK) {
  734                         u_int32_t               io, mem, irq;
  735 
  736                         /* Save important PCI config data. */
  737                         io = pci_conf_read(pc, pa->pa_tag, WB_PCI_LOIO);
  738                         mem = pci_conf_read(pc, pa->pa_tag, WB_PCI_LOMEM);
  739                         irq = pci_conf_read(pc, pa->pa_tag, WB_PCI_INTLINE);
  740 
  741                         /* Reset the power state. */
  742                         printf("%s: chip is in D%d power mode "
  743                             "-- setting to D0\n", sc->sc_dev.dv_xname,
  744                             command & WB_PSTATE_MASK);
  745                         command &= 0xFFFFFFFC;
  746                         pci_conf_write(pc, pa->pa_tag, WB_PCI_PWRMGMTCTRL,
  747                             command);
  748 
  749                         /* Restore PCI config data. */
  750                         pci_conf_write(pc, pa->pa_tag, WB_PCI_LOIO, io);
  751                         pci_conf_write(pc, pa->pa_tag, WB_PCI_LOMEM, mem);
  752                         pci_conf_write(pc, pa->pa_tag, WB_PCI_INTLINE, irq);
  753                 }
  754         }
  755 
  756         /*
  757          * Map control/status registers.
  758          */
  759 
  760 #ifdef WB_USEIOSPACE
  761         if (pci_mapreg_map(pa, WB_PCI_LOIO, PCI_MAPREG_TYPE_IO, 0,
  762             &sc->wb_btag, &sc->wb_bhandle, NULL, &size, 0)) {
  763                 printf(": can't map i/o space\n");
  764                 return;
  765         }
  766 #else
  767         if (pci_mapreg_map(pa, WB_PCI_LOMEM, PCI_MAPREG_TYPE_MEM, 0,
  768             &sc->wb_btag, &sc->wb_bhandle, NULL, &size, 0)){
  769                 printf(": can't map mem space\n");
  770                 return;
  771         }
  772 #endif
  773 
  774         /* Allocate interrupt */
  775         if (pci_intr_map(pa, &ih)) {
  776                 printf(": couldn't map interrupt\n");
  777                 goto fail_1;
  778         }
  779         intrstr = pci_intr_string(pc, ih);
  780         sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, wb_intr, sc,
  781             self->dv_xname);
  782         if (sc->sc_ih == NULL) {
  783                 printf(": couldn't establish interrupt");
  784                 if (intrstr != NULL)
  785                         printf(" at %s", intrstr);
  786                 printf("\n");
  787                 goto fail_1;
  788         }
  789         printf(": %s", intrstr);
  790 
  791         sc->wb_cachesize = pci_conf_read(pc, pa->pa_tag, WB_PCI_CACHELEN)&0xff;
  792 
  793         /* Reset the adapter. */
  794         wb_reset(sc);
  795 
  796         /*
  797          * Get station address from the EEPROM.
  798          */
  799         wb_read_eeprom(sc, (caddr_t)&sc->arpcom.ac_enaddr, 0, 3, 0);
  800         printf(", address %s\n", ether_sprintf(sc->arpcom.ac_enaddr));
  801 
  802         if (bus_dmamem_alloc(pa->pa_dmat, sizeof(struct wb_list_data),
  803             PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
  804                 printf(": can't alloc list data\n");
  805                 goto fail_2;
  806         }
  807         if (bus_dmamem_map(pa->pa_dmat, &seg, rseg,
  808             sizeof(struct wb_list_data), &kva, BUS_DMA_NOWAIT)) {
  809                 printf(": can't map list data, size %d\n",
  810                     sizeof(struct wb_list_data));
  811                 goto fail_3;
  812         }
  813         if (bus_dmamap_create(pa->pa_dmat, sizeof(struct wb_list_data), 1,
  814             sizeof(struct wb_list_data), 0, BUS_DMA_NOWAIT, &dmamap)) {
  815                 printf(": can't create dma map\n");
  816                 goto fail_4;
  817         }
  818         if (bus_dmamap_load(pa->pa_dmat, dmamap, kva,
  819             sizeof(struct wb_list_data), NULL, BUS_DMA_NOWAIT)) {
  820                 printf(": can't load dma map\n");
  821                 goto fail_5;
  822         }
  823         sc->wb_ldata = (struct wb_list_data *)kva;
  824         bzero(sc->wb_ldata, sizeof(struct wb_list_data));
  825 
  826         ifp->if_softc = sc;
  827         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
  828         ifp->if_ioctl = wb_ioctl;
  829         ifp->if_start = wb_start;
  830         ifp->if_watchdog = wb_watchdog;
  831         ifp->if_baudrate = 10000000;
  832         IFQ_SET_MAXLEN(&ifp->if_snd, WB_TX_LIST_CNT - 1);
  833         IFQ_SET_READY(&ifp->if_snd);
  834 
  835         bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
  836 
  837         /*
  838          * Do ifmedia setup.
  839          */
  840         wb_stop(sc);
  841 
  842         ifmedia_init(&sc->sc_mii.mii_media, 0, wb_ifmedia_upd, wb_ifmedia_sts);
  843         sc->sc_mii.mii_ifp = ifp;
  844         sc->sc_mii.mii_readreg = wb_miibus_readreg;
  845         sc->sc_mii.mii_writereg = wb_miibus_writereg;
  846         sc->sc_mii.mii_statchg = wb_miibus_statchg;
  847         mii_attach(self, &sc->sc_mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY,
  848             0);
  849         if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
  850                 ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE,0,NULL);
  851                 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE);
  852         } else
  853                 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
  854 
  855         /*
  856          * Call MI attach routines.
  857          */
  858         if_attach(ifp);
  859         ether_ifattach(ifp);
  860 
  861         shutdownhook_establish(wb_shutdown, sc);
  862         return;
  863 
  864 fail_5:
  865         bus_dmamap_destroy(pa->pa_dmat, dmamap);
  866 
  867 fail_4:
  868         bus_dmamem_unmap(pa->pa_dmat, kva,
  869             sizeof(struct wb_list_data));
  870 
  871 fail_3:
  872         bus_dmamem_free(pa->pa_dmat, &seg, rseg);
  873 
  874 fail_2:
  875         pci_intr_disestablish(pc, sc->sc_ih);
  876 
  877 fail_1:
  878         bus_space_unmap(sc->wb_btag, sc->wb_bhandle, size);
  879 }
  880 
  881 /*
  882  * Initialize the transmit descriptors.
  883  */
  884 int wb_list_tx_init(sc)
  885         struct wb_softc         *sc;
  886 {
  887         struct wb_chain_data    *cd;
  888         struct wb_list_data     *ld;
  889         int                     i;
  890 
  891         cd = &sc->wb_cdata;
  892         ld = sc->wb_ldata;
  893 
  894         for (i = 0; i < WB_TX_LIST_CNT; i++) {
  895                 cd->wb_tx_chain[i].wb_ptr = &ld->wb_tx_list[i];
  896                 if (i == (WB_TX_LIST_CNT - 1)) {
  897                         cd->wb_tx_chain[i].wb_nextdesc =
  898                                 &cd->wb_tx_chain[0];
  899                 } else {
  900                         cd->wb_tx_chain[i].wb_nextdesc =
  901                                 &cd->wb_tx_chain[i + 1];
  902                 }
  903         }
  904 
  905         cd->wb_tx_free = &cd->wb_tx_chain[0];
  906         cd->wb_tx_tail = cd->wb_tx_head = NULL;
  907 
  908         return(0);
  909 }
  910 
  911 
  912 /*
  913  * Initialize the RX descriptors and allocate mbufs for them. Note that
  914  * we arrange the descriptors in a closed ring, so that the last descriptor
  915  * points back to the first.
  916  */
  917 int wb_list_rx_init(sc)
  918         struct wb_softc         *sc;
  919 {
  920         struct wb_chain_data    *cd;
  921         struct wb_list_data     *ld;
  922         int                     i;
  923 
  924         cd = &sc->wb_cdata;
  925         ld = sc->wb_ldata;
  926 
  927         for (i = 0; i < WB_RX_LIST_CNT; i++) {
  928                 cd->wb_rx_chain[i].wb_ptr =
  929                         (struct wb_desc *)&ld->wb_rx_list[i];
  930                 cd->wb_rx_chain[i].wb_buf = (void *)&ld->wb_rxbufs[i];
  931                 if (wb_newbuf(sc, &cd->wb_rx_chain[i], NULL) == ENOBUFS)
  932                         return(ENOBUFS);
  933                 if (i == (WB_RX_LIST_CNT - 1)) {
  934                         cd->wb_rx_chain[i].wb_nextdesc = &cd->wb_rx_chain[0];
  935                         ld->wb_rx_list[i].wb_next = 
  936                                         VTOPHYS(&ld->wb_rx_list[0]);
  937                 } else {
  938                         cd->wb_rx_chain[i].wb_nextdesc =
  939                                         &cd->wb_rx_chain[i + 1];
  940                         ld->wb_rx_list[i].wb_next =
  941                                         VTOPHYS(&ld->wb_rx_list[i + 1]);
  942                 }
  943         }
  944 
  945         cd->wb_rx_head = &cd->wb_rx_chain[0];
  946 
  947         return(0);
  948 }
  949 
  950 void
  951 wb_bfree(buf, size, arg)
  952         caddr_t                 buf;
  953         u_int                   size;
  954         void *arg;
  955 {
  956 }
  957 
  958 /*
  959  * Initialize an RX descriptor and attach an MBUF cluster.
  960  */
  961 int
  962 wb_newbuf(sc, c, m)
  963         struct wb_softc *sc;
  964         struct wb_chain_onefrag *c;
  965         struct mbuf *m;
  966 {
  967         struct mbuf             *m_new = NULL;
  968 
  969         if (m == NULL) {
  970                 MGETHDR(m_new, M_DONTWAIT, MT_DATA);
  971                 if (m_new == NULL)
  972                         return(ENOBUFS);
  973                 m_new->m_data = m_new->m_ext.ext_buf = c->wb_buf;
  974                 m_new->m_flags |= M_EXT;
  975                 m_new->m_ext.ext_size = m_new->m_pkthdr.len =
  976                     m_new->m_len = WB_BUFBYTES;
  977                 m_new->m_ext.ext_free = wb_bfree;
  978                 m_new->m_ext.ext_arg = NULL;
  979                 MCLINITREFERENCE(m_new);
  980         } else {
  981                 m_new = m;
  982                 m_new->m_len = m_new->m_pkthdr.len = WB_BUFBYTES;
  983                 m_new->m_data = m_new->m_ext.ext_buf;
  984         }
  985 
  986         m_adj(m_new, sizeof(u_int64_t));
  987 
  988         c->wb_mbuf = m_new;
  989         c->wb_ptr->wb_data = VTOPHYS(mtod(m_new, caddr_t));
  990         c->wb_ptr->wb_ctl = WB_RXCTL_RLINK | ETHER_MAX_DIX_LEN;
  991         c->wb_ptr->wb_status = WB_RXSTAT;
  992 
  993         return(0);
  994 }
  995 
  996 /*
  997  * A frame has been uploaded: pass the resulting mbuf chain up to
  998  * the higher level protocols.
  999  */
 1000 void wb_rxeof(sc)
 1001         struct wb_softc         *sc;
 1002 {
 1003         struct mbuf             *m = NULL;
 1004         struct ifnet            *ifp;
 1005         struct wb_chain_onefrag *cur_rx;
 1006         int                     total_len = 0;
 1007         u_int32_t               rxstat;
 1008 
 1009         ifp = &sc->arpcom.ac_if;
 1010 
 1011         while(!((rxstat = sc->wb_cdata.wb_rx_head->wb_ptr->wb_status) &
 1012                                                         WB_RXSTAT_OWN)) {
 1013                 struct mbuf *m0 = NULL;
 1014 
 1015                 cur_rx = sc->wb_cdata.wb_rx_head;
 1016                 sc->wb_cdata.wb_rx_head = cur_rx->wb_nextdesc;
 1017 
 1018                 m = cur_rx->wb_mbuf;
 1019 
 1020                 if ((rxstat & WB_RXSTAT_MIIERR) ||
 1021                     (WB_RXBYTES(cur_rx->wb_ptr->wb_status) < WB_MIN_FRAMELEN) ||
 1022                     (WB_RXBYTES(cur_rx->wb_ptr->wb_status) > ETHER_MAX_DIX_LEN) ||
 1023                     !(rxstat & WB_RXSTAT_LASTFRAG) ||
 1024                     !(rxstat & WB_RXSTAT_RXCMP)) {
 1025                         ifp->if_ierrors++;
 1026                         wb_newbuf(sc, cur_rx, m);
 1027                         printf("%s: receiver babbling: possible chip "
 1028                                 "bug, forcing reset\n", sc->sc_dev.dv_xname);
 1029                         wb_fixmedia(sc);
 1030                         wb_reset(sc);
 1031                         wb_init(sc);
 1032                         return;
 1033                 }
 1034 
 1035                 if (rxstat & WB_RXSTAT_RXERR) {
 1036                         ifp->if_ierrors++;
 1037                         wb_newbuf(sc, cur_rx, m);
 1038                         break;
 1039                 }
 1040 
 1041                 /* No errors; receive the packet. */    
 1042                 total_len = WB_RXBYTES(cur_rx->wb_ptr->wb_status);
 1043 
 1044                 /*
 1045                  * XXX The Winbond chip includes the CRC with every
 1046                  * received frame, and there's no way to turn this
 1047                  * behavior off (at least, I can't find anything in
 1048                  * the manual that explains how to do it) so we have
 1049                  * to trim off the CRC manually.
 1050                  */
 1051                 total_len -= ETHER_CRC_LEN;
 1052 
 1053                 m0 = m_devget(mtod(m, char *) - ETHER_ALIGN,
 1054                     total_len + ETHER_ALIGN, 0, ifp, NULL);
 1055                 wb_newbuf(sc, cur_rx, m);
 1056                 if (m0 == NULL) {
 1057                         ifp->if_ierrors++;
 1058                         break;
 1059                 }
 1060                 m_adj(m0, ETHER_ALIGN);
 1061                 m = m0;
 1062 
 1063                 ifp->if_ipackets++;
 1064 
 1065 #if NBPFILTER > 0
 1066                 /*
 1067                  * Handle BPF listeners. Let the BPF user see the packet.
 1068                  */
 1069                 if (ifp->if_bpf)
 1070                         bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
 1071 #endif
 1072                 /* pass it on. */
 1073                 ether_input_mbuf(ifp, m);
 1074         }
 1075 
 1076         return;
 1077 }
 1078 
 1079 void wb_rxeoc(sc)
 1080         struct wb_softc         *sc;
 1081 {
 1082         wb_rxeof(sc);
 1083 
 1084         WB_CLRBIT(sc, WB_NETCFG, WB_NETCFG_RX_ON);
 1085         CSR_WRITE_4(sc, WB_RXADDR, VTOPHYS(&sc->wb_ldata->wb_rx_list[0]));
 1086         WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_RX_ON);
 1087         if (CSR_READ_4(sc, WB_ISR) & WB_RXSTATE_SUSPEND)
 1088                 CSR_WRITE_4(sc, WB_RXSTART, 0xFFFFFFFF);
 1089 
 1090         return;
 1091 }
 1092 
 1093 /*
 1094  * A frame was downloaded to the chip. It's safe for us to clean up
 1095  * the list buffers.
 1096  */
 1097 void wb_txeof(sc)
 1098         struct wb_softc         *sc;
 1099 {
 1100         struct wb_chain         *cur_tx;
 1101         struct ifnet            *ifp;
 1102 
 1103         ifp = &sc->arpcom.ac_if;
 1104 
 1105         /* Clear the timeout timer. */
 1106         ifp->if_timer = 0;
 1107 
 1108         if (sc->wb_cdata.wb_tx_head == NULL)
 1109                 return;
 1110 
 1111         /*
 1112          * Go through our tx list and free mbufs for those
 1113          * frames that have been transmitted.
 1114          */
 1115         while(sc->wb_cdata.wb_tx_head->wb_mbuf != NULL) {
 1116                 u_int32_t               txstat;
 1117 
 1118                 cur_tx = sc->wb_cdata.wb_tx_head;
 1119                 txstat = WB_TXSTATUS(cur_tx);
 1120 
 1121                 if ((txstat & WB_TXSTAT_OWN) || txstat == WB_UNSENT)
 1122                         break;
 1123 
 1124                 if (txstat & WB_TXSTAT_TXERR) {
 1125                         ifp->if_oerrors++;
 1126                         if (txstat & WB_TXSTAT_ABORT)
 1127                                 ifp->if_collisions++;
 1128                         if (txstat & WB_TXSTAT_LATECOLL)
 1129                                 ifp->if_collisions++;
 1130                 }
 1131 
 1132                 ifp->if_collisions += (txstat & WB_TXSTAT_COLLCNT) >> 3;
 1133 
 1134                 ifp->if_opackets++;
 1135                 m_freem(cur_tx->wb_mbuf);
 1136                 cur_tx->wb_mbuf = NULL;
 1137 
 1138                 if (sc->wb_cdata.wb_tx_head == sc->wb_cdata.wb_tx_tail) {
 1139                         sc->wb_cdata.wb_tx_head = NULL;
 1140                         sc->wb_cdata.wb_tx_tail = NULL;
 1141                         break;
 1142                 }
 1143 
 1144                 sc->wb_cdata.wb_tx_head = cur_tx->wb_nextdesc;
 1145         }
 1146 
 1147         return;
 1148 }
 1149 
 1150 /*
 1151  * TX 'end of channel' interrupt handler.
 1152  */
 1153 void wb_txeoc(sc)
 1154         struct wb_softc         *sc;
 1155 {
 1156         struct ifnet            *ifp;
 1157 
 1158         ifp = &sc->arpcom.ac_if;
 1159 
 1160         ifp->if_timer = 0;
 1161 
 1162         if (sc->wb_cdata.wb_tx_head == NULL) {
 1163                 ifp->if_flags &= ~IFF_OACTIVE;
 1164                 sc->wb_cdata.wb_tx_tail = NULL;
 1165         } else {
 1166                 if (WB_TXOWN(sc->wb_cdata.wb_tx_head) == WB_UNSENT) {
 1167                         WB_TXOWN(sc->wb_cdata.wb_tx_head) = WB_TXSTAT_OWN;
 1168                         ifp->if_timer = 5;
 1169                         CSR_WRITE_4(sc, WB_TXSTART, 0xFFFFFFFF);
 1170                 }
 1171         }
 1172 
 1173         return;
 1174 }
 1175 
 1176 int wb_intr(arg)
 1177         void                    *arg;
 1178 {
 1179         struct wb_softc         *sc;
 1180         struct ifnet            *ifp;
 1181         u_int32_t               status;
 1182         int                     r = 0;
 1183 
 1184         sc = arg;
 1185         ifp = &sc->arpcom.ac_if;
 1186 
 1187         if (!(ifp->if_flags & IFF_UP))
 1188                 return (r);
 1189 
 1190         /* Disable interrupts. */
 1191         CSR_WRITE_4(sc, WB_IMR, 0x00000000);
 1192 
 1193         for (;;) {
 1194 
 1195                 status = CSR_READ_4(sc, WB_ISR);
 1196                 if (status)
 1197                         CSR_WRITE_4(sc, WB_ISR, status);
 1198 
 1199                 if ((status & WB_INTRS) == 0)
 1200                         break;
 1201 
 1202                 r = 1;
 1203 
 1204                 if ((status & WB_ISR_RX_NOBUF) || (status & WB_ISR_RX_ERR)) {
 1205                         ifp->if_ierrors++;
 1206                         wb_reset(sc);
 1207                         if (status & WB_ISR_RX_ERR)
 1208                                 wb_fixmedia(sc);
 1209                         wb_init(sc);
 1210                         continue;
 1211                 }
 1212 
 1213                 if (status & WB_ISR_RX_OK)
 1214                         wb_rxeof(sc);
 1215 
 1216                 if (status & WB_ISR_RX_IDLE)
 1217                         wb_rxeoc(sc);
 1218 
 1219                 if (status & WB_ISR_TX_OK)
 1220                         wb_txeof(sc);
 1221 
 1222                 if (status & WB_ISR_TX_NOBUF)
 1223                         wb_txeoc(sc);
 1224 
 1225                 if (status & WB_ISR_TX_IDLE) {
 1226                         wb_txeof(sc);
 1227                         if (sc->wb_cdata.wb_tx_head != NULL) {
 1228                                 WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_TX_ON);
 1229                                 CSR_WRITE_4(sc, WB_TXSTART, 0xFFFFFFFF);
 1230                         }
 1231                 }
 1232 
 1233                 if (status & WB_ISR_TX_UNDERRUN) {
 1234                         ifp->if_oerrors++;
 1235                         wb_txeof(sc);
 1236                         WB_CLRBIT(sc, WB_NETCFG, WB_NETCFG_TX_ON);
 1237                         /* Jack up TX threshold */
 1238                         sc->wb_txthresh += WB_TXTHRESH_CHUNK;
 1239                         WB_CLRBIT(sc, WB_NETCFG, WB_NETCFG_TX_THRESH);
 1240                         WB_SETBIT(sc, WB_NETCFG, WB_TXTHRESH(sc->wb_txthresh));
 1241                         WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_TX_ON);
 1242                 }
 1243 
 1244                 if (status & WB_ISR_BUS_ERR) {
 1245                         wb_reset(sc);
 1246                         wb_init(sc);
 1247                 }
 1248 
 1249         }
 1250 
 1251         /* Re-enable interrupts. */
 1252         CSR_WRITE_4(sc, WB_IMR, WB_INTRS);
 1253 
 1254         if (!IFQ_IS_EMPTY(&ifp->if_snd)) {
 1255                 wb_start(ifp);
 1256         }
 1257 
 1258         return (r);
 1259 }
 1260 
 1261 void
 1262 wb_tick(xsc)
 1263         void *xsc;
 1264 {
 1265         struct wb_softc *sc = xsc;
 1266         int s;
 1267 
 1268         s = splnet();
 1269         mii_tick(&sc->sc_mii);
 1270         splx(s);
 1271         timeout_add(&sc->wb_tick_tmo, hz);
 1272 }
 1273 
 1274 /*
 1275  * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data
 1276  * pointers to the fragment pointers.
 1277  */
 1278 int wb_encap(sc, c, m_head)
 1279         struct wb_softc         *sc;
 1280         struct wb_chain         *c;
 1281         struct mbuf             *m_head;
 1282 {
 1283         int                     frag = 0;
 1284         struct wb_desc          *f = NULL;
 1285         int                     total_len;
 1286         struct mbuf             *m;
 1287 
 1288         /*
 1289          * Start packing the mbufs in this chain into
 1290          * the fragment pointers. Stop when we run out
 1291          * of fragments or hit the end of the mbuf chain.
 1292          */
 1293         m = m_head;
 1294         total_len = 0;
 1295 
 1296         for (m = m_head, frag = 0; m != NULL; m = m->m_next) {
 1297                 if (m->m_len != 0) {
 1298                         if (frag == WB_MAXFRAGS)
 1299                                 break;
 1300                         total_len += m->m_len;
 1301                         f = &c->wb_ptr->wb_frag[frag];
 1302                         f->wb_ctl = WB_TXCTL_TLINK | m->m_len;
 1303                         if (frag == 0) {
 1304                                 f->wb_ctl |= WB_TXCTL_FIRSTFRAG;
 1305                                 f->wb_status = 0;
 1306                         } else
 1307                                 f->wb_status = WB_TXSTAT_OWN;
 1308                         f->wb_next = VTOPHYS(&c->wb_ptr->wb_frag[frag + 1]);
 1309                         f->wb_data = VTOPHYS(mtod(m, vaddr_t));
 1310                         frag++;
 1311                 }
 1312         }
 1313 
 1314         /*
 1315          * Handle special case: we used up all 16 fragments,
 1316          * but we have more mbufs left in the chain. Copy the
 1317          * data into an mbuf cluster. Note that we don't
 1318          * bother clearing the values in the other fragment
 1319          * pointers/counters; it wouldn't gain us anything,
 1320          * and would waste cycles.
 1321          */
 1322         if (m != NULL) {
 1323                 struct mbuf             *m_new = NULL;
 1324 
 1325                 MGETHDR(m_new, M_DONTWAIT, MT_DATA);
 1326                 if (m_new == NULL)
 1327                         return(1);
 1328                 if (m_head->m_pkthdr.len > MHLEN) {
 1329                         MCLGET(m_new, M_DONTWAIT);
 1330                         if (!(m_new->m_flags & M_EXT)) {
 1331                                 m_freem(m_new);
 1332                                 return(1);
 1333                         }
 1334                 }
 1335                 m_copydata(m_head, 0, m_head->m_pkthdr.len,     
 1336                                         mtod(m_new, caddr_t));
 1337                 m_new->m_pkthdr.len = m_new->m_len = m_head->m_pkthdr.len;
 1338                 m_freem(m_head);
 1339                 m_head = m_new;
 1340                 f = &c->wb_ptr->wb_frag[0];
 1341                 f->wb_status = 0;
 1342                 f->wb_data = VTOPHYS(mtod(m_new, caddr_t));
 1343                 f->wb_ctl = total_len = m_new->m_len;
 1344                 f->wb_ctl |= WB_TXCTL_TLINK|WB_TXCTL_FIRSTFRAG;
 1345                 frag = 1;
 1346         }
 1347 
 1348         if (total_len < WB_MIN_FRAMELEN) {
 1349                 f = &c->wb_ptr->wb_frag[frag];
 1350                 f->wb_ctl = WB_MIN_FRAMELEN - total_len;
 1351                 f->wb_data = VTOPHYS(&sc->wb_cdata.wb_pad);
 1352                 f->wb_ctl |= WB_TXCTL_TLINK;
 1353                 f->wb_status = WB_TXSTAT_OWN;
 1354                 frag++;
 1355         }
 1356 
 1357         c->wb_mbuf = m_head;
 1358         c->wb_lastdesc = frag - 1;
 1359         WB_TXCTL(c) |= WB_TXCTL_LASTFRAG;
 1360         WB_TXNEXT(c) = VTOPHYS(&c->wb_nextdesc->wb_ptr->wb_frag[0]);
 1361 
 1362         return(0);
 1363 }
 1364 
 1365 /*
 1366  * Main transmit routine. To avoid having to do mbuf copies, we put pointers
 1367  * to the mbuf data regions directly in the transmit lists. We also save a
 1368  * copy of the pointers since the transmit list fragment pointers are
 1369  * physical addresses.
 1370  */
 1371 
 1372 void wb_start(ifp)
 1373         struct ifnet            *ifp;
 1374 {
 1375         struct wb_softc         *sc;
 1376         struct mbuf             *m_head = NULL;
 1377         struct wb_chain         *cur_tx = NULL, *start_tx;
 1378 
 1379         sc = ifp->if_softc;
 1380 
 1381         /*
 1382          * Check for an available queue slot. If there are none,
 1383          * punt.
 1384          */
 1385         if (sc->wb_cdata.wb_tx_free->wb_mbuf != NULL) {
 1386                 ifp->if_flags |= IFF_OACTIVE;
 1387                 return;
 1388         }
 1389 
 1390         start_tx = sc->wb_cdata.wb_tx_free;
 1391 
 1392         while(sc->wb_cdata.wb_tx_free->wb_mbuf == NULL) {
 1393                 IFQ_DEQUEUE(&ifp->if_snd, m_head);
 1394                 if (m_head == NULL)
 1395                         break;
 1396 
 1397                 /* Pick a descriptor off the free list. */
 1398                 cur_tx = sc->wb_cdata.wb_tx_free;
 1399                 sc->wb_cdata.wb_tx_free = cur_tx->wb_nextdesc;
 1400 
 1401                 /* Pack the data into the descriptor. */
 1402                 wb_encap(sc, cur_tx, m_head);
 1403 
 1404                 if (cur_tx != start_tx)
 1405                         WB_TXOWN(cur_tx) = WB_TXSTAT_OWN;
 1406 
 1407 #if NBPFILTER > 0
 1408                 /*
 1409                  * If there's a BPF listener, bounce a copy of this frame
 1410                  * to him.
 1411                  */
 1412                 if (ifp->if_bpf)
 1413                         bpf_mtap(ifp->if_bpf, cur_tx->wb_mbuf,
 1414                             BPF_DIRECTION_OUT);
 1415 #endif
 1416         }
 1417 
 1418         /*
 1419          * If there are no packets queued, bail.
 1420          */
 1421         if (cur_tx == NULL)
 1422                 return;
 1423 
 1424         /*
 1425          * Place the request for the upload interrupt
 1426          * in the last descriptor in the chain. This way, if
 1427          * we're chaining several packets at once, we'll only
 1428          * get an interrupt once for the whole chain rather than
 1429          * once for each packet.
 1430          */
 1431         WB_TXCTL(cur_tx) |= WB_TXCTL_FINT;
 1432         cur_tx->wb_ptr->wb_frag[0].wb_ctl |= WB_TXCTL_FINT;
 1433         sc->wb_cdata.wb_tx_tail = cur_tx;
 1434 
 1435         if (sc->wb_cdata.wb_tx_head == NULL) {
 1436                 sc->wb_cdata.wb_tx_head = start_tx;
 1437                 WB_TXOWN(start_tx) = WB_TXSTAT_OWN;
 1438                 CSR_WRITE_4(sc, WB_TXSTART, 0xFFFFFFFF);
 1439         } else {
 1440                 /*
 1441                  * We need to distinguish between the case where
 1442                  * the own bit is clear because the chip cleared it
 1443                  * and where the own bit is clear because we haven't
 1444                  * set it yet. The magic value WB_UNSET is just some
 1445                  * ramdomly chosen number which doesn't have the own
 1446                  * bit set. When we actually transmit the frame, the
 1447                  * status word will have _only_ the own bit set, so
 1448                  * the txeoc handler will be able to tell if it needs
 1449                  * to initiate another transmission to flush out pending
 1450                  * frames.
 1451                  */
 1452                 WB_TXOWN(start_tx) = WB_UNSENT;
 1453         }
 1454 
 1455         /*
 1456          * Set a timeout in case the chip goes out to lunch.
 1457          */
 1458         ifp->if_timer = 5;
 1459 
 1460         return;
 1461 }
 1462 
 1463 void wb_init(xsc)
 1464         void                    *xsc;
 1465 {
 1466         struct wb_softc *sc = xsc;
 1467         struct ifnet *ifp = &sc->arpcom.ac_if;
 1468         int s, i;
 1469 
 1470         s = splnet();
 1471 
 1472         /*
 1473          * Cancel pending I/O and free all RX/TX buffers.
 1474          */
 1475         wb_stop(sc);
 1476         wb_reset(sc);
 1477 
 1478         sc->wb_txthresh = WB_TXTHRESH_INIT;
 1479 
 1480         /*
 1481          * Set cache alignment and burst length.
 1482          */
 1483 #ifdef foo
 1484         CSR_WRITE_4(sc, WB_BUSCTL, WB_BUSCTL_CONFIG);
 1485         WB_CLRBIT(sc, WB_NETCFG, WB_NETCFG_TX_THRESH);
 1486         WB_SETBIT(sc, WB_NETCFG, WB_TXTHRESH(sc->wb_txthresh));
 1487 #endif
 1488 
 1489         CSR_WRITE_4(sc, WB_BUSCTL, WB_BUSCTL_MUSTBEONE|WB_BUSCTL_ARBITRATION);
 1490         WB_SETBIT(sc, WB_BUSCTL, WB_BURSTLEN_16LONG);
 1491         switch(sc->wb_cachesize) {
 1492         case 32:
 1493                 WB_SETBIT(sc, WB_BUSCTL, WB_CACHEALIGN_32LONG);
 1494                 break;
 1495         case 16:
 1496                 WB_SETBIT(sc, WB_BUSCTL, WB_CACHEALIGN_16LONG);
 1497                 break;
 1498         case 8:
 1499                 WB_SETBIT(sc, WB_BUSCTL, WB_CACHEALIGN_8LONG);
 1500                 break;
 1501         case 0:
 1502         default:
 1503                 WB_SETBIT(sc, WB_BUSCTL, WB_CACHEALIGN_NONE);
 1504                 break;
 1505         }
 1506 
 1507         /* This doesn't tend to work too well at 100Mbps. */
 1508         WB_CLRBIT(sc, WB_NETCFG, WB_NETCFG_TX_EARLY_ON);
 1509 
 1510         /* Init our MAC address */
 1511         for (i = 0; i < ETHER_ADDR_LEN; i++) {
 1512                 CSR_WRITE_1(sc, WB_NODE0 + i, sc->arpcom.ac_enaddr[i]);
 1513         }
 1514 
 1515         /* Init circular RX list. */
 1516         if (wb_list_rx_init(sc) == ENOBUFS) {
 1517                 printf("%s: initialization failed: no "
 1518                         "memory for rx buffers\n", sc->sc_dev.dv_xname);
 1519                 wb_stop(sc);
 1520                 splx(s);
 1521                 return;
 1522         }
 1523 
 1524         /* Init TX descriptors. */
 1525         wb_list_tx_init(sc);
 1526 
 1527         /* If we want promiscuous mode, set the allframes bit. */
 1528         if (ifp->if_flags & IFF_PROMISC) {
 1529                 WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_RX_ALLPHYS);
 1530         } else {
 1531                 WB_CLRBIT(sc, WB_NETCFG, WB_NETCFG_RX_ALLPHYS);
 1532         }
 1533 
 1534         /*
 1535          * Set capture broadcast bit to capture broadcast frames.
 1536          */
 1537         if (ifp->if_flags & IFF_BROADCAST) {
 1538                 WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_RX_BROAD);
 1539         } else {
 1540                 WB_CLRBIT(sc, WB_NETCFG, WB_NETCFG_RX_BROAD);
 1541         }
 1542 
 1543         /*
 1544          * Program the multicast filter, if necessary.
 1545          */
 1546         wb_setmulti(sc);
 1547 
 1548         /*
 1549          * Load the address of the RX list.
 1550          */
 1551         WB_CLRBIT(sc, WB_NETCFG, WB_NETCFG_RX_ON);
 1552         CSR_WRITE_4(sc, WB_RXADDR, VTOPHYS(&sc->wb_ldata->wb_rx_list[0]));
 1553 
 1554         /*
 1555          * Enable interrupts.
 1556          */
 1557         CSR_WRITE_4(sc, WB_IMR, WB_INTRS);
 1558         CSR_WRITE_4(sc, WB_ISR, 0xFFFFFFFF);
 1559 
 1560         /* Enable receiver and transmitter. */
 1561         WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_RX_ON);
 1562         CSR_WRITE_4(sc, WB_RXSTART, 0xFFFFFFFF);
 1563 
 1564         WB_CLRBIT(sc, WB_NETCFG, WB_NETCFG_TX_ON);
 1565         CSR_WRITE_4(sc, WB_TXADDR, VTOPHYS(&sc->wb_ldata->wb_tx_list[0]));
 1566         WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_TX_ON);
 1567 
 1568         ifp->if_flags |= IFF_RUNNING;
 1569         ifp->if_flags &= ~IFF_OACTIVE;
 1570 
 1571         splx(s);
 1572 
 1573         timeout_set(&sc->wb_tick_tmo, wb_tick, sc);
 1574         timeout_add(&sc->wb_tick_tmo, hz);
 1575 
 1576         return;
 1577 }
 1578 
 1579 /*
 1580  * Set media options.
 1581  */
 1582 int
 1583 wb_ifmedia_upd(ifp)
 1584         struct ifnet *ifp;
 1585 {
 1586         struct wb_softc *sc = ifp->if_softc;
 1587 
 1588         if (ifp->if_flags & IFF_UP)
 1589                 wb_init(sc);
 1590 
 1591         return(0);
 1592 }
 1593 
 1594 /*
 1595  * Report current media status.
 1596  */
 1597 void
 1598 wb_ifmedia_sts(ifp, ifmr)
 1599         struct ifnet            *ifp;
 1600         struct ifmediareq       *ifmr;
 1601 {
 1602         struct wb_softc *sc = ifp->if_softc;
 1603         struct mii_data *mii = &sc->sc_mii;
 1604 
 1605         mii_pollstat(mii);
 1606         ifmr->ifm_active = mii->mii_media_active;
 1607         ifmr->ifm_status = mii->mii_media_status;
 1608 }
 1609 
 1610 int wb_ioctl(ifp, command, data)
 1611         struct ifnet            *ifp;
 1612         u_long                  command;
 1613         caddr_t                 data;
 1614 {
 1615         struct wb_softc         *sc = ifp->if_softc;
 1616         struct ifreq            *ifr = (struct ifreq *) data;
 1617         struct ifaddr           *ifa = (struct ifaddr *)data;
 1618         int                     s, error = 0;
 1619 
 1620         s = splnet();
 1621 
 1622         if ((error = ether_ioctl(ifp, &sc->arpcom, command, data)) > 0) {
 1623                 splx(s);
 1624                 return (error);
 1625         }
 1626 
 1627         switch(command) {
 1628         case SIOCSIFADDR:
 1629                 ifp->if_flags |= IFF_UP;
 1630                 switch (ifa->ifa_addr->sa_family) {
 1631 #ifdef INET
 1632                 case AF_INET:
 1633                         wb_init(sc);
 1634                         arp_ifinit(&sc->arpcom, ifa);
 1635                         break;
 1636 #endif /* INET */
 1637                 default:
 1638                         wb_init(sc);
 1639                 }
 1640                 break;
 1641         case SIOCSIFFLAGS:
 1642                 if (ifp->if_flags & IFF_UP) {
 1643                         wb_init(sc);
 1644                 } else {
 1645                         if (ifp->if_flags & IFF_RUNNING)
 1646                                 wb_stop(sc);
 1647                 }
 1648                 error = 0;
 1649                 break;
 1650         case SIOCADDMULTI:
 1651         case SIOCDELMULTI:
 1652                 error = (command == SIOCADDMULTI) ?
 1653                     ether_addmulti(ifr, &sc->arpcom) :
 1654                     ether_delmulti(ifr, &sc->arpcom);
 1655 
 1656                 if (error == ENETRESET) {
 1657                         /*
 1658                          * Multicast list has changed; set the hardware
 1659                          * filter accordingly.
 1660                          */
 1661                         if (ifp->if_flags & IFF_RUNNING)
 1662                                 wb_setmulti(sc);
 1663                         error = 0;
 1664                 }
 1665                 break;
 1666         case SIOCGIFMEDIA:
 1667         case SIOCSIFMEDIA:
 1668                 error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, command);
 1669                 break;
 1670         default:
 1671                 error = ENOTTY;
 1672                 break;
 1673         }
 1674 
 1675         splx(s);
 1676 
 1677         return(error);
 1678 }
 1679 
 1680 void wb_watchdog(ifp)
 1681         struct ifnet            *ifp;
 1682 {
 1683         struct wb_softc         *sc;
 1684 
 1685         sc = ifp->if_softc;
 1686 
 1687         ifp->if_oerrors++;
 1688         printf("%s: watchdog timeout\n", sc->sc_dev.dv_xname);
 1689 
 1690 #ifdef foo
 1691         if (!(wb_phy_readreg(sc, PHY_BMSR) & PHY_BMSR_LINKSTAT))
 1692                 printf("%s: no carrier - transceiver cable problem?\n",
 1693                     sc->sc_dev.dv_xname);
 1694 #endif
 1695         wb_stop(sc);
 1696         wb_reset(sc);
 1697         wb_init(sc);
 1698 
 1699         if (!IFQ_IS_EMPTY(&ifp->if_snd))
 1700                 wb_start(ifp);
 1701 
 1702         return;
 1703 }
 1704 
 1705 /*
 1706  * Stop the adapter and free any mbufs allocated to the
 1707  * RX and TX lists.
 1708  */
 1709 void wb_stop(sc)
 1710         struct wb_softc         *sc;
 1711 {
 1712         int                     i;
 1713         struct ifnet            *ifp;
 1714 
 1715         ifp = &sc->arpcom.ac_if;
 1716         ifp->if_timer = 0;
 1717 
 1718         timeout_del(&sc->wb_tick_tmo);
 1719 
 1720         ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
 1721 
 1722         WB_CLRBIT(sc, WB_NETCFG, (WB_NETCFG_RX_ON|WB_NETCFG_TX_ON));
 1723         CSR_WRITE_4(sc, WB_IMR, 0x00000000);
 1724         CSR_WRITE_4(sc, WB_TXADDR, 0x00000000);
 1725         CSR_WRITE_4(sc, WB_RXADDR, 0x00000000);
 1726 
 1727         /*
 1728          * Free data in the RX lists.
 1729          */
 1730         for (i = 0; i < WB_RX_LIST_CNT; i++) {
 1731                 if (sc->wb_cdata.wb_rx_chain[i].wb_mbuf != NULL) {
 1732                         m_freem(sc->wb_cdata.wb_rx_chain[i].wb_mbuf);
 1733                         sc->wb_cdata.wb_rx_chain[i].wb_mbuf = NULL;
 1734                 }
 1735         }
 1736         bzero((char *)&sc->wb_ldata->wb_rx_list,
 1737                 sizeof(sc->wb_ldata->wb_rx_list));
 1738 
 1739         /*
 1740          * Free the TX list buffers.
 1741          */
 1742         for (i = 0; i < WB_TX_LIST_CNT; i++) {
 1743                 if (sc->wb_cdata.wb_tx_chain[i].wb_mbuf != NULL) {
 1744                         m_freem(sc->wb_cdata.wb_tx_chain[i].wb_mbuf);
 1745                         sc->wb_cdata.wb_tx_chain[i].wb_mbuf = NULL;
 1746                 }
 1747         }
 1748 
 1749         bzero((char *)&sc->wb_ldata->wb_tx_list,
 1750                 sizeof(sc->wb_ldata->wb_tx_list));
 1751 }
 1752 
 1753 /*
 1754  * Stop all chip I/O so that the kernel's probe routines don't
 1755  * get confused by errant DMAs when rebooting.
 1756  */
 1757 void wb_shutdown(arg)
 1758         void                    *arg;
 1759 {
 1760         struct wb_softc         *sc = (struct wb_softc *)arg;
 1761 
 1762         wb_stop(sc);
 1763 
 1764         return;
 1765 }
 1766 
 1767 struct cfattach wb_ca = {
 1768         sizeof(struct wb_softc), wb_probe, wb_attach
 1769 };
 1770 
 1771 struct cfdriver wb_cd = {
 1772         0, "wb", DV_IFNET
 1773 };

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