[BACK]Return to if_sip.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / pci

Annotation of src/sys/dev/pci/if_sip.c, Revision 1.71

1.71    ! thorpej     1: /*     $NetBSD: if_sip.c,v 1.70 2002/09/27 20:40:15 thorpej Exp $      */
1.28      thorpej     2:
                      3: /*-
1.45      thorpej     4:  * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
1.28      thorpej     5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to The NetBSD Foundation
                      8:  * by Jason R. Thorpe.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. All advertising materials mentioning features or use of this software
                     19:  *    must display the following acknowledgement:
                     20:  *     This product includes software developed by the NetBSD
                     21:  *     Foundation, Inc. and its contributors.
                     22:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     23:  *    contributors may be used to endorse or promote products derived
                     24:  *    from this software without specific prior written permission.
                     25:  *
                     26:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     27:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     28:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     29:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     30:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     31:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     32:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     33:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     34:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     35:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     36:  * POSSIBILITY OF SUCH DAMAGE.
                     37:  */
1.1       thorpej    38:
                     39: /*-
                     40:  * Copyright (c) 1999 Network Computer, Inc.
                     41:  * All rights reserved.
                     42:  *
                     43:  * Redistribution and use in source and binary forms, with or without
                     44:  * modification, are permitted provided that the following conditions
                     45:  * are met:
                     46:  * 1. Redistributions of source code must retain the above copyright
                     47:  *    notice, this list of conditions and the following disclaimer.
                     48:  * 2. Redistributions in binary form must reproduce the above copyright
                     49:  *    notice, this list of conditions and the following disclaimer in the
                     50:  *    documentation and/or other materials provided with the distribution.
                     51:  * 3. Neither the name of Network Computer, Inc. nor the names of its
                     52:  *    contributors may be used to endorse or promote products derived
                     53:  *    from this software without specific prior written permission.
                     54:  *
                     55:  * THIS SOFTWARE IS PROVIDED BY NETWORK COMPUTER, INC. AND CONTRIBUTORS
                     56:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     57:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     58:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     59:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     60:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     61:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     62:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     63:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     64:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     65:  * POSSIBILITY OF SUCH DAMAGE.
                     66:  */
                     67:
                     68: /*
1.29      thorpej    69:  * Device driver for the Silicon Integrated Systems SiS 900,
                     70:  * SiS 7016 10/100, National Semiconductor DP83815 10/100, and
                     71:  * National Semiconductor DP83820 10/100/1000 PCI Ethernet
                     72:  * controllers.
1.1       thorpej    73:  *
1.32      thorpej    74:  * Originally written to support the SiS 900 by Jason R. Thorpe for
                     75:  * Network Computer, Inc.
1.29      thorpej    76:  *
                     77:  * TODO:
                     78:  *
1.58      thorpej    79:  *     - Reduce the Rx interrupt load.
1.1       thorpej    80:  */
1.43      lukem      81:
                     82: #include <sys/cdefs.h>
1.71    ! thorpej    83: __KERNEL_RCSID(0, "$NetBSD: if_sip.c,v 1.70 2002/09/27 20:40:15 thorpej Exp $");
1.1       thorpej    84:
                     85: #include "bpfilter.h"
1.65      itojun     86: #include "rnd.h"
1.1       thorpej    87:
                     88: #include <sys/param.h>
                     89: #include <sys/systm.h>
1.9       thorpej    90: #include <sys/callout.h>
1.1       thorpej    91: #include <sys/mbuf.h>
                     92: #include <sys/malloc.h>
                     93: #include <sys/kernel.h>
                     94: #include <sys/socket.h>
                     95: #include <sys/ioctl.h>
                     96: #include <sys/errno.h>
                     97: #include <sys/device.h>
                     98: #include <sys/queue.h>
                     99:
1.12      mrg       100: #include <uvm/uvm_extern.h>            /* for PAGE_SIZE */
1.1       thorpej   101:
1.65      itojun    102: #if NRND > 0
                    103: #include <sys/rnd.h>
                    104: #endif
                    105:
1.1       thorpej   106: #include <net/if.h>
                    107: #include <net/if_dl.h>
                    108: #include <net/if_media.h>
                    109: #include <net/if_ether.h>
                    110:
                    111: #if NBPFILTER > 0
                    112: #include <net/bpf.h>
                    113: #endif
                    114:
                    115: #include <machine/bus.h>
                    116: #include <machine/intr.h>
1.14      tsutsui   117: #include <machine/endian.h>
1.1       thorpej   118:
1.15      thorpej   119: #include <dev/mii/mii.h>
1.1       thorpej   120: #include <dev/mii/miivar.h>
1.29      thorpej   121: #ifdef DP83820
                    122: #include <dev/mii/mii_bitbang.h>
                    123: #endif /* DP83820 */
1.1       thorpej   124:
                    125: #include <dev/pci/pcireg.h>
                    126: #include <dev/pci/pcivar.h>
                    127: #include <dev/pci/pcidevs.h>
                    128:
                    129: #include <dev/pci/if_sipreg.h>
                    130:
1.29      thorpej   131: #ifdef DP83820         /* DP83820 Gigabit Ethernet */
                    132: #define        SIP_DECL(x)     __CONCAT(gsip_,x)
                    133: #else                  /* SiS900 and DP83815 */
1.28      thorpej   134: #define        SIP_DECL(x)     __CONCAT(sip_,x)
1.29      thorpej   135: #endif
                    136:
1.28      thorpej   137: #define        SIP_STR(x)      __STRING(SIP_DECL(x))
                    138:
1.1       thorpej   139: /*
                    140:  * Transmit descriptor list size.  This is arbitrary, but allocate
1.30      thorpej   141:  * enough descriptors for 128 pending transmissions, and 8 segments
1.1       thorpej   142:  * per packet.  This MUST work out to a power of 2.
                    143:  */
1.52      thorpej   144: #define        SIP_NTXSEGS             16
                    145: #define        SIP_NTXSEGS_ALLOC       8
1.1       thorpej   146:
1.30      thorpej   147: #define        SIP_TXQUEUELEN          256
1.52      thorpej   148: #define        SIP_NTXDESC             (SIP_TXQUEUELEN * SIP_NTXSEGS_ALLOC)
1.1       thorpej   149: #define        SIP_NTXDESC_MASK        (SIP_NTXDESC - 1)
                    150: #define        SIP_NEXTTX(x)           (((x) + 1) & SIP_NTXDESC_MASK)
                    151:
1.46      thorpej   152: #if defined(DP83020)
                    153: #define        TX_DMAMAP_SIZE          ETHER_MAX_LEN_JUMBO
                    154: #else
                    155: #define        TX_DMAMAP_SIZE          MCLBYTES
                    156: #endif
                    157:
1.1       thorpej   158: /*
                    159:  * Receive descriptor list size.  We have one Rx buffer per incoming
                    160:  * packet, so this logic is a little simpler.
1.36      thorpej   161:  *
                    162:  * Actually, on the DP83820, we allow the packet to consume more than
                    163:  * one buffer, in order to support jumbo Ethernet frames.  In that
                    164:  * case, a packet may consume up to 5 buffers (assuming a 2048 byte
                    165:  * mbuf cluster).  256 receive buffers is only 51 maximum size packets,
                    166:  * so we'd better be quick about handling receive interrupts.
1.1       thorpej   167:  */
1.36      thorpej   168: #if defined(DP83820)
                    169: #define        SIP_NRXDESC             256
                    170: #else
1.30      thorpej   171: #define        SIP_NRXDESC             128
1.36      thorpej   172: #endif /* DP83820 */
1.1       thorpej   173: #define        SIP_NRXDESC_MASK        (SIP_NRXDESC - 1)
                    174: #define        SIP_NEXTRX(x)           (((x) + 1) & SIP_NRXDESC_MASK)
                    175:
                    176: /*
                    177:  * Control structures are DMA'd to the SiS900 chip.  We allocate them in
                    178:  * a single clump that maps to a single DMA segment to make several things
                    179:  * easier.
                    180:  */
                    181: struct sip_control_data {
                    182:        /*
                    183:         * The transmit descriptors.
                    184:         */
                    185:        struct sip_desc scd_txdescs[SIP_NTXDESC];
                    186:
                    187:        /*
                    188:         * The receive descriptors.
                    189:         */
                    190:        struct sip_desc scd_rxdescs[SIP_NRXDESC];
                    191: };
                    192:
                    193: #define        SIP_CDOFF(x)    offsetof(struct sip_control_data, x)
                    194: #define        SIP_CDTXOFF(x)  SIP_CDOFF(scd_txdescs[(x)])
                    195: #define        SIP_CDRXOFF(x)  SIP_CDOFF(scd_rxdescs[(x)])
                    196:
                    197: /*
                    198:  * Software state for transmit jobs.
                    199:  */
                    200: struct sip_txsoft {
                    201:        struct mbuf *txs_mbuf;          /* head of our mbuf chain */
                    202:        bus_dmamap_t txs_dmamap;        /* our DMA map */
                    203:        int txs_firstdesc;              /* first descriptor in packet */
                    204:        int txs_lastdesc;               /* last descriptor in packet */
                    205:        SIMPLEQ_ENTRY(sip_txsoft) txs_q;
                    206: };
                    207:
                    208: SIMPLEQ_HEAD(sip_txsq, sip_txsoft);
                    209:
                    210: /*
                    211:  * Software state for receive jobs.
                    212:  */
                    213: struct sip_rxsoft {
                    214:        struct mbuf *rxs_mbuf;          /* head of our mbuf chain */
                    215:        bus_dmamap_t rxs_dmamap;        /* our DMA map */
                    216: };
                    217:
                    218: /*
                    219:  * Software state per device.
                    220:  */
                    221: struct sip_softc {
                    222:        struct device sc_dev;           /* generic device information */
                    223:        bus_space_tag_t sc_st;          /* bus space tag */
                    224:        bus_space_handle_t sc_sh;       /* bus space handle */
                    225:        bus_dma_tag_t sc_dmat;          /* bus DMA tag */
                    226:        struct ethercom sc_ethercom;    /* ethernet common data */
                    227:        void *sc_sdhook;                /* shutdown hook */
1.15      thorpej   228:
                    229:        const struct sip_product *sc_model; /* which model are we? */
1.45      thorpej   230:        int sc_rev;                     /* chip revision */
1.1       thorpej   231:
                    232:        void *sc_ih;                    /* interrupt cookie */
                    233:
                    234:        struct mii_data sc_mii;         /* MII/media information */
                    235:
1.9       thorpej   236:        struct callout sc_tick_ch;      /* tick callout */
                    237:
1.1       thorpej   238:        bus_dmamap_t sc_cddmamap;       /* control data DMA map */
                    239: #define        sc_cddma        sc_cddmamap->dm_segs[0].ds_addr
                    240:
                    241:        /*
                    242:         * Software state for transmit and receive descriptors.
                    243:         */
                    244:        struct sip_txsoft sc_txsoft[SIP_TXQUEUELEN];
                    245:        struct sip_rxsoft sc_rxsoft[SIP_NRXDESC];
                    246:
                    247:        /*
                    248:         * Control data structures.
                    249:         */
                    250:        struct sip_control_data *sc_control_data;
                    251: #define        sc_txdescs      sc_control_data->scd_txdescs
                    252: #define        sc_rxdescs      sc_control_data->scd_rxdescs
                    253:
1.30      thorpej   254: #ifdef SIP_EVENT_COUNTERS
                    255:        /*
                    256:         * Event counters.
                    257:         */
                    258:        struct evcnt sc_ev_txsstall;    /* Tx stalled due to no txs */
                    259:        struct evcnt sc_ev_txdstall;    /* Tx stalled due to no txd */
1.56      thorpej   260:        struct evcnt sc_ev_txforceintr; /* Tx interrupts forced */
                    261:        struct evcnt sc_ev_txdintr;     /* Tx descriptor interrupts */
                    262:        struct evcnt sc_ev_txiintr;     /* Tx idle interrupts */
1.30      thorpej   263:        struct evcnt sc_ev_rxintr;      /* Rx interrupts */
1.62      thorpej   264:        struct evcnt sc_ev_hiberr;      /* HIBERR interrupts */
1.31      thorpej   265: #ifdef DP83820
                    266:        struct evcnt sc_ev_rxipsum;     /* IP checksums checked in-bound */
                    267:        struct evcnt sc_ev_rxtcpsum;    /* TCP checksums checked in-bound */
                    268:        struct evcnt sc_ev_rxudpsum;    /* UDP checksums checked in-boudn */
                    269:        struct evcnt sc_ev_txipsum;     /* IP checksums comp. out-bound */
                    270:        struct evcnt sc_ev_txtcpsum;    /* TCP checksums comp. out-bound */
                    271:        struct evcnt sc_ev_txudpsum;    /* UDP checksums comp. out-bound */
                    272: #endif /* DP83820 */
1.30      thorpej   273: #endif /* SIP_EVENT_COUNTERS */
                    274:
1.1       thorpej   275:        u_int32_t sc_txcfg;             /* prototype TXCFG register */
                    276:        u_int32_t sc_rxcfg;             /* prototype RXCFG register */
                    277:        u_int32_t sc_imr;               /* prototype IMR register */
                    278:        u_int32_t sc_rfcr;              /* prototype RFCR register */
                    279:
1.29      thorpej   280:        u_int32_t sc_cfg;               /* prototype CFG register */
                    281:
                    282: #ifdef DP83820
                    283:        u_int32_t sc_gpior;             /* prototype GPIOR register */
                    284: #endif /* DP83820 */
                    285:
1.1       thorpej   286:        u_int32_t sc_tx_fill_thresh;    /* transmit fill threshold */
                    287:        u_int32_t sc_tx_drain_thresh;   /* transmit drain threshold */
                    288:
                    289:        u_int32_t sc_rx_drain_thresh;   /* receive drain threshold */
                    290:
                    291:        int     sc_flags;               /* misc. flags; see below */
                    292:
                    293:        int     sc_txfree;              /* number of free Tx descriptors */
                    294:        int     sc_txnext;              /* next ready Tx descriptor */
1.56      thorpej   295:        int     sc_txwin;               /* Tx descriptors since last intr */
1.1       thorpej   296:
                    297:        struct sip_txsq sc_txfreeq;     /* free Tx descsofts */
                    298:        struct sip_txsq sc_txdirtyq;    /* dirty Tx descsofts */
                    299:
                    300:        int     sc_rxptr;               /* next ready Rx descriptor/descsoft */
1.36      thorpej   301: #if defined(DP83820)
                    302:        int     sc_rxdiscard;
                    303:        int     sc_rxlen;
                    304:        struct mbuf *sc_rxhead;
                    305:        struct mbuf *sc_rxtail;
                    306:        struct mbuf **sc_rxtailp;
                    307: #endif /* DP83820 */
1.65      itojun    308:
                    309: #if NRND > 0
                    310:        rndsource_element_t rnd_source; /* random source */
                    311: #endif
1.1       thorpej   312: };
                    313:
                    314: /* sc_flags */
                    315: #define        SIPF_PAUSED     0x00000001      /* paused (802.3x flow control) */
                    316:
1.36      thorpej   317: #ifdef DP83820
                    318: #define        SIP_RXCHAIN_RESET(sc)                                           \
                    319: do {                                                                   \
                    320:        (sc)->sc_rxtailp = &(sc)->sc_rxhead;                            \
                    321:        *(sc)->sc_rxtailp = NULL;                                       \
                    322:        (sc)->sc_rxlen = 0;                                             \
                    323: } while (/*CONSTCOND*/0)
                    324:
                    325: #define        SIP_RXCHAIN_LINK(sc, m)                                         \
                    326: do {                                                                   \
1.40      thorpej   327:        *(sc)->sc_rxtailp = (sc)->sc_rxtail = (m);                      \
1.36      thorpej   328:        (sc)->sc_rxtailp = &(m)->m_next;                                \
                    329: } while (/*CONSTCOND*/0)
                    330: #endif /* DP83820 */
                    331:
1.30      thorpej   332: #ifdef SIP_EVENT_COUNTERS
                    333: #define        SIP_EVCNT_INCR(ev)      (ev)->ev_count++
                    334: #else
                    335: #define        SIP_EVCNT_INCR(ev)      /* nothing */
                    336: #endif
                    337:
1.1       thorpej   338: #define        SIP_CDTXADDR(sc, x)     ((sc)->sc_cddma + SIP_CDTXOFF((x)))
                    339: #define        SIP_CDRXADDR(sc, x)     ((sc)->sc_cddma + SIP_CDRXOFF((x)))
                    340:
                    341: #define        SIP_CDTXSYNC(sc, x, n, ops)                                     \
                    342: do {                                                                   \
                    343:        int __x, __n;                                                   \
                    344:                                                                        \
                    345:        __x = (x);                                                      \
                    346:        __n = (n);                                                      \
                    347:                                                                        \
                    348:        /* If it will wrap around, sync to the end of the ring. */      \
                    349:        if ((__x + __n) > SIP_NTXDESC) {                                \
                    350:                bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap,       \
                    351:                    SIP_CDTXOFF(__x), sizeof(struct sip_desc) *         \
                    352:                    (SIP_NTXDESC - __x), (ops));                        \
                    353:                __n -= (SIP_NTXDESC - __x);                             \
                    354:                __x = 0;                                                \
                    355:        }                                                               \
                    356:                                                                        \
                    357:        /* Now sync whatever is left. */                                \
                    358:        bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap,               \
                    359:            SIP_CDTXOFF(__x), sizeof(struct sip_desc) * __n, (ops));    \
                    360: } while (0)
                    361:
                    362: #define        SIP_CDRXSYNC(sc, x, ops)                                        \
                    363:        bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap,               \
                    364:            SIP_CDRXOFF((x)), sizeof(struct sip_desc), (ops))
                    365:
1.31      thorpej   366: #ifdef DP83820
                    367: #define        SIP_INIT_RXDESC_EXTSTS  __sipd->sipd_extsts = 0;
1.36      thorpej   368: #define        SIP_RXBUF_LEN           (MCLBYTES - 4)
1.31      thorpej   369: #else
                    370: #define        SIP_INIT_RXDESC_EXTSTS  /* nothing */
1.36      thorpej   371: #define        SIP_RXBUF_LEN           (MCLBYTES - 1)  /* field width */
1.31      thorpej   372: #endif
1.1       thorpej   373: #define        SIP_INIT_RXDESC(sc, x)                                          \
                    374: do {                                                                   \
                    375:        struct sip_rxsoft *__rxs = &(sc)->sc_rxsoft[(x)];               \
                    376:        struct sip_desc *__sipd = &(sc)->sc_rxdescs[(x)];               \
                    377:                                                                        \
1.36      thorpej   378:        __sipd->sipd_link =                                             \
                    379:            htole32(SIP_CDRXADDR((sc), SIP_NEXTRX((x))));               \
                    380:        __sipd->sipd_bufptr =                                           \
                    381:            htole32(__rxs->rxs_dmamap->dm_segs[0].ds_addr);             \
1.14      tsutsui   382:        __sipd->sipd_cmdsts = htole32(CMDSTS_INTR |                     \
1.36      thorpej   383:            (SIP_RXBUF_LEN & CMDSTS_SIZE_MASK));                        \
1.31      thorpej   384:        SIP_INIT_RXDESC_EXTSTS                                          \
1.1       thorpej   385:        SIP_CDRXSYNC((sc), (x), BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); \
                    386: } while (0)
                    387:
1.45      thorpej   388: #define        SIP_CHIP_VERS(sc, v, p, r)                                      \
                    389:        ((sc)->sc_model->sip_vendor == (v) &&                           \
                    390:         (sc)->sc_model->sip_product == (p) &&                          \
                    391:         (sc)->sc_rev == (r))
                    392:
                    393: #define        SIP_CHIP_MODEL(sc, v, p)                                        \
                    394:        ((sc)->sc_model->sip_vendor == (v) &&                           \
                    395:         (sc)->sc_model->sip_product == (p))
                    396:
                    397: #if !defined(DP83820)
                    398: #define        SIP_SIS900_REV(sc, rev)                                         \
                    399:        SIP_CHIP_VERS((sc), PCI_VENDOR_SIS, PCI_PRODUCT_SIS_900, (rev))
                    400: #endif
                    401:
1.14      tsutsui   402: #define SIP_TIMEOUT 1000
                    403:
1.28      thorpej   404: void   SIP_DECL(start)(struct ifnet *);
                    405: void   SIP_DECL(watchdog)(struct ifnet *);
                    406: int    SIP_DECL(ioctl)(struct ifnet *, u_long, caddr_t);
                    407: int    SIP_DECL(init)(struct ifnet *);
                    408: void   SIP_DECL(stop)(struct ifnet *, int);
1.1       thorpej   409:
1.28      thorpej   410: void   SIP_DECL(shutdown)(void *);
1.1       thorpej   411:
1.28      thorpej   412: void   SIP_DECL(reset)(struct sip_softc *);
                    413: void   SIP_DECL(rxdrain)(struct sip_softc *);
                    414: int    SIP_DECL(add_rxbuf)(struct sip_softc *, int);
                    415: void   SIP_DECL(read_eeprom)(struct sip_softc *, int, int, u_int16_t *);
                    416: void   SIP_DECL(tick)(void *);
1.1       thorpej   417:
1.29      thorpej   418: #if !defined(DP83820)
1.28      thorpej   419: void   SIP_DECL(sis900_set_filter)(struct sip_softc *);
1.29      thorpej   420: #endif /* ! DP83820 */
1.28      thorpej   421: void   SIP_DECL(dp83815_set_filter)(struct sip_softc *);
1.15      thorpej   422:
1.29      thorpej   423: #if defined(DP83820)
1.44      thorpej   424: void   SIP_DECL(dp83820_read_macaddr)(struct sip_softc *,
                    425:            const struct pci_attach_args *, u_int8_t *);
