[BACK]Return to if_lmc_common.c CVS log [TXT][DIR] Up to [local] / sys / dev / pci

Annotation of sys/dev/pci/if_lmc_common.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: if_lmc_common.c,v 1.11 2005/11/07 00:29:21 brad Exp $ */
                      2: /*     $NetBSD: if_lmc_common.c,v 1.1 1999/03/25 03:32:43 explorer Exp $       */
                      3:
                      4: /*-
                      5:  * Copyright (c) 1997-1999 LAN Media Corporation (LMC)
                      6:  * All rights reserved.  www.lanmedia.com
                      7:  *
                      8:  * This code is written by Michael Graff <graff@vix.com> for LMC.
                      9:  * The code is derived from permitted modifications to software created
                     10:  * by Matt Thomas (matt@3am-software.com).
                     11:  *
                     12:  * Redistribution and use in source and binary forms, with or without
                     13:  * modification, are permitted provided that the following conditions
                     14:  * are met:
                     15:  * 1. Redistributions of source code must retain the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer.
                     17:  * 2. Redistributions in binary form must reproduce the above
                     18:  *    copyright notice, this list of conditions and the following disclaimer
                     19:  *    in the documentation and/or other materials provided with the
                     20:  *    distribution.
                     21:  * 3. All marketing or advertising materials mentioning features or
                     22:  *    use of this software must display the following acknowledgement:
                     23:  *      This product includes software developed by LAN Media Corporation
                     24:  *      and its contributors.
                     25:  * 4. Neither the name of LAN Media Corporation nor the names of its
                     26:  *    contributors may be used to endorse or promote products derived
                     27:  *    from this software without specific prior written permission.
                     28:  *
                     29:  * THIS SOFTWARE IS PROVIDED BY LAN MEDIA CORPORATION AND CONTRIBUTORS
                     30:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     31:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     32:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     33:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     34:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     35:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     36:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     37:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     38:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
                     39:  * THE POSSIBILITY OF SUCH DAMAGE.
                     40:  */
                     41:
                     42: /*-
                     43:  * Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com)
                     44:  * All rights reserved.
                     45:  *
                     46:  * Redistribution and use in source and binary forms, with or without
                     47:  * modification, are permitted provided that the following conditions
                     48:  * are met:
                     49:  * 1. Redistributions of source code must retain the above copyright
                     50:  *    notice, this list of conditions and the following disclaimer.
                     51:  * 2. The name of the author may not be used to endorse or promote products
                     52:  *    derived from this software without specific prior written permission
                     53:  *
                     54:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     55:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     56:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     57:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     58:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     59:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     60:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     61:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     62:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     63:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     64:  */
                     65:
                     66: #include "bpfilter.h"
                     67:
                     68: #include <sys/param.h>
                     69: #include <sys/systm.h>
                     70: #include <sys/mbuf.h>
                     71: #include <sys/socket.h>
                     72: #include <sys/ioctl.h>
                     73: #include <sys/errno.h>
                     74: #include <sys/malloc.h>
                     75: #include <sys/kernel.h>
                     76: #include <sys/proc.h>  /* only for declaration of wakeup() used by vm.h */
                     77: #include <sys/device.h>
                     78:
                     79: #include <dev/pci/pcidevs.h>
                     80:
                     81: #include <net/if.h>
                     82: #include <net/if_types.h>
                     83: #include <net/if_dl.h>
                     84: #include <net/netisr.h>
                     85:
                     86: #if NBPFILTER > 0
                     87: #include <net/bpf.h>
                     88: #endif
                     89:
                     90: #include <net/if_sppp.h>
                     91:
                     92: #include <machine/bus.h>
                     93:
                     94: #include <dev/pci/pcireg.h>
                     95: #include <dev/pci/pcivar.h>
                     96: #include <dev/ic/dc21040reg.h>
                     97:
                     98: #define d_length1 u.bd_length1
                     99: #define d_length2 u.bd_length2
                    100: #define d_flag u.bd_flag
                    101:
                    102: #include <dev/pci/if_lmc_types.h>
                    103: #include <dev/pci/if_lmcioctl.h>
                    104: #include <dev/pci/if_lmcvar.h>
                    105:
                    106: void
                    107: lmc_gpio_mkinput(lmc_softc_t * const sc, u_int32_t bits)
                    108: {
                    109:        sc->lmc_gpio_io &= ~bits;
                    110:        LMC_CSR_WRITE(sc, csr_gp, TULIP_GP_PINSET | (sc->lmc_gpio_io));
                    111: }
                    112:
                    113: void
                    114: lmc_gpio_mkoutput(lmc_softc_t * const sc, u_int32_t bits)
                    115: {
                    116:        sc->lmc_gpio_io |= bits;
                    117:        LMC_CSR_WRITE(sc, csr_gp, TULIP_GP_PINSET | (sc->lmc_gpio_io));
                    118: }
                    119:
                    120: void
                    121: lmc_led_on(lmc_softc_t * const sc, u_int32_t led)
                    122: {
                    123:        sc->lmc_miireg16 &= ~led;
                    124:        lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
                    125: }
                    126:
                    127: void
                    128: lmc_led_off(lmc_softc_t * const sc, u_int32_t led)
                    129: {
                    130:        sc->lmc_miireg16 |= led;
                    131:        lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
                    132: }
                    133:
                    134: void
                    135: lmc_reset(lmc_softc_t * const sc)
                    136: {
                    137:        sc->lmc_miireg16 |= LMC_MII16_FIFO_RESET;
                    138:        lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
                    139:
                    140:        sc->lmc_miireg16 &= ~LMC_MII16_FIFO_RESET;
                    141:        lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
                    142:
                    143:        /*
                    144:         * make some of the GPIO pins be outputs
                    145:         */
                    146:        lmc_gpio_mkoutput(sc, LMC_GEP_DP | LMC_GEP_RESET);
                    147:
                    148:        /*
                    149:         * drive DP and RESET low to force configuration.  This also forces
                    150:         * the transmitter clock to be internal, but we expect to reset
                    151:         * that later anyway.
                    152:         */
                    153:        sc->lmc_gpio &= ~(LMC_GEP_DP | LMC_GEP_RESET);
                    154:        LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
                    155:
                    156:        /*
                    157:         * hold for more than 10 microseconds
                    158:         */
                    159:        DELAY(50);
                    160:
                    161:        /*
                    162:         * stop driving Xilinx-related signals
                    163:         */
                    164:        lmc_gpio_mkinput(sc, LMC_GEP_DP | LMC_GEP_RESET);
                    165:
                    166:        /*
                    167:         * busy wait for the chip to reset
                    168:         */
                    169:        while ((LMC_CSR_READ(sc, csr_gp) & LMC_GEP_DP) == 0);
                    170:
                    171:        /*
                    172:         * Call media specific init routine
                    173:         */
                    174:        sc->lmc_media->init(sc);
                    175: }
                    176:
                    177: void
                    178: lmc_dec_reset(lmc_softc_t * const sc)
                    179: {
                    180: #ifndef __linux__
                    181:        lmc_ringinfo_t *ri;
                    182:        lmc_desc_t *di;
                    183: #endif
                    184:        u_int32_t val;
                    185:
                    186:        /*
                    187:         * disable all interrupts
                    188:         */
                    189:        sc->lmc_intrmask = 0;
                    190:        LMC_CSR_WRITE(sc, csr_intr, sc->lmc_intrmask);
                    191:
                    192:        /*
                    193:         * we are, obviously, down.
                    194:         */
                    195: #ifndef __linux__
                    196:        sc->lmc_flags &= ~(LMC_IFUP | LMC_MODEMOK);
                    197:
                    198:        DP(("lmc_dec_reset\n"));
                    199: #endif
                    200:
                    201:        /*
                    202:         * Reset the chip with a software reset command.
                    203:         * Wait 10 microseconds (actually 50 PCI cycles but at
                    204:         * 33MHz that comes to two microseconds but wait a
                    205:         * bit longer anyways)
                    206:         */
                    207:        LMC_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET);
                    208:        DELAY(10);
                    209:        sc->lmc_cmdmode = LMC_CSR_READ(sc, csr_command);
                    210:
                    211:        /*
                    212:         * We want:
                    213:         *   no ethernet address in frames we write
                    214:         *   disable padding (txdesc, padding disable)
                    215:         *   ignore runt frames (rdes0 bit 15)
                    216:         *   no receiver watchdog or transmitter jabber timer
                    217:         *       (csr15 bit 0,14 == 1)
                    218:         *   if using 16-bit CRC, turn off CRC (trans desc, crc disable)
                    219:         */
                    220:
                    221: #ifndef TULIP_CMD_RECEIVEALL
                    222: #define TULIP_CMD_RECEIVEALL 0x40000000L
                    223: #endif
                    224:
                    225:        sc->lmc_cmdmode |= ( TULIP_CMD_PROMISCUOUS
                    226:                               | TULIP_CMD_FULLDUPLEX
                    227:                               | TULIP_CMD_PASSBADPKT
                    228:                               | TULIP_CMD_NOHEARTBEAT
                    229:                               | TULIP_CMD_PORTSELECT
                    230:                               | TULIP_CMD_RECEIVEALL
                    231:                               | TULIP_CMD_MUSTBEONE
                    232:                               );
                    233:        sc->lmc_cmdmode &= ~( TULIP_CMD_OPERMODE
                    234:                                | TULIP_CMD_THRESHOLDCTL
                    235:                                | TULIP_CMD_STOREFWD
                    236:                                | TULIP_CMD_TXTHRSHLDCTL
                    237:                                );
                    238:
                    239:        LMC_CSR_WRITE(sc, csr_command, sc->lmc_cmdmode);
                    240:
                    241:        /*
                    242:         * disable receiver watchdog and transmit jabber
                    243:         */
                    244:        val = LMC_CSR_READ(sc, csr_sia_general);
                    245:        val |= (TULIP_WATCHDOG_TXDISABLE | TULIP_WATCHDOG_RXDISABLE);
                    246:        LMC_CSR_WRITE(sc, csr_sia_general, val);
                    247:
                    248:        /*
                    249:         * turn off those LEDs...
                    250:         */
                    251:        sc->lmc_miireg16 |= LMC_MII16_LED_ALL;
                    252:        lmc_led_on(sc, LMC_MII16_LED0);
                    253:
                    254: #ifndef __linux__
                    255:        /*
                    256:         * reprogram the tx desc, rx desc, and PCI bus options
                    257:         */
                    258:        LMC_CSR_WRITE(sc, csr_txlist, sc->lmc_txdescmap->dm_segs[0].ds_addr);
                    259:        LMC_CSR_WRITE(sc, csr_rxlist, sc->lmc_rxdescmap->dm_segs[0].ds_addr);
                    260:        LMC_CSR_WRITE(sc, csr_busmode,
                    261:                (1 << (LMC_BURSTSIZE(sc->lmc_unit) + 8))
                    262:                |TULIP_BUSMODE_CACHE_ALIGN8
                    263:                |TULIP_BUSMODE_READMULTIPLE);
                    264:
                    265:        sc->lmc_txq.ifq_maxlen = LMC_TXDESCS;
                    266:
                    267:        /*
                    268:         * Free all the mbufs that were on the transmit ring.
                    269:         */
                    270:        for (;;) {
                    271:                bus_dmamap_t map;
                    272:                struct mbuf *m;
                    273:
                    274:                IF_DEQUEUE(&sc->lmc_txq, m);
                    275:                if (m == NULL)
                    276:                        break;
                    277:                map = LMC_GETCTX(m, bus_dmamap_t);
                    278:                bus_dmamap_unload(sc->lmc_dmatag, map);
                    279:                sc->lmc_txmaps[sc->lmc_txmaps_free++] = map;
                    280:                m_freem(m);
                    281:        }
                    282:
                    283:        /*
                    284:         * reset descriptor state and reclaim all descriptors.
                    285:         */
                    286:        ri = &sc->lmc_txinfo;
                    287:        ri->ri_nextin = ri->ri_nextout = ri->ri_first;
                    288:        ri->ri_free = ri->ri_max;
                    289:        for (di = ri->ri_first; di < ri->ri_last; di++)
                    290:                di->d_status = 0;
                    291:        bus_dmamap_sync(sc->lmc_dmatag, sc->lmc_txdescmap,
                    292:                0, sc->lmc_txdescmap->dm_mapsize,
                    293:                BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
                    294:
                    295:        /*
                    296:         * We need to collect all the mbufs were on the
                    297:         * receive ring before we reinit it either to put
                    298:         * them back on or to know if we have to allocate
                    299:         * more.
                    300:         */
                    301:        ri = &sc->lmc_rxinfo;
                    302:        ri->ri_nextin = ri->ri_nextout = ri->ri_first;
                    303:        ri->ri_free = ri->ri_max;
                    304:        for (di = ri->ri_first; di < ri->ri_last; di++) {
                    305:                u_int32_t ctl = di->d_ctl;
                    306:                di->d_status = 0;
                    307:                di->d_ctl = LMC_CTL(LMC_CTL_FLGS(ctl),0,0);
                    308:                di->d_addr1 = 0;
                    309:                di->d_addr2 = 0;
                    310:        }
                    311:        bus_dmamap_sync(sc->lmc_dmatag, sc->lmc_rxdescmap,
                    312:                0, sc->lmc_rxdescmap->dm_mapsize,
                    313:                BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
                    314:        for (;;) {
                    315:                bus_dmamap_t map;
                    316:                struct mbuf *m;
                    317:                IF_DEQUEUE(&sc->lmc_rxq, m);
                    318:                if (m == NULL)
                    319:                        break;
                    320:                map = LMC_GETCTX(m, bus_dmamap_t);
                    321:                bus_dmamap_unload(sc->lmc_dmatag, map);
                    322:                sc->lmc_rxmaps[sc->lmc_rxmaps_free++] = map;
                    323:                m_freem(m);
                    324:        }
                    325: #endif
                    326: }
                    327:
                    328: void
                    329: lmc_initcsrs(lmc_softc_t * const sc, lmc_csrptr_t csr_base,
                    330:             size_t csr_size)
                    331: {
                    332:        sc->lmc_csrs.csr_busmode        = csr_base +  0 * csr_size;
                    333:        sc->lmc_csrs.csr_txpoll         = csr_base +  1 * csr_size;
                    334:        sc->lmc_csrs.csr_rxpoll         = csr_base +  2 * csr_size;
                    335:        sc->lmc_csrs.csr_rxlist         = csr_base +  3 * csr_size;
                    336:        sc->lmc_csrs.csr_txlist         = csr_base +  4 * csr_size;
                    337:        sc->lmc_csrs.csr_status         = csr_base +  5 * csr_size;
                    338:        sc->lmc_csrs.csr_command        = csr_base +  6 * csr_size;
                    339:        sc->lmc_csrs.csr_intr           = csr_base +  7 * csr_size;
                    340:        sc->lmc_csrs.csr_missed_frames  = csr_base +  8 * csr_size;
                    341:        sc->lmc_csrs.csr_9              = csr_base +  9 * csr_size;
                    342:        sc->lmc_csrs.csr_10             = csr_base + 10 * csr_size;
                    343:        sc->lmc_csrs.csr_11             = csr_base + 11 * csr_size;
                    344:        sc->lmc_csrs.csr_12             = csr_base + 12 * csr_size;
                    345:        sc->lmc_csrs.csr_13             = csr_base + 13 * csr_size;
                    346:        sc->lmc_csrs.csr_14             = csr_base + 14 * csr_size;
                    347:        sc->lmc_csrs.csr_15             = csr_base + 15 * csr_size;
                    348: }

CVSweb