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