[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

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