1.29      thorpej   426: #else
1.44      thorpej   427: void   SIP_DECL(sis900_read_macaddr)(struct sip_softc *,
                    428:            const struct pci_attach_args *, u_int8_t *);
                    429: void   SIP_DECL(dp83815_read_macaddr)(struct sip_softc *,
                    430:            const struct pci_attach_args *, u_int8_t *);
1.29      thorpej   431: #endif /* DP83820 */
1.25      briggs    432:
1.28      thorpej   433: int    SIP_DECL(intr)(void *);
                    434: void   SIP_DECL(txintr)(struct sip_softc *);
                    435: void   SIP_DECL(rxintr)(struct sip_softc *);
1.1       thorpej   436:
1.29      thorpej   437: #if defined(DP83820)
                    438: int    SIP_DECL(dp83820_mii_readreg)(struct device *, int, int);
                    439: void   SIP_DECL(dp83820_mii_writereg)(struct device *, int, int, int);
                    440: void   SIP_DECL(dp83820_mii_statchg)(struct device *);
                    441: #else
1.28      thorpej   442: int    SIP_DECL(sis900_mii_readreg)(struct device *, int, int);
                    443: void   SIP_DECL(sis900_mii_writereg)(struct device *, int, int, int);
                    444: void   SIP_DECL(sis900_mii_statchg)(struct device *);
1.15      thorpej   445:
1.28      thorpej   446: int    SIP_DECL(dp83815_mii_readreg)(struct device *, int, int);
                    447: void   SIP_DECL(dp83815_mii_writereg)(struct device *, int, int, int);
                    448: void   SIP_DECL(dp83815_mii_statchg)(struct device *);
1.29      thorpej   449: #endif /* DP83820 */
1.1       thorpej   450:
1.28      thorpej   451: int    SIP_DECL(mediachange)(struct ifnet *);
                    452: void   SIP_DECL(mediastatus)(struct ifnet *, struct ifmediareq *);
1.1       thorpej   453:
1.28      thorpej   454: int    SIP_DECL(match)(struct device *, struct cfdata *, void *);
                    455: void   SIP_DECL(attach)(struct device *, struct device *, void *);
1.1       thorpej   456:
1.28      thorpej   457: int    SIP_DECL(copy_small) = 0;
1.2       thorpej   458:
1.71    ! thorpej   459: #ifdef DP83820
        !           460: CFATTACH_DECL(gsip, sizeof(struct sip_softc),
        !           461:     gsip_match, gsip_attach, NULL, NULL)
        !           462: #else
        !           463: CFATTACH_DECL(sip, sizeof(struct sip_softc),
        !           464:     sip_match, sip_attach, NULL, NULL)
        !           465: #endif
1.1       thorpej   466:
1.15      thorpej   467: /*
                    468:  * Descriptions of the variants of the SiS900.
                    469:  */
                    470: struct sip_variant {
1.28      thorpej   471:        int     (*sipv_mii_readreg)(struct device *, int, int);
                    472:        void    (*sipv_mii_writereg)(struct device *, int, int, int);
                    473:        void    (*sipv_mii_statchg)(struct device *);
                    474:        void    (*sipv_set_filter)(struct sip_softc *);
1.44      thorpej   475:        void    (*sipv_read_macaddr)(struct sip_softc *,
                    476:                    const struct pci_attach_args *, u_int8_t *);
1.15      thorpej   477: };
                    478:
1.29      thorpej   479: #if defined(DP83820)
                    480: u_int32_t SIP_DECL(dp83820_mii_bitbang_read)(struct device *);
                    481: void   SIP_DECL(dp83820_mii_bitbang_write)(struct device *, u_int32_t);
                    482:
                    483: const struct mii_bitbang_ops SIP_DECL(dp83820_mii_bitbang_ops) = {
                    484:        SIP_DECL(dp83820_mii_bitbang_read),
                    485:        SIP_DECL(dp83820_mii_bitbang_write),
                    486:        {
                    487:                EROMAR_MDIO,            /* MII_BIT_MDO */
                    488:                EROMAR_MDIO,            /* MII_BIT_MDI */
                    489:                EROMAR_MDC,             /* MII_BIT_MDC */
                    490:                EROMAR_MDDIR,           /* MII_BIT_DIR_HOST_PHY */
                    491:                0,                      /* MII_BIT_DIR_PHY_HOST */
                    492:        }
                    493: };
                    494: #endif /* DP83820 */
                    495:
                    496: #if defined(DP83820)
                    497: const struct sip_variant SIP_DECL(variant_dp83820) = {
                    498:        SIP_DECL(dp83820_mii_readreg),
                    499:        SIP_DECL(dp83820_mii_writereg),
                    500:        SIP_DECL(dp83820_mii_statchg),
                    501:        SIP_DECL(dp83815_set_filter),
                    502:        SIP_DECL(dp83820_read_macaddr),
                    503: };
                    504: #else
1.28      thorpej   505: const struct sip_variant SIP_DECL(variant_sis900) = {
                    506:        SIP_DECL(sis900_mii_readreg),
                    507:        SIP_DECL(sis900_mii_writereg),
                    508:        SIP_DECL(sis900_mii_statchg),
                    509:        SIP_DECL(sis900_set_filter),
                    510:        SIP_DECL(sis900_read_macaddr),
1.15      thorpej   511: };
                    512:
1.28      thorpej   513: const struct sip_variant SIP_DECL(variant_dp83815) = {
                    514:        SIP_DECL(dp83815_mii_readreg),
                    515:        SIP_DECL(dp83815_mii_writereg),
                    516:        SIP_DECL(dp83815_mii_statchg),
                    517:        SIP_DECL(dp83815_set_filter),
                    518:        SIP_DECL(dp83815_read_macaddr),
1.15      thorpej   519: };
1.29      thorpej   520: #endif /* DP83820 */
1.15      thorpej   521:
                    522: /*
                    523:  * Devices supported by this driver.
                    524:  */
                    525: const struct sip_product {
                    526:        pci_vendor_id_t         sip_vendor;
                    527:        pci_product_id_t        sip_product;
                    528:        const char              *sip_name;
                    529:        const struct sip_variant *sip_variant;
1.28      thorpej   530: } SIP_DECL(products)[] = {
1.29      thorpej   531: #if defined(DP83820)
                    532:        { PCI_VENDOR_NS,        PCI_PRODUCT_NS_DP83820,
                    533:          "NatSemi DP83820 Gigabit Ethernet",
                    534:          &SIP_DECL(variant_dp83820) },
                    535: #else
1.15      thorpej   536:        { PCI_VENDOR_SIS,       PCI_PRODUCT_SIS_900,
                    537:          "SiS 900 10/100 Ethernet",
1.28      thorpej   538:          &SIP_DECL(variant_sis900) },
1.15      thorpej   539:        { PCI_VENDOR_SIS,       PCI_PRODUCT_SIS_7016,
                    540:          "SiS 7016 10/100 Ethernet",
1.28      thorpej   541:          &SIP_DECL(variant_sis900) },
1.15      thorpej   542:
                    543:        { PCI_VENDOR_NS,        PCI_PRODUCT_NS_DP83815,
                    544:          "NatSemi DP83815 10/100 Ethernet",
1.28      thorpej   545:          &SIP_DECL(variant_dp83815) },
1.29      thorpej   546: #endif /* DP83820 */
1.15      thorpej   547:
                    548:        { 0,                    0,
                    549:          NULL,
                    550:          NULL },
                    551: };
                    552:
1.28      thorpej   553: static const struct sip_product *
1.29      thorpej   554: SIP_DECL(lookup)(const struct pci_attach_args *pa)
1.1       thorpej   555: {
                    556:        const struct sip_product *sip;
                    557:
1.29      thorpej   558:        for (sip = SIP_DECL(products); sip->sip_name != NULL; sip++) {
1.1       thorpej   559:                if (PCI_VENDOR(pa->pa_id) == sip->sip_vendor &&
                    560:                    PCI_PRODUCT(pa->pa_id) == sip->sip_product)
                    561:                        return (sip);
                    562:        }
                    563:        return (NULL);
                    564: }
                    565:
1.60      thorpej   566: #ifdef DP83820
                    567: /*
                    568:  * I really hate stupid hardware vendors.  There's a bit in the EEPROM
                    569:  * which indicates if the card can do 64-bit data transfers.  Unfortunately,
                    570:  * several vendors of 32-bit cards fail to clear this bit in the EEPROM,
                    571:  * which means we try to use 64-bit data transfers on those cards if we
                    572:  * happen to be plugged into a 32-bit slot.
                    573:  *
                    574:  * What we do is use this table of cards known to be 64-bit cards.  If
                    575:  * you have a 64-bit card who's subsystem ID is not listed in this table,
                    576:  * send the output of "pcictl dump ..." of the device to me so that your
                    577:  * card will use the 64-bit data path when plugged into a 64-bit slot.
                    578:  *
                    579:  *     -- Jason R. Thorpe <thorpej@netbsd.org>
                    580:  *        June 30, 2002
                    581:  */
                    582: static int
                    583: SIP_DECL(check_64bit)(const struct pci_attach_args *pa)
                    584: {
                    585:        static const struct {
                    586:                pci_vendor_id_t c64_vendor;
                    587:                pci_product_id_t c64_product;
                    588:        } card64[] = {
                    589:                /* Asante GigaNIX */
                    590:                { 0x128a,       0x0002 },
1.61      thorpej   591:
                    592:                /* Accton EN1407-T, Planex GN-1000TE */
                    593:                { 0x1113,       0x1407 },
1.60      thorpej   594:
1.69      thorpej   595:                /* Netgear GA-621 */
                    596:                { 0x1385,       0x621a },
                    597:
1.60      thorpej   598:                { 0, 0}
                    599:        };
                    600:        pcireg_t subsys;
                    601:        int i;
                    602:
                    603:        subsys = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
                    604:
                    605:        for (i = 0; card64[i].c64_vendor != 0; i++) {
                    606:                if (PCI_VENDOR(subsys) == card64[i].c64_vendor &&
                    607:                    PCI_PRODUCT(subsys) == card64[i].c64_product)
                    608:                        return (1);
                    609:        }
                    610:
                    611:        return (0);
                    612: }
                    613: #endif /* DP83820 */
                    614:
1.1       thorpej   615: int
1.29      thorpej   616: SIP_DECL(match)(struct device *parent, struct cfdata *cf, void *aux)
1.1       thorpej   617: {
                    618:        struct pci_attach_args *pa = aux;
                    619:
1.29      thorpej   620:        if (SIP_DECL(lookup)(pa) != NULL)
1.1       thorpej   621:                return (1);
                    622:
                    623:        return (0);
                    624: }
                    625:
                    626: void
1.29      thorpej   627: SIP_DECL(attach)(struct device *parent, struct device *self, void *aux)
1.1       thorpej   628: {
                    629:        struct sip_softc *sc = (struct sip_softc *) self;
                    630:        struct pci_attach_args *pa = aux;
                    631:        struct ifnet *ifp = &sc->sc_ethercom.ec_if;
                    632:        pci_chipset_tag_t pc = pa->pa_pc;
                    633:        pci_intr_handle_t ih;
                    634:        const char *intrstr = NULL;
                    635:        bus_space_tag_t iot, memt;
                    636:        bus_space_handle_t ioh, memh;
                    637:        bus_dma_segment_t seg;
                    638:        int ioh_valid, memh_valid;
                    639:        int i, rseg, error;
                    640:        const struct sip_product *sip;
                    641:        pcireg_t pmode;
1.14      tsutsui   642:        u_int8_t enaddr[ETHER_ADDR_LEN];
1.10      mycroft   643:        int pmreg;
1.29      thorpej   644: #ifdef DP83820
                    645:        pcireg_t memtype;
                    646:        u_int32_t reg;
                    647: #endif /* DP83820 */
1.1       thorpej   648:
1.9       thorpej   649:        callout_init(&sc->sc_tick_ch);
                    650:
1.28      thorpej   651:        sip = SIP_DECL(lookup)(pa);
1.1       thorpej   652:        if (sip == NULL) {
                    653:                printf("\n");
1.28      thorpej   654:                panic(SIP_STR(attach) ": impossible");
1.1       thorpej   655:        }
1.45      thorpej   656:        sc->sc_rev = PCI_REVISION(pa->pa_class);
1.1       thorpej   657:
1.50      briggs    658:        printf(": %s, rev %#02x\n", sip->sip_name, sc->sc_rev);
1.1       thorpej   659:
1.15      thorpej   660:        sc->sc_model = sip;
1.5       thorpej   661:
1.1       thorpej   662:        /*
1.46      thorpej   663:         * XXX Work-around broken PXE firmware on some boards.
                    664:         *
                    665:         * The DP83815 shares an address decoder with the MEM BAR
                    666:         * and the ROM BAR.  Make sure the ROM BAR is disabled,
                    667:         * so that memory mapped access works.
                    668:         */
                    669:        pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_MAPREG_ROM,
                    670:            pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_MAPREG_ROM) &
                    671:            ~PCI_MAPREG_ROM_ENABLE);
                    672:
                    673:        /*
1.1       thorpej   674:         * Map the device.
                    675:         */
                    676:        ioh_valid = (pci_mapreg_map(pa, SIP_PCI_CFGIOA,
                    677:            PCI_MAPREG_TYPE_IO, 0,
                    678:            &iot, &ioh, NULL, NULL) == 0);
1.29      thorpej   679: #ifdef DP83820
                    680:        memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, SIP_PCI_CFGMA);
                    681:        switch (memtype) {
                    682:        case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
                    683:        case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
                    684:                memh_valid = (pci_mapreg_map(pa, SIP_PCI_CFGMA,
                    685:                    memtype, 0, &memt, &memh, NULL, NULL) == 0);
                    686:                break;
                    687:        default:
                    688:                memh_valid = 0;
                    689:        }
                    690: #else
1.1       thorpej   691:        memh_valid = (pci_mapreg_map(pa, SIP_PCI_CFGMA,
                    692:            PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0,
                    693:            &memt, &memh, NULL, NULL) == 0);
1.29      thorpej   694: #endif /* DP83820 */
                    695:
1.1       thorpej   696:        if (memh_valid) {
                    697:                sc->sc_st = memt;
                    698:                sc->sc_sh = memh;
                    699:        } else if (ioh_valid) {
                    700:                sc->sc_st = iot;
                    701:                sc->sc_sh = ioh;
                    702:        } else {
                    703:                printf("%s: unable to map device registers\n",
                    704:                    sc->sc_dev.dv_xname);
                    705:                return;
                    706:        }
                    707:
                    708:        sc->sc_dmat = pa->pa_dmat;
                    709:
1.48      thorpej   710:        /*
                    711:         * Make sure bus mastering is enabled.  Also make sure
                    712:         * Write/Invalidate is enabled if we're allowed to use it.
                    713:         */
                    714:        pmreg = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
                    715:        if (pa->pa_flags & PCI_FLAGS_MWI_OKAY)
                    716:                pmreg |= PCI_COMMAND_INVALIDATE_ENABLE;
1.1       thorpej   717:        pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
1.48      thorpej   718:            pmreg | PCI_COMMAND_MASTER_ENABLE);
1.1       thorpej   719:
                    720:        /* Get it out of power save mode if needed. */
1.10      mycroft   721:        if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PWRMGMT, &pmreg, 0)) {
                    722:                pmode = pci_conf_read(pc, pa->pa_tag, pmreg + 4) & 0x3;
1.1       thorpej   723:                if (pmode == 3) {
                    724:                        /*
                    725:                         * The card has lost all configuration data in
                    726:                         * this state, so punt.
                    727:                         */
                    728:                        printf("%s: unable to wake up from power state D3\n",
                    729:                            sc->sc_dev.dv_xname);
                    730:                        return;
                    731:                }
                    732:                if (pmode != 0) {
                    733:                        printf("%s: waking up from power state D%d\n",
                    734:                            sc->sc_dev.dv_xname, pmode);
1.10      mycroft   735:                        pci_conf_write(pc, pa->pa_tag, pmreg + 4, 0);
1.1       thorpej   736:                }
                    737:        }
                    738:
                    739:        /*
                    740:         * Map and establish our interrupt.
                    741:         */
1.23      sommerfe  742:        if (pci_intr_map(pa, &ih)) {
1.1       thorpej   743:                printf("%s: unable to map interrupt\n", sc->sc_dev.dv_xname);
                    744:                return;
                    745:        }
                    746:        intrstr = pci_intr_string(pc, ih);
1.29      thorpej   747:        sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, SIP_DECL(intr), sc);
1.1       thorpej   748:        if (sc->sc_ih == NULL) {
                    749:                printf("%s: unable to establish interrupt",
                    750:                    sc->sc_dev.dv_xname);
                    751:                if (intrstr != NULL)
                    752:                        printf(" at %s", intrstr);
                    753:                printf("\n");
                    754:                return;
                    755:        }
                    756:        printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
                    757:
                    758:        SIMPLEQ_INIT(&sc->sc_txfreeq);
                    759:        SIMPLEQ_INIT(&sc->sc_txdirtyq);
                    760:
                    761:        /*
                    762:         * Allocate the control data structures, and create and load the
                    763:         * DMA map for it.
                    764:         */
                    765:        if ((error = bus_dmamem_alloc(sc->sc_dmat,
                    766:            sizeof(struct sip_control_data), PAGE_SIZE, 0, &seg, 1, &rseg,
                    767:            0)) != 0) {
                    768:                printf("%s: unable to allocate control data, error = %d\n",
                    769:                    sc->sc_dev.dv_xname, error);
                    770:                goto fail_0;
                    771:        }
                    772:
                    773:        if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
                    774:            sizeof(struct sip_control_data), (caddr_t *)&sc->sc_control_data,
                    775:            BUS_DMA_COHERENT)) != 0) {
                    776:                printf("%s: unable to map control data, error = %d\n",
                    777:                    sc->sc_dev.dv_xname, error);
                    778:                goto fail_1;
                    779:        }
                    780:
                    781:        if ((error = bus_dmamap_create(sc->sc_dmat,
                    782:            sizeof(struct sip_control_data), 1,
                    783:            sizeof(struct sip_control_data), 0, 0, &sc->sc_cddmamap)) != 0) {
                    784:                printf("%s: unable to create control data DMA map, "
                    785:                    "error = %d\n", sc->sc_dev.dv_xname, error);
                    786:                goto fail_2;
                    787:        }
                    788:
                    789:        if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap,
                    790:            sc->sc_control_data, sizeof(struct sip_control_data), NULL,
                    791:            0)) != 0) {
                    792:                printf("%s: unable to load control data DMA map, error = %d\n",
                    793:                    sc->sc_dev.dv_xname, error);
                    794:                goto fail_3;
                    795:        }
                    796:
                    797:        /*
                    798:         * Create the transmit buffer DMA maps.
                    799:         */
                    800:        for (i = 0; i < SIP_TXQUEUELEN; i++) {
1.46      thorpej   801:                if ((error = bus_dmamap_create(sc->sc_dmat, TX_DMAMAP_SIZE,
1.1       thorpej   802:                    SIP_NTXSEGS, MCLBYTES, 0, 0,
                    803:                    &sc->sc_txsoft[i].txs_dmamap)) != 0) {
                    804:                        printf("%s: unable to create tx DMA map %d, "
                    805:                            "error = %d\n", sc->sc_dev.dv_xname, i, error);
                    806:                        goto fail_4;
                    807:                }
                    808:        }
                    809:
                    810:        /*
                    811:         * Create the receive buffer DMA maps.
                    812:         */
                    813:        for (i = 0; i < SIP_NRXDESC; i++) {
                    814:                if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
                    815:                    MCLBYTES, 0, 0, &sc->sc_rxsoft[i].rxs_dmamap)) != 0) {
                    816:                        printf("%s: unable to create rx DMA map %d, "
                    817:                            "error = %d\n", sc->sc_dev.dv_xname, i, error);
                    818:                        goto fail_5;
                    819:                }
1.2       thorpej   820:                sc->sc_rxsoft[i].rxs_mbuf = NULL;
1.1       thorpej   821:        }
                    822:
                    823:        /*
                    824:         * Reset the chip to a known state.
                    825:         */
1.29      thorpej   826:        SIP_DECL(reset)(sc);
1.1       thorpej   827:
                    828:        /*
1.29      thorpej   829:         * Read the Ethernet address from the EEPROM.  This might
                    830:         * also fetch other stuff from the EEPROM and stash it
                    831:         * in the softc.
1.1       thorpej   832:         */
1.29      thorpej   833:        sc->sc_cfg = 0;
1.45      thorpej   834: #if !defined(DP83820)
                    835:        if (SIP_SIS900_REV(sc,SIS_REV_635) ||
                    836:            SIP_SIS900_REV(sc,SIS_REV_900B))
                    837:                sc->sc_cfg |= (CFG_PESEL | CFG_RNDCNT);
                    838: #endif
                    839:
1.44      thorpej   840:        (*sip->sip_variant->sipv_read_macaddr)(sc, pa, enaddr);
1.1       thorpej   841:
                    842:        printf("%s: Ethernet address %s\n", sc->sc_dev.dv_xname,
1.14      tsutsui   843:            ether_sprintf(enaddr));
1.1       thorpej   844:
                    845:        /*
1.29      thorpej   846:         * Initialize the configuration register: aggressive PCI
                    847:         * bus request algorithm, default backoff, default OW timer,
                    848:         * default parity error detection.
                    849:         *
                    850:         * NOTE: "Big endian mode" is useless on the SiS900 and
                    851:         * friends -- it affects packet data, not descriptors.
                    852:         */
                    853: #ifdef DP83820
