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

Annotation of sys/arch/vax/boot/boot/if_le.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: if_le.c,v 1.3 2003/11/07 10:16:45 jmc Exp $ */
                      2: /*     $NetBSD: if_le.c,v 1.6 2000/05/20 13:30:03 ragge Exp $ */
                      3: /*
                      4:  * Copyright (c) 1997, 1999 Ludd, University of Lule}, Sweden.
                      5:  * 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. All advertising materials mentioning features or use of this software
                     16:  *    must display the following acknowledgement:
                     17:  *      This product includes software developed at Ludd, University of
                     18:  *      Lule}, Sweden and its contributors.
                     19:  * 4. The name of the author may not be used to endorse or promote products
                     20:  *    derived from this software without specific prior written permission
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     23:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     24:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     25:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     26:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     27:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     28:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     29:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     30:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     31:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     32:  */
                     33:
                     34: /*
                     35:  * Standalone routine for MicroVAX LANCE chip.
                     36:  */
                     37:
                     38: #include <sys/param.h>
                     39: #include <sys/types.h>
                     40: #include <sys/queue.h>
                     41: #include <sys/socket.h>
                     42:
                     43: #include <net/if.h>
                     44:
                     45: #include <netinet/in.h>
                     46: #include <netinet/in_systm.h>
                     47: #include <netinet/if_ether.h>
                     48:
                     49: #include <../include/sid.h>
                     50: #include <../include/rpb.h>
                     51:
                     52: #include <lib/libsa/netif.h>
                     53: #include <lib/libsa/stand.h>
                     54:
                     55: #include <dev/ic/am7990reg.h>
                     56:
                     57: #include "vaxstand.h"
                     58:
                     59: /*
                     60:  * Buffer sizes.
                     61:  */
                     62: #define TLEN    1
                     63: #define NTBUF   (1 << TLEN)
                     64: #define RLEN    3
                     65: #define NRBUF   (1 << RLEN)
                     66: #define BUFSIZE 1518
                     67:
                     68: #define ETHER_MIN_LEN   64      /* minimum frame length, including CRC */
                     69:
                     70: #define        QW_ALLOC(x)     (((int)alloc((x) + 7) + 7) & ~7)
                     71:
                     72: static int le_get(struct iodesc *, void *, size_t, time_t);
                     73: static int le_put(struct iodesc *, void *, size_t);
                     74: static void copyout(void *from, int dest, int len);
                     75: static void copyin(int src, void *to, int len);
                     76:
                     77: struct netif_driver le_driver = {
                     78:        0, 0, 0, 0, le_get, le_put,
                     79: };
                     80:
                     81: /*
                     82:  * Init block & buffer descriptors according to DEC system
                     83:  * specification documentation.
                     84:  */
                     85: struct initblock {
                     86:        short   ib_mode;
                     87:        char    ib_padr[6]; /* Ethernet address */
                     88:        int     ib_ladrf1;
                     89:        int     ib_ladrf2;
                     90:        int     ib_rdr; /* Receive address */
                     91:        int     ib_tdr; /* Transmit address */
                     92: } *initblock = NULL;
                     93:
                     94: struct nireg {
                     95:        volatile u_short ni_rdp;       /* data port */
                     96:        volatile short ni_pad0;
                     97:        volatile short ni_rap;       /* register select port */
                     98: } *nireg;
                     99:
                    100:
                    101: volatile struct        buffdesc {
                    102:        int     bd_adrflg;
                    103:        short   bd_bcnt;
                    104:        short   bd_mcnt;
                    105: } *rdesc, *tdesc;
                    106:
                    107: static int addoff, kopiera = 0;
                    108:
                    109: /* Flags in the address field */
                    110: #define        BR_OWN  0x80000000
                    111: #define        BR_ERR  0x40000000
                    112: #define        BR_FRAM 0x20000000
                    113: #define        BR_OFLO 0x10000000
                    114: #define        BR_CRC  0x08000000
                    115: #define        BR_BUFF 0x04000000
                    116: #define        BR_STP  0x02000000
                    117: #define        BR_ENP  0x01000000
                    118:
                    119: #define        BT_OWN  0x80000000
                    120: #define        BT_ERR  0x40000000
                    121: #define        BT_MORE 0x10000000
                    122: #define        BT_ONE  0x08000000
                    123: #define        BT_DEF  0x04000000
                    124: #define        BT_STP  0x02000000
                    125: #define        BT_ENP  0x01000000
                    126:
                    127: int    next_rdesc, next_tdesc;
                    128:
                    129: #define        LEWRCSR(port, val) { \
                    130:        nireg->ni_rap = (port); \
                    131:        nireg->ni_rdp = (val); \
                    132: }
                    133:
                    134: #define        LERDCSR(port) \
                    135:        (nireg->ni_rap = port, nireg->ni_rdp)
                    136:
                    137: int
                    138: leopen(struct open_file *f, int adapt, int ctlr, int unit, int part)
                    139: {
                    140:        int i, *ea;
                    141:        volatile int to = 100000;
                    142:        u_char eaddr[6];
                    143:
                    144:        next_rdesc = next_tdesc = 0;
                    145:
                    146:        if (vax_boardtype == VAX_BTYP_650 &&
                    147:            ((vax_siedata >> 8) & 0xff) == VAX_SIE_KA640) {
                    148:                kopiera = 1;
                    149:                ea = (void *)0x20084200;
                    150:                nireg = (void *)0x20084400;
                    151:        } else {
                    152:                *(int *)0x20080014 = 0; /* Be sure we do DMA in low 16MB */
                    153:                ea = (void *)0x20090000; /* XXX Ethernet address */
                    154:                nireg = (void *)0x200e0000;
                    155:        }
                    156:        if (askname == 0) /* Override if autoboot */
                    157:                nireg = (void *)bootrpb.csrphy;
                    158:        else /* Tell kernel from where we booted */
                    159:                bootrpb.csrphy = (int)nireg;
                    160:
                    161:        if (vax_boardtype == VAX_BTYP_43)
                    162:                addoff = 0x28000000;
                    163:        else
                    164:                addoff = 0;
                    165: igen:
                    166:        LEWRCSR(LE_CSR0, LE_C0_STOP);
                    167:        while (to--)
                    168:                ;
                    169:
                    170:        for (i = 0; i < 6; i++)
                    171:                eaddr[i] = ea[i] & 0377;
                    172:
                    173:        if (initblock == NULL) {
                    174:                (void *)initblock =
                    175:                    (char *)QW_ALLOC(sizeof(struct initblock)) + addoff;
                    176:                initblock->ib_mode = LE_MODE_NORMAL;
                    177:                bcopy(eaddr, initblock->ib_padr, 6);
                    178:                initblock->ib_ladrf1 = 0;
                    179:                initblock->ib_ladrf2 = 0;
                    180:
                    181:                (int)rdesc = QW_ALLOC(sizeof(struct buffdesc) * NRBUF) + addoff;
                    182:                initblock->ib_rdr = (RLEN << 29) | (int)rdesc;
                    183:                if (kopiera)
                    184:                        initblock->ib_rdr -= (int)initblock;
                    185:                (int)tdesc = QW_ALLOC(sizeof(struct buffdesc) * NTBUF) + addoff;
                    186:                initblock->ib_tdr = (TLEN << 29) | (int)tdesc;
                    187:                if (kopiera)
                    188:                        initblock->ib_tdr -= (int)initblock;
                    189:                if (kopiera)
                    190:                        copyout(initblock, 0, sizeof(struct initblock));
                    191:
                    192:                for (i = 0; i < NRBUF; i++) {
                    193:                        rdesc[i].bd_adrflg = QW_ALLOC(BUFSIZE) | BR_OWN;
                    194:                        if (kopiera)
                    195:                                rdesc[i].bd_adrflg -= (int)initblock;
                    196:                        rdesc[i].bd_bcnt = -BUFSIZE;
                    197:                        rdesc[i].bd_mcnt = 0;
                    198:                }
                    199:                if (kopiera)
                    200:                        copyout((void *)rdesc, (int)rdesc - (int)initblock,
                    201:                            sizeof(struct buffdesc) * NRBUF);
                    202:
                    203:                for (i = 0; i < NTBUF; i++) {
                    204:                        tdesc[i].bd_adrflg = QW_ALLOC(BUFSIZE);
                    205:                        if (kopiera)
                    206:                                tdesc[i].bd_adrflg -= (int)initblock;
                    207:                        tdesc[i].bd_bcnt = 0xf000;
                    208:                        tdesc[i].bd_mcnt = 0;
                    209:                }
                    210:                if (kopiera)
                    211:                        copyout((void *)tdesc, (int)tdesc - (int)initblock,
                    212:                            sizeof(struct buffdesc) * NTBUF);
                    213:        }
                    214:
                    215:        if (kopiera) {
                    216:                LEWRCSR(LE_CSR1, 0);
                    217:                LEWRCSR(LE_CSR2, 0);
                    218:        } else {
                    219:                LEWRCSR(LE_CSR1, (int)initblock & 0xffff);
                    220:                LEWRCSR(LE_CSR2, ((int)initblock >> 16) & 0xff);
                    221:        }
                    222:
                    223:        LEWRCSR(LE_CSR0, LE_C0_INIT);
                    224:
                    225:        to = 100000;
                    226:        while (to--) {
                    227:                if (LERDCSR(LE_CSR0) & LE_C0_IDON)
                    228:                        break;
                    229:                if (LERDCSR(LE_CSR0) & LE_C0_ERR) {
                    230:                        printf("lance init error: csr0 %x\n", LERDCSR(LE_CSR0));
                    231:                        goto igen;
                    232:                }
                    233:        }
                    234:
                    235:        LEWRCSR(LE_CSR0, LE_C0_INEA | LE_C0_STRT | LE_C0_IDON);
                    236:
                    237:        net_devinit(f, &le_driver, eaddr);
                    238:        return 0;
                    239: }
                    240:
                    241: int
                    242: le_get(struct iodesc *desc, void *pkt, size_t maxlen, time_t timeout)
                    243: {
                    244:        int csr, len;
                    245:        volatile int to = 100000 * timeout;
                    246:
                    247: retry:
                    248:        if (to-- == 0)
                    249:                return 0;
                    250:
                    251:        csr = LERDCSR(LE_CSR0);
                    252:        LEWRCSR(LE_CSR0, csr & (LE_C0_BABL|LE_C0_MISS|LE_C0_MERR|LE_C0_RINT));
                    253:
                    254:        if (kopiera)
                    255:                copyin((int)&rdesc[next_rdesc] - (int)initblock,
                    256:                    (void *)&rdesc[next_rdesc], sizeof(struct buffdesc));
                    257:        if (rdesc[next_rdesc].bd_adrflg & BR_OWN)
                    258:                goto retry;
                    259:
                    260:         if (rdesc[next_rdesc].bd_adrflg & BR_ERR)
                    261:                 len = 0;
                    262:         else {
                    263:                if ((len = rdesc[next_rdesc].bd_mcnt - 4) > maxlen)
                    264:                        len = maxlen;
                    265:
                    266:                if (kopiera)
                    267:                        copyin((rdesc[next_rdesc].bd_adrflg&0xffffff),
                    268:                            pkt, len);
                    269:                else
                    270:                        bcopy((char *)(rdesc[next_rdesc].bd_adrflg&0xffffff) +
                    271:                            addoff, pkt, len);
                    272:        }
                    273:
                    274:        rdesc[next_rdesc].bd_mcnt = 0;
                    275:        rdesc[next_rdesc].bd_adrflg |= BR_OWN;
                    276:        if (kopiera)
                    277:                copyout((void *)&rdesc[next_rdesc], (int)&rdesc[next_rdesc] -
                    278:                    (int)initblock, sizeof(struct buffdesc));
                    279:        if (++next_rdesc >= NRBUF)
                    280:                next_rdesc = 0;
                    281:
                    282:
                    283:        if (len == 0)
                    284:                goto retry;
                    285:        return len;
                    286: }
                    287:
                    288: int
                    289: le_put(struct iodesc *desc, void *pkt, size_t len)
                    290: {
                    291:        volatile int to = 100000;
                    292:        int csr;
                    293:
                    294: retry:
                    295:        if (--to == 0)
                    296:                return -1;
                    297:
                    298:        csr = LERDCSR(LE_CSR0);
                    299:        LEWRCSR(LE_CSR0, csr & (LE_C0_MISS|LE_C0_CERR|LE_C0_TINT));
                    300:
                    301:        if (kopiera)
                    302:                copyin((int)&tdesc[next_tdesc] - (int)initblock,
                    303:                    (void *)&tdesc[next_tdesc], sizeof(struct buffdesc));
                    304:        if (tdesc[next_tdesc].bd_adrflg & BT_OWN)
                    305:                goto retry;
                    306:
                    307:        if (kopiera)
                    308:                copyout(pkt, (tdesc[next_tdesc].bd_adrflg & 0xffffff), len);
                    309:        else
                    310:                bcopy(pkt, (char *)(tdesc[next_tdesc].bd_adrflg & 0xffffff) +
                    311:                    addoff, len);
                    312:        tdesc[next_tdesc].bd_bcnt =
                    313:            (len < ETHER_MIN_LEN ? -ETHER_MIN_LEN : -len);
                    314:        tdesc[next_tdesc].bd_mcnt = 0;
                    315:        tdesc[next_tdesc].bd_adrflg |= BT_OWN | BT_STP | BT_ENP;
                    316:        if (kopiera)
                    317:                copyout((void *)&tdesc[next_tdesc], (int)&tdesc[next_tdesc] -
                    318:                    (int)initblock, sizeof(struct buffdesc));
                    319:
                    320:        LEWRCSR(LE_CSR0, LE_C0_TDMD);
                    321:
                    322:        to = 100000;
                    323:        while (((LERDCSR(LE_CSR0) & LE_C0_TINT) == 0) && --to)
                    324:                ;
                    325:
                    326:        LEWRCSR(LE_CSR0, LE_C0_TINT);
                    327:        if (++next_tdesc >= NTBUF)
                    328:                next_tdesc = 0;
                    329:
                    330:        if (to)
                    331:                return len;
                    332:
                    333:        return -1;
                    334: }
                    335:
                    336: int
                    337: leclose(struct open_file *f)
                    338: {
                    339:        LEWRCSR(LE_CSR0, LE_C0_STOP);
                    340:
                    341:        return 0;
                    342: }
                    343:
                    344: void
                    345: copyout(void *f, int dest, int len)
                    346: {
                    347:        short *from = f;
                    348:        short *toaddr;
                    349:
                    350:        toaddr = (short *)0x20120000 + dest;
                    351:
                    352:        while (len > 0) {
                    353:                *toaddr = *from++;
                    354:                toaddr += 2;
                    355:                len -= 2;
                    356:        }
                    357: }
                    358:
                    359: void
                    360: copyin(int src, void *f, int len)
                    361: {
                    362:        short *to = f;
                    363:        short *fromaddr;
                    364:
                    365:        fromaddr = (short *)0x20120000 + src;
                    366:
                    367:        while (len > 0) {
                    368:                *to++ = *fromaddr;
                    369:                fromaddr += 2;
                    370:                len -= 2;
                    371:        }
                    372: }

CVSweb