if_ni.c revision 1.3 1 1.3 mrg /* $NetBSD: if_ni.c,v 1.3 2006/07/01 05:55:34 mrg Exp $ */
2 1.1 ragge /*
3 1.1 ragge * Copyright (c) 2000 Ludd, University of Lule}, Sweden.
4 1.1 ragge * All rights reserved.
5 1.1 ragge *
6 1.1 ragge * Redistribution and use in source and binary forms, with or without
7 1.1 ragge * modification, are permitted provided that the following conditions
8 1.1 ragge * are met:
9 1.1 ragge * 1. Redistributions of source code must retain the above copyright
10 1.1 ragge * notice, this list of conditions and the following disclaimer.
11 1.1 ragge * 2. Redistributions in binary form must reproduce the above copyright
12 1.1 ragge * notice, this list of conditions and the following disclaimer in the
13 1.1 ragge * documentation and/or other materials provided with the distribution.
14 1.1 ragge * 3. All advertising materials mentioning features or use of this software
15 1.1 ragge * must display the following acknowledgement:
16 1.1 ragge * This product includes software developed at Ludd, University of
17 1.1 ragge * Lule}, Sweden and its contributors.
18 1.1 ragge * 4. The name of the author may not be used to endorse or promote products
19 1.1 ragge * derived from this software without specific prior written permission
20 1.1 ragge *
21 1.1 ragge * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 1.1 ragge * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 1.1 ragge * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 1.1 ragge * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 1.1 ragge * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 1.1 ragge * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 1.1 ragge * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 1.1 ragge * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 1.1 ragge * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 1.1 ragge * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 1.1 ragge */
32 1.1 ragge
33 1.1 ragge /*
34 1.1 ragge * Standalone routine for DEBNA Ethernet controller.
35 1.1 ragge */
36 1.1 ragge
37 1.1 ragge #include <sys/param.h>
38 1.1 ragge #include <sys/types.h>
39 1.1 ragge #include <sys/queue.h>
40 1.1 ragge #include <sys/socket.h>
41 1.1 ragge
42 1.1 ragge #include <net/if.h>
43 1.1 ragge #include <net/if_ether.h>
44 1.1 ragge
45 1.1 ragge #include <netinet/in.h>
46 1.1 ragge #include <netinet/in_systm.h>
47 1.1 ragge
48 1.1 ragge #include <../include/sid.h>
49 1.1 ragge #include <../include/rpb.h>
50 1.1 ragge #include <../include/pte.h>
51 1.1 ragge #include <../include/macros.h>
52 1.1 ragge #include <../include/mtpr.h>
53 1.1 ragge #include <../include/scb.h>
54 1.1 ragge
55 1.1 ragge #include <lib/libkern/libkern.h>
56 1.1 ragge
57 1.1 ragge #include <lib/libsa/netif.h>
58 1.1 ragge #include <lib/libsa/stand.h>
59 1.1 ragge #include <lib/libsa/net.h>
60 1.1 ragge
61 1.1 ragge #include <dev/bi/bireg.h>
62 1.1 ragge
63 1.1 ragge #include "vaxstand.h"
64 1.1 ragge
65 1.1 ragge #undef NIDEBUG
66 1.1 ragge /*
67 1.1 ragge * Tunable buffer parameters. Good idea to have them as power of 8; then
68 1.1 ragge * they will fit into a logical VAX page.
69 1.1 ragge */
70 1.1 ragge #define NMSGBUF 8 /* Message queue entries */
71 1.1 ragge #define NTXBUF 16 /* Transmit queue entries */
72 1.1 ragge #define NTXFRAGS 1 /* Number of transmit buffer fragments */
73 1.1 ragge #define NRXBUF 24 /* Receive queue entries */
74 1.1 ragge #define NBDESCS (NTXBUF + NRXBUF)
75 1.1 ragge #define NQUEUES 3 /* RX + TX + MSG */
76 1.1 ragge #define PKTHDR 18 /* Length of (control) packet header */
77 1.1 ragge #define RXADD 18 /* Additional length of receive datagram */
78 1.1 ragge #define TXADD 18 /* "" transmit "" */
79 1.1 ragge #define MSGADD 134 /* "" message "" */
80 1.1 ragge
81 1.1 ragge #include <dev/bi/if_nireg.h>
82 1.1 ragge
83 1.1 ragge
84 1.1 ragge #define SPTSIZ 16384 /* 8MB */
85 1.1 ragge #define roundpg(x) (((int)x + VAX_PGOFSET) & ~VAX_PGOFSET)
86 1.1 ragge #define ALLOC(x) \
87 1.1 ragge allocbase;xbzero((caddr_t)allocbase,x);allocbase+=roundpg(x);
88 1.1 ragge #define nipqb (&gvppqb->nc_pqb)
89 1.1 ragge #define gvp gvppqb
90 1.1 ragge #define NI_WREG(csr, val) *(volatile long *)(niaddr + (csr)) = (val)
91 1.1 ragge #define NI_RREG(csr) *(volatile long *)(niaddr + (csr))
92 1.1 ragge #define DELAY(x) {volatile int i = x * 3;while (--i);}
93 1.1 ragge #define WAITREG(csr,val) while (NI_RREG(csr) & val);
94 1.1 ragge
95 1.1 ragge static int ni_get(struct iodesc *, void *, size_t, time_t);
96 1.1 ragge static int ni_put(struct iodesc *, void *, size_t);
97 1.1 ragge
98 1.1 ragge static int *syspte, allocbase, niaddr;
99 1.1 ragge static struct ni_gvppqb *gvppqb;
100 1.1 ragge static struct ni_fqb *fqb;
101 1.1 ragge static struct ni_bbd *bbd;
102 1.3 mrg static u_char enaddr[6];
103 1.1 ragge static int beenhere = 0;
104 1.1 ragge
105 1.1 ragge struct netif_driver ni_driver = {
106 1.1 ragge 0, 0, 0, 0, ni_get, ni_put,
107 1.1 ragge };
108 1.1 ragge
109 1.1 ragge static void
110 1.1 ragge xbzero(char *a, int s)
111 1.1 ragge {
112 1.1 ragge while (s--)
113 1.1 ragge *a++ = 0;
114 1.1 ragge }
115 1.1 ragge
116 1.1 ragge static int
117 1.1 ragge failtest(int reg, int mask, int test, char *str)
118 1.1 ragge {
119 1.1 ragge int i = 100;
120 1.1 ragge
121 1.1 ragge do {
122 1.1 ragge DELAY(100000);
123 1.1 ragge } while (((NI_RREG(reg) & mask) != test) && --i);
124 1.1 ragge
125 1.1 ragge if (i == 0) {
126 1.1 ragge printf("ni: %s\n", str);
127 1.1 ragge return 1;
128 1.1 ragge }
129 1.1 ragge return 0;
130 1.1 ragge }
131 1.1 ragge
132 1.1 ragge static int
133 1.1 ragge INSQTI(void *e, void *h)
134 1.1 ragge {
135 1.1 ragge int ret;
136 1.1 ragge
137 1.1 ragge while ((ret = insqti(e, h)) == ILCK_FAILED)
138 1.1 ragge ;
139 1.1 ragge return ret;
140 1.1 ragge }
141 1.1 ragge
142 1.1 ragge static void *
143 1.1 ragge REMQHI(void *h)
144 1.1 ragge {
145 1.1 ragge void *ret;
146 1.1 ragge
147 1.1 ragge while ((ret = remqhi(h)) == (void *)ILCK_FAILED)
148 1.1 ragge ;
149 1.1 ragge return ret;
150 1.1 ragge }
151 1.1 ragge
152 1.1 ragge static void
153 1.1 ragge puton(void *pkt, void *q, int args)
154 1.1 ragge {
155 1.1 ragge INSQTI(pkt, q);
156 1.1 ragge
157 1.1 ragge WAITREG(NI_PCR, PCR_OWN);
158 1.1 ragge NI_WREG(NI_PCR, args);
159 1.1 ragge WAITREG(NI_PCR, PCR_OWN);
160 1.1 ragge }
161 1.1 ragge
162 1.1 ragge static void
163 1.1 ragge remput(void *fq, void *pq, int args)
164 1.1 ragge {
165 1.1 ragge struct ni_dg *data;
166 1.1 ragge int res;
167 1.1 ragge
168 1.1 ragge while ((data = REMQHI(fq)) == 0)
169 1.1 ragge ;
170 1.1 ragge
171 1.1 ragge res = INSQTI(data, pq);
172 1.1 ragge if (res == Q_EMPTY) {
173 1.1 ragge WAITREG(NI_PCR, PCR_OWN);
174 1.1 ragge NI_WREG(NI_PCR, args);
175 1.1 ragge }
176 1.1 ragge }
177 1.1 ragge
178 1.1 ragge static void
179 1.1 ragge insput(void *elem, void *q, int args)
180 1.1 ragge {
181 1.1 ragge int res;
182 1.1 ragge
183 1.1 ragge res = INSQTI(elem, q);
184 1.1 ragge if (res == Q_EMPTY) {
185 1.1 ragge WAITREG(NI_PCR, PCR_OWN);
186 1.1 ragge NI_WREG(NI_PCR, args);
187 1.1 ragge }
188 1.1 ragge }
189 1.1 ragge
190 1.1 ragge int
191 1.1 ragge niopen(struct open_file *f, int adapt, int ctlr, int unit, int part)
192 1.1 ragge {
193 1.1 ragge struct ni_dg *data;
194 1.1 ragge struct ni_msg *msg;
195 1.1 ragge struct ni_ptdb *ptdb;
196 1.1 ragge int i, va, res;
197 1.1 ragge
198 1.1 ragge if (beenhere++ && askname == 0)
199 1.1 ragge return 0;
200 1.1 ragge
201 1.2 ragge niaddr = nexaddr & ~(BI_NODESIZE - 1);
202 1.1 ragge bootrpb.csrphy = niaddr;
203 1.1 ragge if (adapt >= 0)
204 1.1 ragge bootrpb.adpphy = adapt;
205 1.1 ragge /*
206 1.1 ragge * We need a bunch of memory, take it from our load
207 1.1 ragge * address plus 1M.
208 1.1 ragge */
209 1.1 ragge allocbase = RELOC + 1024 * 1024;
210 1.1 ragge /*
211 1.1 ragge * First create a SPT for the first 8MB of physmem.
212 1.1 ragge */
213 1.1 ragge syspte = (int *)ALLOC(SPTSIZ*4);
214 1.1 ragge for (i = 0; i < SPTSIZ; i++)
215 1.1 ragge syspte[i] = PG_V|PG_RW|i;
216 1.1 ragge
217 1.1 ragge
218 1.1 ragge gvppqb = (struct ni_gvppqb *)ALLOC(sizeof(struct ni_gvppqb));
219 1.1 ragge fqb = (struct ni_fqb *)ALLOC(sizeof(struct ni_fqb));
220 1.1 ragge bbd = (struct ni_bbd *)ALLOC(sizeof(struct ni_bbd) * NBDESCS);
221 1.1 ragge
222 1.1 ragge /* Init the PQB struct */
223 1.1 ragge nipqb->np_spt = nipqb->np_gpt = (int)syspte;
224 1.1 ragge nipqb->np_sptlen = nipqb->np_gptlen = SPTSIZ;
225 1.1 ragge nipqb->np_vpqb = (u_int32_t)gvp;
226 1.1 ragge nipqb->np_bvplvl = 1;
227 1.1 ragge nipqb->np_vfqb = (u_int32_t)fqb;
228 1.1 ragge nipqb->np_vbdt = (u_int32_t)bbd;
229 1.1 ragge nipqb->np_nbdr = NBDESCS;
230 1.1 ragge
231 1.1 ragge /* Free queue block */
232 1.1 ragge nipqb->np_freeq = NQUEUES;
233 1.1 ragge fqb->nf_mlen = PKTHDR+MSGADD;
234 1.1 ragge fqb->nf_dlen = PKTHDR+TXADD;
235 1.1 ragge fqb->nf_rlen = PKTHDR+RXADD;
236 1.1 ragge #ifdef NIDEBUG
237 1.1 ragge printf("niopen: syspte %p gvp %p fqb %p bbd %p\n",
238 1.1 ragge syspte, gvppqb, fqb, bbd);
239 1.1 ragge #endif
240 1.1 ragge
241 1.1 ragge NI_WREG(BIREG_VAXBICSR, NI_RREG(BIREG_VAXBICSR) | BICSR_NRST);
242 1.1 ragge DELAY(500000);
243 1.1 ragge i = 20;
244 1.1 ragge while ((NI_RREG(BIREG_VAXBICSR) & BICSR_BROKE) && --i)
245 1.1 ragge DELAY(500000);
246 1.1 ragge #ifdef NIDEBUG
247 1.1 ragge if (i == 0) {
248 1.1 ragge printf("ni: BROKE bit set after reset\n");
249 1.1 ragge return 1;
250 1.1 ragge }
251 1.1 ragge #endif
252 1.1 ragge /* Check state */
253 1.1 ragge if (failtest(NI_PSR, PSR_STATE, PSR_UNDEF, "not undefined state"))
254 1.1 ragge return 1;
255 1.1 ragge
256 1.1 ragge /* Clear owner bits */
257 1.1 ragge NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN);
258 1.1 ragge NI_WREG(NI_PCR, NI_RREG(NI_PCR) & ~PCR_OWN);
259 1.1 ragge
260 1.1 ragge /* kick off init */
261 1.1 ragge NI_WREG(NI_PCR, (int)gvppqb | PCR_INIT | PCR_OWN);
262 1.1 ragge while (NI_RREG(NI_PCR) & PCR_OWN)
263 1.1 ragge DELAY(100000);
264 1.1 ragge
265 1.1 ragge /* Check state */
266 1.1 ragge if (failtest(NI_PSR, PSR_INITED, PSR_INITED, "failed initialize"))
267 1.1 ragge return 1;
268 1.1 ragge
269 1.1 ragge NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN);
270 1.1 ragge WAITREG(NI_PCR, PCR_OWN);
271 1.1 ragge NI_WREG(NI_PCR, PCR_OWN|PCR_ENABLE);
272 1.1 ragge WAITREG(NI_PCR, PCR_OWN);
273 1.1 ragge WAITREG(NI_PSR, PSR_OWN);
274 1.1 ragge
275 1.1 ragge /* Check state */
276 1.1 ragge if (failtest(NI_PSR, PSR_STATE, PSR_ENABLED, "failed enable"))
277 1.1 ragge return 1;
278 1.1 ragge
279 1.1 ragge NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN);
280 1.1 ragge
281 1.1 ragge #ifdef NIDEBUG
282 1.1 ragge printf("Set up message free queue\n");
283 1.1 ragge #endif
284 1.1 ragge
285 1.1 ragge /* Set up message free queue */
286 1.1 ragge va = ALLOC(NMSGBUF * 512);
287 1.1 ragge for (i = 0; i < NMSGBUF; i++) {
288 1.1 ragge msg = (void *)(va + i * 512);
289 1.1 ragge
290 1.1 ragge res = INSQTI(msg, &fqb->nf_mforw);
291 1.1 ragge }
292 1.1 ragge WAITREG(NI_PCR, PCR_OWN);
293 1.1 ragge NI_WREG(NI_PCR, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN);
294 1.1 ragge WAITREG(NI_PCR, PCR_OWN);
295 1.1 ragge
296 1.1 ragge #ifdef NIDEBUG
297 1.1 ragge printf("Set up xmit queue\n");
298 1.1 ragge #endif
299 1.1 ragge
300 1.1 ragge /* Set up xmit queue */
301 1.1 ragge va = ALLOC(NTXBUF * 512);
302 1.1 ragge for (i = 0; i < NTXBUF; i++) {
303 1.1 ragge struct ni_dg *data;
304 1.1 ragge
305 1.1 ragge data = (void *)(va + i * 512);
306 1.1 ragge data->nd_status = 0;
307 1.1 ragge data->nd_len = TXADD;
308 1.1 ragge data->nd_ptdbidx = 1;
309 1.1 ragge data->nd_opcode = BVP_DGRAM;
310 1.1 ragge data->bufs[0]._offset = 0;
311 1.1 ragge data->bufs[0]._key = 1;
312 1.1 ragge data->nd_cmdref = allocbase;
313 1.1 ragge bbd[i].nb_key = 1;
314 1.1 ragge bbd[i].nb_status = 0;
315 1.1 ragge bbd[i].nb_pte = (int)&syspte[allocbase>>9];
316 1.1 ragge allocbase += 2048;
317 1.1 ragge data->bufs[0]._index = i;
318 1.1 ragge
319 1.1 ragge res = INSQTI(data, &fqb->nf_dforw);
320 1.1 ragge }
321 1.1 ragge WAITREG(NI_PCR, PCR_OWN);
322 1.1 ragge NI_WREG(NI_PCR, PCR_FREEQNE|PCR_DFREEQ|PCR_OWN);
323 1.1 ragge WAITREG(NI_PCR, PCR_OWN);
324 1.1 ragge
325 1.1 ragge #ifdef NIDEBUG
326 1.1 ragge printf("recv buffers\n");
327 1.1 ragge #endif
328 1.1 ragge
329 1.1 ragge /* recv buffers */
330 1.1 ragge va = ALLOC(NRXBUF * 512);
331 1.1 ragge for (i = 0; i < NRXBUF; i++) {
332 1.1 ragge struct ni_dg *data;
333 1.1 ragge struct ni_bbd *bd;
334 1.1 ragge int idx;
335 1.1 ragge
336 1.1 ragge data = (void *)(va + i * 512);
337 1.1 ragge data->nd_cmdref = allocbase;
338 1.1 ragge data->nd_len = RXADD;
339 1.1 ragge data->nd_opcode = BVP_DGRAMRX;
340 1.1 ragge data->nd_ptdbidx = 2;
341 1.1 ragge data->bufs[0]._key = 1;
342 1.1 ragge
343 1.1 ragge idx = NTXBUF + i;
344 1.1 ragge bd = &bbd[idx];
345 1.1 ragge bd->nb_pte = (int)&syspte[allocbase>>9];
346 1.1 ragge allocbase += 2048;
347 1.1 ragge bd->nb_len = 2048;
348 1.1 ragge bd->nb_status = NIBD_VALID;
349 1.1 ragge bd->nb_key = 1;
350 1.1 ragge data->bufs[0]._offset = 0;
351 1.1 ragge data->bufs[0]._len = bd->nb_len;
352 1.1 ragge data->bufs[0]._index = idx;
353 1.1 ragge
354 1.1 ragge res = INSQTI(data, &fqb->nf_rforw);
355 1.1 ragge }
356 1.1 ragge WAITREG(NI_PCR, PCR_OWN);
357 1.1 ragge NI_WREG(NI_PCR, PCR_FREEQNE|PCR_RFREEQ|PCR_OWN);
358 1.1 ragge WAITREG(NI_PCR, PCR_OWN);
359 1.1 ragge
360 1.1 ragge #ifdef NIDEBUG
361 1.1 ragge printf("Set initial parameters\n");
362 1.1 ragge #endif
363 1.1 ragge
364 1.1 ragge /* Set initial parameters */
365 1.1 ragge msg = REMQHI(&fqb->nf_mforw);
366 1.1 ragge
367 1.1 ragge msg->nm_opcode = BVP_MSG;
368 1.1 ragge msg->nm_status = 0;
369 1.1 ragge msg->nm_len = sizeof(struct ni_param) + 6;
370 1.1 ragge msg->nm_opcode2 = NI_WPARAM;
371 1.1 ragge ((struct ni_param *)&msg->nm_text[0])->np_flags = NP_PAD;
372 1.1 ragge
373 1.1 ragge puton(msg, &gvp->nc_forw0, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN);
374 1.1 ragge
375 1.1 ragge
376 1.1 ragge while ((data = REMQHI(&gvp->nc_forwr)) == 0)
377 1.1 ragge ;
378 1.1 ragge
379 1.1 ragge msg = (struct ni_msg *)data;
380 1.1 ragge #ifdef NIDEBUG
381 1.1 ragge if (msg->nm_opcode2 != NI_WPARAM) {
382 1.1 ragge printf("ni: wrong response code %d\n", msg->nm_opcode2);
383 1.1 ragge insput(data, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN);
384 1.1 ragge }
385 1.1 ragge #endif
386 1.1 ragge bcopy(((struct ni_param *)&msg->nm_text[0])->np_dpa,
387 1.1 ragge enaddr, ETHER_ADDR_LEN);
388 1.1 ragge insput(data, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN);
389 1.1 ragge
390 1.1 ragge #ifdef NIDEBUG
391 1.1 ragge printf("Clear counters\n");
392 1.1 ragge #endif
393 1.1 ragge
394 1.1 ragge /* Clear counters */
395 1.1 ragge msg = REMQHI(&fqb->nf_mforw);
396 1.1 ragge msg->nm_opcode = BVP_MSG;
397 1.1 ragge msg->nm_status = 0;
398 1.1 ragge msg->nm_len = sizeof(struct ni_param) + 6;
399 1.1 ragge msg->nm_opcode2 = NI_RCCNTR;
400 1.1 ragge
401 1.1 ragge puton(msg, &gvp->nc_forw0, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN);
402 1.1 ragge remput(&gvp->nc_forwr, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN);
403 1.1 ragge
404 1.1 ragge #ifdef NIDEBUG
405 1.1 ragge printf("Enable transmit logic\n");
406 1.1 ragge #endif
407 1.1 ragge
408 1.1 ragge /* Enable transmit logic */
409 1.1 ragge msg = REMQHI(&fqb->nf_mforw);
410 1.1 ragge
411 1.1 ragge msg->nm_opcode = BVP_MSG;
412 1.1 ragge msg->nm_status = 0;
413 1.1 ragge msg->nm_len = 18;
414 1.1 ragge msg->nm_opcode2 = NI_STPTDB;
415 1.1 ragge ptdb = (struct ni_ptdb *)&msg->nm_text[0];
416 1.1 ragge bzero(ptdb, sizeof(struct ni_ptdb));
417 1.1 ragge ptdb->np_index = 1;
418 1.1 ragge ptdb->np_fque = 1;
419 1.1 ragge
420 1.1 ragge puton(msg, &gvp->nc_forw0, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN);
421 1.1 ragge remput(&gvp->nc_forwr, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN);
422 1.1 ragge
423 1.1 ragge #ifdef NIDEBUG
424 1.1 ragge printf("ni: hardware address %s\n", ether_sprintf(enaddr));
425 1.1 ragge printf("Setting receive parameters\n");
426 1.1 ragge #endif
427 1.1 ragge msg = REMQHI(&fqb->nf_mforw);
428 1.1 ragge ptdb = (struct ni_ptdb *)&msg->nm_text[0];
429 1.1 ragge bzero(ptdb, sizeof(struct ni_ptdb));
430 1.1 ragge msg->nm_opcode = BVP_MSG;
431 1.1 ragge msg->nm_len = 18;
432 1.1 ragge ptdb->np_index = 2;
433 1.1 ragge ptdb->np_fque = 2;
434 1.1 ragge msg->nm_opcode2 = NI_STPTDB;
435 1.1 ragge ptdb->np_type = ETHERTYPE_IP;
436 1.1 ragge ptdb->np_flags = PTDB_UNKN|PTDB_BDC;
437 1.1 ragge memset(ptdb->np_mcast[0], 0xff, ETHER_ADDR_LEN);
438 1.1 ragge ptdb->np_adrlen = 1;
439 1.1 ragge msg->nm_len += 8;
440 1.1 ragge insput(msg, &gvp->nc_forw0, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN);
441 1.1 ragge remput(&gvp->nc_forwr, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN);
442 1.1 ragge
443 1.1 ragge #ifdef NIDEBUG
444 1.1 ragge printf("finished\n");
445 1.1 ragge #endif
446 1.1 ragge
447 1.1 ragge net_devinit(f, &ni_driver, enaddr);
448 1.1 ragge return 0;
449 1.1 ragge }
450 1.1 ragge
451 1.1 ragge int
452 1.1 ragge ni_get(struct iodesc *desc, void *pkt, size_t maxlen, time_t timeout)
453 1.1 ragge {
454 1.1 ragge struct ni_dg *data;
455 1.1 ragge struct ni_bbd *bd;
456 1.1 ragge int nsec = getsecs() + timeout;
457 1.1 ragge int len, idx;
458 1.1 ragge
459 1.1 ragge loop: while ((data = REMQHI(&gvp->nc_forwr)) == 0 && (nsec > getsecs()))
460 1.1 ragge ;
461 1.1 ragge
462 1.1 ragge if (nsec <= getsecs())
463 1.1 ragge return 0;
464 1.1 ragge
465 1.1 ragge switch (data->nd_opcode) {
466 1.1 ragge case BVP_DGRAMRX:
467 1.1 ragge idx = data->bufs[0]._index;
468 1.1 ragge bd = &bbd[idx];
469 1.1 ragge len = data->bufs[0]._len;
470 1.1 ragge if (len > maxlen)
471 1.1 ragge len = maxlen;
472 1.1 ragge bcopy((caddr_t)data->nd_cmdref, pkt, len);
473 1.1 ragge bd->nb_pte = (int)&syspte[data->nd_cmdref>>9];
474 1.1 ragge data->bufs[0]._len = bd->nb_len = 2048;
475 1.1 ragge data->bufs[0]._offset = 0;
476 1.1 ragge data->bufs[0]._key = 1;
477 1.1 ragge bd->nb_status = NIBD_VALID;
478 1.1 ragge bd->nb_key = 1;
479 1.1 ragge data->nd_len = RXADD;
480 1.1 ragge data->nd_status = 0;
481 1.1 ragge insput(data, &fqb->nf_rforw,
482 1.1 ragge PCR_FREEQNE|PCR_RFREEQ|PCR_OWN);
483 1.1 ragge return len;
484 1.1 ragge
485 1.1 ragge case BVP_DGRAM:
486 1.1 ragge insput(data, &fqb->nf_dforw, PCR_FREEQNE|PCR_DFREEQ|PCR_OWN);
487 1.1 ragge break;
488 1.1 ragge default:
489 1.1 ragge insput(data, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN);
490 1.1 ragge break;
491 1.1 ragge }
492 1.1 ragge
493 1.1 ragge NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~(PSR_OWN|PSR_RSQ));
494 1.1 ragge goto loop;
495 1.1 ragge }
496 1.1 ragge
497 1.1 ragge int
498 1.1 ragge ni_put(struct iodesc *desc, void *pkt, size_t len)
499 1.1 ragge {
500 1.1 ragge struct ni_dg *data;
501 1.1 ragge struct ni_bbd *bdp;
502 1.1 ragge
503 1.1 ragge data = REMQHI(&fqb->nf_dforw);
504 1.1 ragge #ifdef NIDEBUG
505 1.1 ragge if (data == 0) {
506 1.1 ragge printf("ni_put: driver problem, data == 0\n");
507 1.1 ragge return -1;
508 1.1 ragge }
509 1.1 ragge #endif
510 1.1 ragge bdp = &bbd[(data->bufs[0]._index & 0x7fff)];
511 1.1 ragge bdp->nb_status = NIBD_VALID;
512 1.1 ragge bdp->nb_len = (len < 64 ? 64 : len);
513 1.1 ragge bcopy(pkt, (caddr_t)data->nd_cmdref, len);
514 1.1 ragge data->bufs[0]._offset = 0;
515 1.1 ragge data->bufs[0]._len = bdp->nb_len;
516 1.1 ragge data->nd_opcode = BVP_DGRAM;
517 1.1 ragge data->nd_pad3 = 1;
518 1.1 ragge data->nd_ptdbidx = 1;
519 1.1 ragge data->nd_len = 18;
520 1.1 ragge insput(data, &gvp->nc_forw0, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN);
521 1.1 ragge return len;
522 1.1 ragge }
523 1.1 ragge
524 1.1 ragge int
525 1.1 ragge niclose(struct open_file *f)
526 1.1 ragge {
527 1.1 ragge if (beenhere) {
528 1.1 ragge WAITREG(NI_PCR, PCR_OWN);
529 1.1 ragge NI_WREG(NI_PCR, PCR_OWN|PCR_SHUTDOWN);
530 1.1 ragge WAITREG(NI_PCR, PCR_OWN);
531 1.1 ragge }
532 1.1 ragge return 0;
533 1.1 ragge }
534