1.55      thorpej   854:        /*
1.59      thorpej   855:         * Cause the chip to load configuration data from the EEPROM.
1.55      thorpej   856:         */
1.59      thorpej   857:        bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_PTSCR, PTSCR_EELOAD_EN);
                    858:        for (i = 0; i < 10000; i++) {
                    859:                delay(10);
                    860:                if ((bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_PTSCR) &
                    861:                    PTSCR_EELOAD_EN) == 0)
                    862:                        break;
                    863:        }
                    864:        if (bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_PTSCR) &
                    865:            PTSCR_EELOAD_EN) {
                    866:                printf("%s: timeout loading configuration from EEPROM\n",
                    867:                    sc->sc_dev.dv_xname);
                    868:                return;
                    869:        }
1.55      thorpej   870:
1.69      thorpej   871:        sc->sc_gpior = bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_GPIOR);
                    872:
1.29      thorpej   873:        reg = bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_CFG);
                    874:        if (reg & CFG_PCI64_DET) {
1.60      thorpej   875:                printf("%s: 64-bit PCI slot detected", sc->sc_dev.dv_xname);
                    876:                /*
                    877:                 * Check to see if this card is 64-bit.  If so, enable 64-bit
                    878:                 * data transfers.
                    879:                 *
                    880:                 * We can't use the DATA64_EN bit in the EEPROM, because
                    881:                 * vendors of 32-bit cards fail to clear that bit in many
                    882:                 * cases (yet the card still detects that it's in a 64-bit
                    883:                 * slot; go figure).
                    884:                 */
                    885:                if (SIP_DECL(check_64bit)(pa)) {
1.59      thorpej   886:                        sc->sc_cfg |= CFG_DATA64_EN;
1.60      thorpej   887:                        printf(", using 64-bit data transfers");
                    888:                }
                    889:                printf("\n");
1.59      thorpej   890:        }
                    891:
                    892:        /*
                    893:         * XXX Need some PCI flags indicating support for
                    894:         * XXX 64-bit addressing.
                    895:         */
                    896: #if 0
                    897:        if (reg & CFG_M64ADDR)
                    898:                sc->sc_cfg |= CFG_M64ADDR;
                    899:        if (reg & CFG_T64ADDR)
                    900:                sc->sc_cfg |= CFG_T64ADDR;
                    901: #endif
1.55      thorpej   902:
1.59      thorpej   903:        if (reg & (CFG_TBI_EN|CFG_EXT_125)) {
1.29      thorpej   904:                const char *sep = "";
                    905:                printf("%s: using ", sc->sc_dev.dv_xname);
1.59      thorpej   906:                if (reg & CFG_EXT_125) {
                    907:                        sc->sc_cfg |= CFG_EXT_125;
1.29      thorpej   908:                        printf("%s125MHz clock", sep);
                    909:                        sep = ", ";
                    910:                }
1.59      thorpej   911:                if (reg & CFG_TBI_EN) {
                    912:                        sc->sc_cfg |= CFG_TBI_EN;
1.29      thorpej   913:                        printf("%sten-bit interface", sep);
                    914:                        sep = ", ";
                    915:                }
                    916:                printf("\n");
                    917:        }
1.59      thorpej   918:        if ((pa->pa_flags & PCI_FLAGS_MRM_OKAY) == 0 ||
                    919:            (reg & CFG_MRM_DIS) != 0)
1.29      thorpej   920:                sc->sc_cfg |= CFG_MRM_DIS;
1.59      thorpej   921:        if ((pa->pa_flags & PCI_FLAGS_MWI_OKAY) == 0 ||
                    922:            (reg & CFG_MWI_DIS) != 0)
1.29      thorpej   923:                sc->sc_cfg |= CFG_MWI_DIS;
                    924:
                    925:        /*
                    926:         * Use the extended descriptor format on the DP83820.  This
                    927:         * gives us an interface to VLAN tagging and IPv4/TCP/UDP
                    928:         * checksumming.
                    929:         */
                    930:        sc->sc_cfg |= CFG_EXTSTS_EN;
                    931: #endif /* DP83820 */
                    932:
                    933:        /*
1.1       thorpej   934:         * Initialize our media structures and probe the MII.
                    935:         */
                    936:        sc->sc_mii.mii_ifp = ifp;
1.15      thorpej   937:        sc->sc_mii.mii_readreg = sip->sip_variant->sipv_mii_readreg;
                    938:        sc->sc_mii.mii_writereg = sip->sip_variant->sipv_mii_writereg;
                    939:        sc->sc_mii.mii_statchg = sip->sip_variant->sipv_mii_statchg;
1.29      thorpej   940:        ifmedia_init(&sc->sc_mii.mii_media, 0, SIP_DECL(mediachange),
                    941:            SIP_DECL(mediastatus));
1.63      thorpej   942:
1.6       thorpej   943:        mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
1.7       thorpej   944:            MII_OFFSET_ANY, 0);
1.1       thorpej   945:        if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
                    946:                ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL);
                    947:                ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE);
                    948:        } else
                    949:                ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
                    950:
                    951:        ifp = &sc->sc_ethercom.ec_if;
                    952:        strcpy(ifp->if_xname, sc->sc_dev.dv_xname);
                    953:        ifp->if_softc = sc;
                    954:        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1.28      thorpej   955:        ifp->if_ioctl = SIP_DECL(ioctl);
                    956:        ifp->if_start = SIP_DECL(start);
                    957:        ifp->if_watchdog = SIP_DECL(watchdog);
                    958:        ifp->if_init = SIP_DECL(init);
                    959:        ifp->if_stop = SIP_DECL(stop);
1.21      thorpej   960:        IFQ_SET_READY(&ifp->if_snd);
1.1       thorpej   961:
                    962:        /*
1.29      thorpej   963:         * We can support 802.1Q VLAN-sized frames.
                    964:         */
                    965:        sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;
                    966:
                    967: #ifdef DP83820
                    968:        /*
1.36      thorpej   969:         * And the DP83820 can do VLAN tagging in hardware, and
                    970:         * support the jumbo Ethernet MTU.
1.29      thorpej   971:         */
1.36      thorpej   972:        sc->sc_ethercom.ec_capabilities |=
                    973:            ETHERCAP_VLAN_HWTAGGING | ETHERCAP_JUMBO_MTU;
1.31      thorpej   974:
                    975:        /*
                    976:         * The DP83820 can do IPv4, TCPv4, and UDPv4 checksums
                    977:         * in hardware.
                    978:         */
                    979:        ifp->if_capabilities |= IFCAP_CSUM_IPv4 | IFCAP_CSUM_TCPv4 |
                    980:            IFCAP_CSUM_UDPv4;
1.29      thorpej   981: #endif /* DP83820 */
                    982:
                    983:        /*
1.1       thorpej   984:         * Attach the interface.
                    985:         */
                    986:        if_attach(ifp);
1.14      tsutsui   987:        ether_ifattach(ifp, enaddr);
1.65      itojun    988: #if NRND > 0
                    989:        rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname,
                    990:            RND_TYPE_NET, 0);
                    991: #endif
1.1       thorpej   992:
1.46      thorpej   993:        /*
                    994:         * The number of bytes that must be available in
                    995:         * the Tx FIFO before the bus master can DMA more
                    996:         * data into the FIFO.
                    997:         */
                    998:        sc->sc_tx_fill_thresh = 64 / 32;
                    999:
                   1000:        /*
                   1001:         * Start at a drain threshold of 512 bytes.  We will
                   1002:         * increase it if a DMA underrun occurs.
                   1003:         *
                   1004:         * XXX The minimum value of this variable should be
                   1005:         * tuned.  We may be able to improve performance
                   1006:         * by starting with a lower value.  That, however,
                   1007:         * may trash the first few outgoing packets if the
                   1008:         * PCI bus is saturated.
                   1009:         */
1.53      tron     1010:        sc->sc_tx_drain_thresh = 1504 / 32;
1.46      thorpej  1011:
                   1012:        /*
1.47      thorpej  1013:         * Initialize the Rx FIFO drain threshold.
                   1014:         *
1.46      thorpej  1015:         * This is in units of 8 bytes.
                   1016:         *
                   1017:         * We should never set this value lower than 2; 14 bytes are
                   1018:         * required to filter the packet.
                   1019:         */
1.47      thorpej  1020:        sc->sc_rx_drain_thresh = 128 / 8;
1.46      thorpej  1021:
1.30      thorpej  1022: #ifdef SIP_EVENT_COUNTERS
                   1023:        /*
                   1024:         * Attach event counters.
                   1025:         */
                   1026:        evcnt_attach_dynamic(&sc->sc_ev_txsstall, EVCNT_TYPE_MISC,
                   1027:            NULL, sc->sc_dev.dv_xname, "txsstall");
                   1028:        evcnt_attach_dynamic(&sc->sc_ev_txdstall, EVCNT_TYPE_MISC,
                   1029:            NULL, sc->sc_dev.dv_xname, "txdstall");
1.56      thorpej  1030:        evcnt_attach_dynamic(&sc->sc_ev_txforceintr, EVCNT_TYPE_INTR,
                   1031:            NULL, sc->sc_dev.dv_xname, "txforceintr");
                   1032:        evcnt_attach_dynamic(&sc->sc_ev_txdintr, EVCNT_TYPE_INTR,
                   1033:            NULL, sc->sc_dev.dv_xname, "txdintr");
                   1034:        evcnt_attach_dynamic(&sc->sc_ev_txiintr, EVCNT_TYPE_INTR,
                   1035:            NULL, sc->sc_dev.dv_xname, "txiintr");
1.30      thorpej  1036:        evcnt_attach_dynamic(&sc->sc_ev_rxintr, EVCNT_TYPE_INTR,
                   1037:            NULL, sc->sc_dev.dv_xname, "rxintr");
1.62      thorpej  1038:        evcnt_attach_dynamic(&sc->sc_ev_hiberr, EVCNT_TYPE_INTR,
                   1039:            NULL, sc->sc_dev.dv_xname, "hiberr");
1.31      thorpej  1040: #ifdef DP83820
                   1041:        evcnt_attach_dynamic(&sc->sc_ev_rxipsum, EVCNT_TYPE_MISC,
                   1042:            NULL, sc->sc_dev.dv_xname, "rxipsum");
                   1043:        evcnt_attach_dynamic(&sc->sc_ev_rxtcpsum, EVCNT_TYPE_MISC,
                   1044:            NULL, sc->sc_dev.dv_xname, "rxtcpsum");
                   1045:        evcnt_attach_dynamic(&sc->sc_ev_rxudpsum, EVCNT_TYPE_MISC,
                   1046:            NULL, sc->sc_dev.dv_xname, "rxudpsum");
                   1047:        evcnt_attach_dynamic(&sc->sc_ev_txipsum, EVCNT_TYPE_MISC,
                   1048:            NULL, sc->sc_dev.dv_xname, "txipsum");
                   1049:        evcnt_attach_dynamic(&sc->sc_ev_txtcpsum, EVCNT_TYPE_MISC,
                   1050:            NULL, sc->sc_dev.dv_xname, "txtcpsum");
                   1051:        evcnt_attach_dynamic(&sc->sc_ev_txudpsum, EVCNT_TYPE_MISC,
                   1052:            NULL, sc->sc_dev.dv_xname, "txudpsum");
                   1053: #endif /* DP83820 */
1.30      thorpej  1054: #endif /* SIP_EVENT_COUNTERS */
                   1055:
1.1       thorpej  1056:        /*
                   1057:         * Make sure the interface is shutdown during reboot.
                   1058:         */
1.28      thorpej  1059:        sc->sc_sdhook = shutdownhook_establish(SIP_DECL(shutdown), sc);
1.1       thorpej  1060:        if (sc->sc_sdhook == NULL)
                   1061:                printf("%s: WARNING: unable to establish shutdown hook\n",
                   1062:                    sc->sc_dev.dv_xname);
                   1063:        return;
                   1064:
                   1065:        /*
                   1066:         * Free any resources we've allocated during the failed attach
                   1067:         * attempt.  Do this in reverse order and fall through.
                   1068:         */
                   1069:  fail_5:
                   1070:        for (i = 0; i < SIP_NRXDESC; i++) {
                   1071:                if (sc->sc_rxsoft[i].rxs_dmamap != NULL)
                   1072:                        bus_dmamap_destroy(sc->sc_dmat,
                   1073:                            sc->sc_rxsoft[i].rxs_dmamap);
                   1074:        }
                   1075:  fail_4:
                   1076:        for (i = 0; i < SIP_TXQUEUELEN; i++) {
                   1077:                if (sc->sc_txsoft[i].txs_dmamap != NULL)
                   1078:                        bus_dmamap_destroy(sc->sc_dmat,
                   1079:                            sc->sc_txsoft[i].txs_dmamap);
                   1080:        }
                   1081:        bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap);
                   1082:  fail_3:
                   1083:        bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap);
                   1084:  fail_2:
                   1085:        bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_control_data,
                   1086:            sizeof(struct sip_control_data));
                   1087:  fail_1:
                   1088:        bus_dmamem_free(sc->sc_dmat, &seg, rseg);
                   1089:  fail_0:
                   1090:        return;
                   1091: }
                   1092:
                   1093: /*
                   1094:  * sip_shutdown:
                   1095:  *
                   1096:  *     Make sure the interface is stopped at reboot time.
                   1097:  */
                   1098: void
1.28      thorpej  1099: SIP_DECL(shutdown)(void *arg)
1.1       thorpej  1100: {
                   1101:        struct sip_softc *sc = arg;
                   1102:
1.28      thorpej  1103:        SIP_DECL(stop)(&sc->sc_ethercom.ec_if, 1);
1.1       thorpej  1104: }
                   1105:
                   1106: /*
                   1107:  * sip_start:          [ifnet interface function]
                   1108:  *
                   1109:  *     Start packet transmission on the interface.
                   1110:  */
                   1111: void
1.28      thorpej  1112: SIP_DECL(start)(struct ifnet *ifp)
1.1       thorpej  1113: {
                   1114:        struct sip_softc *sc = ifp->if_softc;
                   1115:        struct mbuf *m0, *m;
                   1116:        struct sip_txsoft *txs;
                   1117:        bus_dmamap_t dmamap;
1.57      thorpej  1118:        int error, nexttx, lasttx, seg;
                   1119:        int ofree = sc->sc_txfree;
                   1120: #if 0
                   1121:        int firsttx = sc->sc_txnext;
                   1122: #endif
1.31      thorpej  1123: #ifdef DP83820
                   1124:        u_int32_t extsts;
                   1125: #endif
1.1       thorpej  1126:
                   1127:        /*
                   1128:         * If we've been told to pause, don't transmit any more packets.
                   1129:         */
                   1130:        if (sc->sc_flags & SIPF_PAUSED)
                   1131:                ifp->if_flags |= IFF_OACTIVE;
                   1132:
                   1133:        if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
                   1134:                return;
                   1135:
                   1136:        /*
                   1137:         * Loop through the send queue, setting up transmit descriptors
                   1138:         * until we drain the queue, or use up all available transmit
                   1139:         * descriptors.
                   1140:         */
1.30      thorpej  1141:        for (;;) {
                   1142:                /* Get a work queue entry. */
                   1143:                if ((txs = SIMPLEQ_FIRST(&sc->sc_txfreeq)) == NULL) {
                   1144:                        SIP_EVCNT_INCR(&sc->sc_ev_txsstall);
                   1145:                        break;
                   1146:                }
                   1147:
1.1       thorpej  1148:                /*
                   1149:                 * Grab a packet off the queue.
                   1150:                 */
1.21      thorpej  1151:                IFQ_POLL(&ifp->if_snd, m0);
1.1       thorpej  1152:                if (m0 == NULL)
                   1153:                        break;
1.36      thorpej  1154: #ifndef DP83820
1.22      thorpej  1155:                m = NULL;
1.36      thorpej  1156: #endif
1.1       thorpej  1157:
                   1158:                dmamap = txs->txs_dmamap;
                   1159:
1.36      thorpej  1160: #ifdef DP83820
                   1161:                /*
                   1162:                 * Load the DMA map.  If this fails, the packet either
                   1163:                 * didn't fit in the allotted number of segments, or we
                   1164:                 * were short on resources.  For the too-many-segments
                   1165:                 * case, we simply report an error and drop the packet,
                   1166:                 * since we can't sanely copy a jumbo packet to a single
                   1167:                 * buffer.
                   1168:                 */
                   1169:                error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0,
1.41      thorpej  1170:                    BUS_DMA_WRITE|BUS_DMA_NOWAIT);
1.36      thorpej  1171:                if (error) {
                   1172:                        if (error == EFBIG) {
                   1173:                                printf("%s: Tx packet consumes too many "
                   1174:                                    "DMA segments, dropping...\n",
                   1175:                                    sc->sc_dev.dv_xname);
                   1176:                                IFQ_DEQUEUE(&ifp->if_snd, m0);
                   1177:                                m_freem(m0);
                   1178:                                continue;
                   1179:                        }
                   1180:                        /*
                   1181:                         * Short on resources, just stop for now.
                   1182:                         */
                   1183:                        break;
                   1184:                }
                   1185: #else /* DP83820 */
1.1       thorpej  1186:                /*
                   1187:                 * Load the DMA map.  If this fails, the packet either
                   1188:                 * didn't fit in the alloted number of segments, or we
                   1189:                 * were short on resources.  In this case, we'll copy
                   1190:                 * and try again.
                   1191:                 */
                   1192:                if (bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0,
1.41      thorpej  1193:                    BUS_DMA_WRITE|BUS_DMA_NOWAIT) != 0) {
1.1       thorpej  1194:                        MGETHDR(m, M_DONTWAIT, MT_DATA);
                   1195:                        if (m == NULL) {
                   1196:                                printf("%s: unable to allocate Tx mbuf\n",
                   1197:                                    sc->sc_dev.dv_xname);
                   1198:                                break;
                   1199:                        }
                   1200:                        if (m0->m_pkthdr.len > MHLEN) {
                   1201:                                MCLGET(m, M_DONTWAIT);
                   1202:                                if ((m->m_flags & M_EXT) == 0) {
                   1203:                                        printf("%s: unable to allocate Tx "
                   1204:                                            "cluster\n", sc->sc_dev.dv_xname);
                   1205:                                        m_freem(m);
                   1206:                                        break;
                   1207:                                }
                   1208:                        }
                   1209:                        m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, caddr_t));
                   1210:                        m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len;
                   1211:                        error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap,
1.41      thorpej  1212:                            m, BUS_DMA_WRITE|BUS_DMA_NOWAIT);
1.1       thorpej  1213:                        if (error) {
                   1214:                                printf("%s: unable to load Tx buffer, "
                   1215:                                    "error = %d\n", sc->sc_dev.dv_xname, error);
                   1216:                                break;
                   1217:                        }
                   1218:                }
1.36      thorpej  1219: #endif /* DP83820 */
1.21      thorpej  1220:
1.1       thorpej  1221:                /*
                   1222:                 * Ensure we have enough descriptors free to describe
1.30      thorpej  1223:                 * the packet.  Note, we always reserve one descriptor
                   1224:                 * at the end of the ring as a termination point, to
                   1225:                 * prevent wrap-around.
1.1       thorpej  1226:                 */
1.30      thorpej  1227:                if (dmamap->dm_nsegs > (sc->sc_txfree - 1)) {
1.1       thorpej  1228:                        /*
                   1229:                         * Not enough free descriptors to transmit this
                   1230:                         * packet.  We haven't committed anything yet,
                   1231:                         * so just unload the DMA map, put the packet
                   1232:                         * back on the queue, and punt.  Notify the upper
                   1233:                         * layer that there are not more slots left.
                   1234:                         *
                   1235:                         * XXX We could allocate an mbuf and copy, but
                   1236:                         * XXX is it worth it?
                   1237:                         */
                   1238:                        ifp->if_flags |= IFF_OACTIVE;
                   1239:                        bus_dmamap_unload(sc->sc_dmat, dmamap);
1.36      thorpej  1240: #ifndef DP83820
1.22      thorpej  1241:                        if (m != NULL)
                   1242:                                m_freem(m);
1.36      thorpej  1243: #endif
1.30      thorpej  1244:                        SIP_EVCNT_INCR(&sc->sc_ev_txdstall);
1.1       thorpej  1245:                        break;
1.22      thorpej  1246:                }
                   1247:
                   1248:                IFQ_DEQUEUE(&ifp->if_snd, m0);
