The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/pci/if_sis.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 1997, 1998, 1999
    3  *      Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 3. All advertising materials mentioning features or use of this software
   14  *    must display the following acknowledgement:
   15  *      This product includes software developed by Bill Paul.
   16  * 4. Neither the name of the author nor the names of any co-contributors
   17  *    may be used to endorse or promote products derived from this software
   18  *    without specific prior written permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
   24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   30  * THE POSSIBILITY OF SUCH DAMAGE.
   31  *
   32  * $FreeBSD$
   33  */
   34 
   35 /*
   36  * SiS 900/SiS 7016 fast ethernet PCI NIC driver. Datasheets are
   37  * available from http://www.sis.com.tw.
   38  *
   39  * Written by Bill Paul <wpaul@ee.columbia.edu>
   40  * Electrical Engineering Department
   41  * Columbia University, New York City
   42  */
   43 
   44 /*
   45  * The SiS 900 is a fairly simple chip. It uses bus master DMA with
   46  * simple TX and RX descriptors of 3 longwords in size. The receiver
   47  * has a single perfect filter entry for the station address and a
   48  * 128-bit multicast hash table. The SiS 900 has a built-in MII-based
   49  * transceiver while the 7016 requires an external transceiver chip.
   50  * Both chips offer the standard bit-bang MII interface as well as
   51  * an enchanced PHY interface which simplifies accessing MII registers.
   52  *
   53  * The only downside to this chipset is that RX descriptors must be
   54  * longword aligned.
   55  */
   56 
   57 #include "bpfilter.h"
   58 
   59 #include <sys/param.h>
   60 #include <sys/systm.h>
   61 #include <sys/sockio.h>
   62 #include <sys/mbuf.h>
   63 #include <sys/malloc.h>
   64 #include <sys/kernel.h>
   65 #include <sys/socket.h>
   66 
   67 #include <net/if.h>
   68 #include <net/if_arp.h>
   69 #include <net/ethernet.h>
   70 #include <net/if_dl.h>
   71 #include <net/if_media.h>
   72 
   73 #if NBPFILTER > 0
   74 #include <net/bpf.h>
   75 #endif
   76 
   77 #include <vm/vm.h>              /* for vtophys */
   78 #include <vm/pmap.h>            /* for vtophys */
   79 #include <machine/clock.h>      /* for DELAY */
   80 #include <machine/bus_pio.h>
   81 #include <machine/bus_memio.h>
   82 #include <machine/bus.h>
   83 
   84 #include <pci/pcireg.h>
   85 #include <pci/pcivar.h>
   86 
   87 #define SIS_USEIOSPACE
   88 
   89 #include <pci/if_sisreg.h>
   90 
   91 #ifndef lint
   92 static const char rcsid[] =
   93   "$FreeBSD$";
   94 #endif
   95 
   96 /*
   97  * Various supported device vendors/types and their names.
   98  */
   99 static struct sis_type sis_devs[] = {
  100         { SIS_VENDORID, SIS_DEVICEID_900, "SiS 900 10/100BaseTX" },
  101         { SIS_VENDORID, SIS_DEVICEID_7016, "SiS 7016 10/100BaseTX" },
  102         { 0, 0, NULL }
  103 };
  104 
  105 static struct sis_type sis_phys[] = {
  106         { 0, 0, "<MII-compilant physical interface>" },
  107         { 0, 0, NULL }
  108 };
  109 
  110 static unsigned long            sis_count = 0;
  111 static const char *sis_probe    __P((pcici_t, pcidi_t));
  112 static void sis_attach          __P((pcici_t, int));
  113 
  114 static int sis_newbuf           __P((struct sis_softc *,
  115                                         struct sis_desc *,
  116                                         struct mbuf *));
  117 static int sis_encap            __P((struct sis_softc *,
  118                                         struct mbuf *, u_int32_t *));
  119 static void sis_rxeof           __P((struct sis_softc *));
  120 static void sis_rxeoc           __P((struct sis_softc *));
  121 static void sis_txeof           __P((struct sis_softc *));
  122 static void sis_intr            __P((void *));
  123 static void sis_start           __P((struct ifnet *));
  124 static int sis_ioctl            __P((struct ifnet *, u_long, caddr_t));
  125 static void sis_init            __P((void *));
  126 static void sis_stop            __P((struct sis_softc *));
  127 static void sis_watchdog        __P((struct ifnet *));
  128 static void sis_shutdown        __P((int, void *));
  129 static int sis_ifmedia_upd      __P((struct ifnet *));
  130 static void sis_ifmedia_sts     __P((struct ifnet *, struct ifmediareq *));
  131 
  132 static void sis_delay           __P((struct sis_softc *));
  133 static void sis_eeprom_idle     __P((struct sis_softc *));
  134 static void sis_eeprom_putbyte  __P((struct sis_softc *, int));
  135 static void sis_eeprom_getword  __P((struct sis_softc *, int, u_int16_t *));
  136 static void sis_read_eeprom     __P((struct sis_softc *, caddr_t, int,
  137                                                         int, int));
  138 static void sis_setmulti        __P((struct sis_softc *));
  139 static u_int32_t sis_calchash   __P((caddr_t));
  140 static void sis_reset           __P((struct sis_softc *));
  141 static int sis_list_rx_init     __P((struct sis_softc *));
  142 static int sis_list_tx_init     __P((struct sis_softc *));
  143 
  144 static u_int16_t sis_phy_readreg        __P((struct sis_softc *, int));
  145 static void sis_phy_writereg    __P((struct sis_softc *, int, int));
  146 
  147 static void sis_autoneg_xmit    __P((struct sis_softc *));
  148 static void sis_autoneg_mii     __P((struct sis_softc *, int, int));
  149 static void sis_setmode_mii     __P((struct sis_softc *, int));
  150 static void sis_getmode_mii     __P((struct sis_softc *));
  151 
  152 
  153 #define SIS_SETBIT(sc, reg, x)                          \
  154         CSR_WRITE_4(sc, reg,                            \
  155                 CSR_READ_4(sc, reg) | (x))
  156 
  157 #define SIS_CLRBIT(sc, reg, x)                          \
  158         CSR_WRITE_4(sc, reg,                            \
  159                 CSR_READ_4(sc, reg) & ~(x))
  160 
  161 #define SIO_SET(x)                                      \
  162         CSR_WRITE_4(sc, SIS_EECTL, CSR_READ_4(sc, SIS_EECTL) | x)
  163 
  164 #define SIO_CLR(x)                                      \
  165         CSR_WRITE_4(sc, SIS_EECTL, CSR_READ_4(sc, SIS_EECTL) & ~x)
  166 
  167 static void sis_delay(sc)
  168         struct sis_softc        *sc;
  169 {
  170         int                     idx;
  171 
  172         for (idx = (300 / 33) + 1; idx > 0; idx--)
  173                 CSR_READ_4(sc, SIS_CSR);
  174 
  175         return;
  176 }
  177 
  178 static void sis_eeprom_idle(sc)
  179         struct sis_softc        *sc;
  180 {
  181         register int            i;
  182 
  183         SIO_SET(SIS_EECTL_CSEL);
  184         sis_delay(sc);
  185         SIO_SET(SIS_EECTL_CLK);
  186         sis_delay(sc);
  187 
  188         for (i = 0; i < 25; i++) {
  189                 SIO_CLR(SIS_EECTL_CLK);
  190                 sis_delay(sc);
  191                 SIO_SET(SIS_EECTL_CLK);
  192                 sis_delay(sc);
  193         }
  194 
  195         SIO_CLR(SIS_EECTL_CLK);
  196         sis_delay(sc);
  197         SIO_CLR(SIS_EECTL_CSEL);
  198         sis_delay(sc);
  199         CSR_WRITE_4(sc, SIS_EECTL, 0x00000000);
  200 
  201         return;
  202 }
  203 
  204 /*
  205  * Send a read command and address to the EEPROM, check for ACK.
  206  */
  207 static void sis_eeprom_putbyte(sc, addr)
  208         struct sis_softc        *sc;
  209         int                     addr;
  210 {
  211         register int            d, i;
  212 
  213         d = addr | SIS_EECMD_READ;
  214 
  215         /*
  216          * Feed in each bit and stobe the clock.
  217          */
  218         for (i = 0x400; i; i >>= 1) {
  219                 if (d & i) {
  220                         SIO_SET(SIS_EECTL_DIN);
  221                 } else {
  222                         SIO_CLR(SIS_EECTL_DIN);
  223                 }
  224                 sis_delay(sc);
  225                 SIO_SET(SIS_EECTL_CLK);
  226                 sis_delay(sc);
  227                 SIO_CLR(SIS_EECTL_CLK);
  228                 sis_delay(sc);
  229         }
  230 
  231         return;
  232 }
  233 
  234 /*
  235  * Read a word of data stored in the EEPROM at address 'addr.'
  236  */
  237 static void sis_eeprom_getword(sc, addr, dest)
  238         struct sis_softc        *sc;
  239         int                     addr;
  240         u_int16_t               *dest;
  241 {
  242         register int            i;
  243         u_int16_t               word = 0;
  244 
  245         /* Force EEPROM to idle state. */
  246         sis_eeprom_idle(sc);
  247 
  248         /* Enter EEPROM access mode. */
  249         sis_delay(sc);
  250         SIO_SET(SIS_EECTL_CSEL);
  251         sis_delay(sc);
  252         SIO_SET(SIS_EECTL_CLK);
  253         sis_delay(sc);
  254 
  255         /*
  256          * Send address of word we want to read.
  257          */
  258         sis_eeprom_putbyte(sc, addr);
  259 
  260         /*
  261          * Start reading bits from EEPROM.
  262          */
  263         for (i = 0x8000; i; i >>= 1) {
  264                 SIO_SET(SIS_EECTL_CLK);
  265                 sis_delay(sc);
  266                 if (CSR_READ_4(sc, SIS_EECTL) & SIS_EECTL_DOUT)
  267                         word |= i;
  268                 sis_delay(sc);
  269                 SIO_CLR(SIS_EECTL_CLK);
  270                 sis_delay(sc);
  271         }
  272 
  273         /* Turn off EEPROM access mode. */
  274         sis_eeprom_idle(sc);
  275 
  276         *dest = word;
  277 
  278         return;
  279 }
  280 
  281 /*
  282  * Read a sequence of words from the EEPROM.
  283  */
  284 static void sis_read_eeprom(sc, dest, off, cnt, swap)
  285         struct sis_softc        *sc;
  286         caddr_t                 dest;
  287         int                     off;
  288         int                     cnt;
  289         int                     swap;
  290 {
  291         int                     i;
  292         u_int16_t               word = 0, *ptr;
  293 
  294         for (i = 0; i < cnt; i++) {
  295                 sis_eeprom_getword(sc, off + i, &word);
  296                 ptr = (u_int16_t *)(dest + (i * 2));
  297                 if (swap)
  298                         *ptr = ntohs(word);
  299                 else
  300                         *ptr = word;
  301         }
  302 
  303         return;
  304 }
  305 
  306 static u_int16_t sis_phy_readreg(sc, reg)
  307         struct sis_softc        *sc;
  308         int                     reg;
  309 {
  310         int                     i, val;
  311 
  312         if (sc->sis_type == SIS_TYPE_900 && sc->sis_phy_addr != 0)
  313                 return(0);
  314 
  315         CSR_WRITE_4(sc, SIS_PHYCTL, (sc->sis_phy_addr << 11) |
  316            (reg << 6) | SIS_PHYOP_READ);
  317         SIS_SETBIT(sc, SIS_PHYCTL, SIS_PHYCTL_ACCESS);
  318 
  319         for (i = 0; i < SIS_TIMEOUT; i++) {
  320                 if (!(CSR_READ_4(sc, SIS_PHYCTL) & SIS_PHYCTL_ACCESS))
  321                         break;
  322         }
  323 
  324         if (i == SIS_TIMEOUT) {
  325                 printf("sis%d: PHY failed to come ready\n", sc->sis_unit);
  326                 return(0);
  327         }
  328 
  329         val = (CSR_READ_4(sc, SIS_PHYCTL) >> 16) & 0xFFFF;
  330 
  331         if (val == 0xFFFF)
  332                 return(0);
  333 
  334         return(val);
  335 }
  336 
  337 static void sis_phy_writereg(sc, reg, data)
  338         struct sis_softc        *sc;
  339         int                     reg, data;
  340 {
  341         int                     i;
  342 
  343         if (sc->sis_type == SIS_TYPE_900 && sc->sis_phy_addr != 0)
  344                 return;
  345 
  346         CSR_WRITE_4(sc, SIS_PHYCTL, (data << 16) | (sc->sis_phy_addr << 11) |
  347             (reg << 6) | SIS_PHYOP_WRITE);
  348         SIS_SETBIT(sc, SIS_PHYCTL, SIS_PHYCTL_ACCESS);
  349 
  350         for (i = 0; i < SIS_TIMEOUT; i++) {
  351                 if (!(CSR_READ_4(sc, SIS_PHYCTL) & SIS_PHYCTL_ACCESS))
  352                         break;
  353         }
  354 
  355         if (i == SIS_TIMEOUT)
  356                 printf("sis%d: PHY failed to come ready\n", sc->sis_unit);
  357 
  358         return;
  359 }
  360 
  361 static void sis_setcfg(sc, media)
  362         struct sis_softc        *sc;
  363         u_int16_t               media;
  364 {
  365         if (media & PHY_BMCR_DUPLEX) {
  366                 SIS_SETBIT(sc, SIS_TX_CFG,
  367                     (SIS_TXCFG_IGN_HBEAT|SIS_TXCFG_IGN_CARR));
  368                 SIS_SETBIT(sc, SIS_RX_CFG, SIS_RXCFG_RX_TXPKTS);
  369         } else {
  370                 SIS_CLRBIT(sc, SIS_TX_CFG,
  371                     (SIS_TXCFG_IGN_HBEAT|SIS_TXCFG_IGN_CARR));
  372                 SIS_CLRBIT(sc, SIS_RX_CFG, SIS_RXCFG_RX_TXPKTS);
  373         }
  374 
  375         return;
  376 }
  377 
  378 /*
  379  * Initiate an autonegotiation session.
  380  */
  381 static void sis_autoneg_xmit(sc)
  382         struct sis_softc                *sc;
  383 {
  384         u_int16_t               phy_sts;
  385 
  386         sis_phy_writereg(sc, PHY_BMCR, PHY_BMCR_RESET);
  387         DELAY(500);
  388         while(sis_phy_readreg(sc, PHY_BMCR)
  389                         & PHY_BMCR_RESET);
  390 
  391         phy_sts = sis_phy_readreg(sc, PHY_BMCR);
  392         phy_sts |= PHY_BMCR_AUTONEGENBL|PHY_BMCR_AUTONEGRSTR;
  393         sis_phy_writereg(sc, PHY_BMCR, phy_sts);
  394 
  395         return;
  396 }
  397 
  398 /*
  399  * Invoke autonegotiation on a PHY.
  400  */
  401 static void sis_autoneg_mii(sc, flag, verbose)
  402         struct sis_softc                *sc;
  403         int                     flag;
  404         int                     verbose;
  405 {
  406         u_int16_t               phy_sts = 0, media, advert, ability;
  407         struct ifnet            *ifp;
  408         struct ifmedia          *ifm;
  409 
  410         ifm = &sc->ifmedia;
  411         ifp = &sc->arpcom.ac_if;
  412 
  413         ifm->ifm_media = IFM_ETHER | IFM_AUTO;
  414 
  415         /*
  416          * The 100baseT4 PHY on the 3c905-T4 has the 'autoneg supported'
  417          * bit cleared in the status register, but has the 'autoneg enabled'
  418          * bit set in the control register. This is a contradiction, and
  419          * I'm not sure how to handle it. If you want to force an attempt
  420          * to autoneg for 100baseT4 PHYs, #define FORCE_AUTONEG_TFOUR
  421          * and see what happens.
  422          */
  423 #ifndef FORCE_AUTONEG_TFOUR
  424         /*
  425          * First, see if autoneg is supported. If not, there's
  426          * no point in continuing.
  427          */
  428         phy_sts = sis_phy_readreg(sc, PHY_BMSR);
  429         if (!(phy_sts & PHY_BMSR_CANAUTONEG)) {
  430                 if (verbose)
  431                         printf("sis%d: autonegotiation not supported\n",
  432                                                         sc->sis_unit);
  433                 ifm->ifm_media = IFM_ETHER|IFM_10_T|IFM_HDX;    
  434                 return;
  435         }
  436 #endif
  437 
  438         switch (flag) {
  439         case SIS_FLAG_FORCEDELAY:
  440                 /*
  441                  * XXX Never use this option anywhere but in the probe
  442                  * routine: making the kernel stop dead in its tracks
  443                  * for three whole seconds after we've gone multi-user
  444                  * is really bad manners.
  445                  */
  446                 sis_autoneg_xmit(sc);
  447                 DELAY(5000000);
  448                 break;
  449         case SIS_FLAG_SCHEDDELAY:
  450                 /*
  451                  * Wait for the transmitter to go idle before starting
  452                  * an autoneg session, otherwise sis_start() may clobber
  453                  * our timeout, and we don't want to allow transmission
  454                  * during an autoneg session since that can screw it up.
  455                  */
  456                 if (sc->sis_cdata.sis_tx_cnt) {
  457                         sc->sis_want_auto = 1;
  458                         return;
  459                 }
  460                 sis_autoneg_xmit(sc);
  461                 ifp->if_timer = 5;
  462                 sc->sis_autoneg = 1;
  463                 sc->sis_want_auto = 0;
  464                 return;
  465                 break;
  466         case SIS_FLAG_DELAYTIMEO:
  467                 ifp->if_timer = 0;
  468                 sc->sis_autoneg = 0;
  469                 break;
  470         default:
  471                 printf("sis%d: invalid autoneg flag: %d\n", sc->sis_unit, flag);
  472                 return;
  473         }
  474 
  475         if (sis_phy_readreg(sc, PHY_BMSR) & PHY_BMSR_AUTONEGCOMP) {
  476                 if (verbose)
  477                         printf("sis%d: autoneg complete, ", sc->sis_unit);
  478                 phy_sts = sis_phy_readreg(sc, PHY_BMSR);
  479         } else {
  480                 if (verbose)
  481                         printf("sis%d: autoneg not complete, ", sc->sis_unit);
  482         }
  483 
  484         media = sis_phy_readreg(sc, PHY_BMCR);
  485 
  486         /* Link is good. Report modes and set duplex mode. */
  487         if (sis_phy_readreg(sc, PHY_BMSR) & PHY_BMSR_LINKSTAT) {
  488                 if (verbose)
  489                         printf("link status good ");
  490                 advert = sis_phy_readreg(sc, PHY_ANAR);
  491                 ability = sis_phy_readreg(sc, PHY_LPAR);
  492 
  493                 if (advert & PHY_ANAR_100BT4 && ability & PHY_ANAR_100BT4) {
  494                         ifm->ifm_media = IFM_ETHER|IFM_100_T4;
  495                         media |= PHY_BMCR_SPEEDSEL;
  496                         media &= ~PHY_BMCR_DUPLEX;
  497                         printf("(100baseT4)\n");
  498                 } else if (advert & PHY_ANAR_100BTXFULL &&
  499                         ability & PHY_ANAR_100BTXFULL) {
  500                         ifm->ifm_media = IFM_ETHER|IFM_100_TX|IFM_FDX;
  501                         media |= PHY_BMCR_SPEEDSEL;
  502                         media |= PHY_BMCR_DUPLEX;
  503                         printf("(full-duplex, 100Mbps)\n");
  504                 } else if (advert & PHY_ANAR_100BTXHALF &&
  505                         ability & PHY_ANAR_100BTXHALF) {
  506                         ifm->ifm_media = IFM_ETHER|IFM_100_TX|IFM_HDX;
  507                         media |= PHY_BMCR_SPEEDSEL;
  508                         media &= ~PHY_BMCR_DUPLEX;
  509                         printf("(half-duplex, 100Mbps)\n");
  510                 } else if (advert & PHY_ANAR_10BTFULL &&
  511                         ability & PHY_ANAR_10BTFULL) {
  512                         ifm->ifm_media = IFM_ETHER|IFM_10_T|IFM_FDX;
  513                         media &= ~PHY_BMCR_SPEEDSEL;
  514                         media |= PHY_BMCR_DUPLEX;
  515                         printf("(full-duplex, 10Mbps)\n");
  516                 } else if (advert & PHY_ANAR_10BTHALF &&
  517                         ability & PHY_ANAR_10BTHALF) {
  518                         ifm->ifm_media = IFM_ETHER|IFM_10_T|IFM_HDX;
  519                         media &= ~PHY_BMCR_SPEEDSEL;
  520                         media &= ~PHY_BMCR_DUPLEX;
  521                         printf("(half-duplex, 10Mbps)\n");
  522                 }
  523 
  524                 media &= ~PHY_BMCR_AUTONEGENBL;
  525 
  526                 /* Set ASIC's duplex mode to match the PHY. */
  527                 sis_phy_writereg(sc, PHY_BMCR, media);
  528                 sis_setcfg(sc, media);
  529         } else {
  530                 if (verbose)
  531                         printf("no carrier\n");
  532         }
  533 
  534         sis_init(sc);
  535 
  536         if (sc->sis_tx_pend) {
  537                 sc->sis_autoneg = 0;
  538                 sc->sis_tx_pend = 0;
  539                 sis_start(ifp);
  540         }
  541 
  542         return;
  543 }
  544 
  545 static void sis_getmode_mii(sc)
  546         struct sis_softc                *sc;
  547 {
  548         u_int16_t               bmsr;
  549         struct ifnet            *ifp;
  550 
  551         ifp = &sc->arpcom.ac_if;
  552 
  553         bmsr = sis_phy_readreg(sc, PHY_BMSR);
  554         if (bootverbose)
  555                 printf("sis%d: PHY status word: %x\n", sc->sis_unit, bmsr);
  556 
  557         /* fallback */
  558         sc->ifmedia.ifm_media = IFM_ETHER|IFM_10_T|IFM_HDX;
  559 
  560         if (bmsr & PHY_BMSR_10BTHALF) {
  561                 if (bootverbose)
  562                         printf("sis%d: 10Mbps half-duplex mode supported\n",
  563                                                                 sc->sis_unit);
  564                 ifmedia_add(&sc->ifmedia,
  565                         IFM_ETHER|IFM_10_T|IFM_HDX, 0, NULL);
  566                 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL);
  567         }
  568 
  569         if (bmsr & PHY_BMSR_10BTFULL) {
  570                 if (bootverbose)
  571                         printf("sis%d: 10Mbps full-duplex mode supported\n",
  572                                                                 sc->sis_unit);
  573                 ifmedia_add(&sc->ifmedia,
  574                         IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL);
  575                 sc->ifmedia.ifm_media = IFM_ETHER|IFM_10_T|IFM_FDX;
  576         }
  577 
  578         if (bmsr & PHY_BMSR_100BTXHALF) {
  579                 if (bootverbose)
  580                         printf("sis%d: 100Mbps half-duplex mode supported\n",
  581                                                                 sc->sis_unit);
  582                 ifp->if_baudrate = 100000000;
  583                 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_TX, 0, NULL);
  584                 ifmedia_add(&sc->ifmedia,
  585                         IFM_ETHER|IFM_100_TX|IFM_HDX, 0, NULL);
  586                 sc->ifmedia.ifm_media = IFM_ETHER|IFM_100_TX|IFM_HDX;
  587         }
  588 
  589         if (bmsr & PHY_BMSR_100BTXFULL) {
  590                 if (bootverbose)
  591                         printf("sis%d: 100Mbps full-duplex mode supported\n",
  592                                                                 sc->sis_unit);
  593                 ifp->if_baudrate = 100000000;
  594                 ifmedia_add(&sc->ifmedia,
  595                         IFM_ETHER|IFM_100_TX|IFM_FDX, 0, NULL);
  596                 sc->ifmedia.ifm_media = IFM_ETHER|IFM_100_TX|IFM_FDX;
  597         }
  598 
  599         /* Some also support 100BaseT4. */
  600         if (bmsr & PHY_BMSR_100BT4) {
  601                 if (bootverbose)
  602                         printf("sis%d: 100baseT4 mode supported\n", sc->sis_unit);
  603                 ifp->if_baudrate = 100000000;
  604                 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_T4, 0, NULL);
  605                 sc->ifmedia.ifm_media = IFM_ETHER|IFM_100_T4;
  606 #ifdef FORCE_AUTONEG_TFOUR
  607                 if (bootverbose)
  608                         printf("sis%d: forcing on autoneg support for BT4\n",
  609                                                          sc->sis_unit);
  610                 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_AUTO, 0 NULL):
  611                 sc->ifmedia.ifm_media = IFM_ETHER|IFM_AUTO;
  612 #endif
  613         }
  614 
  615         if (bmsr & PHY_BMSR_CANAUTONEG) {
  616                 if (bootverbose)
  617                         printf("sis%d: autoneg supported\n", sc->sis_unit);
  618                 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL);
  619                 sc->ifmedia.ifm_media = IFM_ETHER|IFM_AUTO;
  620         }
  621 
  622         return;
  623 }
  624 
  625 /*
  626  * Set speed and duplex mode.
  627  */
  628 static void sis_setmode_mii(sc, media)
  629         struct sis_softc                *sc;
  630         int                     media;
  631 {
  632         u_int16_t               bmcr;
  633         struct ifnet            *ifp;
  634 
  635         ifp = &sc->arpcom.ac_if;
  636 
  637         /*
  638          * If an autoneg session is in progress, stop it.
  639          */
  640         if (sc->sis_autoneg) {
  641                 printf("sis%d: canceling autoneg session\n", sc->sis_unit);
  642                 ifp->if_timer = sc->sis_autoneg = sc->sis_want_auto = 0;
  643                 bmcr = sis_phy_readreg(sc, PHY_BMCR);
  644                 bmcr &= ~PHY_BMCR_AUTONEGENBL;
  645                 sis_phy_writereg(sc, PHY_BMCR, bmcr);
  646         }
  647 
  648         printf("sis%d: selecting MII, ", sc->sis_unit);
  649 
  650         bmcr = sis_phy_readreg(sc, PHY_BMCR);
  651 
  652         bmcr &= ~(PHY_BMCR_AUTONEGENBL|PHY_BMCR_SPEEDSEL|
  653                         PHY_BMCR_DUPLEX|PHY_BMCR_LOOPBK);
  654 
  655         if (IFM_SUBTYPE(media) == IFM_100_T4) {
  656                 printf("100Mbps/T4, half-duplex\n");
  657                 bmcr |= PHY_BMCR_SPEEDSEL;
  658                 bmcr &= ~PHY_BMCR_DUPLEX;
  659         }
  660 
  661         if (IFM_SUBTYPE(media) == IFM_100_TX) {
  662                 printf("100Mbps, ");
  663                 bmcr |= PHY_BMCR_SPEEDSEL;
  664         }
  665 
  666         if (IFM_SUBTYPE(media) == IFM_10_T) {
  667                 printf("10Mbps, ");
  668                 bmcr &= ~PHY_BMCR_SPEEDSEL;
  669         }
  670 
  671         if ((media & IFM_GMASK) == IFM_FDX) {
  672                 printf("full duplex\n");
  673                 bmcr |= PHY_BMCR_DUPLEX;
  674         } else {
  675                 printf("half duplex\n");
  676                 bmcr &= ~PHY_BMCR_DUPLEX;
  677         }
  678 
  679         sis_phy_writereg(sc, PHY_BMCR, bmcr);
  680         sis_setcfg(sc, bmcr);
  681 
  682         return;
  683 }
  684 
  685 static u_int32_t sis_calchash(addr)
  686         caddr_t                 addr;
  687 {
  688         u_int32_t               crc, carry; 
  689         int                     i, j;
  690         u_int8_t                c;
  691 
  692         /* Compute CRC for the address value. */
  693         crc = 0xFFFFFFFF; /* initial value */
  694 
  695         for (i = 0; i < 6; i++) {
  696                 c = *(addr + i);
  697                 for (j = 0; j < 8; j++) {
  698                         carry = ((crc & 0x80000000) ? 1 : 0) ^ (c & 0x01);
  699                         crc <<= 1;
  700                         c >>= 1;
  701                         if (carry)
  702                                 crc = (crc ^ 0x04c11db6) | carry;
  703                 }
  704         }
  705 
  706         /* return the filter bit position */
  707         return((crc >> 25) & 0x0000007F);
  708 }
  709 
  710 static void sis_setmulti(sc)
  711         struct sis_softc        *sc;
  712 {
  713         struct ifnet            *ifp;
  714         struct ifmultiaddr      *ifma;
  715         u_int32_t               h = 0, i, filtsave;
  716 
  717         ifp = &sc->arpcom.ac_if;
  718 
  719         if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
  720                 SIS_SETBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_ALLMULTI);
  721                 return;
  722         }
  723 
  724         SIS_CLRBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_ALLMULTI);
  725 
  726         filtsave = CSR_READ_4(sc, SIS_RXFILT_CTL);
  727 
  728         /* first, zot all the existing hash bits */
  729         for (i = 0; i < 8; i++) {
  730                 CSR_WRITE_4(sc, SIS_RXFILT_CTL, (4 + ((i * 16) >> 4)) << 16);
  731                 CSR_WRITE_4(sc, SIS_RXFILT_DATA, 0);
  732         }
  733 
  734         /* now program new ones */
  735         for (ifma = ifp->if_multiaddrs.lh_first; ifma != NULL;
  736             ifma = ifma->ifma_link.le_next) {
  737                 if (ifma->ifma_addr->sa_family != AF_LINK)
  738                         continue;
  739                 h = sis_calchash(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
  740                 CSR_WRITE_4(sc, SIS_RXFILT_CTL, (4 + (h >> 4)) << 16);
  741                 SIS_SETBIT(sc, SIS_RXFILT_DATA, (1 << (h & 0xF)));
  742         }
  743 
  744         CSR_WRITE_4(sc, SIS_RXFILT_CTL, filtsave);
  745 
  746         return;
  747 }
  748 
  749 static void sis_reset(sc)
  750         struct sis_softc        *sc;
  751 {
  752         register int            i;
  753 
  754         SIS_SETBIT(sc, SIS_CSR, SIS_CSR_RESET);
  755 
  756         for (i = 0; i < SIS_TIMEOUT; i++) {
  757                 if (!(CSR_READ_4(sc, SIS_CSR) & SIS_CSR_RESET))
  758                         break;
  759         }
  760 
  761         if (i == SIS_TIMEOUT)
  762                 printf("sis%d: reset never completed\n", sc->sis_unit);
  763 
  764         /* Wait a little while for the chip to get its brains in order. */
  765         DELAY(1000);
  766         return;
  767 }
  768 
  769 /*
  770  * Probe for a SiS chip. Check the PCI vendor and device
  771  * IDs against our list and return a device name if we find a match.
  772  */
  773 static const char *
  774 sis_probe(config_id, device_id)
  775         pcici_t                 config_id;
  776         pcidi_t                 device_id;
  777 {
  778         struct sis_type         *t;
  779 
  780         t = sis_devs;
  781 
  782         while(t->sis_name != NULL) {
  783                 if ((device_id & 0xFFFF) == t->sis_vid &&
  784                     ((device_id >> 16) & 0xFFFF) == t->sis_did) {
  785                         return(t->sis_name);
  786                 }
  787                 t++;
  788         }
  789 
  790         return(NULL);
  791 }
  792 
  793 /*
  794  * Attach the interface. Allocate softc structures, do ifmedia
  795  * setup and ethernet/BPF attach.
  796  */
  797 static void
  798 sis_attach(config_id, unit)
  799         pcici_t                 config_id;
  800         int                     unit;
  801 {
  802         int                     s, i;
  803 #ifndef SIS_USEIOSPACE
  804         vm_offset_t             pbase, vbase;
  805 #endif
  806         u_char                  eaddr[ETHER_ADDR_LEN];
  807         u_int32_t               command;
  808         struct sis_softc        *sc;
  809         struct ifnet            *ifp;
  810         int                     media = IFM_ETHER|IFM_100_TX|IFM_FDX;
  811         struct sis_type         *p;
  812         u_int16_t               phy_vid, phy_did, phy_sts;
  813         u_int16_t               did;
  814 
  815         s = splimp();
  816 
  817         sc = malloc(sizeof(struct sis_softc), M_DEVBUF, M_NOWAIT);
  818         if (sc == NULL) {
  819                 printf("sis%d: no memory for softc struct!\n", unit);
  820                 goto fail;
  821         }
  822         bzero(sc, sizeof(struct sis_softc));
  823 
  824         did = (pci_conf_read(config_id, SIS_PCI_VENDOR_ID) >> 16) & 0xFFFF;
  825         if (did == SIS_DEVICEID_900)
  826                 sc->sis_type = SIS_TYPE_900;
  827         if (did == SIS_DEVICEID_7016)
  828                 sc->sis_type = SIS_TYPE_7016;
  829 
  830         /*
  831          * Handle power management nonsense.
  832          */
  833 
  834         command = pci_conf_read(config_id, SIS_PCI_CAPID) & 0x000000FF;
  835         if (command == 0x01) {
  836 
  837                 command = pci_conf_read(config_id, SIS_PCI_PWRMGMTCTRL);
  838                 if (command & SIS_PSTATE_MASK) {
  839                         u_int32_t               iobase, membase, irq;
  840 
  841                         /* Save important PCI config data. */
  842                         iobase = pci_conf_read(config_id, SIS_PCI_LOIO);
  843                         membase = pci_conf_read(config_id, SIS_PCI_LOMEM);
  844                         irq = pci_conf_read(config_id, SIS_PCI_INTLINE);
  845 
  846                         /* Reset the power state. */
  847                         printf("sis%d: chip is in D%d power mode "
  848                         "-- setting to D0\n", unit, command & SIS_PSTATE_MASK);
  849                         command &= 0xFFFFFFFC;
  850                         pci_conf_write(config_id, SIS_PCI_PWRMGMTCTRL, command);
  851 
  852                         /* Restore PCI config data. */
  853                         pci_conf_write(config_id, SIS_PCI_LOIO, iobase);
  854                         pci_conf_write(config_id, SIS_PCI_LOMEM, membase);
  855                         pci_conf_write(config_id, SIS_PCI_INTLINE, irq);
  856                 }
  857         }
  858 
  859         /*
  860          * Map control/status registers.
  861          */
  862         command = pci_conf_read(config_id, PCI_COMMAND_STATUS_REG);
  863         command |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN);
  864         pci_conf_write(config_id, PCI_COMMAND_STATUS_REG, command);
  865         command = pci_conf_read(config_id, PCI_COMMAND_STATUS_REG);
  866 
  867 #ifdef SIS_USEIOSPACE
  868         if (!(command & PCIM_CMD_PORTEN)) {
  869                 printf("sis%d: failed to enable I/O ports!\n", unit);
  870                 free(sc, M_DEVBUF);
  871                 goto fail;
  872         }
  873 
  874         if (!pci_map_port(config_id, SIS_PCI_LOIO,
  875                                         (u_short *)&(sc->sis_bhandle))) {
  876                 printf ("sis%d: couldn't map ports\n", unit);
  877                 goto fail;
  878         }
  879 #ifdef __i386__
  880         sc->sis_btag = I386_BUS_SPACE_IO;
  881 #endif
  882 #ifdef __alpha__
  883         sc->sis_btag = ALPHA_BUS_SPACE_IO;
  884 #endif
  885 #else
  886         if (!(command & PCIM_CMD_MEMEN)) {
  887                 printf("sis%d: failed to enable memory mapping!\n", unit);
  888                 goto fail;
  889         }
  890 
  891         if (!pci_map_mem(config_id, SIS_PCI_LOMEM, &vbase, &pbase)) {
  892                 printf ("sis%d: couldn't map memory\n", unit);
  893                 goto fail;
  894         }
  895 #ifdef __i386__
  896         sc->sis_btag = I386_BUS_SPACE_MEM;
  897 #endif
  898 #ifdef __alpha__
  899         sc->sis_btag = ALPHA_BUS_SPACE_MEM;
  900 #endif
  901         sc->sis_bhandle = vbase;
  902 #endif
  903 
  904         /* Allocate interrupt */
  905         if (!pci_map_int(config_id, sis_intr, sc, &net_imask)) {
  906                 printf("sis%d: couldn't map interrupt\n", unit);
  907                 goto fail;
  908         }
  909 
  910         /* Reset the adapter. */
  911         sis_reset(sc);
  912 
  913         /*
  914          * Get station address from the EEPROM.
  915          */
  916         sis_read_eeprom(sc, (caddr_t)&eaddr, SIS_EE_NODEADDR, 3, 0);
  917 
  918         /*
  919          * A SiS chip was detected. Inform the world.
  920          */
  921         printf("sis%d: Ethernet address: %6D\n", unit, eaddr, ":");
  922 
  923         sc->sis_unit = unit;
  924         bcopy(eaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
  925 
  926         sc->sis_ldata = contigmalloc(sizeof(struct sis_list_data), M_DEVBUF,
  927             M_NOWAIT, 0x100000, 0xffffffff, PAGE_SIZE, 0);
  928 
  929         if (sc->sis_ldata == NULL) {
  930                 printf("sis%d: no memory for list buffers!\n", unit);
  931                 free(sc, M_DEVBUF);
  932                 goto fail;
  933         }
  934         bzero(sc->sis_ldata, sizeof(struct sis_list_data));
  935 
  936         ifp = &sc->arpcom.ac_if;
  937         ifp->if_softc = sc;
  938         ifp->if_unit = unit;
  939         ifp->if_name = "sis";
  940         ifp->if_mtu = ETHERMTU;
  941         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
  942         ifp->if_ioctl = sis_ioctl;
  943         ifp->if_output = ether_output;
  944         ifp->if_start = sis_start;
  945         ifp->if_watchdog = sis_watchdog;
  946         ifp->if_init = sis_init;
  947         ifp->if_baudrate = 10000000;
  948         ifp->if_snd.ifq_maxlen = SIS_TX_LIST_CNT - 1;
  949 
  950         if (bootverbose)
  951                 printf("sis%d: probing for a PHY\n", sc->sis_unit);
  952         for (i = SIS_PHYADDR_MIN; i < SIS_PHYADDR_MAX + 1; i++) {
  953                 if (bootverbose)
  954                         printf("sis%d: checking address: %d\n",
  955                                                 sc->sis_unit, i);
  956                 sc->sis_phy_addr = i;
  957                 sis_phy_writereg(sc, PHY_BMCR, PHY_BMCR_RESET);
  958                 DELAY(500);
  959                 while(sis_phy_readreg(sc, PHY_BMCR)
  960                                 & PHY_BMCR_RESET);
  961                 if ((phy_sts = sis_phy_readreg(sc, PHY_BMSR)))
  962                         break;
  963         }
  964         if (phy_sts) {
  965                 phy_vid = sis_phy_readreg(sc, PHY_VENID);
  966                 phy_did = sis_phy_readreg(sc, PHY_DEVID);
  967                 if (bootverbose)
  968                         printf("sis%d: found PHY at address %d, ",
  969                                 sc->sis_unit, sc->sis_phy_addr);
  970                 if (bootverbose)
  971                         printf("vendor id: %x device id: %x\n",
  972                         phy_vid, phy_did);
  973                 p = sis_phys;
  974                 while(p->sis_vid) {
  975                         if (phy_vid == p->sis_vid &&
  976                                 (phy_did | 0x000F) == p->sis_did) {
  977                                 sc->sis_pinfo = p;
  978                                 break;
  979                         }
  980                         p++;
  981                 }
  982                 if (sc->sis_pinfo == NULL)
  983                         sc->sis_pinfo = &sis_phys[PHY_UNKNOWN];
  984                 if (bootverbose)
  985                         printf("sis%d: PHY type: %s\n",
  986                                 sc->sis_unit, sc->sis_pinfo->sis_name);
  987         } else {
  988                 printf("sis%d: MII without any phy!\n", sc->sis_unit);
  989                 free(sc->sis_ldata, M_DEVBUF);
  990                 free(sc, M_DEVBUF);
  991                 goto fail;
  992         }
  993 
  994         /*
  995          * Do ifmedia setup.
  996          */
  997         ifmedia_init(&sc->ifmedia, 0, sis_ifmedia_upd, sis_ifmedia_sts);
  998 
  999         sis_getmode_mii(sc);
 1000         sis_autoneg_mii(sc, SIS_FLAG_FORCEDELAY, 1);
 1001 
 1002         media = sc->ifmedia.ifm_media;
 1003         sis_stop(sc);
 1004 
 1005         ifmedia_set(&sc->ifmedia, media);
 1006 
 1007         /*
 1008          * Call MI attach routines.
 1009          */
 1010         if_attach(ifp);
 1011         ether_ifattach(ifp);
 1012 
 1013 #if NBPFILTER > 0
 1014         bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
 1015 #endif
 1016         at_shutdown(sis_shutdown, sc, SHUTDOWN_POST_SYNC);
 1017 
 1018 fail:
 1019         splx(s);
 1020         return;
 1021 }
 1022 
 1023 
 1024 /*
 1025  * Initialize the transmit descriptors.
 1026  */
 1027 static int sis_list_tx_init(sc)
 1028         struct sis_softc        *sc;
 1029 {
 1030         struct sis_list_data    *ld;
 1031         struct sis_ring_data    *cd;
 1032         int                     i;
 1033 
 1034         cd = &sc->sis_cdata;
 1035         ld = sc->sis_ldata;
 1036 
 1037         for (i = 0; i < SIS_TX_LIST_CNT; i++) {
 1038                 if (i == (SIS_TX_LIST_CNT - 1)) {
 1039                         ld->sis_tx_list[i].sis_nextdesc =
 1040                             &ld->sis_tx_list[0];
 1041                         ld->sis_tx_list[i].sis_next =
 1042                             vtophys(&ld->sis_tx_list[0]);
 1043                 } else {
 1044                         ld->sis_tx_list[i].sis_nextdesc =
 1045                             &ld->sis_tx_list[i + 1];
 1046                         ld->sis_tx_list[i].sis_next =
 1047                             vtophys(&ld->sis_tx_list[i + 1]);
 1048                 }
 1049                 ld->sis_tx_list[i].sis_mbuf = NULL;
 1050                 ld->sis_tx_list[i].sis_ptr = 0;
 1051                 ld->sis_tx_list[i].sis_ctl = 0;
 1052         }
 1053 
 1054         cd->sis_tx_prod = cd->sis_tx_cons = cd->sis_tx_cnt = 0;
 1055 
 1056         return(0);
 1057 }
 1058 
 1059 
 1060 /*
 1061  * Initialize the RX descriptors and allocate mbufs for them. Note that
 1062  * we arrange the descriptors in a closed ring, so that the last descriptor
 1063  * points back to the first.
 1064  */
 1065 static int sis_list_rx_init(sc)
 1066         struct sis_softc        *sc;
 1067 {
 1068         struct sis_list_data    *ld;
 1069         struct sis_ring_data    *cd;
 1070         int                     i;
 1071 
 1072         ld = sc->sis_ldata;
 1073         cd = &sc->sis_cdata;
 1074 
 1075         for (i = 0; i < SIS_RX_LIST_CNT; i++) {
 1076                 if (sis_newbuf(sc, &ld->sis_rx_list[i], NULL) == ENOBUFS)
 1077                         return(ENOBUFS);
 1078                 if (i == (SIS_RX_LIST_CNT - 1)) {
 1079                         ld->sis_rx_list[i].sis_nextdesc =
 1080                             &ld->sis_rx_list[0];
 1081                         ld->sis_rx_list[i].sis_next =
 1082                             vtophys(&ld->sis_rx_list[0]);
 1083                 } else {
 1084                         ld->sis_rx_list[i].sis_nextdesc =
 1085                             &ld->sis_rx_list[i + 1];
 1086                         ld->sis_rx_list[i].sis_next =
 1087                             vtophys(&ld->sis_rx_list[i + 1]);
 1088                 }
 1089         }
 1090 
 1091         cd->sis_rx_prod = 0;
 1092 
 1093         return(0);
 1094 }
 1095 
 1096 /*
 1097  * Initialize an RX descriptor and attach an MBUF cluster.
 1098  */
 1099 static int sis_newbuf(sc, c, m)
 1100         struct sis_softc        *sc;
 1101         struct sis_desc         *c;
 1102         struct mbuf             *m;
 1103 {
 1104         struct mbuf             *m_new = NULL;
 1105 
 1106         if (m == NULL) {
 1107                 MGETHDR(m_new, M_DONTWAIT, MT_DATA);
 1108                 if (m_new == NULL) {
 1109                         printf("sis%d: no memory for rx list "
 1110                             "-- packet dropped!\n", sc->sis_unit);
 1111                         return(ENOBUFS);
 1112                 }
 1113 
 1114                 MCLGET(m_new, M_DONTWAIT);
 1115                 if (!(m_new->m_flags & M_EXT)) {
 1116                         printf("sis%d: no memory for rx list "
 1117                             "-- packet dropped!\n", sc->sis_unit);
 1118                         m_freem(m_new);
 1119                         return(ENOBUFS);
 1120                 }
 1121                 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
 1122         } else {
 1123                 m_new = m;
 1124                 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
 1125                 m_new->m_data = m_new->m_ext.ext_buf;
 1126         }
 1127 
 1128         m_adj(m_new, sizeof(u_int64_t));
 1129 
 1130         c->sis_mbuf = m_new;
 1131         c->sis_ptr = vtophys(mtod(m_new, caddr_t));
 1132         c->sis_ctl = SIS_RXLEN;
 1133 
 1134         return(0);
 1135 }
 1136 
 1137 /*
 1138  * A frame has been uploaded: pass the resulting mbuf chain up to
 1139  * the higher level protocols.
 1140  */
 1141 static void sis_rxeof(sc)
 1142         struct sis_softc        *sc;
 1143 {
 1144         struct ether_header     *eh;
 1145         struct mbuf             *m;
 1146         struct ifnet            *ifp;
 1147         struct sis_desc         *cur_rx;
 1148         int                     i, total_len = 0;
 1149         u_int32_t               rxstat;
 1150 
 1151         ifp = &sc->arpcom.ac_if;
 1152         i = sc->sis_cdata.sis_rx_prod;
 1153 
 1154         while(SIS_OWNDESC(&sc->sis_ldata->sis_rx_list[i])) {
 1155                 struct mbuf             *m0 = NULL;
 1156 
 1157                 cur_rx = &sc->sis_ldata->sis_rx_list[i];
 1158                 rxstat = cur_rx->sis_rxstat;
 1159                 m = cur_rx->sis_mbuf;
 1160                 cur_rx->sis_mbuf = NULL;
 1161                 total_len = SIS_RXBYTES(cur_rx);
 1162                 SIS_INC(i, SIS_RX_LIST_CNT);
 1163 
 1164                 /*
 1165                  * If an error occurs, update stats, clear the
 1166                  * status word and leave the mbuf cluster in place:
 1167                  * it should simply get re-used next time this descriptor
 1168                  * comes up in the ring.
 1169                  */
 1170                 if (!(rxstat & SIS_CMDSTS_PKT_OK)) {
 1171                         ifp->if_ierrors++;
 1172                         if (rxstat & SIS_RXSTAT_COLL)
 1173                                 ifp->if_collisions++;
 1174                         sis_newbuf(sc, cur_rx, m);
 1175                         continue;
 1176                 }
 1177 
 1178                 /* No errors; receive the packet. */    
 1179                 m0 = m_devget(mtod(m, char *) - ETHER_ALIGN,
 1180                     total_len + ETHER_ALIGN, 0, ifp, NULL);
 1181                 sis_newbuf(sc, cur_rx, m);
 1182                 if (m0 == NULL) {
 1183                         ifp->if_ierrors++;
 1184                         continue;
 1185                 }
 1186                 m_adj(m0, ETHER_ALIGN);
 1187                 m = m0;
 1188 
 1189                 ifp->if_ipackets++;
 1190                 eh = mtod(m, struct ether_header *);
 1191 #if NBPFILTER > 0
 1192                 /*
 1193                  * Handle BPF listeners. Let the BPF user see the packet, but
 1194                  * don't pass it up to the ether_input() layer unless it's
 1195                  * a broadcast packet, multicast packet, matches our ethernet
 1196                  * address or the interface is in promiscuous mode.
 1197                  */
 1198                 if (ifp->if_bpf) {
 1199                         bpf_mtap(ifp, m);
 1200                         if (ifp->if_flags & IFF_PROMISC &&
 1201                             (bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
 1202                             ETHER_ADDR_LEN) && !(eh->ether_dhost[0] & 1))) {
 1203                                 m_freem(m);
 1204                                 continue;
 1205                         }
 1206                 }
 1207 #endif
 1208                 /* Remove header from mbuf and pass it on. */
 1209                 m_adj(m, sizeof(struct ether_header));
 1210                 ether_input(ifp, eh, m);
 1211         }
 1212 
 1213         sc->sis_cdata.sis_rx_prod = i;
 1214 
 1215         return;
 1216 }
 1217 
 1218 void sis_rxeoc(sc)
 1219         struct sis_softc        *sc;
 1220 {
 1221         sis_rxeof(sc);
 1222         sis_init(sc);
 1223         return;
 1224 }
 1225 
 1226 /*
 1227  * A frame was downloaded to the chip. It's safe for us to clean up
 1228  * the list buffers.
 1229  */
 1230 
 1231 static void sis_txeof(sc)
 1232         struct sis_softc        *sc;
 1233 {
 1234         struct sis_desc         *cur_tx = NULL;
 1235         struct ifnet            *ifp;
 1236         u_int32_t               idx;
 1237 
 1238         ifp = &sc->arpcom.ac_if;
 1239 
 1240         /* Clear the timeout timer. */
 1241         ifp->if_timer = 0;
 1242 
 1243         /*
 1244          * Go through our tx list and free mbufs for those
 1245          * frames that have been transmitted.
 1246          */
 1247         idx = sc->sis_cdata.sis_tx_cons;
 1248         while (idx != sc->sis_cdata.sis_tx_prod) {
 1249                 cur_tx = &sc->sis_ldata->sis_tx_list[idx];
 1250 
 1251                 if (SIS_OWNDESC(cur_tx))
 1252                         break;
 1253 
 1254                 if (cur_tx->sis_ctl & SIS_CMDSTS_MORE) {
 1255                         sc->sis_cdata.sis_tx_cnt--;
 1256                         SIS_INC(idx, SIS_TX_LIST_CNT);
 1257                         continue;
 1258                 }
 1259 
 1260                 if (!(cur_tx->sis_ctl & SIS_CMDSTS_PKT_OK)) {
 1261                         ifp->if_oerrors++;
 1262                         if (cur_tx->sis_txstat & SIS_TXSTAT_EXCESSCOLLS)
 1263                                 ifp->if_collisions++;
 1264                         if (cur_tx->sis_txstat & SIS_TXSTAT_OUTOFWINCOLL)
 1265                                 ifp->if_collisions++;
 1266                 }
 1267 
 1268                 ifp->if_collisions +=
 1269                     (cur_tx->sis_txstat & SIS_TXSTAT_COLLCNT) >> 16;
 1270 
 1271                 ifp->if_opackets++;
 1272                 if (cur_tx->sis_mbuf != NULL) {
 1273                         m_freem(cur_tx->sis_mbuf);
 1274                         cur_tx->sis_mbuf = NULL;
 1275                 }
 1276 
 1277                 sc->sis_cdata.sis_tx_cnt--;
 1278                 SIS_INC(idx, SIS_TX_LIST_CNT);
 1279                 ifp->if_timer = 0;
 1280         }
 1281 
 1282         sc->sis_cdata.sis_tx_cons = idx;
 1283 
 1284         if (cur_tx != NULL)
 1285                 ifp->if_flags &= ~IFF_OACTIVE;
 1286 
 1287         return;
 1288 }
 1289 
 1290 static void sis_intr(arg)
 1291         void                    *arg;
 1292 {
 1293         struct sis_softc        *sc;
 1294         struct ifnet            *ifp;
 1295         u_int32_t               status;
 1296 
 1297         sc = arg;
 1298         ifp = &sc->arpcom.ac_if;
 1299 
 1300         /* Supress unwanted interrupts */
 1301         if (!(ifp->if_flags & IFF_UP)) {
 1302                 sis_stop(sc);
 1303                 return;
 1304         }
 1305 
 1306         /* Disable interrupts. */
 1307         CSR_WRITE_4(sc, SIS_IER, 0);
 1308 
 1309         for (;;) {
 1310                 /* Reading the ISR register clears all interrupts. */
 1311                 status = CSR_READ_4(sc, SIS_ISR);
 1312 
 1313                 if ((status & SIS_INTRS) == 0)
 1314                         break;
 1315 
 1316                 if ((status & SIS_ISR_TX_OK) ||
 1317                     (status & SIS_ISR_TX_ERR) ||
 1318                     (status & SIS_ISR_TX_IDLE))
 1319                         sis_txeof(sc);
 1320 
 1321                 if (status & SIS_ISR_RX_OK)
 1322                         sis_rxeof(sc);
 1323 
 1324                 if ((status & SIS_ISR_RX_ERR) ||
 1325                     (status & SIS_ISR_RX_OFLOW)) {
 1326                         sis_rxeoc(sc);
 1327                 }
 1328 
 1329                 if (status & SIS_ISR_SYSERR) {
 1330                         sis_reset(sc);
 1331                         sis_init(sc);
 1332                 }
 1333         }
 1334 
 1335         /* Re-enable interrupts. */
 1336         CSR_WRITE_4(sc, SIS_IER, 1);
 1337 
 1338         if (ifp->if_snd.ifq_head != NULL)
 1339                 sis_start(ifp);
 1340 
 1341         return;
 1342 }
 1343 
 1344 /*
 1345  * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data
 1346  * pointers to the fragment pointers.
 1347  */
 1348 static int sis_encap(sc, m_head, txidx)
 1349         struct sis_softc        *sc;
 1350         struct mbuf             *m_head;
 1351         u_int32_t               *txidx;
 1352 {
 1353         struct sis_desc         *f = NULL;
 1354         struct mbuf             *m;
 1355         int                     frag, cur, cnt = 0;
 1356 
 1357         /*
 1358          * Start packing the mbufs in this chain into
 1359          * the fragment pointers. Stop when we run out
 1360          * of fragments or hit the end of the mbuf chain.
 1361          */
 1362         m = m_head;
 1363         cur = frag = *txidx;
 1364 
 1365         for (m = m_head; m != NULL; m = m->m_next) {
 1366                 if (m->m_len != 0) {
 1367                         if ((SIS_TX_LIST_CNT -
 1368                             (sc->sis_cdata.sis_tx_cnt + cnt)) < 2)
 1369                                 return(ENOBUFS);
 1370                         f = &sc->sis_ldata->sis_tx_list[frag];
 1371                         f->sis_ctl = SIS_CMDSTS_MORE | m->m_len;
 1372                         f->sis_ptr = vtophys(mtod(m, vm_offset_t));
 1373                         if (cnt != 0)
 1374                                 f->sis_ctl |= SIS_CMDSTS_OWN;
 1375                         cur = frag;
 1376                         SIS_INC(frag, SIS_TX_LIST_CNT);
 1377                         cnt++;
 1378                 }
 1379         }
 1380 
 1381         if (m != NULL)
 1382                 return(ENOBUFS);
 1383 
 1384         sc->sis_ldata->sis_tx_list[cur].sis_mbuf = m_head;
 1385         sc->sis_ldata->sis_tx_list[cur].sis_ctl &= ~SIS_CMDSTS_MORE;
 1386         sc->sis_ldata->sis_tx_list[*txidx].sis_ctl |= SIS_CMDSTS_OWN;
 1387         sc->sis_cdata.sis_tx_cnt += cnt;
 1388         *txidx = frag;
 1389 
 1390         return(0);
 1391 }
 1392 
 1393 /*
 1394  * Main transmit routine. To avoid having to do mbuf copies, we put pointers
 1395  * to the mbuf data regions directly in the transmit lists. We also save a
 1396  * copy of the pointers since the transmit list fragment pointers are
 1397  * physical addresses.
 1398  */
 1399 
 1400 static void sis_start(ifp)
 1401         struct ifnet            *ifp;
 1402 {
 1403         struct sis_softc        *sc;
 1404         struct mbuf             *m_head = NULL;
 1405         u_int32_t               idx;
 1406 
 1407         sc = ifp->if_softc;
 1408 
 1409         if (sc->sis_autoneg)
 1410                 return;
 1411 
 1412         idx = sc->sis_cdata.sis_tx_prod;
 1413 
 1414         if (ifp->if_flags & IFF_OACTIVE)
 1415                 return;
 1416 
 1417         while(sc->sis_ldata->sis_tx_list[idx].sis_mbuf == NULL) {
 1418                 IF_DEQUEUE(&ifp->if_snd, m_head);
 1419                 if (m_head == NULL)
 1420                         break;
 1421 
 1422                 if (sis_encap(sc, m_head, &idx)) {
 1423                         IF_PREPEND(&ifp->if_snd, m_head);
 1424                         ifp->if_flags |= IFF_OACTIVE;
 1425                         break;
 1426                 }
 1427 
 1428 #if NBPFILTER > 0
 1429                 /*
 1430                  * If there's a BPF listener, bounce a copy of this frame
 1431                  * to him.
 1432                  */
 1433                 if (ifp->if_bpf)
 1434                         bpf_mtap(ifp, m_head);
 1435 #endif
 1436         }
 1437 
 1438         /* Transmit */
 1439         sc->sis_cdata.sis_tx_prod = idx;
 1440         SIS_SETBIT(sc, SIS_CSR, SIS_CSR_TX_ENABLE);
 1441 
 1442         /*
 1443          * Set a timeout in case the chip goes out to lunch.
 1444          */
 1445         ifp->if_timer = 5;
 1446 
 1447         return;
 1448 }
 1449 
 1450 static void sis_init(xsc)
 1451         void                    *xsc;
 1452 {
 1453         struct sis_softc        *sc = xsc;
 1454         struct ifnet            *ifp = &sc->arpcom.ac_if;
 1455         int                     s;
 1456         u_int16_t               phy_bmcr;
 1457 
 1458         if (sc->sis_autoneg)
 1459                 return;
 1460 
 1461         s = splimp();
 1462 
 1463         /*
 1464          * Cancel pending I/O and free all RX/TX buffers.
 1465          */
 1466         sis_stop(sc);
 1467 
 1468         phy_bmcr = sis_phy_readreg(sc, PHY_BMCR);
 1469 
 1470         /* Set MAC address */
 1471         CSR_WRITE_4(sc, SIS_RXFILT_CTL, SIS_FILTADDR_PAR0);
 1472         CSR_WRITE_4(sc, SIS_RXFILT_DATA,
 1473             ((u_int16_t *)sc->arpcom.ac_enaddr)[0]);
 1474         CSR_WRITE_4(sc, SIS_RXFILT_CTL, SIS_FILTADDR_PAR1);
 1475         CSR_WRITE_4(sc, SIS_RXFILT_DATA,
 1476             ((u_int16_t *)sc->arpcom.ac_enaddr)[1]);
 1477         CSR_WRITE_4(sc, SIS_RXFILT_CTL, SIS_FILTADDR_PAR2);
 1478         CSR_WRITE_4(sc, SIS_RXFILT_DATA,
 1479             ((u_int16_t *)sc->arpcom.ac_enaddr)[2]);
 1480 
 1481         /* Init circular RX list. */
 1482         if (sis_list_rx_init(sc) == ENOBUFS) {
 1483                 printf("sis%d: initialization failed: no "
 1484                         "memory for rx buffers\n", sc->sis_unit);
 1485                 sis_stop(sc);
 1486                 (void)splx(s);
 1487                 return;
 1488         }
 1489 
 1490         /*
 1491          * Init tx descriptors.
 1492          */
 1493         sis_list_tx_init(sc);
 1494 
 1495          /* If we want promiscuous mode, set the allframes bit. */
 1496         if (ifp->if_flags & IFF_PROMISC) {
 1497                 SIS_SETBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_ALLPHYS);
 1498         } else {
 1499                 SIS_CLRBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_ALLPHYS);
 1500         }
 1501 
 1502         /*
 1503          * Set the capture broadcast bit to capture broadcast frames.
 1504          */
 1505         if (ifp->if_flags & IFF_BROADCAST) {
 1506                 SIS_SETBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_BROAD);
 1507         } else {
 1508                 SIS_CLRBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_BROAD);
 1509         }
 1510 
 1511         /*
 1512          * Load the multicast filter.
 1513          */
 1514         sis_setmulti(sc);
 1515 
 1516         /* Turn the receive filter on */
 1517         SIS_SETBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_ENABLE);
 1518 
 1519         /*
 1520          * Load the address of the RX and TX lists.
 1521          */
 1522         CSR_WRITE_4(sc, SIS_RX_LISTPTR,
 1523             vtophys(&sc->sis_ldata->sis_rx_list[0]));
 1524         CSR_WRITE_4(sc, SIS_TX_LISTPTR,
 1525             vtophys(&sc->sis_ldata->sis_tx_list[0]));
 1526 
 1527         /* Set RX configuration */
 1528         CSR_WRITE_4(sc, SIS_RX_CFG, SIS_RXCFG);
 1529         /* Set TX configuration */
 1530         CSR_WRITE_4(sc, SIS_TX_CFG, SIS_TXCFG);
 1531 
 1532         /*
 1533          * Enable interrupts.
 1534          */
 1535         CSR_WRITE_4(sc, SIS_IMR, SIS_INTRS);
 1536         CSR_WRITE_4(sc, SIS_IER, 1);
 1537 
 1538         /* Enable receiver and transmitter. */
 1539         SIS_CLRBIT(sc, SIS_CSR, SIS_CSR_TX_DISABLE|SIS_CSR_RX_DISABLE);
 1540         SIS_SETBIT(sc, SIS_CSR, SIS_CSR_RX_ENABLE);
 1541 
 1542         sis_phy_writereg(sc, PHY_BMCR, phy_bmcr);
 1543 
 1544         ifp->if_flags |= IFF_RUNNING;
 1545         ifp->if_flags &= ~IFF_OACTIVE;
 1546 
 1547         (void)splx(s);
 1548 
 1549         return;
 1550 }
 1551 
 1552 /*
 1553  * Set media options.
 1554  */
 1555 static int sis_ifmedia_upd(ifp)
 1556         struct ifnet            *ifp;
 1557 {
 1558         struct sis_softc                *sc;
 1559         struct ifmedia          *ifm;
 1560 
 1561         sc = ifp->if_softc;
 1562         ifm = &sc->ifmedia;
 1563 
 1564         if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
 1565                 return(EINVAL);
 1566 
 1567         if (IFM_SUBTYPE(ifm->ifm_media) == IFM_AUTO)
 1568                 sis_autoneg_mii(sc, SIS_FLAG_SCHEDDELAY, 1);
 1569         else {
 1570                 sis_setmode_mii(sc, ifm->ifm_media);
 1571         }
 1572 
 1573         return(0);
 1574 }
 1575 
 1576 /*
 1577  * Report current media status.
 1578  */
 1579 static void sis_ifmedia_sts(ifp, ifmr)
 1580         struct ifnet            *ifp;
 1581         struct ifmediareq       *ifmr;
 1582 {
 1583         struct sis_softc                *sc;
 1584         u_int16_t               advert = 0, ability = 0;
 1585 
 1586         sc = ifp->if_softc;
 1587 
 1588         ifmr->ifm_active = IFM_ETHER;
 1589 
 1590         if (!(sis_phy_readreg(sc, PHY_BMCR) & PHY_BMCR_AUTONEGENBL)) {
 1591                 if (sis_phy_readreg(sc, PHY_BMCR) & PHY_BMCR_SPEEDSEL)
 1592                         ifmr->ifm_active = IFM_ETHER|IFM_100_TX;
 1593                 else
 1594                         ifmr->ifm_active = IFM_ETHER|IFM_10_T;
 1595                 if (sis_phy_readreg(sc, PHY_BMCR) & PHY_BMCR_DUPLEX)
 1596                         ifmr->ifm_active |= IFM_FDX;
 1597                 else
 1598                         ifmr->ifm_active |= IFM_HDX;
 1599                 return;
 1600         }
 1601 
 1602         ability = sis_phy_readreg(sc, PHY_LPAR);
 1603         advert = sis_phy_readreg(sc, PHY_ANAR);
 1604         if (advert & PHY_ANAR_100BT4 &&
 1605                 ability & PHY_ANAR_100BT4) {
 1606                 ifmr->ifm_active = IFM_ETHER|IFM_100_T4;
 1607         } else if (advert & PHY_ANAR_100BTXFULL &&
 1608                 ability & PHY_ANAR_100BTXFULL) {
 1609                 ifmr->ifm_active = IFM_ETHER|IFM_100_TX|IFM_FDX;
 1610         } else if (advert & PHY_ANAR_100BTXHALF &&
 1611                 ability & PHY_ANAR_100BTXHALF) {
 1612                 ifmr->ifm_active = IFM_ETHER|IFM_100_TX|IFM_HDX;
 1613         } else if (advert & PHY_ANAR_10BTFULL &&
 1614                 ability & PHY_ANAR_10BTFULL) {
 1615                 ifmr->ifm_active = IFM_ETHER|IFM_10_T|IFM_FDX;
 1616         } else if (advert & PHY_ANAR_10BTHALF &&
 1617                 ability & PHY_ANAR_10BTHALF) {
 1618                 ifmr->ifm_active = IFM_ETHER|IFM_10_T|IFM_HDX;
 1619         }
 1620 
 1621         return;
 1622 }
 1623 
 1624 static int sis_ioctl(ifp, command, data)
 1625         struct ifnet            *ifp;
 1626         u_long                  command;
 1627         caddr_t                 data;
 1628 {
 1629         struct sis_softc        *sc = ifp->if_softc;
 1630         struct ifreq            *ifr = (struct ifreq *) data;
 1631         int                     s, error = 0;
 1632 
 1633         s = splimp();
 1634 
 1635         switch(command) {
 1636         case SIOCSIFADDR:
 1637         case SIOCGIFADDR:
 1638         case SIOCSIFMTU:
 1639                 error = ether_ioctl(ifp, command, data);
 1640                 break;
 1641         case SIOCSIFFLAGS:
 1642                 if (ifp->if_flags & IFF_UP) {
 1643                         sis_init(sc);
 1644                 } else {
 1645                         if (ifp->if_flags & IFF_RUNNING)
 1646                                 sis_stop(sc);
 1647                 }
 1648                 error = 0;
 1649                 break;
 1650         case SIOCADDMULTI:
 1651         case SIOCDELMULTI:
 1652                 sis_setmulti(sc);
 1653                 error = 0;
 1654                 break;
 1655         case SIOCGIFMEDIA:
 1656         case SIOCSIFMEDIA:
 1657                 error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command);
 1658                 break;
 1659         default:
 1660                 error = EINVAL;
 1661                 break;
 1662         }
 1663 
 1664         (void)splx(s);
 1665 
 1666         return(error);
 1667 }
 1668 
 1669 static void sis_watchdog(ifp)
 1670         struct ifnet            *ifp;
 1671 {
 1672         struct sis_softc        *sc;
 1673 
 1674         sc = ifp->if_softc;
 1675 
 1676         if (sc->sis_autoneg) {
 1677                 sis_autoneg_mii(sc, SIS_FLAG_DELAYTIMEO, 1);
 1678                 return;
 1679         }
 1680 
 1681         ifp->if_oerrors++;
 1682         printf("sis%d: watchdog timeout\n", sc->sis_unit);
 1683 
 1684         sis_stop(sc);
 1685         sis_reset(sc);
 1686         sis_init(sc);
 1687 
 1688         if (ifp->if_snd.ifq_head != NULL)
 1689                 sis_start(ifp);
 1690 
 1691         return;
 1692 }
 1693 
 1694 /*
 1695  * Stop the adapter and free any mbufs allocated to the
 1696  * RX and TX lists.
 1697  */
 1698 static void sis_stop(sc)
 1699         struct sis_softc        *sc;
 1700 {
 1701         register int            i;
 1702         struct ifnet            *ifp;
 1703 
 1704         ifp = &sc->arpcom.ac_if;
 1705         ifp->if_timer = 0;
 1706 
 1707         CSR_WRITE_4(sc, SIS_IER, 0);
 1708         CSR_WRITE_4(sc, SIS_IMR, 0);
 1709         SIS_SETBIT(sc, SIS_CSR, SIS_CSR_TX_DISABLE|SIS_CSR_RX_DISABLE);
 1710         DELAY(1000);
 1711         CSR_WRITE_4(sc, SIS_TX_LISTPTR, 0);
 1712         CSR_WRITE_4(sc, SIS_RX_LISTPTR, 0);
 1713 
 1714         /*
 1715          * Free data in the RX lists.
 1716          */
 1717         for (i = 0; i < SIS_RX_LIST_CNT; i++) {
 1718                 if (sc->sis_ldata->sis_rx_list[i].sis_mbuf != NULL) {
 1719                         m_freem(sc->sis_ldata->sis_rx_list[i].sis_mbuf);
 1720                         sc->sis_ldata->sis_rx_list[i].sis_mbuf = NULL;
 1721                 }
 1722         }
 1723         bzero((char *)&sc->sis_ldata->sis_rx_list,
 1724                 sizeof(sc->sis_ldata->sis_rx_list));
 1725 
 1726         /*
 1727          * Free the TX list buffers.
 1728          */
 1729         for (i = 0; i < SIS_TX_LIST_CNT; i++) {
 1730                 if (sc->sis_ldata->sis_tx_list[i].sis_mbuf != NULL) {
 1731                         m_freem(sc->sis_ldata->sis_tx_list[i].sis_mbuf);
 1732                         sc->sis_ldata->sis_tx_list[i].sis_mbuf = NULL;
 1733                 }
 1734         }
 1735 
 1736         bzero((char *)&sc->sis_ldata->sis_tx_list,
 1737                 sizeof(sc->sis_ldata->sis_tx_list));
 1738 
 1739         ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
 1740 
 1741         return;
 1742 }
 1743 
 1744 /*
 1745  * Stop all chip I/O so that the kernel's probe routines don't
 1746  * get confused by errant DMAs when rebooting.
 1747  */
 1748 static void sis_shutdown(howto, arg)
 1749         int                     howto;
 1750         void                    *arg;
 1751 {
 1752         struct sis_softc        *sc;
 1753 
 1754         sc = arg;
 1755 
 1756         sis_reset(sc);
 1757         sis_stop(sc);
 1758 
 1759         return;
 1760 }
 1761 
 1762 static struct pci_device sis_device = {
 1763         "sis",
 1764         sis_probe,
 1765         sis_attach,
 1766         &sis_count,
 1767         NULL
 1768 };
 1769 #ifdef COMPAT_PCI_DRIVER
 1770 COMPAT_PCI_DRIVER(sis, sis_device);
 1771 #else
 1772 DATA_SET(pcidevice_set, sis_device);
 1773 #endif

Cache object: 76e58de784c8476c1775ba43a72511b6


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.