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