[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

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