1.36      thorpej  1249: #ifndef DP83820
1.22      thorpej  1250:                if (m != NULL) {
                   1251:                        m_freem(m0);
                   1252:                        m0 = m;
1.1       thorpej  1253:                }
1.36      thorpej  1254: #endif
1.1       thorpej  1255:
                   1256:                /*
                   1257:                 * WE ARE NOW COMMITTED TO TRANSMITTING THE PACKET.
                   1258:                 */
                   1259:
                   1260:                /* Sync the DMA map. */
                   1261:                bus_dmamap_sync(sc->sc_dmat, dmamap, 0, dmamap->dm_mapsize,
                   1262:                    BUS_DMASYNC_PREWRITE);
                   1263:
                   1264:                /*
                   1265:                 * Initialize the transmit descriptors.
                   1266:                 */
                   1267:                for (nexttx = sc->sc_txnext, seg = 0;
                   1268:                     seg < dmamap->dm_nsegs;
                   1269:                     seg++, nexttx = SIP_NEXTTX(nexttx)) {
                   1270:                        /*
                   1271:                         * If this is the first descriptor we're
                   1272:                         * enqueueing, don't set the OWN bit just
                   1273:                         * yet.  That could cause a race condition.
                   1274:                         * We'll do it below.
                   1275:                         */
                   1276:                        sc->sc_txdescs[nexttx].sipd_bufptr =
1.14      tsutsui  1277:                            htole32(dmamap->dm_segs[seg].ds_addr);
1.1       thorpej  1278:                        sc->sc_txdescs[nexttx].sipd_cmdsts =
1.57      thorpej  1279:                            htole32((nexttx == sc->sc_txnext ? 0 : CMDSTS_OWN) |
1.14      tsutsui  1280:                            CMDSTS_MORE | dmamap->dm_segs[seg].ds_len);
1.29      thorpej  1281: #ifdef DP83820
                   1282:                        sc->sc_txdescs[nexttx].sipd_extsts = 0;
                   1283: #endif /* DP83820 */
1.1       thorpej  1284:                        lasttx = nexttx;
                   1285:                }
                   1286:
                   1287:                /* Clear the MORE bit on the last segment. */
1.14      tsutsui  1288:                sc->sc_txdescs[lasttx].sipd_cmdsts &= htole32(~CMDSTS_MORE);
1.1       thorpej  1289:
1.56      thorpej  1290:                /*
                   1291:                 * If we're in the interrupt delay window, delay the
                   1292:                 * interrupt.
                   1293:                 */
                   1294:                if (++sc->sc_txwin >= (SIP_TXQUEUELEN * 2 / 3)) {
                   1295:                        SIP_EVCNT_INCR(&sc->sc_ev_txforceintr);
                   1296:                        sc->sc_txdescs[lasttx].sipd_cmdsts |=
                   1297:                            htole32(CMDSTS_INTR);
                   1298:                        sc->sc_txwin = 0;
                   1299:                }
                   1300:
1.29      thorpej  1301: #ifdef DP83820
                   1302:                /*
                   1303:                 * If VLANs are enabled and the packet has a VLAN tag, set
                   1304:                 * up the descriptor to encapsulate the packet for us.
1.31      thorpej  1305:                 *
                   1306:                 * This apparently has to be on the last descriptor of
                   1307:                 * the packet.
1.29      thorpej  1308:                 */
                   1309:                if (sc->sc_ethercom.ec_nvlans != 0 &&
                   1310:                    (m = m_aux_find(m0, AF_LINK, ETHERTYPE_VLAN)) != NULL) {
                   1311:                        sc->sc_txdescs[lasttx].sipd_extsts |=
                   1312:                            htole32(EXTSTS_VPKT |
                   1313:                                    htons(*mtod(m, int *) & EXTSTS_VTCI));
                   1314:                }
1.31      thorpej  1315:
                   1316:                /*
                   1317:                 * If the upper-layer has requested IPv4/TCPv4/UDPv4
                   1318:                 * checksumming, set up the descriptor to do this work
                   1319:                 * for us.
                   1320:                 *
                   1321:                 * This apparently has to be on the first descriptor of
                   1322:                 * the packet.
                   1323:                 *
                   1324:                 * Byte-swap constants so the compiler can optimize.
                   1325:                 */
                   1326:                extsts = 0;
                   1327:                if (m0->m_pkthdr.csum_flags & M_CSUM_IPv4) {
                   1328:                        KDASSERT(ifp->if_capenable & IFCAP_CSUM_IPv4);
                   1329:                        SIP_EVCNT_INCR(&sc->sc_ev_txipsum);
                   1330:                        extsts |= htole32(EXTSTS_IPPKT);
                   1331:                }
                   1332:                if (m0->m_pkthdr.csum_flags & M_CSUM_TCPv4) {
                   1333:                        KDASSERT(ifp->if_capenable & IFCAP_CSUM_TCPv4);
                   1334:                        SIP_EVCNT_INCR(&sc->sc_ev_txtcpsum);
                   1335:                        extsts |= htole32(EXTSTS_TCPPKT);
                   1336:                } else if (m0->m_pkthdr.csum_flags & M_CSUM_UDPv4) {
                   1337:                        KDASSERT(ifp->if_capenable & IFCAP_CSUM_UDPv4);
                   1338:                        SIP_EVCNT_INCR(&sc->sc_ev_txudpsum);
                   1339:                        extsts |= htole32(EXTSTS_UDPPKT);
                   1340:                }
                   1341:                sc->sc_txdescs[sc->sc_txnext].sipd_extsts |= extsts;
1.29      thorpej  1342: #endif /* DP83820 */
                   1343:
1.1       thorpej  1344:                /* Sync the descriptors we're using. */
                   1345:                SIP_CDTXSYNC(sc, sc->sc_txnext, dmamap->dm_nsegs,
                   1346:                    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
                   1347:
                   1348:                /*
1.57      thorpej  1349:                 * The entire packet is set up.  Give the first descrptor
                   1350:                 * to the chip now.
                   1351:                 */
                   1352:                sc->sc_txdescs[sc->sc_txnext].sipd_cmdsts |=
                   1353:                    htole32(CMDSTS_OWN);
                   1354:                SIP_CDTXSYNC(sc, sc->sc_txnext, 1,
                   1355:                    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
                   1356:
                   1357:                /*
1.1       thorpej  1358:                 * Store a pointer to the packet so we can free it later,
                   1359:                 * and remember what txdirty will be once the packet is
                   1360:                 * done.
                   1361:                 */
                   1362:                txs->txs_mbuf = m0;
                   1363:                txs->txs_firstdesc = sc->sc_txnext;
                   1364:                txs->txs_lastdesc = lasttx;
                   1365:
                   1366:                /* Advance the tx pointer. */
                   1367:                sc->sc_txfree -= dmamap->dm_nsegs;
                   1368:                sc->sc_txnext = nexttx;
                   1369:
1.54      lukem    1370:                SIMPLEQ_REMOVE_HEAD(&sc->sc_txfreeq, txs_q);
1.1       thorpej  1371:                SIMPLEQ_INSERT_TAIL(&sc->sc_txdirtyq, txs, txs_q);
                   1372:
                   1373: #if NBPFILTER > 0
                   1374:                /*
                   1375:                 * Pass the packet to any BPF listeners.
                   1376:                 */
                   1377:                if (ifp->if_bpf)
                   1378:                        bpf_mtap(ifp->if_bpf, m0);
                   1379: #endif /* NBPFILTER > 0 */
                   1380:        }
                   1381:
                   1382:        if (txs == NULL || sc->sc_txfree == 0) {
                   1383:                /* No more slots left; notify upper layer. */
                   1384:                ifp->if_flags |= IFF_OACTIVE;
                   1385:        }
                   1386:
                   1387:        if (sc->sc_txfree != ofree) {
1.30      thorpej  1388:                /*
                   1389:                 * Start the transmit process.  Note, the manual says
                   1390:                 * that if there are no pending transmissions in the
                   1391:                 * chip's internal queue (indicated by TXE being clear),
                   1392:                 * then the driver software must set the TXDP to the
                   1393:                 * first descriptor to be transmitted.  However, if we
                   1394:                 * do this, it causes serious performance degredation on
                   1395:                 * the DP83820 under load, not setting TXDP doesn't seem
                   1396:                 * to adversely affect the SiS 900 or DP83815.
                   1397:                 *
                   1398:                 * Well, I guess it wouldn't be the first time a manual
                   1399:                 * has lied -- and they could be speaking of the NULL-
                   1400:                 * terminated descriptor list case, rather than OWN-
                   1401:                 * terminated rings.
                   1402:                 */
                   1403: #if 0
1.1       thorpej  1404:                if ((bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_CR) &
                   1405:                     CR_TXE) == 0) {
                   1406:                        bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_TXDP,
                   1407:                            SIP_CDTXADDR(sc, firsttx));
                   1408:                        bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_CR, CR_TXE);
                   1409:                }
1.30      thorpej  1410: #else
                   1411:                bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_CR, CR_TXE);
                   1412: #endif
1.1       thorpej  1413:
                   1414:                /* Set a watchdog timer in case the chip flakes out. */
                   1415:                ifp->if_timer = 5;
                   1416:        }
                   1417: }
                   1418:
                   1419: /*
                   1420:  * sip_watchdog:       [ifnet interface function]
                   1421:  *
                   1422:  *     Watchdog timer handler.
                   1423:  */
                   1424: void
1.28      thorpej  1425: SIP_DECL(watchdog)(struct ifnet *ifp)
1.1       thorpej  1426: {
                   1427:        struct sip_softc *sc = ifp->if_softc;
                   1428:
                   1429:        /*
                   1430:         * The chip seems to ignore the CMDSTS_INTR bit sometimes!
                   1431:         * If we get a timeout, try and sweep up transmit descriptors.
                   1432:         * If we manage to sweep them all up, ignore the lack of
                   1433:         * interrupt.
                   1434:         */
1.28      thorpej  1435:        SIP_DECL(txintr)(sc);
1.1       thorpej  1436:
                   1437:        if (sc->sc_txfree != SIP_NTXDESC) {
                   1438:                printf("%s: device timeout\n", sc->sc_dev.dv_xname);
                   1439:                ifp->if_oerrors++;
                   1440:
                   1441:                /* Reset the interface. */
1.28      thorpej  1442:                (void) SIP_DECL(init)(ifp);
1.1       thorpej  1443:        } else if (ifp->if_flags & IFF_DEBUG)
                   1444:                printf("%s: recovered from device timeout\n",
                   1445:                    sc->sc_dev.dv_xname);
                   1446:
                   1447:        /* Try to get more packets going. */
1.28      thorpej  1448:        SIP_DECL(start)(ifp);
1.1       thorpej  1449: }
                   1450:
                   1451: /*
                   1452:  * sip_ioctl:          [ifnet interface function]
                   1453:  *
                   1454:  *     Handle control requests from the operator.
                   1455:  */
                   1456: int
1.28      thorpej  1457: SIP_DECL(ioctl)(struct ifnet *ifp, u_long cmd, caddr_t data)
1.1       thorpej  1458: {
                   1459:        struct sip_softc *sc = ifp->if_softc;
                   1460:        struct ifreq *ifr = (struct ifreq *)data;
1.17      thorpej  1461:        int s, error;
1.1       thorpej  1462:
                   1463:        s = splnet();
                   1464:
                   1465:        switch (cmd) {
1.17      thorpej  1466:        case SIOCSIFMEDIA:
                   1467:        case SIOCGIFMEDIA:
                   1468:                error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
1.1       thorpej  1469:                break;
                   1470:
1.17      thorpej  1471:        default:
                   1472:                error = ether_ioctl(ifp, cmd, data);
1.1       thorpej  1473:                if (error == ENETRESET) {
                   1474:                        /*
                   1475:                         * Multicast list has changed; set the hardware filter
                   1476:                         * accordingly.
                   1477:                         */
1.15      thorpej  1478:                        (*sc->sc_model->sip_variant->sipv_set_filter)(sc);
1.1       thorpej  1479:                        error = 0;
                   1480:                }
                   1481:                break;
                   1482:        }
                   1483:
                   1484:        /* Try to get more packets going. */
1.28      thorpej  1485:        SIP_DECL(start)(ifp);
1.1       thorpej  1486:
                   1487:        splx(s);
                   1488:        return (error);
                   1489: }
                   1490:
                   1491: /*
                   1492:  * sip_intr:
                   1493:  *
                   1494:  *     Interrupt service routine.
                   1495:  */
                   1496: int
1.28      thorpej  1497: SIP_DECL(intr)(void *arg)
1.1       thorpej  1498: {
                   1499:        struct sip_softc *sc = arg;
                   1500:        struct ifnet *ifp = &sc->sc_ethercom.ec_if;
                   1501:        u_int32_t isr;
                   1502:        int handled = 0;
                   1503:
                   1504:        for (;;) {
                   1505:                /* Reading clears interrupt. */
                   1506:                isr = bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_ISR);
                   1507:                if ((isr & sc->sc_imr) == 0)
                   1508:                        break;
1.65      itojun   1509:
                   1510: #if NRND > 0
1.66      itojun   1511:                if (RND_ENABLED(&sc->rnd_source))
                   1512:                        rnd_add_uint32(&sc->rnd_source, isr);
1.65      itojun   1513: #endif
1.1       thorpej  1514:
                   1515:                handled = 1;
                   1516:
                   1517:                if (isr & (ISR_RXORN|ISR_RXIDLE|ISR_RXDESC)) {
1.30      thorpej  1518:                        SIP_EVCNT_INCR(&sc->sc_ev_rxintr);
                   1519:
1.1       thorpej  1520:                        /* Grab any new packets. */
1.28      thorpej  1521:                        SIP_DECL(rxintr)(sc);
1.1       thorpej  1522:
                   1523:                        if (isr & ISR_RXORN) {
                   1524:                                printf("%s: receive FIFO overrun\n",
                   1525:                                    sc->sc_dev.dv_xname);
                   1526:
                   1527:                                /* XXX adjust rx_drain_thresh? */
                   1528:                        }
                   1529:
                   1530:                        if (isr & ISR_RXIDLE) {
                   1531:                                printf("%s: receive ring overrun\n",
                   1532:                                    sc->sc_dev.dv_xname);
                   1533:
                   1534:                                /* Get the receive process going again. */
                   1535:                                bus_space_write_4(sc->sc_st, sc->sc_sh,
                   1536:                                    SIP_RXDP, SIP_CDRXADDR(sc, sc->sc_rxptr));
                   1537:                                bus_space_write_4(sc->sc_st, sc->sc_sh,
                   1538:                                    SIP_CR, CR_RXE);
                   1539:                        }
                   1540:                }
                   1541:
1.56      thorpej  1542:                if (isr & (ISR_TXURN|ISR_TXDESC|ISR_TXIDLE)) {
                   1543: #ifdef SIP_EVENT_COUNTERS
                   1544:                        if (isr & ISR_TXDESC)
                   1545:                                SIP_EVCNT_INCR(&sc->sc_ev_txdintr);
                   1546:                        else if (isr & ISR_TXIDLE)
                   1547:                                SIP_EVCNT_INCR(&sc->sc_ev_txiintr);
                   1548: #endif
1.30      thorpej  1549:
1.1       thorpej  1550:                        /* Sweep up transmit descriptors. */
1.28      thorpej  1551:                        SIP_DECL(txintr)(sc);
1.1       thorpej  1552:
                   1553:                        if (isr & ISR_TXURN) {
                   1554:                                u_int32_t thresh;
                   1555:
                   1556:                                printf("%s: transmit FIFO underrun",
                   1557:                                    sc->sc_dev.dv_xname);
                   1558:
                   1559:                                thresh = sc->sc_tx_drain_thresh + 1;
                   1560:                                if (thresh <= TXCFG_DRTH &&
                   1561:                                    (thresh * 32) <= (SIP_TXFIFO_SIZE -
                   1562:                                     (sc->sc_tx_fill_thresh * 32))) {
                   1563:                                        printf("; increasing Tx drain "
                   1564:                                            "threshold to %u bytes\n",
                   1565:                                            thresh * 32);
                   1566:                                        sc->sc_tx_drain_thresh = thresh;
1.28      thorpej  1567:                                        (void) SIP_DECL(init)(ifp);
1.1       thorpej  1568:                                } else {
1.28      thorpej  1569:                                        (void) SIP_DECL(init)(ifp);
1.1       thorpej  1570:                                        printf("\n");
                   1571:                                }
                   1572:                        }
                   1573:                }
                   1574:
1.29      thorpej  1575: #if !defined(DP83820)
1.1       thorpej  1576:                if (sc->sc_imr & (ISR_PAUSE_END|ISR_PAUSE_ST)) {
                   1577:                        if (isr & ISR_PAUSE_ST) {
                   1578:                                sc->sc_flags |= SIPF_PAUSED;
                   1579:                                ifp->if_flags |= IFF_OACTIVE;
                   1580:                        }
                   1581:                        if (isr & ISR_PAUSE_END) {
                   1582:                                sc->sc_flags &= ~SIPF_PAUSED;
                   1583:                                ifp->if_flags &= ~IFF_OACTIVE;
                   1584:                        }
                   1585:                }
1.29      thorpej  1586: #endif /* ! DP83820 */
1.1       thorpej  1587:
                   1588:                if (isr & ISR_HIBERR) {
1.62      thorpej  1589:                        int want_init = 0;
                   1590:
                   1591:                        SIP_EVCNT_INCR(&sc->sc_ev_hiberr);
                   1592:
1.1       thorpej  1593: #define        PRINTERR(bit, str)                                              \
1.62      thorpej  1594:                        do {                                            \
1.68      itojun   1595:                                if ((isr & (bit)) != 0) {               \
                   1596:                                        if ((ifp->if_flags & IFF_DEBUG) != 0) \
                   1597:                                                printf("%s: %s\n",      \
                   1598:                                                    sc->sc_dev.dv_xname, str); \
1.62      thorpej  1599:                                        want_init = 1;                  \
                   1600:                                }                                       \
                   1601:                        } while (/*CONSTCOND*/0)
                   1602:
1.1       thorpej  1603:                        PRINTERR(ISR_DPERR, "parity error");
                   1604:                        PRINTERR(ISR_SSERR, "system error");
                   1605:                        PRINTERR(ISR_RMABT, "master abort");
                   1606:                        PRINTERR(ISR_RTABT, "target abort");
                   1607:                        PRINTERR(ISR_RXSOVR, "receive status FIFO overrun");
1.62      thorpej  1608:                        /*
                   1609:                         * Ignore:
                   1610:                         *      Tx reset complete
                   1611:                         *      Rx reset complete
                   1612:                         */
                   1613:                        if (want_init)
                   1614:                                (void) SIP_DECL(init)(ifp);
1.1       thorpej  1615: #undef PRINTERR
                   1616:                }
                   1617:        }
                   1618:
                   1619:        /* Try to get more packets going. */
1.28      thorpej  1620:        SIP_DECL(start)(ifp);
1.1       thorpej  1621:
                   1622:        return (handled);
                   1623: }
                   1624:
                   1625: /*
                   1626:  * sip_txintr:
                   1627:  *
                   1628:  *     Helper; handle transmit interrupts.
                   1629:  */
                   1630: void
