[BACK]Return to if_le.c CVS log [TXT][DIR] Up to [local] / sys / arch / mvme68k / dev

Annotation of sys/arch/mvme68k/dev/if_le.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: if_le.c,v 1.31 2006/01/11 07:21:58 miod Exp $ */
        !             2:
        !             3: /*-
        !             4:  * Copyright (c) 1982, 1992, 1993
        !             5:  *     The Regents of the University of California.  All rights reserved.
        !             6:  *
        !             7:  * Redistribution and use in source and binary forms, with or without
        !             8:  * modification, are permitted provided that the following conditions
        !             9:  * are met:
        !            10:  * 1. Redistributions of source code must retain the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer.
        !            12:  * 2. Redistributions in binary form must reproduce the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer in the
        !            14:  *    documentation and/or other materials provided with the distribution.
        !            15:  * 3. Neither the name of the University nor the names of its contributors
        !            16:  *    may be used to endorse or promote products derived from this software
        !            17:  *    without specific prior written permission.
        !            18:  *
        !            19:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            20:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            21:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            22:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            23:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            24:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            25:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            26:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            27:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            28:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            29:  * SUCH DAMAGE.
        !            30:  *
        !            31:  *     @(#)if_le.c     8.2 (Berkeley) 10/30/93
        !            32:  */
        !            33:
        !            34: #include "bpfilter.h"
        !            35:
        !            36: #include <sys/param.h>
        !            37: #include <sys/systm.h>
        !            38: #include <sys/mbuf.h>
        !            39: #include <sys/syslog.h>
        !            40: #include <sys/socket.h>
        !            41: #include <sys/device.h>
        !            42: #include <sys/malloc.h>
        !            43:
        !            44: #include <net/if.h>
        !            45:
        !            46: #ifdef INET
        !            47: #include <netinet/in.h>
        !            48: #include <netinet/if_ether.h>
        !            49: #endif
        !            50:
        !            51: #include <net/if_media.h>
        !            52:
        !            53: #include <machine/autoconf.h>
        !            54: #include <machine/cpu.h>
        !            55:
        !            56: #include <dev/ic/am7990reg.h>
        !            57: #include <dev/ic/am7990var.h>
        !            58:
        !            59: #include <mvme68k/dev/if_lereg.h>
        !            60: #include <mvme68k/dev/if_levar.h>
        !            61: #include <mvme68k/dev/vme.h>
        !            62:
        !            63: #include "pcc.h"
        !            64: #if NPCC > 0
        !            65: #include <mvme68k/dev/pccreg.h>
        !            66: #endif
        !            67:
        !            68: /* autoconfiguration driver */
        !            69: void  leattach(struct device *, struct device *, void *);
        !            70: int   lematch(struct device *, void *, void *);
        !            71:
        !            72: struct cfattach le_ca = {
        !            73:        sizeof(struct le_softc), lematch, leattach
        !            74: };
        !            75:
        !            76: static int lebustype;
        !            77:
        !            78: void lewrcsr(struct am7990_softc *, u_int16_t, u_int16_t);
        !            79: u_int16_t lerdcsr(struct am7990_softc *, u_int16_t);
        !            80: void vlewrcsr(struct am7990_softc *, u_int16_t, u_int16_t);
        !            81: u_int16_t vlerdcsr(struct am7990_softc *, u_int16_t);
        !            82: void nvram_cmd(struct am7990_softc *, u_char, u_short);
        !            83: u_int16_t nvram_read(struct am7990_softc *, u_char);
        !            84: void vleetheraddr(struct am7990_softc *);
        !            85: void vleinit(struct am7990_softc *);
        !            86: void vlereset(struct am7990_softc *);
        !            87: int vle_intr(void *);
        !            88: void vle_copytobuf_contig(struct am7990_softc *, void *, int, int);
        !            89: void vle_zerobuf_contig(struct am7990_softc *, int, int);
        !            90:
        !            91: /* send command to the nvram controller */
        !            92: void
        !            93: nvram_cmd(sc, cmd, addr)
        !            94:        struct am7990_softc *sc;
        !            95:        u_char cmd;
        !            96:        u_short addr;
        !            97: {
        !            98:        int i;
        !            99:        struct vlereg1 *reg1 = (struct vlereg1 *)((struct le_softc *)sc)->sc_r1;
        !           100:
        !           101:        for (i=0;i<8;i++) {
        !           102:                reg1->ler1_ear=((cmd|(addr<<1))>>i);
        !           103:                CDELAY;
        !           104:        }
        !           105: }
        !           106:
        !           107: /* read nvram one bit at a time */
        !           108: u_int16_t
        !           109: nvram_read(sc, nvram_addr)
        !           110:        struct am7990_softc *sc;
        !           111:        u_char nvram_addr;
        !           112: {
        !           113:        u_short val = 0, mask = 0x04000;
        !           114:        u_int16_t wbit;
        !           115:        /* these used by macros DO NOT CHANGE!*/
        !           116:        struct vlereg1 *reg1 = (struct vlereg1 *)((struct le_softc *)sc)->sc_r1;
        !           117:        ((struct le_softc *)sc)->csr = 0x4f;
        !           118:        ENABLE_NVRAM;
        !           119:        nvram_cmd(sc, NVRAM_RCL, 0);
        !           120:        DISABLE_NVRAM;
        !           121:        CDELAY;
        !           122:        ENABLE_NVRAM;
        !           123:        nvram_cmd(sc, NVRAM_READ, nvram_addr);
        !           124:        for (wbit=0; wbit<15; wbit++) {
        !           125:                (reg1->ler1_ear & 0x01) ? (val = (val | mask)) : (val = (val & (~mask)));
        !           126:                mask = mask>>1;
        !           127:                CDELAY;
        !           128:        }
        !           129:        (reg1->ler1_ear & 0x01) ? (val = (val | 0x8000)) : (val = (val & 0x7FFF));
        !           130:        CDELAY;
        !           131:        DISABLE_NVRAM;
        !           132:        return (val);
        !           133: }
        !           134:
        !           135: void
        !           136: vleetheraddr(sc)
        !           137:        struct am7990_softc *sc;
        !           138: {
        !           139:        u_char * cp = sc->sc_arpcom.ac_enaddr;
        !           140:        u_int16_t ival[3];
        !           141:        u_char i;
        !           142:
        !           143:        for (i=0; i<3; i++) {
        !           144:                ival[i] = nvram_read(sc, i);
        !           145:        }
        !           146:        memcpy(cp, &ival[0], 6);
        !           147: }
        !           148:
        !           149: void
        !           150: lewrcsr(sc, port, val)
        !           151:        struct am7990_softc *sc;
        !           152:        u_int16_t port, val;
        !           153: {
        !           154:        register struct lereg1 *ler1 = (struct lereg1 *)((struct le_softc *)sc)->sc_r1;
        !           155:
        !           156:        ler1->ler1_rap = port;
        !           157:        ler1->ler1_rdp = val;
        !           158: }
        !           159:
        !           160: void
        !           161: vlewrcsr(sc, port, val)
        !           162:        struct am7990_softc *sc;
        !           163:        u_int16_t port, val;
        !           164: {
        !           165:        register struct vlereg1 *ler1 = (struct vlereg1 *)((struct le_softc *)sc)->sc_r1;
        !           166:
        !           167:        ler1->ler1_rap = port;
        !           168:        ler1->ler1_rdp = val;
        !           169: }
        !           170:
        !           171: u_int16_t
        !           172: lerdcsr(sc, port)
        !           173:        struct am7990_softc *sc;
        !           174:        u_int16_t port;
        !           175: {
        !           176:        register struct lereg1 *ler1 = (struct lereg1 *)((struct le_softc *)sc)->sc_r1;
        !           177:        u_int16_t val;
        !           178:
        !           179:        ler1->ler1_rap = port;
        !           180:        val = ler1->ler1_rdp;
        !           181:        return (val);
        !           182: }
        !           183:
        !           184: u_int16_t
        !           185: vlerdcsr(sc, port)
        !           186:        struct am7990_softc *sc;
        !           187:        u_int16_t port;
        !           188: {
        !           189:        register struct vlereg1 *ler1 = (struct vlereg1 *)((struct le_softc *)sc)->sc_r1;
        !           190:        u_int16_t val;
        !           191:
        !           192:        ler1->ler1_rap = port;
        !           193:        val = ler1->ler1_rdp;
        !           194:        return (val);
        !           195: }
        !           196:
        !           197: /* init MVME376, set ipl and vec */
        !           198: void
        !           199: vleinit(sc)
        !           200:        struct am7990_softc *sc;
        !           201: {
        !           202:        register struct vlereg1 *reg1 = (struct vlereg1 *)((struct le_softc *)sc)->sc_r1;
        !           203:        u_char vec = ((struct le_softc *)sc)->sc_vec;
        !           204:        u_char ipl = ((struct le_softc *)sc)->sc_ipl;
        !           205:        ((struct le_softc *)sc)->csr = 0x4f;
        !           206:        WRITE_CSR_AND( ~ipl );
        !           207:        SET_VEC(vec);
        !           208:        return;
        !           209: }
        !           210:
        !           211: /* MVME376 hardware reset */
        !           212: void
        !           213: vlereset(sc)
        !           214:        struct am7990_softc *sc;
        !           215: {
        !           216:        register struct vlereg1 *reg1 = (struct vlereg1 *)((struct le_softc *)sc)->sc_r1;
        !           217:        RESET_HW;
        !           218: #ifdef LEDEBUG
        !           219:        if (sc->sc_debug) {
        !           220:                printf("\nle: hardware reset\n");
        !           221:        }
        !           222: #endif
        !           223:        SYSFAIL_CL;
        !           224:        return;
        !           225: }
        !           226:
        !           227: int
        !           228: vle_intr(sc)
        !           229:        void *sc;
        !           230: {
        !           231:        register struct vlereg1 *reg1 = (struct vlereg1 *)((struct le_softc *)sc)->sc_r1;
        !           232:        int rc;
        !           233:        rc = am7990_intr(sc);
        !           234:        ENABLE_INTR;
        !           235:        return (rc);
        !           236: }
        !           237:
        !           238: void
        !           239: vle_copytobuf_contig(sc, from, boff, len)
        !           240:        struct am7990_softc *sc;
        !           241:        void *from;
        !           242:        int boff, len;
        !           243: {
        !           244:        volatile caddr_t buf = sc->sc_mem;
        !           245:
        !           246:        /*
        !           247:         * Do the cache stuff
        !           248:         */
        !           249:        dma_cachectl(buf + boff, len);
        !           250:        /*
        !           251:         * Just call bcopy() to do the work.
        !           252:         */
        !           253:        bcopy(from, buf + boff, len);
        !           254: }
        !           255:
        !           256: void
        !           257: vle_zerobuf_contig(sc, boff, len)
        !           258:        struct am7990_softc *sc;
        !           259:        int boff, len;
        !           260: {
        !           261:        volatile caddr_t buf = sc->sc_mem;
        !           262:        /*
        !           263:         * Do the cache stuff
        !           264:         */
        !           265:        dma_cachectl(buf + boff, len);
        !           266:        /*
        !           267:         * Just let bzero() do the work
        !           268:         */
        !           269:        bzero(buf + boff, len);
        !           270: }
        !           271:
        !           272: int
        !           273: lematch(parent, vcf, args)
        !           274:        struct device *parent;
        !           275:        void *vcf, *args;
        !           276: {
        !           277:        struct confargs *ca = args;
        !           278:        /* check physical addr for bogus MVME162 addr @0xffffd200. weird XXX - smurph */
        !           279:        if (cputyp == CPU_162 && ca->ca_paddr == 0xffffd200)
        !           280:                return (0);
        !           281:
        !           282:        return (!badvaddr((vaddr_t)ca->ca_vaddr, 2));
        !           283: }
        !           284:
        !           285: /*
        !           286:  * Interface exists: make available by filling in network interface
        !           287:  * record.  System will initialize the interface when it is ready
        !           288:  * to accept packets.
        !           289:  */
        !           290: void
        !           291: leattach(parent, self, aux)
        !           292:        struct device *parent;
        !           293:        struct device *self;
        !           294:        void *aux;
        !           295: {
        !           296:        register struct le_softc *lesc = (struct le_softc *)self;
        !           297:        struct am7990_softc *sc = &lesc->sc_am7990;
        !           298:        struct confargs *ca = aux;
        !           299:        int pri = ca->ca_ipl;
        !           300:        extern void *etherbuf;
        !           301:        paddr_t addr;
        !           302:        int card;
        !           303:
        !           304:        /* XXX the following declarations should be elsewhere */
        !           305:        extern void myetheraddr(u_char *);
        !           306:
        !           307:        lebustype = ca->ca_bustype;
        !           308:
        !           309:        switch (lebustype) {
        !           310:        case BUS_VMES:
        !           311:                /*
        !           312:                 * get the first available etherbuf.  MVME376 uses its own
        !           313:                 * dual-ported RAM for etherbuf.  It is set by dip switches
        !           314:                 * on board.  We support the six Motorola address locations,
        !           315:                 * however, the board can be set up at any other address.
        !           316:                 * XXX These physical addresses should be mapped in extio!!!
        !           317:                 */
        !           318:                switch (ca->ca_paddr) {
        !           319:                case 0xffff1200:
        !           320:                        card = 0;
        !           321:                        break;
        !           322:                case 0xffff1400:
        !           323:                        card = 1;
        !           324:                        break;
        !           325:                case 0xffff1600:
        !           326:                        card = 2;
        !           327:                        break;
        !           328:                case 0xffff5400:
        !           329:                        card = 3;
        !           330:                        break;
        !           331:                case 0xffff5600:
        !           332:                        card = 4;
        !           333:                        break;
        !           334:                case 0xffffa400:
        !           335:                        card = 5;
        !           336:                        break;
        !           337:                default:
        !           338:                        printf(": unsupported address\n");
        !           339:                        return;
        !           340:                }
        !           341:
        !           342:                addr = VLEMEMBASE - (card * VLEMEMSIZE);
        !           343:
        !           344:                sc->sc_mem = (void *)mapiodev(addr, VLEMEMSIZE);
        !           345:                if (sc->sc_mem == NULL) {
        !           346:                        printf("\n%s: no more memory in external I/O map\n",
        !           347:                            sc->sc_dev.dv_xname);
        !           348:                        return;
        !           349:                }
        !           350:                sc->sc_addr = addr & 0x00ffffff;
        !           351:
        !           352:                lesc->sc_r1 = (void *)ca->ca_vaddr;
        !           353:                lesc->sc_ipl = ca->ca_ipl;
        !           354:                lesc->sc_vec = ca->ca_vec;
        !           355:                sc->sc_memsize = VLEMEMSIZE;
        !           356:                sc->sc_conf3 = LE_C3_BSWP;
        !           357:                sc->sc_hwreset = vlereset;
        !           358:                sc->sc_rdcsr = vlerdcsr;
        !           359:                sc->sc_wrcsr = vlewrcsr;
        !           360:                sc->sc_hwinit = vleinit;
        !           361:                sc->sc_copytodesc = vle_copytobuf_contig;
        !           362:                sc->sc_copyfromdesc = am7990_copyfrombuf_contig;
        !           363:                sc->sc_copytobuf = vle_copytobuf_contig;
        !           364:                sc->sc_copyfrombuf = am7990_copyfrombuf_contig;
        !           365:                sc->sc_zerobuf = am7990_zerobuf_contig;
        !           366:                /* get ether address */
        !           367:                vleetheraddr(sc);
        !           368:                break;
        !           369:        case BUS_PCC:
        !           370:                sc->sc_mem = etherbuf;
        !           371:                lesc->sc_r1 = (void *)ca->ca_vaddr;
        !           372:                sc->sc_conf3 = LE_C3_BSWP /*| LE_C3_ACON | LE_C3_BCON*/;
        !           373:                sc->sc_addr = kvtop((vaddr_t)sc->sc_mem);
        !           374:                sc->sc_memsize = LEMEMSIZE;
        !           375:                sc->sc_rdcsr = lerdcsr;
        !           376:                sc->sc_wrcsr = lewrcsr;
        !           377:                sc->sc_hwreset = NULL;
        !           378:                sc->sc_hwinit = NULL;
        !           379:                sc->sc_copytodesc = am7990_copytobuf_contig;
        !           380:                sc->sc_copyfromdesc = am7990_copyfrombuf_contig;
        !           381:                sc->sc_copytobuf = am7990_copytobuf_contig;
        !           382:                sc->sc_copyfrombuf = am7990_copyfrombuf_contig;
        !           383:                sc->sc_zerobuf = am7990_zerobuf_contig;
        !           384:                /* get ether address */
        !           385:                myetheraddr(sc->sc_arpcom.ac_enaddr);
        !           386:                break;
        !           387:        default:
        !           388:                printf(": unknown bus type\n");
        !           389:                return;
        !           390:        }
        !           391:
        !           392:        am7990_config(sc);
        !           393:
        !           394:        /* connect the interrupt */
        !           395:        switch (lebustype) {
        !           396:        case BUS_VMES:
        !           397:                lesc->sc_ih.ih_fn = vle_intr;
        !           398:                lesc->sc_ih.ih_arg = sc;
        !           399:                lesc->sc_ih.ih_ipl = pri;
        !           400:                vmeintr_establish(ca->ca_vec + 0, &lesc->sc_ih, self->dv_xname);
        !           401:                break;
        !           402: #if NPCC > 0
        !           403:        case BUS_PCC:
        !           404:                lesc->sc_ih.ih_fn = am7990_intr;
        !           405:                lesc->sc_ih.ih_arg = sc;
        !           406:                lesc->sc_ih.ih_ipl = pri;
        !           407:                pccintr_establish(PCCV_LE, &lesc->sc_ih, self->dv_xname);
        !           408:                sys_pcc->pcc_leirq = pri | PCC_IRQ_IEN;
        !           409:                break;
        !           410: #endif
        !           411:        }
        !           412: }

CVSweb