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