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

Annotation of sys/arch/vax/boot/boot/if_de.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: if_de.c,v 1.2 2005/12/10 11:45:43 miod Exp $ */
        !             2: /*     $NetBSD: if_de.c,v 1.2 2002/05/24 21:41:40 ragge Exp $  */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 2000 Ludd, University of Lule}, Sweden. 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:  *     Standalone routine for the DEUNA Ethernet controller.
        !            34:  */
        !            35:
        !            36: #include <sys/param.h>
        !            37: #include <sys/types.h>
        !            38: #include <sys/socket.h>
        !            39: #include <sys/queue.h>
        !            40:
        !            41: #include <net/if.h>
        !            42:
        !            43: #include <netinet/in.h>
        !            44: #include <netinet/in_systm.h>
        !            45: #include <netinet/if_ether.h>
        !            46:
        !            47: #include <lib/libsa/netif.h>
        !            48: #include <lib/libsa/stand.h>
        !            49:
        !            50: #include <arch/vax/qbus/if_dereg.h>
        !            51:
        !            52: #include "arch/vax/include/sid.h"
        !            53: #include "arch/vax/include/rpb.h"
        !            54: #include "arch/vax/include/pte.h"
        !            55:
        !            56: #include "vaxstand.h"
        !            57:
        !            58: static int de_get(struct iodesc *, void *, size_t, time_t);
        !            59: static int de_put(struct iodesc *, void *, size_t);
        !            60: static void dewait(char *);
        !            61:
        !            62: struct netif_driver de_driver = {
        !            63:        0, 0, 0, 0, de_get, de_put,
        !            64: };
        !            65:
        !            66: #define NRCV 8         /* allocate 8 receive descriptors */
        !            67: #define NXMT 4         /* and 4 transmit - must be >1 */
        !            68:
        !            69: struct de_cdata {
        !            70:        /* the following structures are always mapped in */
        !            71:         struct  de_pcbb dc_pcbb;        /* port control block */
        !            72:         struct  de_ring dc_xrent[NXMT]; /* transmit ring entries */
        !            73:         struct  de_ring dc_rrent[NRCV]; /* receive ring entries */
        !            74:         struct  de_udbbuf dc_udbbuf;    /* UNIBUS data buffer */
        !            75:        char    dc_rbuf[NRCV][ETHER_MAX_LEN];
        !            76:        char    dc_xbuf[NXMT][ETHER_MAX_LEN];
        !            77:         /* end mapped area */
        !            78: };
        !            79:
        !            80: static volatile struct de_cdata *dc, *pdc;
        !            81: static volatile char *addr;
        !            82: static int crx, ctx;
        !            83: #define DE_WCSR(csr, val) *(volatile u_short *)(addr + (csr)) = (val)
        !            84: #define DE_WLOW(val) *(volatile u_char *)(addr + DE_PCSR0) = (val)
        !            85: #define DE_WHIGH(val) *(volatile u_char *)(addr + DE_PCSR0 + 1) = (val)
        !            86: #define DE_RCSR(csr) *(volatile u_short *)(addr + (csr))
        !            87: #define LOWORD(x)       ((u_int)(x) & 0xffff)
        !            88: #define HIWORD(x)       (((u_int)(x) >> 16) & 0x3)
        !            89: #define        dereg(x)        ((x) & 017777)
        !            90:
        !            91: int
        !            92: deopen(struct open_file *f, int adapt, int ctlr, int unit, int part)
        !            93: {
        !            94:        int i, cdata, *map, npgs;
        !            95:        char eaddr[6];
        !            96:
        !            97:        /* point to the device in memory */
        !            98:        if (askname == 0) /* Override if autoboot */
        !            99:                addr = (char *)bootrpb.csrphy;
        !           100:        else {
        !           101:                addr = (char *)csrbase + dereg(0174510);
        !           102:                bootrpb.csrphy = (int)addr;
        !           103:        }
        !           104: #ifdef DEV_DEBUG
        !           105:        printf("deopen: csrbase %x addr %p nexaddr %x\n",
        !           106:            csrbase, addr, nexaddr);
        !           107: #endif
        !           108:        /* reset the device and wait for completion */
        !           109:        DE_WCSR(DE_PCSR0, 0);
        !           110:        {volatile int j = 100; while (--j);}
        !           111:        DE_WCSR(DE_PCSR0, PCSR0_RSET);
        !           112:        dewait("reset");
        !           113:
        !           114:        /* Map in the control structures and buffers */
        !           115:        dc = alloc(sizeof(struct de_cdata));
        !           116:        (int)pdc = (int)dc & VAX_PGOFSET;
        !           117:        map = (int *)nexaddr + 512;
        !           118:        npgs = (sizeof(struct de_cdata) >> VAX_PGSHIFT) + 1;
        !           119:        cdata = (int)dc >> VAX_PGSHIFT;
        !           120:        for (i = 0; i < npgs; i++) {
        !           121:                map[i] = PG_V | (cdata + i);
        !           122:        }
        !           123:
        !           124:        bzero((char *)dc, sizeof(struct de_cdata));
        !           125:
        !           126:        /* Tell the DEUNA about our PCB */
        !           127:        DE_WCSR(DE_PCSR2, LOWORD(pdc));
        !           128:        DE_WCSR(DE_PCSR3, HIWORD(pdc));
        !           129:        DE_WLOW(CMD_GETPCBB);
        !           130:        dewait("pcbb");
        !           131:
        !           132:        /* Get our address */
        !           133:        dc->dc_pcbb.pcbb0 = FC_RDPHYAD;
        !           134:        DE_WLOW(CMD_GETCMD);
        !           135:        dewait("read physaddr");
        !           136:        bcopy((char *)&dc->dc_pcbb.pcbb2, eaddr, 6);
        !           137:
        !           138:        /* Create and link the descriptors */
        !           139:        for (i=0; i < NRCV; i++) {
        !           140:                volatile struct de_ring *rp = &dc->dc_rrent[i];
        !           141:
        !           142:                rp->r_lenerr = 0;
        !           143:                rp->r_segbl = LOWORD(&pdc->dc_rbuf[i][0]);
        !           144:                rp->r_segbh = HIWORD(&pdc->dc_rbuf[i][0]);
        !           145:                rp->r_flags = RFLG_OWN;
        !           146:                rp->r_slen = ETHER_MAX_LEN;
        !           147:        }
        !           148:        for (i=0; i < NXMT; i++) {
        !           149:                volatile struct de_ring *rp = &dc->dc_xrent[i];
        !           150:
        !           151:                rp->r_segbl = LOWORD(&pdc->dc_xbuf[i][0]);
        !           152:                rp->r_segbh = HIWORD(&pdc->dc_xbuf[i][0]);
        !           153:                rp->r_tdrerr = 0;
        !           154:                rp->r_flags = 0;
        !           155:        }
        !           156:        crx = ctx = 0;
        !           157:
        !           158:        /* set the transmit and receive ring header addresses */
        !           159:        dc->dc_pcbb.pcbb0 = FC_WTRING;
        !           160:        dc->dc_pcbb.pcbb2 = LOWORD(&pdc->dc_udbbuf);
        !           161:        dc->dc_pcbb.pcbb4 = HIWORD(&pdc->dc_udbbuf);
        !           162:
        !           163:        dc->dc_udbbuf.b_tdrbl = LOWORD(&pdc->dc_xrent[0]);
        !           164:        dc->dc_udbbuf.b_tdrbh = HIWORD(&pdc->dc_xrent[0]);
        !           165:        dc->dc_udbbuf.b_telen = sizeof (struct de_ring) / sizeof(u_int16_t);
        !           166:        dc->dc_udbbuf.b_trlen = NXMT;
        !           167:        dc->dc_udbbuf.b_rdrbl = LOWORD(&pdc->dc_rrent[0]);
        !           168:        dc->dc_udbbuf.b_rdrbh = HIWORD(&pdc->dc_rrent[0]);
        !           169:        dc->dc_udbbuf.b_relen = sizeof (struct de_ring) / sizeof(u_int16_t);
        !           170:        dc->dc_udbbuf.b_rrlen = NRCV;
        !           171:
        !           172:        DE_WLOW(CMD_GETCMD);
        !           173:        dewait("wtring");
        !           174:
        !           175:        dc->dc_pcbb.pcbb0 = FC_WTMODE;
        !           176:        dc->dc_pcbb.pcbb2 = MOD_DRDC|MOD_TPAD|MOD_HDX;
        !           177:        DE_WLOW(CMD_GETCMD);
        !           178:        dewait("wtmode");
        !           179:
        !           180:        DE_WLOW(CMD_START);
        !           181:        dewait("start");
        !           182:
        !           183:        DE_WLOW(CMD_PDMD);
        !           184:        dewait("initpoll");
        !           185:        /* Should be running by now */
        !           186:
        !           187:        net_devinit(f, &de_driver, eaddr);
        !           188:
        !           189:        return 0;
        !           190: }
        !           191:
        !           192: int
        !           193: de_get(struct iodesc *desc, void *pkt, size_t maxlen, time_t timeout)
        !           194: {
        !           195:        volatile int to = 100000 * timeout;
        !           196:        int len, csr0;
        !           197:
        !           198:        if ((csr0 = DE_RCSR(DE_PCSR0)) & PCSR0_INTR)
        !           199:                DE_WHIGH(csr0 >> 8);
        !           200: retry:
        !           201:        if (to-- == 0)
        !           202:                return 0;
        !           203:
        !           204:        if (dc->dc_rrent[crx].r_flags & RFLG_OWN)
        !           205:                goto retry;
        !           206:
        !           207:        if (dc->dc_rrent[crx].r_flags & RFLG_ERRS)
        !           208:                len = 0;
        !           209:        else
        !           210:                len = dc->dc_rrent[crx].r_lenerr & RERR_MLEN;
        !           211:
        !           212:        if (len > maxlen)
        !           213:                len = maxlen;
        !           214:        if (len)
        !           215:                bcopy((char *)&dc->dc_rbuf[crx][0], pkt, len);
        !           216:
        !           217:        dc->dc_rrent[crx].r_flags = RFLG_OWN;
        !           218:        dc->dc_rrent[crx].r_lenerr = 0;
        !           219: #ifdef DEV_DEBUG
        !           220:        printf("Got packet: len %d idx %d maxlen %ld\n", len, crx, maxlen);
        !           221: #endif
        !           222:        if (++crx == NRCV)
        !           223:                crx = 0;
        !           224:
        !           225:        if (len == 0)
        !           226:                goto retry;
        !           227:        return len;
        !           228: }
        !           229:
        !           230:
        !           231: int
        !           232: de_put(struct iodesc *desc, void *pkt, size_t len)
        !           233: {
        !           234:        volatile int to = 100000;
        !           235:        int csr0;
        !           236:
        !           237:        if ((csr0 = DE_RCSR(DE_PCSR0)) & PCSR0_INTR)
        !           238:                DE_WHIGH(csr0 >> 8);
        !           239: #ifdef DEV_DEBUG
        !           240:        printf("de_put: len %ld\n", len);
        !           241: #endif
        !           242: retry:
        !           243:        if (to-- == 0)
        !           244:                return -1;
        !           245:
        !           246:        if (dc->dc_xrent[ctx].r_flags & RFLG_OWN)
        !           247:                goto retry;
        !           248:
        !           249:        bcopy(pkt, (char *)&dc->dc_xbuf[ctx][0], len);
        !           250:
        !           251:        dc->dc_xrent[ctx].r_slen = len;
        !           252:        dc->dc_xrent[ctx].r_tdrerr = 0;
        !           253:        dc->dc_xrent[ctx].r_flags = XFLG_OWN|XFLG_STP|XFLG_ENP;
        !           254:
        !           255:        DE_WLOW(CMD_PDMD);
        !           256:        dewait("start");
        !           257:
        !           258:        if (++ctx == NXMT)
        !           259:                ctx = 0;
        !           260:        return len;
        !           261: }
        !           262:
        !           263: int
        !           264: declose(struct open_file *f)
        !           265: {
        !           266:        DE_WCSR(DE_PCSR0, PCSR0_RSET);
        !           267:        dewait("close");
        !           268:        return 0;
        !           269: }
        !           270:
        !           271: void
        !           272: dewait(char *fn)
        !           273: {
        !           274:        int csr0;
        !           275:
        !           276: #ifdef DEV_DEBUG
        !           277:        printf("dewait: %s...", fn);
        !           278: #endif
        !           279:        while ((DE_RCSR(DE_PCSR0) & PCSR0_INTR) == 0)
        !           280:                ;
        !           281:        csr0 = DE_RCSR(DE_PCSR0);
        !           282:        DE_WHIGH(csr0 >> 8);
        !           283: #ifdef DEV_DEBUG
        !           284:        if (csr0 & PCSR0_PCEI)
        !           285:                printf("failed! CSR0 %x", csr0);
        !           286:        else
        !           287:                printf("done");
        !           288:        printf(", PCSR1 %x\n", DE_RCSR(DE_PCSR1));
        !           289: #endif
        !           290: }

CVSweb