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

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

CVSweb <webmaster@jp.NetBSD.org>