1.28      thorpej  1631: SIP_DECL(txintr)(struct sip_softc *sc)
1.1       thorpej  1632: {
                   1633:        struct ifnet *ifp = &sc->sc_ethercom.ec_if;
                   1634:        struct sip_txsoft *txs;
                   1635:        u_int32_t cmdsts;
                   1636:
                   1637:        if ((sc->sc_flags & SIPF_PAUSED) == 0)
                   1638:                ifp->if_flags &= ~IFF_OACTIVE;
                   1639:
                   1640:        /*
                   1641:         * Go through our Tx list and free mbufs for those
                   1642:         * frames which have been transmitted.
                   1643:         */
                   1644:        while ((txs = SIMPLEQ_FIRST(&sc->sc_txdirtyq)) != NULL) {
                   1645:                SIP_CDTXSYNC(sc, txs->txs_firstdesc, txs->txs_dmamap->dm_nsegs,
                   1646:                    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
                   1647:
1.14      tsutsui  1648:                cmdsts = le32toh(sc->sc_txdescs[txs->txs_lastdesc].sipd_cmdsts);
1.1       thorpej  1649:                if (cmdsts & CMDSTS_OWN)
                   1650:                        break;
                   1651:
1.54      lukem    1652:                SIMPLEQ_REMOVE_HEAD(&sc->sc_txdirtyq, txs_q);
1.1       thorpej  1653:
                   1654:                sc->sc_txfree += txs->txs_dmamap->dm_nsegs;
                   1655:
                   1656:                bus_dmamap_sync(sc->sc_dmat, txs->txs_dmamap,
                   1657:                    0, txs->txs_dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
                   1658:                bus_dmamap_unload(sc->sc_dmat, txs->txs_dmamap);
                   1659:                m_freem(txs->txs_mbuf);
                   1660:                txs->txs_mbuf = NULL;
                   1661:
                   1662:                SIMPLEQ_INSERT_TAIL(&sc->sc_txfreeq, txs, txs_q);
                   1663:
                   1664:                /*
                   1665:                 * Check for errors and collisions.
                   1666:                 */
                   1667:                if (cmdsts &
                   1668:                    (CMDSTS_Tx_TXA|CMDSTS_Tx_TFU|CMDSTS_Tx_ED|CMDSTS_Tx_EC)) {
1.34      simonb   1669:                        ifp->if_oerrors++;
                   1670:                        if (cmdsts & CMDSTS_Tx_EC)
                   1671:                                ifp->if_collisions += 16;
1.1       thorpej  1672:                        if (ifp->if_flags & IFF_DEBUG) {
1.34      simonb   1673:                                if (cmdsts & CMDSTS_Tx_ED)
1.1       thorpej  1674:                                        printf("%s: excessive deferral\n",
                   1675:                                            sc->sc_dev.dv_xname);
1.34      simonb   1676:                                if (cmdsts & CMDSTS_Tx_EC)
1.1       thorpej  1677:                                        printf("%s: excessive collisions\n",
                   1678:                                            sc->sc_dev.dv_xname);
                   1679:                        }
                   1680:                } else {
                   1681:                        /* Packet was transmitted successfully. */
                   1682:                        ifp->if_opackets++;
                   1683:                        ifp->if_collisions += CMDSTS_COLLISIONS(cmdsts);
                   1684:                }
                   1685:        }
                   1686:
                   1687:        /*
                   1688:         * If there are no more pending transmissions, cancel the watchdog
                   1689:         * timer.
                   1690:         */
1.56      thorpej  1691:        if (txs == NULL) {
1.1       thorpej  1692:                ifp->if_timer = 0;
1.56      thorpej  1693:                sc->sc_txwin = 0;
                   1694:        }
1.1       thorpej  1695: }
                   1696:
1.35      thorpej  1697: #if defined(DP83820)
1.1       thorpej  1698: /*
                   1699:  * sip_rxintr:
                   1700:  *
                   1701:  *     Helper; handle receive interrupts.
                   1702:  */
                   1703: void
1.28      thorpej  1704: SIP_DECL(rxintr)(struct sip_softc *sc)
1.1       thorpej  1705: {
                   1706:        struct ifnet *ifp = &sc->sc_ethercom.ec_if;
                   1707:        struct sip_rxsoft *rxs;
1.36      thorpej  1708:        struct mbuf *m, *tailm;
1.35      thorpej  1709:        u_int32_t cmdsts, extsts;
1.1       thorpej  1710:        int i, len;
                   1711:
                   1712:        for (i = sc->sc_rxptr;; i = SIP_NEXTRX(i)) {
                   1713:                rxs = &sc->sc_rxsoft[i];
                   1714:
                   1715:                SIP_CDRXSYNC(sc, i, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
                   1716:
1.14      tsutsui  1717:                cmdsts = le32toh(sc->sc_rxdescs[i].sipd_cmdsts);
1.29      thorpej  1718:                extsts = le32toh(sc->sc_rxdescs[i].sipd_extsts);
1.1       thorpej  1719:
                   1720:                /*
                   1721:                 * NOTE: OWN is set if owned by _consumer_.  We're the
                   1722:                 * consumer of the receive ring, so if the bit is clear,
                   1723:                 * we have processed all of the packets.
                   1724:                 */
                   1725:                if ((cmdsts & CMDSTS_OWN) == 0) {
                   1726:                        /*
                   1727:                         * We have processed all of the receive buffers.
                   1728:                         */
                   1729:                        break;
                   1730:                }
                   1731:
1.36      thorpej  1732:                if (__predict_false(sc->sc_rxdiscard)) {
                   1733:                        SIP_INIT_RXDESC(sc, i);
                   1734:                        if ((cmdsts & CMDSTS_MORE) == 0) {
                   1735:                                /* Reset our state. */
                   1736:                                sc->sc_rxdiscard = 0;
                   1737:                        }
                   1738:                        continue;
                   1739:                }
                   1740:
                   1741:                bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0,
                   1742:                    rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
                   1743:
                   1744:                m = rxs->rxs_mbuf;
                   1745:
                   1746:                /*
                   1747:                 * Add a new receive buffer to the ring.
                   1748:                 */
                   1749:                if (SIP_DECL(add_rxbuf)(sc, i) != 0) {
                   1750:                        /*
                   1751:                         * Failed, throw away what we've done so
                   1752:                         * far, and discard the rest of the packet.
                   1753:                         */
                   1754:                        ifp->if_ierrors++;
                   1755:                        bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0,
                   1756:                            rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
                   1757:                        SIP_INIT_RXDESC(sc, i);
                   1758:                        if (cmdsts & CMDSTS_MORE)
                   1759:                                sc->sc_rxdiscard = 1;
                   1760:                        if (sc->sc_rxhead != NULL)
                   1761:                                m_freem(sc->sc_rxhead);
                   1762:                        SIP_RXCHAIN_RESET(sc);
                   1763:                        continue;
                   1764:                }
                   1765:
                   1766:                SIP_RXCHAIN_LINK(sc, m);
                   1767:
                   1768:                /*
                   1769:                 * If this is not the end of the packet, keep
                   1770:                 * looking.
                   1771:                 */
                   1772:                if (cmdsts & CMDSTS_MORE) {
                   1773:                        sc->sc_rxlen += m->m_len;
                   1774:                        continue;
                   1775:                }
                   1776:
1.1       thorpej  1777:                /*
1.36      thorpej  1778:                 * Okay, we have the entire packet now...
                   1779:                 */
                   1780:                *sc->sc_rxtailp = NULL;
                   1781:                m = sc->sc_rxhead;
                   1782:                tailm = sc->sc_rxtail;
                   1783:
                   1784:                SIP_RXCHAIN_RESET(sc);
                   1785:
                   1786:                /*
                   1787:                 * If an error occurred, update stats and drop the packet.
1.1       thorpej  1788:                 */
1.36      thorpej  1789:                if (cmdsts & (CMDSTS_Rx_RXA|CMDSTS_Rx_RUNT|
1.1       thorpej  1790:                    CMDSTS_Rx_ISE|CMDSTS_Rx_CRCE|CMDSTS_Rx_FAE)) {
                   1791:                        ifp->if_ierrors++;
                   1792:                        if ((cmdsts & CMDSTS_Rx_RXA) != 0 &&
                   1793:                            (cmdsts & CMDSTS_Rx_RXO) == 0) {
                   1794:                                /* Receive overrun handled elsewhere. */
                   1795:                                printf("%s: receive descriptor error\n",
                   1796:                                    sc->sc_dev.dv_xname);
                   1797:                        }
                   1798: #define        PRINTERR(bit, str)                                              \
1.67      itojun   1799:                        if ((ifp->if_flags & IFF_DEBUG) != 0 &&         \
                   1800:                            (cmdsts & (bit)) != 0)                      \
1.1       thorpej  1801:                                printf("%s: %s\n", sc->sc_dev.dv_xname, str)
                   1802:                        PRINTERR(CMDSTS_Rx_RUNT, "runt packet");
                   1803:                        PRINTERR(CMDSTS_Rx_ISE, "invalid symbol error");
                   1804:                        PRINTERR(CMDSTS_Rx_CRCE, "CRC error");
                   1805:                        PRINTERR(CMDSTS_Rx_FAE, "frame alignment error");
                   1806: #undef PRINTERR
1.36      thorpej  1807:                        m_freem(m);
1.1       thorpej  1808:                        continue;
                   1809:                }
                   1810:
                   1811:                /*
1.40      thorpej  1812:                 * No errors.
1.36      thorpej  1813:                 *
                   1814:                 * Note, the DP83820 includes the CRC with
                   1815:                 * every packet.
1.1       thorpej  1816:                 */
1.18      thorpej  1817:                len = CMDSTS_SIZE(cmdsts);
1.36      thorpej  1818:                tailm->m_len = len - sc->sc_rxlen;
1.1       thorpej  1819:
                   1820:                /*
1.2       thorpej  1821:                 * If the packet is small enough to fit in a
                   1822:                 * single header mbuf, allocate one and copy
                   1823:                 * the data into it.  This greatly reduces
                   1824:                 * memory consumption when we receive lots
                   1825:                 * of small packets.
1.1       thorpej  1826:                 */
1.36      thorpej  1827:                if (SIP_DECL(copy_small) != 0 && len <= (MHLEN - 2)) {
                   1828:                        struct mbuf *nm;
                   1829:                        MGETHDR(nm, M_DONTWAIT, MT_DATA);
                   1830:                        if (nm == NULL) {
1.2       thorpej  1831:                                ifp->if_ierrors++;
1.36      thorpej  1832:                                m_freem(m);
1.2       thorpej  1833:                                continue;
                   1834:                        }
1.36      thorpej  1835:                        nm->m_data += 2;
                   1836:                        nm->m_pkthdr.len = nm->m_len = len;
                   1837:                        m_copydata(m, 0, len, mtod(nm, caddr_t));
                   1838:                        m_freem(m);
                   1839:                        m = nm;
1.1       thorpej  1840:                }
1.36      thorpej  1841: #ifndef __NO_STRICT_ALIGNMENT
                   1842:                else {
                   1843:                        /*
                   1844:                         * The DP83820's receive buffers must be 4-byte
                   1845:                         * aligned.  But this means that the data after
                   1846:                         * the Ethernet header is misaligned.  To compensate,
                   1847:                         * we have artificially shortened the buffer size
                   1848:                         * in the descriptor, and we do an overlapping copy
                   1849:                         * of the data two bytes further in (in the first
                   1850:                         * buffer of the chain only).
                   1851:                         */
                   1852:                        memmove(mtod(m, caddr_t) + 2, mtod(m, caddr_t),
                   1853:                            m->m_len);
                   1854:                        m->m_data += 2;
1.1       thorpej  1855:                }
1.36      thorpej  1856: #endif /* ! __NO_STRICT_ALIGNMENT */
1.1       thorpej  1857:
1.29      thorpej  1858:                /*
                   1859:                 * If VLANs are enabled, VLAN packets have been unwrapped
                   1860:                 * for us.  Associate the tag with the packet.
                   1861:                 */
                   1862:                if (sc->sc_ethercom.ec_nvlans != 0 &&
                   1863:                    (extsts & EXTSTS_VPKT) != 0) {
                   1864:                        struct mbuf *vtag;
                   1865:
                   1866:                        vtag = m_aux_add(m, AF_LINK, ETHERTYPE_VLAN);
                   1867:                        if (vtag == NULL) {
1.40      thorpej  1868:                                ifp->if_ierrors++;
1.29      thorpej  1869:                                printf("%s: unable to allocate VLAN tag\n",
                   1870:                                    sc->sc_dev.dv_xname);
                   1871:                                m_freem(m);
                   1872:                                continue;
                   1873:                        }
                   1874:
                   1875:                        *mtod(vtag, int *) = ntohs(extsts & EXTSTS_VTCI);
                   1876:                        vtag->m_len = sizeof(int);
                   1877:                }
1.31      thorpej  1878:
                   1879:                /*
                   1880:                 * Set the incoming checksum information for the
                   1881:                 * packet.
                   1882:                 */
                   1883:                if ((extsts & EXTSTS_IPPKT) != 0) {
                   1884:                        SIP_EVCNT_INCR(&sc->sc_ev_rxipsum);
                   1885:                        m->m_pkthdr.csum_flags |= M_CSUM_IPv4;
                   1886:                        if (extsts & EXTSTS_Rx_IPERR)
                   1887:                                m->m_pkthdr.csum_flags |= M_CSUM_IPv4_BAD;
                   1888:                        if (extsts & EXTSTS_TCPPKT) {
                   1889:                                SIP_EVCNT_INCR(&sc->sc_ev_rxtcpsum);
                   1890:                                m->m_pkthdr.csum_flags |= M_CSUM_TCPv4;
                   1891:                                if (extsts & EXTSTS_Rx_TCPERR)
                   1892:                                        m->m_pkthdr.csum_flags |=
                   1893:                                            M_CSUM_TCP_UDP_BAD;
                   1894:                        } else if (extsts & EXTSTS_UDPPKT) {
                   1895:                                SIP_EVCNT_INCR(&sc->sc_ev_rxudpsum);
                   1896:                                m->m_pkthdr.csum_flags |= M_CSUM_UDPv4;
                   1897:                                if (extsts & EXTSTS_Rx_UDPERR)
                   1898:                                        m->m_pkthdr.csum_flags |=
                   1899:                                            M_CSUM_TCP_UDP_BAD;
                   1900:                        }
                   1901:                }
1.40      thorpej  1902:
                   1903:                ifp->if_ipackets++;
                   1904:                m->m_flags |= M_HASFCS;
                   1905:                m->m_pkthdr.rcvif = ifp;
                   1906:                m->m_pkthdr.len = len;
                   1907:
                   1908: #if NBPFILTER > 0
                   1909:                /*
                   1910:                 * Pass this up to any BPF listeners, but only
                   1911:                 * pass if up the stack if it's for us.
                   1912:                 */
                   1913:                if (ifp->if_bpf)
                   1914:                        bpf_mtap(ifp->if_bpf, m);
                   1915: #endif /* NBPFILTER > 0 */
1.29      thorpej  1916:
1.1       thorpej  1917:                /* Pass it on. */
                   1918:                (*ifp->if_input)(ifp, m);
                   1919:        }
                   1920:
                   1921:        /* Update the receive pointer. */
                   1922:        sc->sc_rxptr = i;
                   1923: }
1.35      thorpej  1924: #else /* ! DP83820 */
                   1925: /*
                   1926:  * sip_rxintr:
                   1927:  *
                   1928:  *     Helper; handle receive interrupts.
                   1929:  */
                   1930: void
                   1931: SIP_DECL(rxintr)(struct sip_softc *sc)
                   1932: {
                   1933:        struct ifnet *ifp = &sc->sc_ethercom.ec_if;
                   1934:        struct sip_rxsoft *rxs;
                   1935:        struct mbuf *m;
                   1936:        u_int32_t cmdsts;
                   1937:        int i, len;
                   1938:
                   1939:        for (i = sc->sc_rxptr;; i = SIP_NEXTRX(i)) {
                   1940:                rxs = &sc->sc_rxsoft[i];
                   1941:
                   1942:                SIP_CDRXSYNC(sc, i, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
                   1943:
                   1944:                cmdsts = le32toh(sc->sc_rxdescs[i].sipd_cmdsts);
                   1945:
                   1946:                /*
                   1947:                 * NOTE: OWN is set if owned by _consumer_.  We're the
                   1948:                 * consumer of the receive ring, so if the bit is clear,
                   1949:                 * we have processed all of the packets.
                   1950:                 */
                   1951:                if ((cmdsts & CMDSTS_OWN) == 0) {
                   1952:                        /*
                   1953:                         * We have processed all of the receive buffers.
                   1954:                         */
                   1955:                        break;
                   1956:                }
                   1957:
                   1958:                /*
                   1959:                 * If any collisions were seen on the wire, count one.
                   1960:                 */
                   1961:                if (cmdsts & CMDSTS_Rx_COL)
                   1962:                        ifp->if_collisions++;
                   1963:
                   1964:                /*
                   1965:                 * If an error occurred, update stats, clear the status
                   1966:                 * word, and leave the packet buffer in place.  It will
                   1967:                 * simply be reused the next time the ring comes around.
                   1968:                 */
1.36      thorpej  1969:                if (cmdsts & (CMDSTS_Rx_RXA|CMDSTS_Rx_RUNT|
1.35      thorpej  1970:                    CMDSTS_Rx_ISE|CMDSTS_Rx_CRCE|CMDSTS_Rx_FAE)) {
                   1971:                        ifp->if_ierrors++;
                   1972:                        if ((cmdsts & CMDSTS_Rx_RXA) != 0 &&
                   1973:                            (cmdsts & CMDSTS_Rx_RXO) == 0) {
                   1974:                                /* Receive overrun handled elsewhere. */
                   1975:                                printf("%s: receive descriptor error\n",
                   1976:                                    sc->sc_dev.dv_xname);
                   1977:                        }
                   1978: #define        PRINTERR(bit, str)                                              \
1.67      itojun   1979:                        if ((ifp->if_flags & IFF_DEBUG) != 0 &&         \
                   1980:                            (cmdsts & (bit)) != 0)                      \
1.35      thorpej  1981:                                printf("%s: %s\n", sc->sc_dev.dv_xname, str)
                   1982:                        PRINTERR(CMDSTS_Rx_RUNT, "runt packet");
                   1983:                        PRINTERR(CMDSTS_Rx_ISE, "invalid symbol error");
                   1984:                        PRINTERR(CMDSTS_Rx_CRCE, "CRC error");
                   1985:                        PRINTERR(CMDSTS_Rx_FAE, "frame alignment error");
                   1986: #undef PRINTERR
                   1987:                        SIP_INIT_RXDESC(sc, i);
                   1988:                        continue;
                   1989:                }
                   1990:
                   1991:                bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0,
                   1992:                    rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
                   1993:
                   1994:                /*
                   1995:                 * No errors; receive the packet.  Note, the SiS 900
                   1996:                 * includes the CRC with every packet.
                   1997:                 */
                   1998:                len = CMDSTS_SIZE(cmdsts);
                   1999:
                   2000: #ifdef __NO_STRICT_ALIGNMENT
                   2001:                /*
                   2002:                 * If the packet is small enough to fit in a
                   2003:                 * single header mbuf, allocate one and copy
                   2004:                 * the data into it.  This greatly reduces
                   2005:                 * memory consumption when we receive lots
                   2006:                 * of small packets.
                   2007:                 *
                   2008:                 * Otherwise, we add a new buffer to the receive
                   2009:                 * chain.  If this fails, we drop the packet and
                   2010:                 * recycle the old buffer.
                   2011:                 */
                   2012:                if (SIP_DECL(copy_small) != 0 && len <= MHLEN) {
                   2013:                        MGETHDR(m, M_DONTWAIT, MT_DATA);
                   2014:                        if (m == NULL)
                   2015:                                goto dropit;
                   2016:                        memcpy(mtod(m, caddr_t),
                   2017:                            mtod(rxs->rxs_mbuf, caddr_t), len);
                   2018:                        SIP_INIT_RXDESC(sc, i);
                   2019:                        bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0,
                   2020:                            rxs->rxs_dmamap->dm_mapsize,
                   2021:                            BUS_DMASYNC_PREREAD);
                   2022:                } else {
                   2023:                        m = rxs->rxs_mbuf;
                   2024:                        if (SIP_DECL(add_rxbuf)(sc, i) != 0) {
                   2025:  dropit:
                   2026:                                ifp->if_ierrors++;
                   2027:                                SIP_INIT_RXDESC(sc, i);
                   2028:                                bus_dmamap_sync(sc->sc_dmat,
                   2029:                                    rxs->rxs_dmamap, 0,
                   2030:                                    rxs->rxs_dmamap->dm_mapsize,
                   2031:                                    BUS_DMASYNC_PREREAD);
                   2032:                                continue;
                   2033:                        }
                   2034:                }
                   2035: #else
                   2036:                /*
                   2037:                 * The SiS 900's receive buffers must be 4-byte aligned.
                   2038:                 * But this means that the data after the Ethernet header
                   2039:                 * is misaligned.  We must allocate a new buffer and
                   2040:                 * copy the data, shifted forward 2 bytes.
                   2041:                 */
                   2042:                MGETHDR(m, M_DONTWAIT, MT_DATA);
                   2043:                if (m == NULL) {
                   2044:  dropit:
                   2045:                        ifp->if_ierrors++;
                   2046:                        SIP_INIT_RXDESC(sc, i);
                   2047:                        bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0,
                   2048:                            rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
                   2049:                        continue;
                   2050:                }
                   2051:                if (len > (MHLEN - 2)) {
                   2052:                        MCLGET(m, M_DONTWAIT);
                   2053:                        if ((m->m_flags & M_EXT) == 0) {
                   2054:                                m_freem(m);
                   2055:                                goto dropit;
                   2056:                        }
                   2057:                }
                   2058:                m->m_data += 2;
                   2059:
                   2060:                /*
                   2061:                 * Note that we use clusters for incoming frames, so the
                   2062:                 * buffer is virtually contiguous.
                   2063:                 */
                   2064:                memcpy(mtod(m, caddr_t), mtod(rxs->rxs_mbuf, caddr_t), len);
                   2065:
                   2066:                /* Allow the receive descriptor to continue using its mbuf. */
                   2067:                SIP_INIT_RXDESC(sc, i);
                   2068:                bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0,
                   2069:                    rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
                   2070: #endif /* __NO_STRICT_ALIGNMENT */
                   2071:
                   2072:                ifp->if_ipackets++;
                   2073:                m->m_flags |= M_HASFCS;
                   2074:                m->m_pkthdr.rcvif = ifp;
                   2075:                m->m_pkthdr.len = m->m_len = len;
                   2076:
                   2077: #if NBPFILTER > 0
                   2078:                /*
                   2079:                 * Pass this up to any BPF listeners, but only
                   2080:                 * pass if up the stack if it's for us.
                   2081:                 */
                   2082:                if (ifp->if_bpf)
                   2083:                        bpf_mtap(ifp->if_bpf, m);
                   2084: #endif /* NBPFILTER > 0 */
                   2085:
                   2086:                /* Pass it on. */
                   2087:                (*ifp->if_input)(ifp, m);
                   2088:        }
                   2089:
                   2090:        /* Update the receive pointer. */
                   2091:        sc->sc_rxptr = i;
                   2092: }
                   2093: #endif /* DP83820 */
1.1       thorpej  2094:
                   2095: /*
                   2096:  * sip_tick:
                   2097:  *
                   2098:  *     One second timer, used to tick the MII.
                   2099:  */
                   2100: void
1.28      thorpej  2101: SIP_DECL(tick)(void *arg)
1.1       thorpej  2102: {
                   2103:        struct sip_softc *sc = arg;
                   2104:        int s;
                   2105:
                   2106:        s = splnet();
                   2107:        mii_tick(&sc->sc_mii);
                   2108:        splx(s);
                   2109:
1.29      thorpej  2110:        callout_reset(&sc->sc_tick_ch, hz, SIP_DECL(tick), sc);
1.1       thorpej  2111: }
                   2112:
                   2113: /*
                   2114:  * sip_reset:
                   2115:  *
                   2116:  *     Perform a soft reset on the SiS 900.
                   2117:  */
                   2118: void
1.28      thorpej  2119: SIP_DECL(reset)(struct sip_softc *sc)
1.1       thorpej  2120: {
                   2121:        bus_space_tag_t st = sc->sc_st;
                   2122:        bus_space_handle_t sh = sc->sc_sh;
                   2123:        int i;
                   2124:
1.45      thorpej  2125:        bus_space_write_4(st, sh, SIP_IER, 0);
                   2126:        bus_space_write_4(st, sh, SIP_IMR, 0);
                   2127:        bus_space_write_4(st, sh, SIP_RFCR, 0);
1.1       thorpej  2128:        bus_space_write_4(st, sh, SIP_CR, CR_RST);
                   2129:
1.14      tsutsui  2130:        for (i = 0; i < SIP_TIMEOUT; i++) {
                   2131:                if ((bus_space_read_4(st, sh, SIP_CR) & CR_RST) == 0)
                   2132:                        break;
1.1       thorpej  2133:                delay(2);
                   2134:        }
                   2135:
1.14      tsutsui  2136:        if (i == SIP_TIMEOUT)
                   2137:                printf("%s: reset failed to complete\n", sc->sc_dev.dv_xname);
                   2138:
                   2139:        delay(1000);
1.29      thorpej  2140:
                   2141: #ifdef DP83820
                   2142:        /*
                   2143:         * Set the general purpose I/O bits.  Do it here in case we
                   2144:         * need to have GPIO set up to talk to the media interface.
                   2145:         */
                   2146:        bus_space_write_4(st, sh, SIP_GPIOR, sc->sc_gpior);
                   2147:        delay(1000);
                   2148: #endif /* DP83820 */
1.1       thorpej  2149: }
                   2150:
                   2151: /*
1.17      thorpej  2152:  * sip_init:           [ ifnet interface function ]
1.1       thorpej  2153:  *
                   2154:  *     Initialize the interface.  Must be called at splnet().
                   2155:  */
1.2       thorpej  2156: int
1.28      thorpej  2157: SIP_DECL(init)(struct ifnet *ifp)
1.1       thorpej  2158: {
1.17      thorpej  2159:        struct sip_softc *sc = ifp->if_softc;
1.1       thorpej  2160:        bus_space_tag_t st = sc->sc_st;
                   2161:        bus_space_handle_t sh = sc->sc_sh;
                   2162:        struct sip_txsoft *txs;
1.2       thorpej  2163:        struct sip_rxsoft *rxs;
1.1       thorpej  2164:        struct sip_desc *sipd;
1.29      thorpej  2165:        u_int32_t reg;
1.2       thorpej  2166:        int i, error = 0;
1.1       thorpej  2167:
                   2168:        /*
                   2169:         * Cancel any pending I/O.
                   2170:         */
1.28      thorpej  2171:        SIP_DECL(stop)(ifp, 0);
1.1       thorpej  2172:
                   2173:        /*
                   2174:         * Reset the chip to a known state.
                   2175:         */
1.28      thorpej  2176:        SIP_DECL(reset)(sc);
1.1       thorpej  2177:
1.29      thorpej  2178: #if !defined(DP83820)
1.45      thorpej  2179:        if (SIP_CHIP_MODEL(sc, PCI_VENDOR_NS, PCI_PRODUCT_NS_DP83815)) {
1.25      briggs   2180:                /*
                   2181:                 * DP83815 manual, page 78:
                   2182:                 *    4.4 Recommended Registers Configuration
                   2183:                 *    For optimum performance of the DP83815, version noted
                   2184:                 *    as DP83815CVNG (SRR = 203h), the listed register
                   2185:                 *    modifications must be followed in sequence...
                   2186:                 *
                   2187:                 * It's not clear if this should be 302h or 203h because that
                   2188:                 * chip name is listed as SRR 302h in the description of the
1.26      briggs   2189:                 * SRR register.  However, my revision 302h DP83815 on the
                   2190:                 * Netgear FA311 purchased in 02/2001 needs these settings
                   2191:                 * to avoid tons of errors in AcceptPerfectMatch (non-
                   2192:                 * IFF_PROMISC) mode.  I do not know if other revisions need
                   2193:                 * this set or not.  [briggs -- 09 March 2001]
                   2194:                 *
                   2195:                 * Note that only the low-order 12 bits of 0xe4 are documented
                   2196:                 * and that this sets reserved bits in that register.
1.25      briggs   2197:                 */
1.29      thorpej  2198:                reg = bus_space_read_4(st, sh, SIP_NS_SRR);
                   2199:                if (reg == 0x302) {
1.25      briggs   2200:                        bus_space_write_4(st, sh, 0x00cc, 0x0001);
                   2201:                        bus_space_write_4(st, sh, 0x00e4, 0x189C);
                   2202:                        bus_space_write_4(st, sh, 0x00fc, 0x0000);
                   2203:                        bus_space_write_4(st, sh, 0x00f4, 0x5040);
                   2204:                        bus_space_write_4(st, sh, 0x00f8, 0x008c);
                   2205:                }
                   2206:        }
1.29      thorpej  2207: #endif /* ! DP83820 */
1.25      briggs   2208:
1.1       thorpej  2209:        /*
                   2210:         * Initialize the transmit descriptor ring.
                   2211:         */
                   2212:        for (i = 0; i < SIP_NTXDESC; i++) {
                   2213:                sipd = &sc->sc_txdescs[i];
                   2214:                memset(sipd, 0, sizeof(struct sip_desc));
1.14      tsutsui  2215:                sipd->sipd_link = htole32(SIP_CDTXADDR(sc, SIP_NEXTTX(i)));
1.1       thorpej  2216:        }
                   2217:        SIP_CDTXSYNC(sc, 0, SIP_NTXDESC,
                   2218:            BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
                   2219:        sc->sc_txfree = SIP_NTXDESC;
                   2220:        sc->sc_txnext = 0;
1.56      thorpej  2221:        sc->sc_txwin = 0;
1.1       thorpej  2222:
                   2223:        /*
                   2224:         * Initialize the transmit job descriptors.
                   2225:         */
                   2226:        SIMPLEQ_INIT(&sc->sc_txfreeq);
                   2227:        SIMPLEQ_INIT(&sc->sc_txdirtyq);
                   2228:        for (i = 0; i < SIP_TXQUEUELEN; i++) {
                   2229:                txs = &sc->sc_txsoft[i];
                   2230:                txs->txs_mbuf = NULL;
                   2231:                SIMPLEQ_INSERT_TAIL(&sc->sc_txfreeq, txs, txs_q);
                   2232:        }
                   2233:
                   2234:        /*
                   2235:         * Initialize the receive descriptor and receive job
1.2       thorpej  2236:         * descriptor rings.
1.1       thorpej  2237:         */
1.2       thorpej  2238:        for (i = 0; i < SIP_NRXDESC; i++) {
                   2239:                rxs = &sc->sc_rxsoft[i];
                   2240:                if (rxs->rxs_mbuf == NULL) {
1.28      thorpej  2241:                        if ((error = SIP_DECL(add_rxbuf)(sc, i)) != 0) {
1.2       thorpej  2242:                                printf("%s: unable to allocate or map rx "
                   2243:                                    "buffer %d, error = %d\n",
                   2244:                                    sc->sc_dev.dv_xname, i, error);
                   2245:                                /*
                   2246:                                 * XXX Should attempt to run with fewer receive
                   2247:                                 * XXX buffers instead of just failing.
                   2248:                                 */
1.28      thorpej  2249:                                SIP_DECL(rxdrain)(sc);
1.2       thorpej  2250:                                goto out;
                   2251:                        }
1.42      thorpej  2252:                } else
                   2253:                        SIP_INIT_RXDESC(sc, i);
1.2       thorpej  2254:        }
1.1       thorpej  2255:        sc->sc_rxptr = 0;
1.36      thorpej  2256: #ifdef DP83820
                   2257:        sc->sc_rxdiscard = 0;
                   2258:        SIP_RXCHAIN_RESET(sc);
                   2259: #endif /* DP83820 */
1.1       thorpej  2260:
                   2261:        /*
1.29      thorpej  2262:         * Set the configuration register; it's already initialized
                   2263:         * in sip_attach().
1.1       thorpej  2264:         */
1.29      thorpej  2265:        bus_space_write_4(st, sh, SIP_CFG, sc->sc_cfg);
1.1       thorpej  2266:
                   2267:        /*
                   2268:         * Initialize the prototype TXCFG register.
                   2269:         */
1.45      thorpej  2270: #if defined(DP83820)
                   2271:        sc->sc_txcfg = TXCFG_MXDMA_512;
                   2272:        sc->sc_rxcfg = RXCFG_MXDMA_512;
                   2273: #else
                   2274:        if ((SIP_SIS900_REV(sc, SIS_REV_635) ||
                   2275:             SIP_SIS900_REV(sc, SIS_REV_900B)) &&
                   2276:            (bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_CFG) & CFG_EDBMASTEN)) {
                   2277:                sc->sc_txcfg = TXCFG_MXDMA_64;
                   2278:                sc->sc_rxcfg = RXCFG_MXDMA_64;
                   2279:        } else {
                   2280:                sc->sc_txcfg = TXCFG_MXDMA_512;
                   2281:                sc->sc_rxcfg = RXCFG_MXDMA_512;
                   2282:        }
                   2283: #endif /* DP83820 */
                   2284:
                   2285:        sc->sc_txcfg |= TXCFG_ATP |
1.1       thorpej  2286:            (sc->sc_tx_fill_thresh << TXCFG_FLTH_SHIFT) |
                   2287:            sc->sc_tx_drain_thresh;
                   2288:        bus_space_write_4(st, sh, SIP_TXCFG, sc->sc_txcfg);
                   2289:
                   2290:        /*
                   2291:         * Initialize the receive drain threshold if we have never
                   2292:         * done so.
                   2293:         */
                   2294:        if (sc->sc_rx_drain_thresh == 0) {
                   2295:                /*
                   2296:                 * XXX This value should be tuned.  This is set to the
                   2297:                 * maximum of 248 bytes, and we may be able to improve
                   2298:                 * performance by decreasing it (although we should never
                   2299:                 * set this value lower than 2; 14 bytes are required to
                   2300:                 * filter the packet).
                   2301:                 */
                   2302:                sc->sc_rx_drain_thresh = RXCFG_DRTH >> RXCFG_DRTH_SHIFT;
                   2303:        }
                   2304:
                   2305:        /*
                   2306:         * Initialize the prototype RXCFG register.
                   2307:         */
1.45      thorpej  2308:        sc->sc_rxcfg |= (sc->sc_rx_drain_thresh << RXCFG_DRTH_SHIFT);
1.1       thorpej  2309:        bus_space_write_4(st, sh, SIP_RXCFG, sc->sc_rxcfg);
                   2310:
1.29      thorpej  2311: #ifdef DP83820
                   2312:        /*
                   2313:         * Initialize the VLAN/IP receive control register.
1.31      thorpej  2314:         * We enable checksum computation on all incoming
                   2315:         * packets, and do not reject packets w/ bad checksums.
1.29      thorpej  2316:         */
                   2317:        reg = 0;
1.31      thorpej  2318:        if (ifp->if_capenable &
                   2319:            (IFCAP_CSUM_IPv4|IFCAP_CSUM_TCPv4|IFCAP_CSUM_UDPv4))
                   2320:                reg |= VRCR_IPEN;
1.29      thorpej  2321:        if (sc->sc_ethercom.ec_nvlans != 0)
                   2322:                reg |= VRCR_VTDEN|VRCR_VTREN;
                   2323:        bus_space_write_4(st, sh, SIP_VRCR, reg);
                   2324:
                   2325:        /*
                   2326:         * Initialize the VLAN/IP transmit control register.
1.31      thorpej  2327:         * We enable outgoing checksum computation on a
                   2328:         * per-packet basis.
1.29      thorpej  2329:         */
                   2330:        reg = 0;
1.31      thorpej  2331:        if (ifp->if_capenable &
                   2332:            (IFCAP_CSUM_IPv4|IFCAP_CSUM_TCPv4|IFCAP_CSUM_UDPv4))
                   2333:                reg |= VTCR_PPCHK;
1.29      thorpej  2334:        if (sc->sc_ethercom.ec_nvlans != 0)
                   2335:                reg |= VTCR_VPPTI;
                   2336:        bus_space_write_4(st, sh, SIP_VTCR, reg);
                   2337:
                   2338:        /*
                   2339:         * If we're using VLANs, initialize the VLAN data register.
                   2340:         * To understand why we bswap the VLAN Ethertype, see section
                   2341:         * 4.2.36 of the DP83820 manual.
                   2342:         */
                   2343:        if (sc->sc_ethercom.ec_nvlans != 0)
                   2344:                bus_space_write_4(st, sh, SIP_VDR, bswap16(ETHERTYPE_VLAN));
                   2345: #endif /* DP83820 */
                   2346:
1.1       thorpej  2347:        /*
                   2348:         * Give the transmit and receive rings to the chip.
                   2349:         */
                   2350:        bus_space_write_4(st, sh, SIP_TXDP, SIP_CDTXADDR(sc, sc->sc_txnext));
                   2351:        bus_space_write_4(st, sh, SIP_RXDP, SIP_CDRXADDR(sc, sc->sc_rxptr));
                   2352:
                   2353:        /*
                   2354:         * Initialize the interrupt mask.
                   2355:         */
                   2356:        sc->sc_imr = ISR_DPERR|ISR_SSERR|ISR_RMABT|ISR_RTABT|ISR_RXSOVR|
1.56      thorpej  2357:            ISR_TXURN|ISR_TXDESC|ISR_TXIDLE|ISR_RXORN|ISR_RXIDLE|ISR_RXDESC;
1.1       thorpej  2358:        bus_space_write_4(st, sh, SIP_IMR, sc->sc_imr);
                   2359:
1.45      thorpej  2360:        /* Set up the receive filter. */
                   2361:        (*sc->sc_model->sip_variant->sipv_set_filter)(sc);
                   2362:
1.1       thorpej  2363:        /*
                   2364:         * Set the current media.  Do this after initializing the prototype
                   2365:         * IMR, since sip_mii_statchg() modifies the IMR for 802.3x flow
                   2366:         * control.
                   2367:         */
                   2368:        mii_mediachg(&sc->sc_mii);
                   2369:
                   2370:        /*
                   2371:         * Enable interrupts.
                   2372:         */
                   2373:        bus_space_write_4(st, sh, SIP_IER, IER_IE);
                   2374:
                   2375:        /*
                   2376:         * Start the transmit and receive processes.
                   2377:         */
                   2378:        bus_space_write_4(st, sh, SIP_CR, CR_RXE | CR_TXE);
                   2379:
                   2380:        /*
                   2381:         * Start the one second MII clock.
                   2382:         */
1.29      thorpej  2383:        callout_reset(&sc->sc_tick_ch, hz, SIP_DECL(tick), sc);
1.1       thorpej  2384:
                   2385:        /*
                   2386:         * ...all done!
                   2387:         */
                   2388:        ifp->if_flags |= IFF_RUNNING;
                   2389:        ifp->if_flags &= ~IFF_OACTIVE;
1.2       thorpej  2390:
                   2391:  out:
                   2392:        if (error)
                   2393:                printf("%s: interface not running\n", sc->sc_dev.dv_xname);
                   2394:        return (error);
                   2395: }
                   2396:
                   2397: /*
                   2398:  * sip_drain:
                   2399:  *
                   2400:  *     Drain the receive queue.
                   2401:  */
                   2402: void
1.28      thorpej  2403: SIP_DECL(rxdrain)(struct sip_softc *sc)
1.2       thorpej  2404: {
                   2405:        struct sip_rxsoft *rxs;
                   2406:        int i;
                   2407:
                   2408:        for (i = 0; i < SIP_NRXDESC; i++) {
                   2409:                rxs = &sc->sc_rxsoft[i];
                   2410:                if (rxs->rxs_mbuf != NULL) {
                   2411:                        bus_dmamap_unload(sc->sc_dmat, rxs->rxs_dmamap);
                   2412:                        m_freem(rxs->rxs_mbuf);
                   2413:                        rxs->rxs_mbuf = NULL;
                   2414:                }
                   2415:        }
1.1       thorpej  2416: }
                   2417:
                   2418: /*
1.17      thorpej  2419:  * sip_stop:           [ ifnet interface function ]
1.1       thorpej  2420:  *
                   2421:  *     Stop transmission on the interface.
                   2422:  */
                   2423: void
1.28      thorpej  2424: SIP_DECL(stop)(struct ifnet *ifp, int disable)
1.1       thorpej  2425: {
1.17      thorpej  2426:        struct sip_softc *sc = ifp->if_softc;
1.1       thorpej  2427:        bus_space_tag_t st = sc->sc_st;
                   2428:        bus_space_handle_t sh = sc->sc_sh;
                   2429:        struct sip_txsoft *txs;
                   2430:        u_int32_t cmdsts = 0;           /* DEBUG */
                   2431:
                   2432:        /*
                   2433:         * Stop the one second clock.
                   2434:         */
1.9       thorpej  2435:        callout_stop(&sc->sc_tick_ch);
1.4       thorpej  2436:
                   2437:        /* Down the MII. */
                   2438:        mii_down(&sc->sc_mii);
1.1       thorpej  2439:
                   2440:        /*
                   2441:         * Disable interrupts.
                   2442:         */
                   2443:        bus_space_write_4(st, sh, SIP_IER, 0);
                   2444:
                   2445:        /*
                   2446:         * Stop receiver and transmitter.
                   2447:         */
                   2448:        bus_space_write_4(st, sh, SIP_CR, CR_RXD | CR_TXD);
                   2449:
                   2450:        /*
                   2451:         * Release any queued transmit buffers.
                   2452:         */
                   2453:        while ((txs = SIMPLEQ_FIRST(&sc->sc_txdirtyq)) != NULL) {
                   2454:                if ((ifp->if_flags & IFF_DEBUG) != 0 &&
                   2455:                    SIMPLEQ_NEXT(txs, txs_q) == NULL &&
1.14      tsutsui  2456:                    (le32toh(sc->sc_txdescs[txs->txs_lastdesc].sipd_cmdsts) &
1.1       thorpej  2457:                     CMDSTS_INTR) == 0)
                   2458:                        printf("%s: sip_stop: last descriptor does not "
                   2459:                            "have INTR bit set\n", sc->sc_dev.dv_xname);
1.54      lukem    2460:                SIMPLEQ_REMOVE_HEAD(&sc->sc_txdirtyq, txs_q);
1.1       thorpej  2461: #ifdef DIAGNOSTIC
                   2462:                if (txs->txs_mbuf == NULL) {
                   2463:                        printf("%s: dirty txsoft with no mbuf chain\n",
                   2464:                            sc->sc_dev.dv_xname);
                   2465:                        panic("sip_stop");
                   2466:                }
                   2467: #endif
                   2468:                cmdsts |=               /* DEBUG */
1.14      tsutsui  2469:                    le32toh(sc->sc_txdescs[txs->txs_lastdesc].sipd_cmdsts);
1.1       thorpej  2470:                bus_dmamap_unload(sc->sc_dmat, txs->txs_dmamap);
                   2471:                m_freem(txs->txs_mbuf);
                   2472:                txs->txs_mbuf = NULL;
                   2473:                SIMPLEQ_INSERT_TAIL(&sc->sc_txfreeq, txs, txs_q);
1.2       thorpej  2474:        }
                   2475:
1.17      thorpej  2476:        if (disable)
1.28      thorpej  2477:                SIP_DECL(rxdrain)(sc);
1.1       thorpej  2478:
                   2479:        /*
                   2480:         * Mark the interface down and cancel the watchdog timer.
                   2481:         */
                   2482:        ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
                   2483:        ifp->if_timer = 0;
                   2484:
                   2485:        if ((ifp->if_flags & IFF_DEBUG) != 0 &&
                   2486:            (cmdsts & CMDSTS_INTR) == 0 && sc->sc_txfree != SIP_NTXDESC)
                   2487:                printf("%s: sip_stop: no INTR bits set in dirty tx "
                   2488:                    "descriptors\n", sc->sc_dev.dv_xname);
                   2489: }
                   2490:
                   2491: /*
                   2492:  * sip_read_eeprom:
                   2493:  *
                   2494:  *     Read data from the serial EEPROM.
                   2495:  */
                   2496: void
1.28      thorpej  2497: SIP_DECL(read_eeprom)(struct sip_softc *sc, int word, int wordcnt,
                   2498:     u_int16_t *data)
1.1       thorpej  2499: {
                   2500:        bus_space_tag_t st = sc->sc_st;
                   2501:        bus_space_handle_t sh = sc->sc_sh;
                   2502:        u_int16_t reg;
                   2503:        int i, x;
                   2504:
                   2505:        for (i = 0; i < wordcnt; i++) {
                   2506:                /* Send CHIP SELECT. */
                   2507:                reg = EROMAR_EECS;
                   2508:                bus_space_write_4(st, sh, SIP_EROMAR, reg);
                   2509:
                   2510:                /* Shift in the READ opcode. */
                   2511:                for (x = 3; x > 0; x--) {
                   2512:                        if (SIP_EEPROM_OPC_READ & (1 << (x - 1)))
                   2513:                                reg |= EROMAR_EEDI;
                   2514:                        else
                   2515:                                reg &= ~EROMAR_EEDI;
                   2516:                        bus_space_write_4(st, sh, SIP_EROMAR, reg);
                   2517:                        bus_space_write_4(st, sh, SIP_EROMAR,
                   2518:                            reg | EROMAR_EESK);
                   2519:                        delay(4);
                   2520:                        bus_space_write_4(st, sh, SIP_EROMAR, reg);
                   2521:                        delay(4);
                   2522:                }
                   2523:
                   2524:                /* Shift in address. */
                   2525:                for (x = 6; x > 0; x--) {
                   2526:                        if ((word + i) & (1 << (x - 1)))
                   2527:                                reg |= EROMAR_EEDI;
                   2528:                        else
                   2529:                                reg &= ~EROMAR_EEDI;
                   2530:                        bus_space_write_4(st, sh, SIP_EROMAR, reg);
                   2531:                        bus_space_write_4(st, sh, SIP_EROMAR,
                   2532:                            reg | EROMAR_EESK);
                   2533:                        delay(4);
                   2534:                        bus_space_write_4(st, sh, SIP_EROMAR, reg);
                   2535:                        delay(4);
                   2536:                }
                   2537:
                   2538:                /* Shift out data. */
                   2539:                reg = EROMAR_EECS;
                   2540:                data[i] = 0;
                   2541:                for (x = 16; x > 0; x--) {
                   2542:                        bus_space_write_4(st, sh, SIP_EROMAR,
                   2543:                            reg | EROMAR_EESK);
                   2544:                        delay(4);
                   2545:                        if (bus_space_read_4(st, sh, SIP_EROMAR) & EROMAR_EEDO)
                   2546:                                data[i] |= (1 << (x - 1));
                   2547:                        bus_space_write_4(st, sh, SIP_EROMAR, reg);
1.13      tsutsui  2548:                        delay(4);
1.1       thorpej  2549:                }
                   2550:
                   2551:                /* Clear CHIP SELECT. */
                   2552:                bus_space_write_4(st, sh, SIP_EROMAR, 0);
                   2553:                delay(4);
                   2554:        }
                   2555: }
                   2556:
                   2557: /*
                   2558:  * sip_add_rxbuf:
                   2559:  *
                   2560:  *     Add a receive buffer to the indicated descriptor.
                   2561:  */
                   2562: int
1.28      thorpej  2563: SIP_DECL(add_rxbuf)(struct sip_softc *sc, int idx)
1.1       thorpej  2564: {
                   2565:        struct sip_rxsoft *rxs = &sc->sc_rxsoft[idx];
                   2566:        struct mbuf *m;
                   2567:        int error;
                   2568:
                   2569:        MGETHDR(m, M_DONTWAIT, MT_DATA);
                   2570:        if (m == NULL)
                   2571:                return (ENOBUFS);
                   2572:
                   2573:        MCLGET(m, M_DONTWAIT);
                   2574:        if ((m->m_flags & M_EXT) == 0) {
                   2575:                m_freem(m);
                   2576:                return (ENOBUFS);
                   2577:        }
1.36      thorpej  2578:
                   2579: #if defined(DP83820)
                   2580:        m->m_len = SIP_RXBUF_LEN;
                   2581: #endif /* DP83820 */
1.1       thorpej  2582:
                   2583:        if (rxs->rxs_mbuf != NULL)
                   2584:                bus_dmamap_unload(sc->sc_dmat, rxs->rxs_dmamap);
                   2585:
                   2586:        rxs->rxs_mbuf = m;
                   2587:
                   2588:        error = bus_dmamap_load(sc->sc_dmat, rxs->rxs_dmamap,
1.41      thorpej  2589:            m->m_ext.ext_buf, m->m_ext.ext_size, NULL,
                   2590:            BUS_DMA_READ|BUS_DMA_NOWAIT);
1.1       thorpej  2591:        if (error) {
                   2592:                printf("%s: can't load rx DMA map %d, error = %d\n",
                   2593:                    sc->sc_dev.dv_xname, idx, error);
                   2594:                panic("sip_add_rxbuf");         /* XXX */
                   2595:        }
                   2596:
                   2597:        bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0,
                   2598:            rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
                   2599:
                   2600:        SIP_INIT_RXDESC(sc, idx);
                   2601:
                   2602:        return (0);
                   2603: }
                   2604:
1.29      thorpej  2605: #if !defined(DP83820)
1.1       thorpej  2606: /*
1.15      thorpej  2607:  * sip_sis900_set_filter:
1.1       thorpej  2608:  *
                   2609:  *     Set up the receive filter.
                   2610:  */
                   2611: void
1.28      thorpej  2612: SIP_DECL(sis900_set_filter)(struct sip_softc *sc)
1.1       thorpej  2613: {
                   2614:        bus_space_tag_t st = sc->sc_st;
                   2615:        bus_space_handle_t sh = sc->sc_sh;
                   2616:        struct ethercom *ec = &sc->sc_ethercom;
                   2617:        struct ifnet *ifp = &sc->sc_ethercom.ec_if;
                   2618:        struct ether_multi *enm;
1.11      thorpej  2619:        u_int8_t *cp;
1.1       thorpej  2620:        struct ether_multistep step;
1.45      thorpej  2621:        u_int32_t crc, mchash[16];
1.1       thorpej  2622:
                   2623:        /*
                   2624:         * Initialize the prototype RFCR.
                   2625:         */
                   2626:        sc->sc_rfcr = RFCR_RFEN;
                   2627:        if (ifp->if_flags & IFF_BROADCAST)
                   2628:                sc->sc_rfcr |= RFCR_AAB;
                   2629:        if (ifp->if_flags & IFF_PROMISC) {
                   2630:                sc->sc_rfcr |= RFCR_AAP;
                   2631:                goto allmulti;
                   2632:        }
                   2633:
                   2634:        /*
                   2635:         * Set up the multicast address filter by passing all multicast
                   2636:         * addresses through a CRC generator, and then using the high-order
                   2637:         * 6 bits as an index into the 128 bit multicast hash table (only
                   2638:         * the lower 16 bits of each 32 bit multicast hash register are
                   2639:         * valid).  The high order bits select the register, while the
                   2640:         * rest of the bits select the bit within the register.
                   2641:         */
                   2642:
                   2643:        memset(mchash, 0, sizeof(mchash));
                   2644:
                   2645:        ETHER_FIRST_MULTI(step, ec, enm);
                   2646:        while (enm != NULL) {
1.37      thorpej  2647:                if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
1.1       thorpej  2648:                        /*
                   2649:                         * We must listen to a range of multicast addresses.
                   2650:                         * For now, just accept all multicasts, rather than
                   2651:                         * trying to set only those filter bits needed to match
                   2652:                         * the range.  (At this time, the only use of address
                   2653:                         * ranges is for IP multicast routing, for which the
                   2654:                         * range is big enough to require all bits set.)
                   2655:                         */
                   2656:                        goto allmulti;
                   2657:                }
                   2658:
1.45      thorpej  2659:                crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN);
1.11      thorpej  2660:
1.45      thorpej  2661:                if (SIP_SIS900_REV(sc, SIS_REV_635) ||
                   2662:                    SIP_SIS900_REV(sc, SIS_REV_900B)) {
                   2663:                        /* Just want the 8 most significant bits. */
                   2664:                        crc >>= 24;
                   2665:                } else {
                   2666:                        /* Just want the 7 most significant bits. */
                   2667:                        crc >>= 25;
                   2668:                }
1.1       thorpej  2669:
                   2670:                /* Set the corresponding bit in the hash table. */
                   2671:                mchash[crc >> 4] |= 1 << (crc & 0xf);
                   2672:
                   2673:                ETHER_NEXT_MULTI(step, enm);
                   2674:        }
                   2675:
                   2676:        ifp->if_flags &= ~IFF_ALLMULTI;
                   2677:        goto setit;
                   2678:
                   2679:  allmulti:
                   2680:        ifp->if_flags |= IFF_ALLMULTI;
                   2681:        sc->sc_rfcr |= RFCR_AAM;
                   2682:
                   2683:  setit:
                   2684: #define        FILTER_EMIT(addr, data)                                         \
                   2685:        bus_space_write_4(st, sh, SIP_RFCR, (addr));                    \
1.14      tsutsui  2686:        delay(1);                                                       \
                   2687:        bus_space_write_4(st, sh, SIP_RFDR, (data));                    \
                   2688:        delay(1)
1.1       thorpej  2689:
                   2690:        /*
                   2691:         * Disable receive filter, and program the node address.
                   2692:         */
                   2693:        cp = LLADDR(ifp->if_sadl);
                   2694:        FILTER_EMIT(RFCR_RFADDR_NODE0, (cp[1] << 8) | cp[0]);
                   2695:        FILTER_EMIT(RFCR_RFADDR_NODE2, (cp[3] << 8) | cp[2]);
                   2696:        FILTER_EMIT(RFCR_RFADDR_NODE4, (cp[5] << 8) | cp[4]);
                   2697:
                   2698:        if ((ifp->if_flags & IFF_ALLMULTI) == 0) {
                   2699:                /*
                   2700:                 * Program the multicast hash table.
                   2701:                 */
                   2702:                FILTER_EMIT(RFCR_RFADDR_MC0, mchash[0]);
                   2703:                FILTER_EMIT(RFCR_RFADDR_MC1, mchash[1]);
                   2704:                FILTER_EMIT(RFCR_RFADDR_MC2, mchash[2]);
                   2705:                FILTER_EMIT(RFCR_RFADDR_MC3, mchash[3]);
                   2706:                FILTER_EMIT(RFCR_RFADDR_MC4, mchash[4]);
                   2707:                FILTER_EMIT(RFCR_RFADDR_MC5, mchash[5]);
                   2708:                FILTER_EMIT(RFCR_RFADDR_MC6, mchash[6]);
                   2709:                FILTER_EMIT(RFCR_RFADDR_MC7, mchash[7]);
1.45      thorpej  2710:                if (SIP_SIS900_REV(sc, SIS_REV_635) ||
                   2711:                    SIP_SIS900_REV(sc, SIS_REV_900B)) {
                   2712:                        FILTER_EMIT(RFCR_RFADDR_MC8, mchash[8]);
                   2713:                        FILTER_EMIT(RFCR_RFADDR_MC9, mchash[9]);
                   2714:                        FILTER_EMIT(RFCR_RFADDR_MC10, mchash[10]);
                   2715:                        FILTER_EMIT(RFCR_RFADDR_MC11, mchash[11]);
                   2716:                        FILTER_EMIT(RFCR_RFADDR_MC12, mchash[12]);
                   2717:                        FILTER_EMIT(RFCR_RFADDR_MC13, mchash[13]);
                   2718:                        FILTER_EMIT(RFCR_RFADDR_MC14, mchash[14]);
                   2719:                        FILTER_EMIT(RFCR_RFADDR_MC15, mchash[15]);
                   2720:                }
1.1       thorpej  2721:        }
                   2722: #undef FILTER_EMIT
                   2723:
                   2724:        /*
                   2725:         * Re-enable the receiver filter.
                   2726:         */
                   2727:        bus_space_write_4(st, sh, SIP_RFCR, sc->sc_rfcr);
                   2728: }
1.29      thorpej  2729: #endif /* ! DP83820 */
1.1       thorpej  2730:
                   2731: /*
1.15      thorpej  2732:  * sip_dp83815_set_filter:
                   2733:  *
                   2734:  *     Set up the receive filter.
                   2735:  */
                   2736: void
1.28      thorpej  2737: SIP_DECL(dp83815_set_filter)(struct sip_softc *sc)
1.15      thorpej  2738: {
                   2739:        bus_space_tag_t st = sc->sc_st;
                   2740:        bus_space_handle_t sh = sc->sc_sh;
                   2741:        struct ethercom *ec = &sc->sc_ethercom;
                   2742:        struct ifnet *ifp = &sc->sc_ethercom.ec_if;
                   2743:        struct ether_multi *enm;
                   2744:        u_int8_t *cp;
                   2745:        struct ether_multistep step;
1.29      thorpej  2746:        u_int32_t crc, hash, slot, bit;
                   2747: #ifdef DP83820
                   2748: #define        MCHASH_NWORDS   128
                   2749: #else
                   2750: #define        MCHASH_NWORDS   32
                   2751: #endif /* DP83820 */
                   2752:        u_int16_t mchash[MCHASH_NWORDS];
1.15      thorpej  2753:        int i;
                   2754:
                   2755:        /*
                   2756:         * Initialize the prototype RFCR.
1.27      briggs   2757:         * Enable the receive filter, and accept on
                   2758:         *    Perfect (destination address) Match
1.26      briggs   2759:         * If IFF_BROADCAST, also accept all broadcast packets.
                   2760:         * If IFF_PROMISC, accept all unicast packets (and later, set
                   2761:         *    IFF_ALLMULTI and accept all multicast, too).
1.15      thorpej  2762:         */
1.27      briggs   2763:        sc->sc_rfcr = RFCR_RFEN | RFCR_APM;
1.15      thorpej  2764:        if (ifp->if_flags & IFF_BROADCAST)
                   2765:                sc->sc_rfcr |= RFCR_AAB;
                   2766:        if (ifp->if_flags & IFF_PROMISC) {
                   2767:                sc->sc_rfcr |= RFCR_AAP;
                   2768:                goto allmulti;
                   2769:        }
                   2770:
1.29      thorpej  2771: #ifdef DP83820
1.15      thorpej  2772:        /*
1.29      thorpej  2773:         * Set up the DP83820 multicast address filter by passing all multicast
                   2774:         * addresses through a CRC generator, and then using the high-order
                   2775:         * 11 bits as an index into the 2048 bit multicast hash table.  The
                   2776:         * high-order 7 bits select the slot, while the low-order 4 bits
                   2777:         * select the bit within the slot.  Note that only the low 16-bits
                   2778:         * of each filter word are used, and there are 128 filter words.
                   2779:         */
                   2780: #else
                   2781:        /*
                   2782:         * Set up the DP83815 multicast address filter by passing all multicast
1.15      thorpej  2783:         * addresses through a CRC generator, and then using the high-order
                   2784:         * 9 bits as an index into the 512 bit multicast hash table.  The
1.29      thorpej  2785:         * high-order 5 bits select the slot, while the low-order 4 bits
1.15      thorpej  2786:         * select the bit within the slot.  Note that only the low 16-bits
1.29      thorpej  2787:         * of each filter word are used, and there are 32 filter words.
1.15      thorpej  2788:         */
1.29      thorpej  2789: #endif /* DP83820 */
1.15      thorpej  2790:
                   2791:        memset(mchash, 0, sizeof(mchash));
                   2792:
1.26      briggs   2793:        ifp->if_flags &= ~IFF_ALLMULTI;
1.15      thorpej  2794:        ETHER_FIRST_MULTI(step, ec, enm);
1.38      thorpej  2795:        if (enm == NULL)
                   2796:                goto setit;
                   2797:        while (enm != NULL) {
1.39      thorpej  2798:                if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
1.15      thorpej  2799:                        /*
                   2800:                         * We must listen to a range of multicast addresses.
                   2801:                         * For now, just accept all multicasts, rather than
                   2802:                         * trying to set only those filter bits needed to match
                   2803:                         * the range.  (At this time, the only use of address
                   2804:                         * ranges is for IP multicast routing, for which the
                   2805:                         * range is big enough to require all bits set.)
                   2806:                         */
1.38      thorpej  2807:                        goto allmulti;
                   2808:                }
1.26      briggs   2809:
1.38      thorpej  2810:                crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN);
1.29      thorpej  2811:
1.49      is       2812: #ifdef DP83820
1.38      thorpej  2813:                /* Just want the 11 most significant bits. */
                   2814:                hash = crc >> 21;
1.29      thorpej  2815: #else
1.38      thorpej  2816:                /* Just want the 9 most significant bits. */
                   2817:                hash = crc >> 23;
1.29      thorpej  2818: #endif /* DP83820 */
1.49      is       2819:
1.38      thorpej  2820:                slot = hash >> 4;
                   2821:                bit = hash & 0xf;
1.15      thorpej  2822:
1.38      thorpej  2823:                /* Set the corresponding bit in the hash table. */
                   2824:                mchash[slot] |= 1 << bit;
1.15      thorpej  2825:
1.38      thorpej  2826:                ETHER_NEXT_MULTI(step, enm);
1.15      thorpej  2827:        }
1.38      thorpej  2828:        sc->sc_rfcr |= RFCR_MHEN;
1.15      thorpej  2829:        goto setit;
                   2830:
                   2831:  allmulti:
                   2832:        ifp->if_flags |= IFF_ALLMULTI;
                   2833:        sc->sc_rfcr |= RFCR_AAM;
                   2834:
                   2835:  setit:
                   2836: #define        FILTER_EMIT(addr, data)                                         \
                   2837:        bus_space_write_4(st, sh, SIP_RFCR, (addr));                    \
                   2838:        delay(1);                                                       \
                   2839:        bus_space_write_4(st, sh, SIP_RFDR, (data));                    \
