[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

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