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

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

1.1     ! nbrk        1: /*     $OpenBSD: if_qe.c,v 1.3 2002/06/11 09:36:23 hugh Exp $ */
        !             2: /*     $NetBSD: if_qe.c,v 1.3 2000/05/20 13:30:03 ragge Exp $ */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 1998 Roar Thronęs.  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 by Roar Thronęs.
        !            18:  * 4. The name of the author may not be used to endorse or promote products
        !            19:  *    derived from this software without specific prior written permission
        !            20:  *
        !            21:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            22:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            23:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            24:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            25:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            26:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            27:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            28:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            29:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            30:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            31:  *
        !            32:  *     Standalone routine for the DEQNA.
        !            33:  */
        !            34:
        !            35: #include <sys/param.h>
        !            36: #include <sys/types.h>
        !            37:
        !            38: #include <netinet/in.h>
        !            39: #include <netinet/in_systm.h>
        !            40:
        !            41: #include <lib/libsa/netif.h>
        !            42: #include <lib/libsa/stand.h>
        !            43:
        !            44: #include <arch/vax/if/if_qereg.h>
        !            45:
        !            46: #include "../include/rpb.h"
        !            47:
        !            48: #include "vaxstand.h"
        !            49:
        !            50: static int qe_get(struct iodesc *desc, void *pkt, size_t, time_t timeout);
        !            51: static int qe_put(struct iodesc *desc, void *pkt, size_t);
        !            52: static void qe_init(u_char *eaddr);
        !            53:
        !            54: struct netif_driver qe_driver = {
        !            55:        0, 0, 0, 0, qe_get, qe_put,
        !            56: };
        !            57:
        !            58: #define NRCV   1                      /* Receive descriptors          */
        !            59: #define NXMT   1                       /* Transmit descriptors         */
        !            60:
        !            61: #define QE_INTS               (QE_RCV_INT | QE_XMIT_INT)
        !            62: #define MAXPACKETSIZE  0x800           /* Because of (buggy) DEQNA */
        !            63:
        !            64: static struct  qe_softc {
        !            65:        struct  qe_ring rring[NRCV+2];  /* Receive ring descriptors     */
        !            66:        struct  qe_ring tring[NXMT+2];  /* Xmit ring descriptors        */
        !            67:        u_char  setup_pkt[16][8];       /* Setup packet                 */
        !            68:        char    qein[2048], qeout[2048];/* Packet buffers               */
        !            69: } qe_softc;
        !            70:
        !            71: static struct qe_softc *sc = &qe_softc;
        !            72: static int addr;
        !            73:
        !            74: #define QE_WCSR(csr, val) \
        !            75:        (*((volatile u_short *)(addr + (csr))) = (val))
        !            76: #define QE_RCSR(csr) \
        !            77:        *((volatile u_short *)(addr + (csr)))
        !            78: #define DELAY(x)               {volatile int i = x;while (--i);}
        !            79: #define LOWORD(x)      ((int)(x) & 0xffff)
        !            80: #define HIWORD(x)      (((int)(x) >> 16) & 0x3f)
        !            81: #define qereg(x) ((x) & 017777)
        !            82:
        !            83: int
        !            84: qeopen(struct open_file *f, int adapt, int ctlr, int unit, int part) {
        !            85:        u_char eaddr[6];
        !            86:
        !            87:        if (askname == 0)
        !            88:                addr = bootrpb.csrphy;  /* Autoboot; use RPB instead */
        !            89:        else {
        !            90:                addr = 0x20000000;
        !            91:                if (unit == 0)
        !            92:                        addr += qereg(0774440); /* XQA0 */
        !            93:                else if (unit == 1)
        !            94:                        addr += qereg(0174460); /* XQB0 */
        !            95:                else
        !            96:                        return ECTLR;
        !            97:        }
        !            98:
        !            99:        qe_init(eaddr);
        !           100:
        !           101:        net_devinit(f, &qe_driver, eaddr);
        !           102:        return 0;
        !           103: }
        !           104:
        !           105: void
        !           106: qe_init(u_char *eaddr)
        !           107: {
        !           108:        int i,j;
        !           109:
        !           110:        QE_WCSR(QE_CSR_CSR, QE_RESET);
        !           111:        QE_WCSR(QE_CSR_CSR, QE_RCSR(QE_CSR_CSR) & ~QE_RESET);
        !           112:
        !           113:        for (i = 0; i < 6; i++) {
        !           114:                sc->setup_pkt[i][1] = QE_RCSR(i * 2);
        !           115:                sc->setup_pkt[i+8][1] = QE_RCSR(i * 2);
        !           116:                sc->setup_pkt[i][2] = 0xff;
        !           117:                sc->setup_pkt[i+8][2] = QE_RCSR(i * 2);
        !           118:                for (j=3; j < 8; j++) {
        !           119:                        sc->setup_pkt[i][j] = QE_RCSR(i * 2);
        !           120:                        sc->setup_pkt[i+8][j] = QE_RCSR(i * 2);
        !           121:                }
        !           122:                eaddr[i] = QE_RCSR(i * 2);
        !           123:        }
        !           124:
        !           125:        bzero((caddr_t)sc->rring, sizeof(struct qe_ring));
        !           126:        sc->rring->qe_buf_len = -64;
        !           127:        sc->rring->qe_addr_lo = (short)((int)sc->setup_pkt);
        !           128:        sc->rring->qe_addr_hi = (short)((int)sc->setup_pkt >> 16);
        !           129:
        !           130:        bzero((caddr_t)sc->tring, sizeof(struct qe_ring));
        !           131:        sc->tring->qe_buf_len = -64;
        !           132:        sc->tring->qe_addr_lo = (short)((int)sc->setup_pkt);
        !           133:        sc->tring->qe_addr_hi = (short)((int)sc->setup_pkt >> 16);
        !           134:
        !           135:        sc->rring[0].qe_flag = sc->rring[0].qe_status1 = QE_NOTYET;
        !           136:        sc->rring->qe_addr_hi |= QE_VALID;
        !           137:
        !           138:        sc->tring[0].qe_flag = sc->tring[0].qe_status1 = QE_NOTYET;
        !           139:        sc->tring->qe_addr_hi |= QE_VALID | QE_SETUP | QE_EOMSG;
        !           140:
        !           141:        QE_WCSR(QE_CSR_CSR, QE_XMIT_INT | QE_RCV_INT);
        !           142:
        !           143:        QE_WCSR(QE_CSR_RCLL, LOWORD(sc->rring));
        !           144:        QE_WCSR(QE_CSR_RCLH, HIWORD(sc->rring));
        !           145:        QE_WCSR(QE_CSR_XMTL, LOWORD(sc->tring));
        !           146:        QE_WCSR(QE_CSR_XMTH, HIWORD(sc->tring));
        !           147:
        !           148:        while ((QE_RCSR(QE_CSR_CSR) & QE_INTS) != QE_INTS)
        !           149:                ;
        !           150:        QE_WCSR(QE_CSR_CSR, QE_RCSR(QE_CSR_CSR) | QE_INTS);
        !           151:        QE_WCSR(QE_CSR_CSR, QE_RCSR(QE_CSR_CSR) & ~(QE_INT_ENABLE|QE_ELOOP));
        !           152:        QE_WCSR(QE_CSR_CSR, QE_RCSR(QE_CSR_CSR) | QE_ILOOP);
        !           153:
        !           154:        sc->rring[0].qe_addr_lo = (short)((int)sc->qein & 0xffff);
        !           155:        sc->rring[0].qe_addr_hi = (short)((int)sc->qein >> 16);
        !           156:        sc->rring[0].qe_buf_len=-MAXPACKETSIZE/2;
        !           157:        sc->rring[0].qe_addr_hi |= QE_VALID;
        !           158:        sc->rring[0].qe_flag=sc->rring[0].qe_status1=QE_NOTYET;
        !           159:        sc->rring[0].qe_status2=1;
        !           160:
        !           161:        sc->rring[1].qe_addr_lo = 0;
        !           162:        sc->rring[1].qe_addr_hi = 0;
        !           163:        sc->rring[1].qe_flag=sc->rring[1].qe_status1=QE_NOTYET;
        !           164:        sc->rring[1].qe_status2=1;
        !           165:
        !           166:        sc->tring[0].qe_addr_lo = (short)((int)sc->qeout & 0xffff);
        !           167:        sc->tring[0].qe_addr_hi = (short)((int)sc->qeout >> 16);
        !           168:        sc->tring[0].qe_buf_len=0;
        !           169:        sc->tring[0].qe_flag=sc->tring[0].qe_status1=QE_NOTYET;
        !           170:        sc->tring[0].qe_addr_hi |= QE_EOMSG|QE_VALID;
        !           171:
        !           172:        sc->tring[1].qe_flag=sc->tring[1].qe_status1=QE_NOTYET;
        !           173:        sc->tring[1].qe_addr_lo = 0;
        !           174:        sc->tring[1].qe_addr_hi = 0;
        !           175:
        !           176:        QE_WCSR(QE_CSR_CSR, QE_RCSR(QE_CSR_CSR) | QE_RCV_ENABLE);
        !           177:        QE_WCSR(QE_CSR_RCLL, LOWORD(sc->rring));
        !           178:        QE_WCSR(QE_CSR_RCLH, HIWORD(sc->rring));
        !           179: }
        !           180:
        !           181: int
        !           182: qe_get(struct iodesc *desc, void *pkt, size_t maxlen, time_t timeout) {
        !           183:        int len, j;
        !           184:
        !           185: retry:
        !           186:        for(j = 0x10000;j && (QE_RCSR(QE_CSR_CSR) & QE_RCV_INT) == 0; j--)
        !           187:                ;
        !           188:
        !           189:        if ((QE_RCSR(QE_CSR_CSR) & QE_RCV_INT) == 0)
        !           190:                goto fail;
        !           191:
        !           192:        QE_WCSR(QE_CSR_CSR, QE_RCSR(QE_CSR_CSR) & ~(QE_RCV_ENABLE|QE_XMIT_INT));
        !           193:
        !           194:        len= ((sc->rring[0].qe_status1 & QE_RBL_HI) |
        !           195:            (sc->rring[0].qe_status2 & QE_RBL_LO)) + 60;
        !           196:
        !           197:        if (sc->rring[0].qe_status1 & 0xc000)
        !           198:                goto fail;
        !           199:
        !           200:        if (len == 0)
        !           201:                goto retry;
        !           202:
        !           203:        bcopy((void*)sc->qein,pkt,len);
        !           204:
        !           205:
        !           206: end:
        !           207:        sc->rring[0].qe_status2 = sc->rring[1].qe_status2 = 1;
        !           208:        sc->rring[0].qe_flag=sc->rring[0].qe_status1=QE_NOTYET;
        !           209:        sc->rring[1].qe_flag=sc->rring[1].qe_status1=QE_NOTYET;
        !           210:        QE_WCSR(QE_CSR_CSR, QE_RCSR(QE_CSR_CSR) | QE_RCV_ENABLE);
        !           211:
        !           212:        QE_WCSR(QE_CSR_RCLL, LOWORD(sc->rring));
        !           213:        QE_WCSR(QE_CSR_RCLH, HIWORD(sc->rring));
        !           214:        return len;
        !           215:
        !           216: fail:  len = -1;
        !           217:        goto end;
        !           218: }
        !           219:
        !           220: int
        !           221: qe_put(struct iodesc *desc, void *pkt, size_t len) {
        !           222:        int j;
        !           223:
        !           224:        bcopy(pkt, (char *)sc->qeout, len);
        !           225:        sc->tring[0].qe_buf_len=-len/2;
        !           226:        sc->tring[0].qe_flag=sc->tring[0].qe_status1=QE_NOTYET;
        !           227:        sc->tring[1].qe_flag=sc->tring[1].qe_status1=QE_NOTYET;
        !           228:
        !           229:        QE_WCSR(QE_CSR_XMTL, LOWORD(sc->tring));
        !           230:        QE_WCSR(QE_CSR_XMTH, HIWORD(sc->tring));
        !           231:
        !           232:        for(j = 0; (j < 0x10000) && ((QE_RCSR(QE_CSR_CSR) & QE_XMIT_INT) == 0); j++)
        !           233:                ;
        !           234:
        !           235:        if ((QE_RCSR(QE_CSR_CSR) & QE_XMIT_INT) == 0) {
        !           236:                char eaddr[6];
        !           237:
        !           238:                qe_init(eaddr);
        !           239:                return -1;
        !           240:        }
        !           241:        QE_WCSR(QE_CSR_CSR, QE_RCSR(QE_CSR_CSR) & ~QE_RCV_INT);
        !           242:
        !           243:        if (sc->tring[0].qe_status1 & 0xc000) {
        !           244:                char eaddr[6];
        !           245:
        !           246:                qe_init(eaddr);
        !           247:                return -1;
        !           248:        }
        !           249:        return len;
        !           250: }
        !           251:
        !           252: int
        !           253: qeclose(struct open_file *nif)
        !           254: {
        !           255:        QE_WCSR(QE_CSR_CSR, QE_RESET);
        !           256:        QE_WCSR(QE_CSR_CSR, QE_RCSR(QE_CSR_CSR) & ~QE_RESET);
        !           257:
        !           258:        return 0;
        !           259: }

CVSweb