1.39      thorpej  2840:        delay(1)
1.15      thorpej  2841:
                   2842:        /*
                   2843:         * Disable receive filter, and program the node address.
                   2844:         */
                   2845:        cp = LLADDR(ifp->if_sadl);
1.26      briggs   2846:        FILTER_EMIT(RFCR_NS_RFADDR_PMATCH0, (cp[1] << 8) | cp[0]);
                   2847:        FILTER_EMIT(RFCR_NS_RFADDR_PMATCH2, (cp[3] << 8) | cp[2]);
                   2848:        FILTER_EMIT(RFCR_NS_RFADDR_PMATCH4, (cp[5] << 8) | cp[4]);
1.15      thorpej  2849:
                   2850:        if ((ifp->if_flags & IFF_ALLMULTI) == 0) {
                   2851:                /*
                   2852:                 * Program the multicast hash table.
                   2853:                 */
1.39      thorpej  2854:                for (i = 0; i < MCHASH_NWORDS; i++) {
1.15      thorpej  2855:                        FILTER_EMIT(RFCR_NS_RFADDR_FILTMEM + (i * 2),
1.29      thorpej  2856:                            mchash[i]);
1.39      thorpej  2857:                }
1.15      thorpej  2858:        }
                   2859: #undef FILTER_EMIT
