[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     ! 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