1.29      thorpej  2860: #undef MCHASH_NWORDS
1.15      thorpej  2861:
                   2862:        /*
                   2863:         * Re-enable the receiver filter.
                   2864:         */
                   2865:        bus_space_write_4(st, sh, SIP_RFCR, sc->sc_rfcr);
1.29      thorpej  2866: }
                   2867:
                   2868: #if defined(DP83820)
                   2869: /*
                   2870:  * sip_dp83820_mii_readreg:    [mii interface function]
                   2871:  *
                   2872:  *     Read a PHY register on the MII of the DP83820.
                   2873:  */
                   2874: int
                   2875: SIP_DECL(dp83820_mii_readreg)(struct device *self, int phy, int reg)
                   2876: {
1.63      thorpej  2877:        struct sip_softc *sc = (void *) self;
                   2878:
                   2879:        if (sc->sc_cfg & CFG_TBI_EN) {
                   2880:                bus_addr_t tbireg;
                   2881:                int rv;
                   2882:
                   2883:                if (phy != 0)
                   2884:                        return (0);
                   2885:
                   2886:                switch (reg) {
                   2887:                case MII_BMCR:          tbireg = SIP_TBICR; break;
                   2888:                case MII_BMSR:          tbireg = SIP_TBISR; break;
                   2889:                case MII_ANAR:          tbireg = SIP_TANAR; break;
                   2890:                case MII_ANLPAR:        tbireg = SIP_TANLPAR; break;
                   2891:                case MII_ANER:          tbireg = SIP_TANER; break;
1.64      thorpej  2892:                case MII_EXTSR:
                   2893:                        /*
                   2894:                         * Don't even bother reading the TESR register.
                   2895:                         * The manual documents that the device has
                   2896:                         * 1000baseX full/half capability, but the
                   2897:                         * register itself seems read back 0 on some
                   2898:                         * boards.  Just hard-code the result.
                   2899:                         */
                   2900:                        return (EXTSR_1000XFDX|EXTSR_1000XHDX);
                   2901:
1.63      thorpej  2902:                default:
                   2903:                        return (0);
                   2904:                }
                   2905:
                   2906:                rv = bus_space_read_4(sc->sc_st, sc->sc_sh, tbireg) & 0xffff;
                   2907:                if (tbireg == SIP_TBISR) {
                   2908:                        /* LINK and ACOMP are switched! */
                   2909:                        int val = rv;
                   2910:
                   2911:                        rv = 0;
                   2912:                        if (val & TBISR_MR_LINK_STATUS)
                   2913:                                rv |= BMSR_LINK;
                   2914:                        if (val & TBISR_MR_AN_COMPLETE)
                   2915:                                rv |= BMSR_ACOMP;
1.64      thorpej  2916:
                   2917:                        /*
                   2918:                         * The manual claims this register reads back 0
                   2919:                         * on hard and soft reset.  But we want to let
                   2920:                         * the gentbi driver know that we support auto-
                   2921:                         * negotiation, so hard-code this bit in the
                   2922:                         * result.
                   2923:                         */
1.69      thorpej  2924:                        rv |= BMSR_ANEG | BMSR_EXTSTAT;
1.63      thorpej  2925:                }
                   2926:
                   2927:                return (rv);
                   2928:        }
1.29      thorpej  2929:
                   2930:        return (mii_bitbang_readreg(self, &SIP_DECL(dp83820_mii_bitbang_ops),
                   2931:            phy, reg));
                   2932: }
                   2933:
                   2934: /*
                   2935:  * sip_dp83820_mii_writereg:   [mii interface function]
                   2936:  *
                   2937:  *     Write a PHY register on the MII of the DP83820.
                   2938:  */
                   2939: void
                   2940: SIP_DECL(dp83820_mii_writereg)(struct device *self, int phy, int reg, int val)
                   2941: {
1.63      thorpej  2942:        struct sip_softc *sc = (void *) self;
                   2943:
                   2944:        if (sc->sc_cfg & CFG_TBI_EN) {
                   2945:                bus_addr_t tbireg;
                   2946:
                   2947:                if (phy != 0)
                   2948:                        return;
                   2949:
                   2950:                switch (reg) {
                   2951:                case MII_BMCR:          tbireg = SIP_TBICR; break;
                   2952:                case MII_ANAR:          tbireg = SIP_TANAR; break;
                   2953:                case MII_ANLPAR:        tbireg = SIP_TANLPAR; break;
                   2954:                default:
                   2955:                        return;
                   2956:                }
                   2957:
                   2958:                bus_space_write_4(sc->sc_st, sc->sc_sh, tbireg, val);
                   2959:                return;
                   2960:        }
1.29      thorpej  2961:
                   2962:        mii_bitbang_writereg(self, &SIP_DECL(dp83820_mii_bitbang_ops),
                   2963:            phy, reg, val);
                   2964: }
                   2965:
                   2966: /*
                   2967:  * sip_dp83815_mii_statchg:    [mii interface function]
                   2968:  *
                   2969:  *     Callback from MII layer when media changes.
                   2970:  */
                   2971: void
                   2972: SIP_DECL(dp83820_mii_statchg)(struct device *self)
                   2973: {
                   2974:        struct sip_softc *sc = (struct sip_softc *) self;
                   2975:        u_int32_t cfg;
                   2976:
                   2977:        /*
                   2978:         * Update TXCFG for full-duplex operation.
                   2979:         */
                   2980:        if ((sc->sc_mii.mii_media_active & IFM_FDX) != 0)
                   2981:                sc->sc_txcfg |= (TXCFG_CSI | TXCFG_HBI);
                   2982:        else
                   2983:                sc->sc_txcfg &= ~(TXCFG_CSI | TXCFG_HBI);
                   2984:
                   2985:        /*
                   2986:         * Update RXCFG for full-duplex or loopback.
                   2987:         */
                   2988:        if ((sc->sc_mii.mii_media_active & IFM_FDX) != 0 ||
                   2989:            IFM_SUBTYPE(sc->sc_mii.mii_media_active) == IFM_LOOP)
                   2990:                sc->sc_rxcfg |= RXCFG_ATX;
                   2991:        else
                   2992:                sc->sc_rxcfg &= ~RXCFG_ATX;
                   2993:
                   2994:        /*
                   2995:         * Update CFG for MII/GMII.
                   2996:         */
                   2997:        if (sc->sc_ethercom.ec_if.if_baudrate == IF_Mbps(1000))
                   2998:                cfg = sc->sc_cfg | CFG_MODE_1000;
                   2999:        else
                   3000:                cfg = sc->sc_cfg;
                   3001:
                   3002:        /*
                   3003:         * XXX 802.3x flow control.
                   3004:         */
                   3005:
                   3006:        bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_CFG, cfg);
                   3007:        bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_TXCFG, sc->sc_txcfg);
                   3008:        bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_RXCFG, sc->sc_rxcfg);
1.15      thorpej  3009: }
                   3010:
                   3011: /*
1.29      thorpej  3012:  * sip_dp83820_mii_bitbang_read: [mii bit-bang interface function]
                   3013:  *
                   3014:  *     Read the MII serial port for the MII bit-bang module.
                   3015:  */
                   3016: u_int32_t
                   3017: SIP_DECL(dp83820_mii_bitbang_read)(struct device *self)
                   3018: {
                   3019:        struct sip_softc *sc = (void *) self;
                   3020:
                   3021:        return (bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_EROMAR));
                   3022: }
                   3023:
                   3024: /*
                   3025:  * sip_dp83820_mii_bitbang_write: [mii big-bang interface function]
                   3026:  *
                   3027:  *     Write the MII serial port for the MII bit-bang module.
                   3028:  */
                   3029: void
                   3030: SIP_DECL(dp83820_mii_bitbang_write)(struct device *self, u_int32_t val)
                   3031: {
                   3032:        struct sip_softc *sc = (void *) self;
                   3033:
                   3034:        bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_EROMAR, val);
                   3035: }
                   3036: #else /* ! DP83820 */
                   3037: /*
1.15      thorpej  3038:  * sip_sis900_mii_readreg:     [mii interface function]
1.1       thorpej  3039:  *
                   3040:  *     Read a PHY register on the MII.
                   3041:  */
                   3042: int
1.28      thorpej  3043: SIP_DECL(sis900_mii_readreg)(struct device *self, int phy, int reg)
1.1       thorpej  3044: {
                   3045:        struct sip_softc *sc = (struct sip_softc *) self;
                   3046:        u_int32_t enphy;
                   3047:
                   3048:        /*
                   3049:         * The SiS 900 has only an internal PHY on the MII.  Only allow
                   3050:         * MII address 0.
                   3051:         */
1.45      thorpej  3052:        if (sc->sc_model->sip_product == PCI_PRODUCT_SIS_900 &&
                   3053:            sc->sc_rev < SIS_REV_635 && phy != 0)
1.1       thorpej  3054:                return (0);
                   3055:
                   3056:        bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_ENPHY,
1.5       thorpej  3057:            (phy << ENPHY_PHYADDR_SHIFT) | (reg << ENPHY_REGADDR_SHIFT) |
                   3058:            ENPHY_RWCMD | ENPHY_ACCESS);
1.1       thorpej  3059:        do {
                   3060:                enphy = bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_ENPHY);
                   3061:        } while (enphy & ENPHY_ACCESS);
                   3062:        return ((enphy & ENPHY_PHYDATA) >> ENPHY_DATA_SHIFT);
                   3063: }
                   3064:
                   3065: /*
1.15      thorpej  3066:  * sip_sis900_mii_writereg:    [mii interface function]
1.1       thorpej  3067:  *
                   3068:  *     Write a PHY register on the MII.
                   3069:  */
                   3070: void
1.28      thorpej  3071: SIP_DECL(sis900_mii_writereg)(struct device *self, int phy, int reg, int val)
1.1       thorpej  3072: {
                   3073:        struct sip_softc *sc = (struct sip_softc *) self;
                   3074:        u_int32_t enphy;
                   3075:
                   3076:        /*
                   3077:         * The SiS 900 has only an internal PHY on the MII.  Only allow
                   3078:         * MII address 0.
                   3079:         */
1.45      thorpej  3080:        if (sc->sc_model->sip_product == PCI_PRODUCT_SIS_900 &&
                   3081:            sc->sc_rev < SIS_REV_635 && phy != 0)
1.1       thorpej  3082:                return;
                   3083:
                   3084:        bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_ENPHY,
1.5       thorpej  3085:            (val << ENPHY_DATA_SHIFT) | (phy << ENPHY_PHYADDR_SHIFT) |
                   3086:            (reg << ENPHY_REGADDR_SHIFT) | ENPHY_ACCESS);
1.1       thorpej  3087:        do {
                   3088:                enphy = bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_ENPHY);
                   3089:        } while (enphy & ENPHY_ACCESS);
                   3090: }
                   3091:
                   3092: /*
1.15      thorpej  3093:  * sip_sis900_mii_statchg:     [mii interface function]
1.1       thorpej  3094:  *
                   3095:  *     Callback from MII layer when media changes.
                   3096:  */
                   3097: void
1.28      thorpej  3098: SIP_DECL(sis900_mii_statchg)(struct device *self)
1.1       thorpej  3099: {
                   3100:        struct sip_softc *sc = (struct sip_softc *) self;
                   3101:        u_int32_t flowctl;
                   3102:
                   3103:        /*
                   3104:         * Update TXCFG for full-duplex operation.
                   3105:         */
                   3106:        if ((sc->sc_mii.mii_media_active & IFM_FDX) != 0)
                   3107:                sc->sc_txcfg |= (TXCFG_CSI | TXCFG_HBI);
                   3108:        else
                   3109:                sc->sc_txcfg &= ~(TXCFG_CSI | TXCFG_HBI);
                   3110:
                   3111:        /*
                   3112:         * Update RXCFG for full-duplex or loopback.
                   3113:         */
                   3114:        if ((sc->sc_mii.mii_media_active & IFM_FDX) != 0 ||
                   3115:            IFM_SUBTYPE(sc->sc_mii.mii_media_active) == IFM_LOOP)
                   3116:                sc->sc_rxcfg |= RXCFG_ATX;
                   3117:        else
                   3118:                sc->sc_rxcfg &= ~RXCFG_ATX;
                   3119:
                   3120:        /*
                   3121:         * Update IMR for use of 802.3x flow control.
                   3122:         */
                   3123:        if ((sc->sc_mii.mii_media_active & IFM_FLOW) != 0) {
                   3124:                sc->sc_imr |= (ISR_PAUSE_END|ISR_PAUSE_ST);
                   3125:                flowctl = FLOWCTL_FLOWEN;
                   3126:        } else {
                   3127:                sc->sc_imr &= ~(ISR_PAUSE_END|ISR_PAUSE_ST);
                   3128:                flowctl = 0;
                   3129:        }
                   3130:
                   3131:        bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_TXCFG, sc->sc_txcfg);
                   3132:        bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_RXCFG, sc->sc_rxcfg);
                   3133:        bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_IMR, sc->sc_imr);
                   3134:        bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_FLOWCTL, flowctl);
1.15      thorpej  3135: }
                   3136:
                   3137: /*
                   3138:  * sip_dp83815_mii_readreg:    [mii interface function]
                   3139:  *
                   3140:  *     Read a PHY register on the MII.
                   3141:  */
                   3142: int
1.28      thorpej  3143: SIP_DECL(dp83815_mii_readreg)(struct device *self, int phy, int reg)
1.15      thorpej  3144: {
                   3145:        struct sip_softc *sc = (struct sip_softc *) self;
                   3146:        u_int32_t val;
                   3147:
                   3148:        /*
                   3149:         * The DP83815 only has an internal PHY.  Only allow
                   3150:         * MII address 0.
                   3151:         */
                   3152:        if (phy != 0)
                   3153:                return (0);
                   3154:
                   3155:        /*
                   3156:         * Apparently, after a reset, the DP83815 can take a while
                   3157:         * to respond.  During this recovery period, the BMSR returns
                   3158:         * a value of 0.  Catch this -- it's not supposed to happen
                   3159:         * (the BMSR has some hardcoded-to-1 bits), and wait for the
                   3160:         * PHY to come back to life.
                   3161:         *
                   3162:         * This works out because the BMSR is the first register
                   3163:         * read during the PHY probe process.
                   3164:         */
                   3165:        do {
                   3166:                val = bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_NS_PHY(reg));
                   3167:        } while (reg == MII_BMSR && val == 0);
                   3168:
                   3169:        return (val & 0xffff);
                   3170: }
                   3171:
                   3172: /*
                   3173:  * sip_dp83815_mii_writereg:   [mii interface function]
                   3174:  *
                   3175:  *     Write a PHY register to the MII.
                   3176:  */
                   3177: void
1.28      thorpej  3178: SIP_DECL(dp83815_mii_writereg)(struct device *self, int phy, int reg, int val)
1.15      thorpej  3179: {
                   3180:        struct sip_softc *sc = (struct sip_softc *) self;
                   3181:
                   3182:        /*
                   3183:         * The DP83815 only has an internal PHY.  Only allow
                   3184:         * MII address 0.
                   3185:         */
                   3186:        if (phy != 0)
                   3187:                return;
                   3188:
                   3189:        bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_NS_PHY(reg), val);
                   3190: }
                   3191:
                   3192: /*
                   3193:  * sip_dp83815_mii_statchg:    [mii interface function]
                   3194:  *
                   3195:  *     Callback from MII layer when media changes.
                   3196:  */
                   3197: void
1.28      thorpej  3198: SIP_DECL(dp83815_mii_statchg)(struct device *self)
1.15      thorpej  3199: {
                   3200:        struct sip_softc *sc = (struct sip_softc *) self;
                   3201:
                   3202:        /*
                   3203:         * Update TXCFG for full-duplex operation.
                   3204:         */
                   3205:        if ((sc->sc_mii.mii_media_active & IFM_FDX) != 0)
                   3206:                sc->sc_txcfg |= (TXCFG_CSI | TXCFG_HBI);
                   3207:        else
                   3208:                sc->sc_txcfg &= ~(TXCFG_CSI | TXCFG_HBI);
                   3209:
                   3210:        /*
                   3211:         * Update RXCFG for full-duplex or loopback.
                   3212:         */
                   3213:        if ((sc->sc_mii.mii_media_active & IFM_FDX) != 0 ||
                   3214:            IFM_SUBTYPE(sc->sc_mii.mii_media_active) == IFM_LOOP)
                   3215:                sc->sc_rxcfg |= RXCFG_ATX;
                   3216:        else
                   3217:                sc->sc_rxcfg &= ~RXCFG_ATX;
                   3218:
                   3219:        /*
                   3220:         * XXX 802.3x flow control.
                   3221:         */
                   3222:
                   3223:        bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_TXCFG, sc->sc_txcfg);
                   3224:        bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_RXCFG, sc->sc_rxcfg);
1.25      briggs   3225: }
1.29      thorpej  3226: #endif /* DP83820 */
                   3227:
                   3228: #if defined(DP83820)
                   3229: void
1.44      thorpej  3230: SIP_DECL(dp83820_read_macaddr)(struct sip_softc *sc,
                   3231:     const struct pci_attach_args *pa, u_int8_t *enaddr)
1.29      thorpej  3232: {
                   3233:        u_int16_t eeprom_data[SIP_DP83820_EEPROM_LENGTH / 2];
                   3234:        u_int8_t cksum, *e, match;
                   3235:        int i;
                   3236:
                   3237:        /*
                   3238:         * EEPROM data format for the DP83820 can be found in
                   3239:         * the DP83820 manual, section 4.2.4.
                   3240:         */
1.25      briggs   3241:
1.29      thorpej  3242:        SIP_DECL(read_eeprom)(sc, 0,
                   3243:            sizeof(eeprom_data) / sizeof(eeprom_data[0]), eeprom_data);
                   3244:
                   3245:        match = eeprom_data[SIP_DP83820_EEPROM_CHECKSUM / 2] >> 8;
                   3246:        match = ~(match - 1);
                   3247:
                   3248:        cksum = 0x55;
                   3249:        e = (u_int8_t *) eeprom_data;
                   3250:        for (i = 0; i < SIP_DP83820_EEPROM_CHECKSUM; i++)
                   3251:                cksum += *e++;
                   3252:
                   3253:        if (cksum != match)
                   3254:                printf("%s: Checksum (%x) mismatch (%x)",
                   3255:                    sc->sc_dev.dv_xname, cksum, match);
                   3256:
                   3257:        enaddr[0] = eeprom_data[SIP_DP83820_EEPROM_PMATCH2 / 2] & 0xff;
                   3258:        enaddr[1] = eeprom_data[SIP_DP83820_EEPROM_PMATCH2 / 2] >> 8;
                   3259:        enaddr[2] = eeprom_data[SIP_DP83820_EEPROM_PMATCH1 / 2] & 0xff;
                   3260:        enaddr[3] = eeprom_data[SIP_DP83820_EEPROM_PMATCH1 / 2] >> 8;
                   3261:        enaddr[4] = eeprom_data[SIP_DP83820_EEPROM_PMATCH0 / 2] & 0xff;
                   3262:        enaddr[5] = eeprom_data[SIP_DP83820_EEPROM_PMATCH0 / 2] >> 8;
                   3263: }
                   3264: #else /* ! DP83820 */
1.25      briggs   3265: void
1.44      thorpej  3266: SIP_DECL(sis900_read_macaddr)(struct sip_softc *sc,
                   3267:     const struct pci_attach_args *pa, u_int8_t *enaddr)
1.25      briggs   3268: {
                   3269:        u_int16_t myea[ETHER_ADDR_LEN / 2];
                   3270:
1.50      briggs   3271:        switch (sc->sc_rev) {
1.44      thorpej  3272:        case SIS_REV_630S:
                   3273:        case SIS_REV_630E:
                   3274:        case SIS_REV_630EA1:
1.51      briggs   3275:        case SIS_REV_630ET:
1.45      thorpej  3276:        case SIS_REV_635:
1.44      thorpej  3277:                /*
                   3278:                 * The MAC address for the on-board Ethernet of
                   3279:                 * the SiS 630 chipset is in the NVRAM.  Kick
                   3280:                 * the chip into re-loading it from NVRAM, and
                   3281:                 * read the MAC address out of the filter registers.
                   3282:                 */
                   3283:                bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_CR, CR_RLD);
                   3284:
                   3285:                bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_RFCR,
                   3286:                    RFCR_RFADDR_NODE0);
                   3287:                myea[0] = bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_RFDR) &
                   3288:                    0xffff;
                   3289:
                   3290:                bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_RFCR,
                   3291:                    RFCR_RFADDR_NODE2);
                   3292:                myea[1] = bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_RFDR) &
                   3293:                    0xffff;
                   3294:
                   3295:                bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_RFCR,
                   3296:                    RFCR_RFADDR_NODE4);
                   3297:                myea[2] = bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_RFDR) &
                   3298:                    0xffff;
                   3299:                break;
                   3300:
                   3301:        default:
                   3302:                SIP_DECL(read_eeprom)(sc, SIP_EEPROM_ETHERNET_ID0 >> 1,
                   3303:                    sizeof(myea) / sizeof(myea[0]), myea);
                   3304:        }
1.25      briggs   3305:
                   3306:        enaddr[0] = myea[0] & 0xff;
                   3307:        enaddr[1] = myea[0] >> 8;
                   3308:        enaddr[2] = myea[1] & 0xff;
                   3309:        enaddr[3] = myea[1] >> 8;
                   3310:        enaddr[4] = myea[2] & 0xff;
                   3311:        enaddr[5] = myea[2] >> 8;
                   3312: }
                   3313:
1.29      thorpej  3314: /* Table and macro to bit-reverse an octet. */
                   3315: static const u_int8_t bbr4[] = {0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15};
1.25      briggs   3316: #define bbr(v) ((bbr4[(v)&0xf] << 4) | bbr4[((v)>>4) & 0xf])
                   3317:
                   3318: void
1.44      thorpej  3319: SIP_DECL(dp83815_read_macaddr)(struct sip_softc *sc,
                   3320:     const struct pci_attach_args *pa, u_int8_t *enaddr)
1.25      briggs   3321: {
                   3322:        u_int16_t eeprom_data[SIP_DP83815_EEPROM_LENGTH / 2], *ea;
                   3323:        u_int8_t cksum, *e, match;
                   3324:        int i;
                   3325:
1.29      thorpej  3326:        SIP_DECL(read_eeprom)(sc, 0, sizeof(eeprom_data) /
                   3327:            sizeof(eeprom_data[0]), eeprom_data);
1.25      briggs   3328:
                   3329:        match = eeprom_data[SIP_DP83815_EEPROM_CHECKSUM/2] >> 8;
                   3330:        match = ~(match - 1);
                   3331:
                   3332:        cksum = 0x55;
                   3333:        e = (u_int8_t *) eeprom_data;
                   3334:        for (i=0 ; i<SIP_DP83815_EEPROM_CHECKSUM ; i++) {
                   3335:                cksum += *e++;
                   3336:        }
                   3337:        if (cksum != match) {
                   3338:                printf("%s: Checksum (%x) mismatch (%x)",
                   3339:                    sc->sc_dev.dv_xname, cksum, match);
                   3340:        }
                   3341:
                   3342:        /*
                   3343:         * Unrolled because it makes slightly more sense this way.
                   3344:         * The DP83815 stores the MAC address in bit 0 of word 6
                   3345:         * through bit 15 of word 8.
                   3346:         */
                   3347:        ea = &eeprom_data[6];
                   3348:        enaddr[0] = ((*ea & 0x1) << 7);
                   3349:        ea++;
                   3350:        enaddr[0] |= ((*ea & 0xFE00) >> 9);
                   3351:        enaddr[1] = ((*ea & 0x1FE) >> 1);
                   3352:        enaddr[2] = ((*ea & 0x1) << 7);
                   3353:        ea++;
                   3354:        enaddr[2] |= ((*ea & 0xFE00) >> 9);
                   3355:        enaddr[3] = ((*ea & 0x1FE) >> 1);
                   3356:        enaddr[4] = ((*ea & 0x1) << 7);
                   3357:        ea++;
                   3358:        enaddr[4] |= ((*ea & 0xFE00) >> 9);
                   3359:        enaddr[5] = ((*ea & 0x1FE) >> 1);
                   3360:
                   3361:        /*
                   3362:         * In case that's not weird enough, we also need to reverse
                   3363:         * the bits in each byte.  This all actually makes more sense
                   3364:         * if you think about the EEPROM storage as an array of bits
                   3365:         * being shifted into bytes, but that's not how we're looking
                   3366:         * at it here...
                   3367:         */
1.28      thorpej  3368:        for (i = 0; i < 6 ;i++)
1.25      briggs   3369:                enaddr[i] = bbr(enaddr[i]);
1.1       thorpej  3370: }
1.29      thorpej  3371: #endif /* DP83820 */
1.1       thorpej  3372:
                   3373: /*
                   3374:  * sip_mediastatus:    [ifmedia interface function]
                   3375:  *
                   3376:  *     Get the current interface media status.
                   3377:  */
                   3378: void
1.28      thorpej  3379: SIP_DECL(mediastatus)(struct ifnet *ifp, struct ifmediareq *ifmr)
1.1       thorpej  3380: {
                   3381:        struct sip_softc *sc = ifp->if_softc;
                   3382:
                   3383:        mii_pollstat(&sc->sc_mii);
                   3384:        ifmr->ifm_status = sc->sc_mii.mii_media_status;
                   3385:        ifmr->ifm_active = sc->sc_mii.mii_media_active;
                   3386: }
                   3387:
                   3388: /*
                   3389:  * sip_mediachange:    [ifmedia interface function]
                   3390:  *
                   3391:  *     Set hardware to newly-selected media.
                   3392:  */
                   3393: int
1.28      thorpej  3394: SIP_DECL(mediachange)(struct ifnet *ifp)
1.1       thorpej  3395: {
                   3396:        struct sip_softc *sc = ifp->if_softc;
                   3397:
                   3398:        if (ifp->if_flags & IFF_UP)
                   3399:                mii_mediachg(&sc->sc_mii);
                   3400:        return (0);
                   3401: }

CVSweb <webmaster@jp.NetBSD.org>