1 /*
2 * dp8390.c
3 *
4 * This file contains a ethernet device driver for NS dp8390 based ethernet
5 * cards.
6 *
7 * The valid messages and their parameters are:
8 *
9 * m_type DL_PORT DL_PROC DL_COUNT DL_MODE DL_ADDR
10 * |------------+----------+---------+----------+---------+---------|
11 * | HARDINT | | | | | |
12 * |------------|----------|---------|----------|---------|---------|
13 * | DL_WRITE | port nr | proc nr | count | mode | address |
14 * |------------|----------|---------|----------|---------|---------|
15 * | DL_WRITEV | port nr | proc nr | count | mode | address |
16 * |------------|----------|---------|----------|---------|---------|
17 * | DL_READ | port nr | proc nr | count | | address |
18 * |------------|----------|---------|----------|---------|---------|
19 * | DL_READV | port nr | proc nr | count | | address |
20 * |------------|----------|---------|----------|---------|---------|
21 * | DL_INIT | port nr | proc nr | mode | | address |
22 * |------------|----------|---------|----------|---------|---------|
23 * | DL_GETSTAT | port nr | proc nr | | | address |
24 * |------------|----------|---------|----------|---------|---------|
25 * | DL_STOP | port_nr | | | | |
26 * |------------|----------|---------|----------|---------|---------|
27 *
28 * The messages sent are:
29 *
30 * m-type DL_PORT DL_PROC DL_COUNT DL_STAT DL_CLCK
31 * |-------------+----------+---------+----------+---------+---------|
32 * |DL_TASK_REPLY| port nr | proc nr | rd-count | err|stat| clock |
33 * |-------------+----------+---------+----------+---------+---------|
34 *
35 * m_type m3_i1 m3_i2 m3_ca1
36 * |-------------+---------+-----------+---------------|
37 * |DL_INIT_REPLY| port nr | last port | ethernet addr |
38 * |-------------+---------+-----------+---------------|
39 *
40 * Created: before Dec 28, 1992 by Philip Homburg <philip@f-mnx.phicoh.com>
41 *
42 * Modified Mar 10 1994 by Philip Homburg
43 * Become a generic dp8390 driver.
44 *
45 * Modified Dec 20 1996 by G. Falzoni <falzoni@marina.scn.de>
46 * Added support for 3c503 boards.
47 */
48
49 #include "../drivers.h"
50
51 #include <stdlib.h>
52 #include <minix/com.h>
53 #include <net/hton.h>
54 #include <net/gen/ether.h>
55 #include <net/gen/eth_io.h>
56 #include "assert.h"
57
58 #include "local.h"
59 #include "dp8390.h"
60
61 #define DE_PORT_NR 3
62
63 static dpeth_t de_table[DE_PORT_NR];
64 static u16_t eth_ign_proto;
65 static char *progname;
66
67 /* Configuration */
68 typedef struct dp_conf
69 {
70 port_t dpc_port;
71 int dpc_irq;
72 phys_bytes dpc_mem;
73 char *dpc_envvar;
74 } dp_conf_t;
75
76 dp_conf_t dp_conf[]= /* Card addresses */
77 {
78 /* I/O port, IRQ, Buffer address, Env. var. */
79 { 0x280, 3, 0xD0000, "DPETH0" },
80 { 0x300, 5, 0xC8000, "DPETH1" },
81 { 0x380, 10, 0xD8000, "DPETH2" },
82 };
83
84 /* Test if dp_conf has exactly DE_PORT_NR entries. If not then you will see
85 * the error: "array size is negative".
86 */
87 extern int ___dummy[DE_PORT_NR == sizeof(dp_conf)/sizeof(dp_conf[0]) ? 1 : -1];
88
89 /* Card inits configured out? */
90 #if !ENABLE_WDETH
91 #define wdeth_probe(dep) (0)
92 #endif
93 #if !ENABLE_NE2000
94 #define ne_probe(dep) (0)
95 #endif
96 #if !ENABLE_3C503
97 #define el2_probe(dep) (0)
98 #endif
99
100 /* Some clones of the dp8390 and the PC emulator 'Bochs' require the CR_STA
101 * on writes to the CR register. Additional CR_STAs do not appear to hurt
102 * genuine dp8390s
103 */
104 #define CR_EXTRA CR_STA
105
106 #if ENABLE_PCI
107 _PROTOTYPE( static void pci_conf, (void) );
108 #endif
109 _PROTOTYPE( static void do_vwrite, (message *mp, int from_int,
110 int vectored) );
111 _PROTOTYPE( static void do_vread, (message *mp, int vectored) );
112 _PROTOTYPE( static void do_init, (message *mp) );
113 _PROTOTYPE( static void do_int, (dpeth_t *dep) );
114 _PROTOTYPE( static void do_getstat, (message *mp) );
115 _PROTOTYPE( static void do_getname, (message *mp) );
116 _PROTOTYPE( static void do_stop, (message *mp) );
117 _PROTOTYPE( static void dp_init, (dpeth_t *dep) );
118 _PROTOTYPE( static void dp_confaddr, (dpeth_t *dep) );
119 _PROTOTYPE( static void dp_reinit, (dpeth_t *dep) );
120 _PROTOTYPE( static void dp_reset, (dpeth_t *dep) );
121 _PROTOTYPE( static void dp_check_ints, (dpeth_t *dep) );
122 _PROTOTYPE( static void dp_recv, (dpeth_t *dep) );
123 _PROTOTYPE( static void dp_send, (dpeth_t *dep) );
124 _PROTOTYPE( static void dp8390_stop, (void) );
125 _PROTOTYPE( static void dp_getblock, (dpeth_t *dep, int page,
126 size_t offset, size_t size, void *dst) );
127 _PROTOTYPE( static void dp_pio8_getblock, (dpeth_t *dep, int page,
128 size_t offset, size_t size, void *dst) );
129 _PROTOTYPE( static void dp_pio16_getblock, (dpeth_t *dep, int page,
130 size_t offset, size_t size, void *dst) );
131 _PROTOTYPE( static int dp_pkt2user, (dpeth_t *dep, int page,
132 int length) );
133 _PROTOTYPE( static void dp_user2nic, (dpeth_t *dep, iovec_dat_t *iovp,
134 vir_bytes offset, int nic_addr, vir_bytes count) );
135 _PROTOTYPE( static void dp_pio8_user2nic, (dpeth_t *dep,
136 iovec_dat_t *iovp, vir_bytes offset,
137 int nic_addr, vir_bytes count) );
138 _PROTOTYPE( static void dp_pio16_user2nic, (dpeth_t *dep,
139 iovec_dat_t *iovp, vir_bytes offset,
140 int nic_addr, vir_bytes count) );
141 _PROTOTYPE( static void dp_nic2user, (dpeth_t *dep, int nic_addr,
142 iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) );
143 _PROTOTYPE( static void dp_pio8_nic2user, (dpeth_t *dep, int nic_addr,
144 iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) );
145 _PROTOTYPE( static void dp_pio16_nic2user, (dpeth_t *dep, int nic_addr,
146 iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) );
147 _PROTOTYPE( static void dp_next_iovec, (iovec_dat_t *iovp) );
148 _PROTOTYPE( static void conf_hw, (dpeth_t *dep) );
149 _PROTOTYPE( static void update_conf, (dpeth_t *dep, dp_conf_t *dcp) );
150 _PROTOTYPE( static int calc_iovec_size, (iovec_dat_t *iovp) );
151 _PROTOTYPE( static void reply, (dpeth_t *dep, int err, int may_block) );
152 _PROTOTYPE( static void mess_reply, (message *req, message *reply) );
153 _PROTOTYPE( static void get_userdata, (int user_proc,
154 vir_bytes user_addr, vir_bytes count, void *loc_addr) );
155 _PROTOTYPE( static void put_userdata, (int user_proc,
156 vir_bytes user_addr, vir_bytes count, void *loc_addr) );
157 _PROTOTYPE( static void insb, (port_t port, void *buf, size_t size) );
158 _PROTOTYPE( static void insw, (port_t port, void *buf, size_t size) );
159 _PROTOTYPE( static void do_vir_insb, (port_t port, int proc,
160 vir_bytes buf, size_t size) );
161 _PROTOTYPE( static void do_vir_insw, (port_t port, int proc,
162 vir_bytes buf, size_t size) );
163 _PROTOTYPE( static void do_vir_outsb, (port_t port, int proc,
164 vir_bytes buf, size_t size) );
165 _PROTOTYPE( static void do_vir_outsw, (port_t port, int proc,
166 vir_bytes buf, size_t size) );
167
168 /*===========================================================================*
169 * dpeth_task *
170 *===========================================================================*/
171 int main(int argc, char *argv[])
172 {
173 message m;
174 int i, irq, r, tasknr;
175 dpeth_t *dep;
176 long v;
177
178 if (argc < 1)
179 {
180 panic("DP8390",
181 "A head which at this time has no name", NO_NUM);
182 }
183 (progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]);
184
185 env_setargs(argc, argv);
186
187 for (i= 0, dep= de_table; i<DE_PORT_NR; i++, dep++)
188 {
189 strcpy(dep->de_name, "dp8390#0");
190 dep->de_name[7] += i;
191 }
192
193 v= 0;
194 (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL);
195 eth_ign_proto= htons((u16_t) v);
196
197 /* Try to notify inet that we are present (again) */
198 r = findproc("inet", &tasknr);
199 if (r == OK)
200 notify(tasknr);
201
202 while (TRUE)
203 {
204 if ((r= receive(ANY, &m)) != OK)
205 panic("", "dp8390: receive failed", r);
206
207 switch (m.m_type)
208 {
209 case DEV_PING: notify(m.m_source); continue;
210 case DL_WRITE: do_vwrite(&m, FALSE, FALSE); break;
211 case DL_WRITEV: do_vwrite(&m, FALSE, TRUE); break;
212 case DL_READ: do_vread(&m, FALSE); break;
213 case DL_READV: do_vread(&m, TRUE); break;
214 case DL_INIT: do_init(&m); break;
215 case DL_GETSTAT: do_getstat(&m); break;
216 case DL_GETNAME: do_getname(&m); break;
217 case DL_STOP: do_stop(&m); break;
218 case HARD_INT:
219 for (i= 0, dep= &de_table[0]; i<DE_PORT_NR; i++, dep++)
220 {
221 if (dep->de_mode != DEM_ENABLED)
222 continue;
223 assert(dep->de_flags & DEF_ENABLED);
224 irq= dep->de_irq;
225 assert(irq >= 0 && irq < NR_IRQ_VECTORS);
226 if (dep->de_int_pending || 1)
227 {
228 dep->de_int_pending= 0;
229 dp_check_ints(dep);
230 do_int(dep);
231 r= sys_irqenable(&dep->de_hook);
232 if (r != OK)
233 {
234 panic("DP8390",
235 "unable enable interrupts", r);
236 }
237 }
238 }
239 break;
240 case SYS_SIG: {
241 sigset_t sigset = m.NOTIFY_ARG;
242 if (sigismember(&sigset, SIGKSTOP)) dp8390_stop();
243 break;
244 }
245 case SYN_ALARM:
246 printf("dp8390: strange, got SYN_ALARM\n");
247 break;
248 default:
249 panic("", "dp8390: illegal message", m.m_type);
250 }
251 }
252 }
253
254 #if 0
255 /*===========================================================================*
256 * dp8390_dump *
257 *===========================================================================*/
258 void dp8390_dump()
259 {
260 dpeth_t *dep;
261 int i, isr;
262
263 printf("\n");
264 for (i= 0, dep = &de_table[0]; i<DE_PORT_NR; i++, dep++)
265 {
266 #if XXX
267 if (dep->de_mode == DEM_DISABLED)
268 printf("dp8390 port %d is disabled\n", i);
269 else if (dep->de_mode == DEM_SINK)
270 printf("dp8390 port %d is in sink mode\n", i);
271 #endif
272
273 if (dep->de_mode != DEM_ENABLED)
274 continue;
275
276 printf("dp8390 statistics of port %d:\n", i);
277
278 printf("recvErr :%8ld\t", dep->de_stat.ets_recvErr);
279 printf("sendErr :%8ld\t", dep->de_stat.ets_sendErr);
280 printf("OVW :%8ld\n", dep->de_stat.ets_OVW);
281
282 printf("CRCerr :%8ld\t", dep->de_stat.ets_CRCerr);
283 printf("frameAll :%8ld\t", dep->de_stat.ets_frameAll);
284 printf("missedP :%8ld\n", dep->de_stat.ets_missedP);
285
286 printf("packetR :%8ld\t", dep->de_stat.ets_packetR);
287 printf("packetT :%8ld\t", dep->de_stat.ets_packetT);
288 printf("transDef :%8ld\n", dep->de_stat.ets_transDef);
289
290 printf("collision :%8ld\t", dep->de_stat.ets_collision);
291 printf("transAb :%8ld\t", dep->de_stat.ets_transAb);
292 printf("carrSense :%8ld\n", dep->de_stat.ets_carrSense);
293
294 printf("fifoUnder :%8ld\t", dep->de_stat.ets_fifoUnder);
295 printf("fifoOver :%8ld\t", dep->de_stat.ets_fifoOver);
296 printf("CDheartbeat:%8ld\n", dep->de_stat.ets_CDheartbeat);
297
298 printf("OWC :%8ld\t", dep->de_stat.ets_OWC);
299
300 isr= inb_reg0(dep, DP_ISR);
301 printf("dp_isr = 0x%x + 0x%x, de_flags = 0x%x\n", isr,
302 inb_reg0(dep, DP_ISR), dep->de_flags);
303 }
304 }
305 #endif
306
307 /*===========================================================================*
308 * dp8390_stop *
309 *===========================================================================*/
310 static void dp8390_stop()
311 {
312 message mess;
313 int i;
314
315 for (i= 0; i<DE_PORT_NR; i++)
316 {
317 if (de_table[i].de_mode != DEM_ENABLED)
318 continue;
319 mess.m_type= DL_STOP;
320 mess.DL_PORT= i;
321 do_stop(&mess);
322 }
323 }
324
325 #if ENABLE_PCI
326 /*===========================================================================*
327 * pci_conf *
328 *===========================================================================*/
329 static void pci_conf()
330 {
331 int i, h;
332 char *envvar;
333 struct dpeth *dep;
334 static char envfmt[] = "*:d.d.d";
335 long v;
336 static int first_time= 1;
337
338 if (!first_time)
339 return;
340 first_time= 0;
341
342 for (i= 0, dep= de_table; i<DE_PORT_NR; i++, dep++)
343 {
344 envvar= dp_conf[i].dpc_envvar;
345 if (!(dep->de_pci= env_prefix(envvar, "pci")))
346 continue; /* no PCI config */
347 v= 0;
348 (void) env_parse(envvar, envfmt, 1, &v, 0, 255);
349 dep->de_pcibus= v;
350 v= 0;
351 (void) env_parse(envvar, envfmt, 2, &v, 0, 255);
352 dep->de_pcidev= v;
353 v= 0;
354 (void) env_parse(envvar, envfmt, 3, &v, 0, 255);
355 dep->de_pcifunc= v;
356 }
357
358 for (h= 1; h >= 0; h--) {
359 for (i= 0, dep= de_table; i<DE_PORT_NR; i++, dep++)
360 {
361 if (!dep->de_pci)
362 continue;
363 if (((dep->de_pcibus | dep->de_pcidev |
364 dep->de_pcifunc) != 0) != h)
365 {
366 continue;
367 }
368 if (!rtl_probe(dep))
369 dep->de_pci= -1;
370 }
371 }
372 }
373 #endif /* ENABLE_PCI */
374
375 /*===========================================================================*
376 * do_vwrite *
377 *===========================================================================*/
378 static void do_vwrite(mp, from_int, vectored)
379 message *mp;
380 int from_int;
381 int vectored;
382 {
383 int port, count, size;
384 int sendq_head;
385 dpeth_t *dep;
386
387 port = mp->DL_PORT;
388 count = mp->DL_COUNT;
389 if (port < 0 || port >= DE_PORT_NR)
390 panic("", "dp8390: illegal port", port);
391 dep= &de_table[port];
392 dep->de_client= mp->DL_PROC;
393
394 if (dep->de_mode == DEM_SINK)
395 {
396 assert(!from_int);
397 dep->de_flags |= DEF_PACK_SEND;
398 reply(dep, OK, FALSE);
399 return;
400 }
401 assert(dep->de_mode == DEM_ENABLED);
402 assert(dep->de_flags & DEF_ENABLED);
403 if (dep->de_flags & DEF_SEND_AVAIL)
404 panic("", "dp8390: send already in progress", NO_NUM);
405
406 sendq_head= dep->de_sendq_head;
407 if (dep->de_sendq[sendq_head].sq_filled)
408 {
409 if (from_int)
410 panic("", "dp8390: should not be sending\n", NO_NUM);
411 dep->de_sendmsg= *mp;
412 dep->de_flags |= DEF_SEND_AVAIL;
413 reply(dep, OK, FALSE);
414 return;
415 }
416 assert(!(dep->de_flags & DEF_PACK_SEND));
417
418 if (vectored)
419 {
420 get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
421 (count > IOVEC_NR ? IOVEC_NR : count) *
422 sizeof(iovec_t), dep->de_write_iovec.iod_iovec);
423 dep->de_write_iovec.iod_iovec_s = count;
424 dep->de_write_iovec.iod_proc_nr = mp->DL_PROC;
425 dep->de_write_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR;
426
427 dep->de_tmp_iovec = dep->de_write_iovec;
428 size = calc_iovec_size(&dep->de_tmp_iovec);
429 }
430 else
431 {
432 dep->de_write_iovec.iod_iovec[0].iov_addr =
433 (vir_bytes) mp->DL_ADDR;
434 dep->de_write_iovec.iod_iovec[0].iov_size =
435 mp->DL_COUNT;
436 dep->de_write_iovec.iod_iovec_s = 1;
437 dep->de_write_iovec.iod_proc_nr = mp->DL_PROC;
438 dep->de_write_iovec.iod_iovec_addr = 0;
439 size= mp->DL_COUNT;
440 }
441 if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED)
442 {
443 panic("", "dp8390: invalid packet size", size);
444 }
445 (dep->de_user2nicf)(dep, &dep->de_write_iovec, 0,
446 dep->de_sendq[sendq_head].sq_sendpage * DP_PAGESIZE,
447 size);
448 dep->de_sendq[sendq_head].sq_filled= TRUE;
449 if (dep->de_sendq_tail == sendq_head)
450 {
451 outb_reg0(dep, DP_TPSR, dep->de_sendq[sendq_head].sq_sendpage);
452 outb_reg0(dep, DP_TBCR1, size >> 8);
453 outb_reg0(dep, DP_TBCR0, size & 0xff);
454 outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);/* there it goes.. */
455 }
456 else
457 dep->de_sendq[sendq_head].sq_size= size;
458
459 if (++sendq_head == dep->de_sendq_nr)
460 sendq_head= 0;
461 assert(sendq_head < SENDQ_NR);
462 dep->de_sendq_head= sendq_head;
463
464 dep->de_flags |= DEF_PACK_SEND;
465
466 /* If the interrupt handler called, don't send a reply. The reply
467 * will be sent after all interrupts are handled.
468 */
469 if (from_int)
470 return;
471 reply(dep, OK, FALSE);
472
473 assert(dep->de_mode == DEM_ENABLED);
474 assert(dep->de_flags & DEF_ENABLED);
475 }
476
477 /*===========================================================================*
478 * do_vread *
479 *===========================================================================*/
480 static void do_vread(mp, vectored)
481 message *mp;
482 int vectored;
483 {
484 int port, count;
485 int size;
486 dpeth_t *dep;
487
488 port = mp->DL_PORT;
489 count = mp->DL_COUNT;
490 if (port < 0 || port >= DE_PORT_NR)
491 panic("", "dp8390: illegal port", port);
492 dep= &de_table[port];
493 dep->de_client= mp->DL_PROC;
494 if (dep->de_mode == DEM_SINK)
495 {
496 reply(dep, OK, FALSE);
497 return;
498 }
499 assert(dep->de_mode == DEM_ENABLED);
500 assert(dep->de_flags & DEF_ENABLED);
501
502 if(dep->de_flags & DEF_READING)
503 panic("", "dp8390: read already in progress", NO_NUM);
504
505 if (vectored)
506 {
507 get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
508 (count > IOVEC_NR ? IOVEC_NR : count) *
509 sizeof(iovec_t), dep->de_read_iovec.iod_iovec);
510 dep->de_read_iovec.iod_iovec_s = count;
511 dep->de_read_iovec.iod_proc_nr = mp->DL_PROC;
512 dep->de_read_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR;
513
514 dep->de_tmp_iovec = dep->de_read_iovec;
515 size= calc_iovec_size(&dep->de_tmp_iovec);
516 }
517 else
518 {
519 dep->de_read_iovec.iod_iovec[0].iov_addr =
520 (vir_bytes) mp->DL_ADDR;
521 dep->de_read_iovec.iod_iovec[0].iov_size =
522 mp->DL_COUNT;
523 dep->de_read_iovec.iod_iovec_s = 1;
524 dep->de_read_iovec.iod_proc_nr = mp->DL_PROC;
525 dep->de_read_iovec.iod_iovec_addr = 0;
526 size= count;
527 }
528 if (size < ETH_MAX_PACK_SIZE_TAGGED)
529 panic("", "dp8390: wrong packet size", size);
530 dep->de_flags |= DEF_READING;
531
532 dp_recv(dep);
533
534 if ((dep->de_flags & (DEF_READING|DEF_STOPPED)) ==
535 (DEF_READING|DEF_STOPPED))
536 {
537 /* The chip is stopped, and all arrived packets are
538 * delivered.
539 */
540 dp_reset(dep);
541 }
542 reply(dep, OK, FALSE);
543 }
544
545 /*===========================================================================*
546 * do_init *
547 *===========================================================================*/
548 static void do_init(mp)
549 message *mp;
550 {
551 int port;
552 dpeth_t *dep;
553 message reply_mess;
554
555 #if ENABLE_PCI
556 pci_conf(); /* Configure PCI devices. */
557 #endif
558
559 port = mp->DL_PORT;
560 if (port < 0 || port >= DE_PORT_NR)
561 {
562 reply_mess.m_type= DL_INIT_REPLY;
563 reply_mess.m3_i1= ENXIO;
564 mess_reply(mp, &reply_mess);
565 return;
566 }
567 dep= &de_table[port];
568 if (dep->de_mode == DEM_DISABLED)
569 {
570 /* This is the default, try to (re)locate the device. */
571 conf_hw(dep);
572 if (dep->de_mode == DEM_DISABLED)
573 {
574 /* Probe failed, or the device is configured off. */
575 reply_mess.m_type= DL_INIT_REPLY;
576 reply_mess.m3_i1= ENXIO;
577 mess_reply(mp, &reply_mess);
578 return;
579 }
580 if (dep->de_mode == DEM_ENABLED)
581 dp_init(dep);
582 }
583
584 if (dep->de_mode == DEM_SINK)
585 {
586 strncpy((char *) dep->de_address.ea_addr, "ZDP", 6);
587 dep->de_address.ea_addr[5] = port;
588 dp_confaddr(dep);
589 reply_mess.m_type = DL_INIT_REPLY;
590 reply_mess.m3_i1 = mp->DL_PORT;
591 reply_mess.m3_i2 = DE_PORT_NR;
592 *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
593 mess_reply(mp, &reply_mess);
594 return;
595 }
596 assert(dep->de_mode == DEM_ENABLED);
597 assert(dep->de_flags & DEF_ENABLED);
598
599 dep->de_flags &= ~(DEF_PROMISC | DEF_MULTI | DEF_BROAD);
600
601 if (mp->DL_MODE & DL_PROMISC_REQ)
602 dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD;
603 if (mp->DL_MODE & DL_MULTI_REQ)
604 dep->de_flags |= DEF_MULTI;
605 if (mp->DL_MODE & DL_BROAD_REQ)
606 dep->de_flags |= DEF_BROAD;
607
608 dep->de_client = mp->m_source;
609 dp_reinit(dep);
610
611 reply_mess.m_type = DL_INIT_REPLY;
612 reply_mess.m3_i1 = mp->DL_PORT;
613 reply_mess.m3_i2 = DE_PORT_NR;
614 *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
615
616 mess_reply(mp, &reply_mess);
617 }
618
619 /*===========================================================================*
620 * do_int *
621 *===========================================================================*/
622 static void do_int(dep)
623 dpeth_t *dep;
624 {
625 if (dep->de_flags & (DEF_PACK_SEND | DEF_PACK_RECV))
626 reply(dep, OK, TRUE);
627 }
628
629 /*===========================================================================*
630 * do_getstat *
631 *===========================================================================*/
632 static void do_getstat(mp)
633 message *mp;
634 {
635 int port;
636 dpeth_t *dep;
637
638 port = mp->DL_PORT;
639 if (port < 0 || port >= DE_PORT_NR)
640 panic("", "dp8390: illegal port", port);
641 dep= &de_table[port];
642 dep->de_client= mp->DL_PROC;
643 if (dep->de_mode == DEM_SINK)
644 {
645 put_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
646 (vir_bytes) sizeof(dep->de_stat), &dep->de_stat);
647 reply(dep, OK, FALSE);
648 return;
649 }
650 assert(dep->de_mode == DEM_ENABLED);
651 assert(dep->de_flags & DEF_ENABLED);
652
653 dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0);
654 dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1);
655 dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2);
656
657 put_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
658 (vir_bytes) sizeof(dep->de_stat), &dep->de_stat);
659 reply(dep, OK, FALSE);
660 }
661
662 /*===========================================================================*
663 * do_getname *
664 *===========================================================================*/
665 static void do_getname(mp)
666 message *mp;
667 {
668 int r;
669
670 strncpy(mp->DL_NAME, progname, sizeof(mp->DL_NAME));
671 mp->DL_NAME[sizeof(mp->DL_NAME)-1]= '\0';
672 mp->m_type= DL_NAME_REPLY;
673 r= send(mp->m_source, mp);
674 if (r != OK)
675 panic("dp8390", "do_getname: send failed: %d\n", r);
676 }
677
678 /*===========================================================================*
679 * do_stop *
680 *===========================================================================*/
681 static void do_stop(mp)
682 message *mp;
683 {
684 int port;
685 dpeth_t *dep;
686
687 port = mp->DL_PORT;
688
689 if (port < 0 || port >= DE_PORT_NR)
690 panic("", "dp8390: illegal port", port);
691 dep= &de_table[port];
692 if (dep->de_mode == DEM_SINK)
693 return;
694 assert(dep->de_mode == DEM_ENABLED);
695
696 if (!(dep->de_flags & DEF_ENABLED))
697 return;
698
699 outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
700 (dep->de_stopf)(dep);
701
702 dep->de_flags= DEF_EMPTY;
703 }
704
705 /*===========================================================================*
706 * dp_init *
707 *===========================================================================*/
708 static void dp_init(dep)
709 dpeth_t *dep;
710 {
711 int dp_rcr_reg;
712 int i, r;
713
714 /* General initialization */
715 dep->de_flags = DEF_EMPTY;
716 (*dep->de_initf)(dep);
717
718 dp_confaddr(dep);
719
720 if (debug)
721 {
722 printf("%s: Ethernet address ", dep->de_name);
723 for (i= 0; i < 6; i++)
724 printf("%x%c", dep->de_address.ea_addr[i],
725 i < 5 ? ':' : '\n');
726 }
727
728 /* Initialization of the dp8390 following the mandatory procedure
729 * in reference manual ("DP8390D/NS32490D NIC Network Interface
730 * Controller", National Semiconductor, July 1995, Page 29).
731 */
732 /* Step 1: */
733 outb_reg0(dep, DP_CR, CR_PS_P0 | CR_STP | CR_DM_ABORT);
734 /* Step 2: */
735 if (dep->de_16bit)
736 outb_reg0(dep, DP_DCR, DCR_WORDWIDE | DCR_8BYTES | DCR_BMS);
737 else
738 outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES | DCR_BMS);
739 /* Step 3: */
740 outb_reg0(dep, DP_RBCR0, 0);
741 outb_reg0(dep, DP_RBCR1, 0);
742 /* Step 4: */
743 dp_rcr_reg = 0;
744 if (dep->de_flags & DEF_PROMISC)
745 dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM;
746 if (dep->de_flags & DEF_BROAD)
747 dp_rcr_reg |= RCR_AB;
748 if (dep->de_flags & DEF_MULTI)
749 dp_rcr_reg |= RCR_AM;
750 outb_reg0(dep, DP_RCR, dp_rcr_reg);
751 /* Step 5: */
752 outb_reg0(dep, DP_TCR, TCR_INTERNAL);
753 /* Step 6: */
754 outb_reg0(dep, DP_BNRY, dep->de_startpage);
755 outb_reg0(dep, DP_PSTART, dep->de_startpage);
756 outb_reg0(dep, DP_PSTOP, dep->de_stoppage);
757 /* Step 7: */
758 outb_reg0(dep, DP_ISR, 0xFF);
759 /* Step 8: */
760 outb_reg0(dep, DP_IMR, IMR_PRXE | IMR_PTXE | IMR_RXEE | IMR_TXEE |
761 IMR_OVWE | IMR_CNTE);
762 /* Step 9: */
763 outb_reg0(dep, DP_CR, CR_PS_P1 | CR_DM_ABORT | CR_STP);
764
765 outb_reg1(dep, DP_PAR0, dep->de_address.ea_addr[0]);
766 outb_reg1(dep, DP_PAR1, dep->de_address.ea_addr[1]);
767 outb_reg1(dep, DP_PAR2, dep->de_address.ea_addr[2]);
768 outb_reg1(dep, DP_PAR3, dep->de_address.ea_addr[3]);
769 outb_reg1(dep, DP_PAR4, dep->de_address.ea_addr[4]);
770 outb_reg1(dep, DP_PAR5, dep->de_address.ea_addr[5]);
771
772 outb_reg1(dep, DP_MAR0, 0xff);
773 outb_reg1(dep, DP_MAR1, 0xff);
774 outb_reg1(dep, DP_MAR2, 0xff);
775 outb_reg1(dep, DP_MAR3, 0xff);
776 outb_reg1(dep, DP_MAR4, 0xff);
777 outb_reg1(dep, DP_MAR5, 0xff);
778 outb_reg1(dep, DP_MAR6, 0xff);
779 outb_reg1(dep, DP_MAR7, 0xff);
780
781 outb_reg1(dep, DP_CURR, dep->de_startpage + 1);
782 /* Step 10: */
783 outb_reg0(dep, DP_CR, CR_DM_ABORT | CR_STA);
784 /* Step 11: */
785 outb_reg0(dep, DP_TCR, TCR_NORMAL);
786
787 inb_reg0(dep, DP_CNTR0); /* reset counters by reading */
788 inb_reg0(dep, DP_CNTR1);
789 inb_reg0(dep, DP_CNTR2);
790
791 /* Finish the initialization. */
792 dep->de_flags |= DEF_ENABLED;
793 for (i= 0; i<dep->de_sendq_nr; i++)
794 dep->de_sendq[i].sq_filled= 0;
795 dep->de_sendq_head= 0;
796 dep->de_sendq_tail= 0;
797 if (!dep->de_prog_IO)
798 {
799 dep->de_user2nicf= dp_user2nic;
800 dep->de_nic2userf= dp_nic2user;
801 dep->de_getblockf= dp_getblock;
802 }
803 else if (dep->de_16bit)
804 {
805 dep->de_user2nicf= dp_pio16_user2nic;
806 dep->de_nic2userf= dp_pio16_nic2user;
807 dep->de_getblockf= dp_pio16_getblock;
808 }
809 else
810 {
811 dep->de_user2nicf= dp_pio8_user2nic;
812 dep->de_nic2userf= dp_pio8_nic2user;
813 dep->de_getblockf= dp_pio8_getblock;
814 }
815
816 /* Set the interrupt handler and policy. Do not automatically
817 * reenable interrupts. Return the IRQ line number on interrupts.
818 */
819 dep->de_hook = dep->de_irq;
820 r= sys_irqsetpolicy(dep->de_irq, 0, &dep->de_hook);
821 if (r != OK)
822 panic("DP8390", "sys_irqsetpolicy failed", r);
823
824 r= sys_irqenable(&dep->de_hook);
825 if (r != OK)
826 {
827 panic("DP8390", "unable enable interrupts", r);
828 }
829 }
830
831 /*===========================================================================*
832 * dp_confaddr *
833 *===========================================================================*/
834 static void dp_confaddr(dep)
835 dpeth_t *dep;
836 {
837 int i;
838 char eakey[16];
839 static char eafmt[]= "x:x:x:x:x:x";
840 long v;
841
842 /* User defined ethernet address? */
843 strcpy(eakey, dp_conf[dep-de_table].dpc_envvar);
844 strcat(eakey, "_EA");
845
846 for (i= 0; i < 6; i++)
847 {
848 v= dep->de_address.ea_addr[i];
849 if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET)
850 {
851 break;
852 }
853 dep->de_address.ea_addr[i]= v;
854 }
855
856 if (i != 0 && i != 6) env_panic(eakey); /* It's all or nothing */
857 }
858
859 /*===========================================================================*
860 * dp_reinit *
861 *===========================================================================*/
862 static void dp_reinit(dep)
863 dpeth_t *dep;
864 {
865 int dp_rcr_reg;
866
867 outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
868
869 dp_rcr_reg = 0;
870 if (dep->de_flags & DEF_PROMISC)
871 dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM;
872 if (dep->de_flags & DEF_BROAD)
873 dp_rcr_reg |= RCR_AB;
874 if (dep->de_flags & DEF_MULTI)
875 dp_rcr_reg |= RCR_AM;
876 outb_reg0(dep, DP_RCR, dp_rcr_reg);
877 }
878
879 /*===========================================================================*
880 * dp_reset *
881 *===========================================================================*/
882 static void dp_reset(dep)
883 dpeth_t *dep;
884 {
885 int i;
886
887 /* Stop chip */
888 outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
889 outb_reg0(dep, DP_RBCR0, 0);
890 outb_reg0(dep, DP_RBCR1, 0);
891 for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RST) == 0); i++)
892 ; /* Do nothing */
893 outb_reg0(dep, DP_TCR, TCR_1EXTERNAL|TCR_OFST);
894 outb_reg0(dep, DP_CR, CR_STA|CR_DM_ABORT);
895 outb_reg0(dep, DP_TCR, TCR_NORMAL);
896
897 /* Acknowledge the ISR_RDC (remote dma) interrupt. */
898 for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RDC) == 0); i++)
899 ; /* Do nothing */
900 outb_reg0(dep, DP_ISR, inb_reg0(dep, DP_ISR) & ~ISR_RDC);
901
902 /* Reset the transmit ring. If we were transmitting a packet, we
903 * pretend that the packet is processed. Higher layers will
904 * retransmit if the packet wasn't actually sent.
905 */
906 dep->de_sendq_head= dep->de_sendq_tail= 0;
907 for (i= 0; i<dep->de_sendq_nr; i++)
908 dep->de_sendq[i].sq_filled= 0;
909 dp_send(dep);
910 dep->de_flags &= ~DEF_STOPPED;
911 }
912
913 /*===========================================================================*
914 * dp_check_ints *
915 *===========================================================================*/
916 static void dp_check_ints(dep)
917 dpeth_t *dep;
918 {
919 int isr, tsr;
920 int size, sendq_tail;
921
922 if (!(dep->de_flags & DEF_ENABLED))
923 panic("", "dp8390: got premature interrupt", NO_NUM);
924
925 for(;;)
926 {
927 isr = inb_reg0(dep, DP_ISR);
928 if (!isr)
929 break;
930 outb_reg0(dep, DP_ISR, isr);
931 if (isr & (ISR_PTX|ISR_TXE))
932 {
933 if (isr & ISR_TXE)
934 {
935 #if DEBUG
936 { printf("%s: got send Error\n", dep->de_name); }
937 #endif
938 dep->de_stat.ets_sendErr++;
939 }
940 else
941 {
942 tsr = inb_reg0(dep, DP_TSR);
943
944 if (tsr & TSR_PTX) dep->de_stat.ets_packetT++;
945 #if 0 /* Reserved in later manuals, should be ignored */
946 if (!(tsr & TSR_DFR))
947 {
948 /* In most (all?) implementations of
949 * the dp8390, this bit is set
950 * when the packet is not deferred
951 */
952 dep->de_stat.ets_transDef++;
953 }
954 #endif
955 if (tsr & TSR_COL) dep->de_stat.ets_collision++;
956 if (tsr & TSR_ABT) dep->de_stat.ets_transAb++;
957 if (tsr & TSR_CRS) dep->de_stat.ets_carrSense++;
958 if (tsr & TSR_FU
959 && ++dep->de_stat.ets_fifoUnder <= 10)
960 {
961 printf("%s: fifo underrun\n",
962 dep->de_name);
963 }
964 if (tsr & TSR_CDH
965 && ++dep->de_stat.ets_CDheartbeat <= 10)
966 {
967 printf("%s: CD heart beat failure\n",
968 dep->de_name);
969 }
970 if (tsr & TSR_OWC) dep->de_stat.ets_OWC++;
971 }
972 sendq_tail= dep->de_sendq_tail;
973
974 if (!(dep->de_sendq[sendq_tail].sq_filled))
975 {
976 /* Software bug? */
977 assert(!debug);
978
979 /* Or hardware bug? */
980 printf(
981 "%s: transmit interrupt, but not sending\n",
982 dep->de_name);
983 continue;
984 }
985 dep->de_sendq[sendq_tail].sq_filled= 0;
986 if (++sendq_tail == dep->de_sendq_nr)
987 sendq_tail= 0;
988 dep->de_sendq_tail= sendq_tail;
989 if (dep->de_sendq[sendq_tail].sq_filled)
990 {
991 size= dep->de_sendq[sendq_tail].sq_size;
992 outb_reg0(dep, DP_TPSR,
993 dep->de_sendq[sendq_tail].sq_sendpage);
994 outb_reg0(dep, DP_TBCR1, size >> 8);
995 outb_reg0(dep, DP_TBCR0, size & 0xff);
996 outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);
997 }
998 if (dep->de_flags & DEF_SEND_AVAIL)
999 dp_send(dep);
1000 }
1001
1002 if (isr & ISR_PRX)
1003 {
1004 /* Only call dp_recv if there is a read request */
1005 if (dep->de_flags & DEF_READING)
1006 dp_recv(dep);
1007 }
1008
1009 if (isr & ISR_RXE) dep->de_stat.ets_recvErr++;
1010 if (isr & ISR_CNT)
1011 {
1012 dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0);
1013 dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1);
1014 dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2);
1015 }
1016 if (isr & ISR_OVW)
1017 {
1018 dep->de_stat.ets_OVW++;
1019 #if 0
1020 { printW(); printf(
1021 "%s: got overwrite warning\n", dep->de_name); }
1022 #endif
1023 if (dep->de_flags & DEF_READING)
1024 {
1025 printf(
1026 "dp_check_ints: strange: overwrite warning and pending read request\n");
1027 dp_recv(dep);
1028 }
1029 }
1030 if (isr & ISR_RDC)
1031 {
1032 /* Nothing to do */
1033 }
1034 if (isr & ISR_RST)
1035 {
1036 /* this means we got an interrupt but the ethernet
1037 * chip is shutdown. We set the flag DEF_STOPPED,
1038 * and continue processing arrived packets. When the
1039 * receive buffer is empty, we reset the dp8390.
1040 */
1041 #if 0
1042 { printW(); printf(
1043 "%s: NIC stopped\n", dep->de_name); }
1044 #endif
1045 dep->de_flags |= DEF_STOPPED;
1046 break;
1047 }
1048 }
1049 if ((dep->de_flags & (DEF_READING|DEF_STOPPED)) ==
1050 (DEF_READING|DEF_STOPPED))
1051 {
1052 /* The chip is stopped, and all arrived packets are
1053 * delivered.
1054 */
1055 dp_reset(dep);
1056 }
1057 }
1058
1059 /*===========================================================================*
1060 * dp_recv *
1061 *===========================================================================*/
1062 static void dp_recv(dep)
1063 dpeth_t *dep;
1064 {
1065 dp_rcvhdr_t header;
1066 unsigned pageno, curr, next;
1067 vir_bytes length;
1068 int packet_processed, r;
1069 u16_t eth_type;
1070
1071 packet_processed = FALSE;
1072 pageno = inb_reg0(dep, DP_BNRY) + 1;
1073 if (pageno == dep->de_stoppage) pageno = dep->de_startpage;
1074
1075 do
1076 {
1077 outb_reg0(dep, DP_CR, CR_PS_P1 | CR_EXTRA);
1078 curr = inb_reg1(dep, DP_CURR);
1079 outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
1080
1081 if (curr == pageno) break;
1082
1083 (dep->de_getblockf)(dep, pageno, (size_t)0, sizeof(header),
1084 &header);
1085 (dep->de_getblockf)(dep, pageno, sizeof(header) +
1086 2*sizeof(ether_addr_t), sizeof(eth_type), ð_type);
1087
1088 length = (header.dr_rbcl | (header.dr_rbch << 8)) -
1089 sizeof(dp_rcvhdr_t);
1090 next = header.dr_next;
1091 if (length < ETH_MIN_PACK_SIZE ||
1092 length > ETH_MAX_PACK_SIZE_TAGGED)
1093 {
1094 printf("%s: packet with strange length arrived: %d\n",
1095 dep->de_name, (int) length);
1096 next= curr;
1097 }
1098 else if (next < dep->de_startpage || next >= dep->de_stoppage)
1099 {
1100 printf("%s: strange next page\n", dep->de_name);
1101 next= curr;
1102 }
1103 else if (eth_type == eth_ign_proto)
1104 {
1105 /* Hack: ignore packets of a given protocol, useful
1106 * if you share a net with 80 computers sending
1107 * Amoeba FLIP broadcasts. (Protocol 0x8146.)
1108 */
1109 static int first= 1;
1110 if (first)
1111 {
1112 first= 0;
1113 printf("%s: dropping proto 0x%04x packets\n",
1114 dep->de_name,
1115 ntohs(eth_ign_proto));
1116 }
1117 dep->de_stat.ets_packetR++;
1118 }
1119 else if (header.dr_status & RSR_FO)
1120 {
1121 /* This is very serious, so we issue a warning and
1122 * reset the buffers */
1123 printf("%s: fifo overrun, resetting receive buffer\n",
1124 dep->de_name);
1125 dep->de_stat.ets_fifoOver++;
1126 next = curr;
1127 }
1128 else if ((header.dr_status & RSR_PRX) &&
1129 (dep->de_flags & DEF_ENABLED))
1130 {
1131 r = dp_pkt2user(dep, pageno, length);
1132 if (r != OK)
1133 return;
1134
1135 packet_processed = TRUE;
1136 dep->de_stat.ets_packetR++;
1137 }
1138 if (next == dep->de_startpage)
1139 outb_reg0(dep, DP_BNRY, dep->de_stoppage - 1);
1140 else
1141 outb_reg0(dep, DP_BNRY, next - 1);
1142
1143 pageno = next;
1144 }
1145 while (!packet_processed);
1146 }
1147
1148 /*===========================================================================*
1149 * dp_send *
1150 *===========================================================================*/
1151 static void dp_send(dep)
1152 dpeth_t *dep;
1153 {
1154 if (!(dep->de_flags & DEF_SEND_AVAIL))
1155 return;
1156
1157 dep->de_flags &= ~DEF_SEND_AVAIL;
1158 switch(dep->de_sendmsg.m_type)
1159 {
1160 case DL_WRITE: do_vwrite(&dep->de_sendmsg, TRUE, FALSE); break;
1161 case DL_WRITEV: do_vwrite(&dep->de_sendmsg, TRUE, TRUE); break;
1162 default:
1163 panic("", "dp8390: wrong type:", dep->de_sendmsg.m_type);
1164 break;
1165 }
1166 }
1167
1168 /*===========================================================================*
1169 * dp_getblock *
1170 *===========================================================================*/
1171 static void dp_getblock(dep, page, offset, size, dst)
1172 dpeth_t *dep;
1173 int page;
1174 size_t offset;
1175 size_t size;
1176 void *dst;
1177 {
1178 int r;
1179
1180 offset = page * DP_PAGESIZE + offset;
1181
1182 r = sys_vircopy(SELF, BIOS_SEG, dep->de_linmem + offset,
1183 SELF, D, (vir_bytes)dst, size);
1184
1185 if (r != OK)
1186 panic("DP8390", "dp_getblock: sys_vircopy failed", r);
1187 }
1188
1189 /*===========================================================================*
1190 * dp_pio8_getblock *
1191 *===========================================================================*/
1192 static void dp_pio8_getblock(dep, page, offset, size, dst)
1193 dpeth_t *dep;
1194 int page;
1195 size_t offset;
1196 size_t size;
1197 void *dst;
1198 {
1199 offset = page * DP_PAGESIZE + offset;
1200 outb_reg0(dep, DP_RBCR0, size & 0xFF);
1201 outb_reg0(dep, DP_RBCR1, size >> 8);
1202 outb_reg0(dep, DP_RSAR0, offset & 0xFF);
1203 outb_reg0(dep, DP_RSAR1, offset >> 8);
1204 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
1205
1206 insb(dep->de_data_port, dst, size);
1207 }
1208
1209 /*===========================================================================*
1210 * dp_pio16_getblock *
1211 *===========================================================================*/
1212 static void dp_pio16_getblock(dep, page, offset, size, dst)
1213 dpeth_t *dep;
1214 int page;
1215 size_t offset;
1216 size_t size;
1217 void *dst;
1218 {
1219 offset = page * DP_PAGESIZE + offset;
1220 outb_reg0(dep, DP_RBCR0, size & 0xFF);
1221 outb_reg0(dep, DP_RBCR1, size >> 8);
1222 outb_reg0(dep, DP_RSAR0, offset & 0xFF);
1223 outb_reg0(dep, DP_RSAR1, offset >> 8);
1224 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
1225
1226 assert (!(size & 1));
1227 insw(dep->de_data_port, dst, size);
1228 }
1229
1230 /*===========================================================================*
1231 * dp_pkt2user *
1232 *===========================================================================*/
1233 static int dp_pkt2user(dep, page, length)
1234 dpeth_t *dep;
1235 int page, length;
1236 {
1237 int last, count;
1238
1239 if (!(dep->de_flags & DEF_READING))
1240 return EGENERIC;
1241
1242 last = page + (length - 1) / DP_PAGESIZE;
1243 if (last >= dep->de_stoppage)
1244 {
1245 count = (dep->de_stoppage - page) * DP_PAGESIZE -
1246 sizeof(dp_rcvhdr_t);
1247
1248 /* Save read_iovec since we need it twice. */
1249 dep->de_tmp_iovec = dep->de_read_iovec;
1250 (dep->de_nic2userf)(dep, page * DP_PAGESIZE +
1251 sizeof(dp_rcvhdr_t), &dep->de_tmp_iovec, 0, count);
1252 (dep->de_nic2userf)(dep, dep->de_startpage * DP_PAGESIZE,
1253 &dep->de_read_iovec, count, length - count);
1254 }
1255 else
1256 {
1257 (dep->de_nic2userf)(dep, page * DP_PAGESIZE +
1258 sizeof(dp_rcvhdr_t), &dep->de_read_iovec, 0, length);
1259 }
1260
1261 dep->de_read_s = length;
1262 dep->de_flags |= DEF_PACK_RECV;
1263 dep->de_flags &= ~DEF_READING;
1264
1265 return OK;
1266 }
1267
1268 /*===========================================================================*
1269 * dp_user2nic *
1270 *===========================================================================*/
1271 static void dp_user2nic(dep, iovp, offset, nic_addr, count)
1272 dpeth_t *dep;
1273 iovec_dat_t *iovp;
1274 vir_bytes offset;
1275 int nic_addr;
1276 vir_bytes count;
1277 {
1278 vir_bytes vir_hw, vir_user;
1279 int bytes, i, r;
1280
1281 vir_hw = dep->de_linmem + nic_addr;
1282
1283 i= 0;
1284 while (count > 0)
1285 {
1286 if (i >= IOVEC_NR)
1287 {
1288 dp_next_iovec(iovp);
1289 i= 0;
1290 continue;
1291 }
1292 assert(i < iovp->iod_iovec_s);
1293 if (offset >= iovp->iod_iovec[i].iov_size)
1294 {
1295 offset -= iovp->iod_iovec[i].iov_size;
1296 i++;
1297 continue;
1298 }
1299 bytes = iovp->iod_iovec[i].iov_size - offset;
1300 if (bytes > count)
1301 bytes = count;
1302
1303 r= sys_vircopy(iovp->iod_proc_nr, D,
1304 iovp->iod_iovec[i].iov_addr + offset,
1305 SELF, BIOS_SEG, vir_hw, bytes);
1306 if (r != OK)
1307 panic("DP8390", "dp_user2nic: sys_vircopy failed", r);
1308
1309 count -= bytes;
1310 vir_hw += bytes;
1311 offset += bytes;
1312 }
1313 assert(count == 0);
1314 }
1315
1316 /*===========================================================================*
1317 * dp_pio8_user2nic *
1318 *===========================================================================*/
1319 static void dp_pio8_user2nic(dep, iovp, offset, nic_addr, count)
1320 dpeth_t *dep;
1321 iovec_dat_t *iovp;
1322 vir_bytes offset;
1323 int nic_addr;
1324 vir_bytes count;
1325 {
1326 phys_bytes phys_user;
1327 int bytes, i;
1328
1329 outb_reg0(dep, DP_ISR, ISR_RDC);
1330
1331 outb_reg0(dep, DP_RBCR0, count & 0xFF);
1332 outb_reg0(dep, DP_RBCR1, count >> 8);
1333 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
1334 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
1335 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
1336
1337 i= 0;
1338 while (count > 0)
1339 {
1340 if (i >= IOVEC_NR)
1341 {
1342 dp_next_iovec(iovp);
1343 i= 0;
1344 continue;
1345 }
1346 assert(i < iovp->iod_iovec_s);
1347 if (offset >= iovp->iod_iovec[i].iov_size)
1348 {
1349 offset -= iovp->iod_iovec[i].iov_size;
1350 i++;
1351 continue;
1352 }
1353 bytes = iovp->iod_iovec[i].iov_size - offset;
1354 if (bytes > count)
1355 bytes = count;
1356
1357 do_vir_outsb(dep->de_data_port, iovp->iod_proc_nr,
1358 iovp->iod_iovec[i].iov_addr + offset, bytes);
1359 count -= bytes;
1360 offset += bytes;
1361 }
1362 assert(count == 0);
1363
1364 for (i= 0; i<100; i++)
1365 {
1366 if (inb_reg0(dep, DP_ISR) & ISR_RDC)
1367 break;
1368 }
1369 if (i == 100)
1370 {
1371 panic("", "dp8390: remote dma failed to complete", NO_NUM);
1372 }
1373 }
1374
1375 /*===========================================================================*
1376 * dp_pio16_user2nic *
1377 *===========================================================================*/
1378 static void dp_pio16_user2nic(dep, iovp, offset, nic_addr, count)
1379 dpeth_t *dep;
1380 iovec_dat_t *iovp;
1381 vir_bytes offset;
1382 int nic_addr;
1383 vir_bytes count;
1384 {
1385 vir_bytes vir_user;
1386 vir_bytes ecount;
1387 int i, r, bytes, user_proc;
1388 u8_t two_bytes[2];
1389 int odd_byte;
1390
1391 ecount= (count+1) & ~1;
1392 odd_byte= 0;
1393
1394 outb_reg0(dep, DP_ISR, ISR_RDC);
1395 outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
1396 outb_reg0(dep, DP_RBCR1, ecount >> 8);
1397 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
1398 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
1399 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
1400
1401 i= 0;
1402 while (count > 0)
1403 {
1404 if (i >= IOVEC_NR)
1405 {
1406 dp_next_iovec(iovp);
1407 i= 0;
1408 continue;
1409 }
1410 assert(i < iovp->iod_iovec_s);
1411 if (offset >= iovp->iod_iovec[i].iov_size)
1412 {
1413 offset -= iovp->iod_iovec[i].iov_size;
1414 i++;
1415 continue;
1416 }
1417 bytes = iovp->iod_iovec[i].iov_size - offset;
1418 if (bytes > count)
1419 bytes = count;
1420
1421 user_proc= iovp->iod_proc_nr;
1422 vir_user= iovp->iod_iovec[i].iov_addr + offset;
1423 if (odd_byte)
1424 {
1425 r= sys_vircopy(user_proc, D, vir_user,
1426 SELF, D, (vir_bytes)&two_bytes[1], 1);
1427 if (r != OK)
1428 {
1429 panic("DP8390",
1430 "dp_pio16_user2nic: sys_vircopy failed",
1431 r);
1432 }
1433 outw(dep->de_data_port, *(u16_t *)two_bytes);
1434 count--;
1435 offset++;
1436 bytes--;
1437 vir_user++;
1438 odd_byte= 0;
1439 if (!bytes)
1440 continue;
1441 }
1442 ecount= bytes & ~1;
1443 if (ecount != 0)
1444 {
1445 do_vir_outsw(dep->de_data_port, user_proc, vir_user,
1446 ecount);
1447 count -= ecount;
1448 offset += ecount;
1449 bytes -= ecount;
1450 vir_user += ecount;
1451 }
1452 if (bytes)
1453 {
1454 assert(bytes == 1);
1455 r= sys_vircopy(user_proc, D, vir_user,
1456 SELF, D, (vir_bytes)&two_bytes[0], 1);
1457 if (r != OK)
1458 {
1459 panic("DP8390",
1460 "dp_pio16_user2nic: sys_vircopy failed",
1461 r);
1462 }
1463 count--;
1464 offset++;
1465 bytes--;
1466 vir_user++;
1467 odd_byte= 1;
1468 }
1469 }
1470 assert(count == 0);
1471
1472 if (odd_byte)
1473 outw(dep->de_data_port, *(u16_t *)two_bytes);
1474
1475 for (i= 0; i<100; i++)
1476 {
1477 if (inb_reg0(dep, DP_ISR) & ISR_RDC)
1478 break;
1479 }
1480 if (i == 100)
1481 {
1482 panic("", "dp8390: remote dma failed to complete", NO_NUM);
1483 }
1484 }
1485
1486 /*===========================================================================*
1487 * dp_nic2user *
1488 *===========================================================================*/
1489 static void dp_nic2user(dep, nic_addr, iovp, offset, count)
1490 dpeth_t *dep;
1491 int nic_addr;
1492 iovec_dat_t *iovp;
1493 vir_bytes offset;
1494 vir_bytes count;
1495 {
1496 vir_bytes vir_hw, vir_user;
1497 int bytes, i, r;
1498
1499 vir_hw = dep->de_linmem + nic_addr;
1500
1501 i= 0;
1502 while (count > 0)
1503 {
1504 if (i >= IOVEC_NR)
1505 {
1506 dp_next_iovec(iovp);
1507 i= 0;
1508 continue;
1509 }
1510 assert(i < iovp->iod_iovec_s);
1511 if (offset >= iovp->iod_iovec[i].iov_size)
1512 {
1513 offset -= iovp->iod_iovec[i].iov_size;
1514 i++;
1515 continue;
1516 }
1517 bytes = iovp->iod_iovec[i].iov_size - offset;
1518 if (bytes > count)
1519 bytes = count;
1520
1521 r= sys_vircopy(SELF, BIOS_SEG, vir_hw,
1522 iovp->iod_proc_nr, D,
1523 iovp->iod_iovec[i].iov_addr + offset, bytes);
1524 if (r != OK)
1525 panic("DP8390", "dp_nic2user: sys_vircopy failed", r);
1526
1527 count -= bytes;
1528 vir_hw += bytes;
1529 offset += bytes;
1530 }
1531 assert(count == 0);
1532 }
1533
1534 /*===========================================================================*
1535 * dp_pio8_nic2user *
1536 *===========================================================================*/
1537 static void dp_pio8_nic2user(dep, nic_addr, iovp, offset, count)
1538 dpeth_t *dep;
1539 int nic_addr;
1540 iovec_dat_t *iovp;
1541 vir_bytes offset;
1542 vir_bytes count;
1543 {
1544 phys_bytes phys_user;
1545 int bytes, i;
1546
1547 outb_reg0(dep, DP_RBCR0, count & 0xFF);
1548 outb_reg0(dep, DP_RBCR1, count >> 8);
1549 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
1550 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
1551 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
1552
1553 i= 0;
1554 while (count > 0)
1555 {
1556 if (i >= IOVEC_NR)
1557 {
1558 dp_next_iovec(iovp);
1559 i= 0;
1560 continue;
1561 }
1562 assert(i < iovp->iod_iovec_s);
1563 if (offset >= iovp->iod_iovec[i].iov_size)
1564 {
1565 offset -= iovp->iod_iovec[i].iov_size;
1566 i++;
1567 continue;
1568 }
1569 bytes = iovp->iod_iovec[i].iov_size - offset;
1570 if (bytes > count)
1571 bytes = count;
1572
1573 do_vir_insb(dep->de_data_port, iovp->iod_proc_nr,
1574 iovp->iod_iovec[i].iov_addr + offset, bytes);
1575 count -= bytes;
1576 offset += bytes;
1577 }
1578 assert(count == 0);
1579 }
1580
1581 /*===========================================================================*
1582 * dp_pio16_nic2user *
1583 *===========================================================================*/
1584 static void dp_pio16_nic2user(dep, nic_addr, iovp, offset, count)
1585 dpeth_t *dep;
1586 int nic_addr;
1587 iovec_dat_t *iovp;
1588 vir_bytes offset;
1589 vir_bytes count;
1590 {
1591 vir_bytes vir_user;
1592 vir_bytes ecount;
1593 int i, r, bytes, user_proc;
1594 u8_t two_bytes[2];
1595 int odd_byte;
1596
1597 ecount= (count+1) & ~1;
1598 odd_byte= 0;
1599
1600 outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
1601 outb_reg0(dep, DP_RBCR1, ecount >> 8);
1602 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
1603 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
1604 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
1605
1606 i= 0;
1607 while (count > 0)
1608 {
1609 if (i >= IOVEC_NR)
1610 {
1611 dp_next_iovec(iovp);
1612 i= 0;
1613 continue;
1614 }
1615 assert(i < iovp->iod_iovec_s);
1616 if (offset >= iovp->iod_iovec[i].iov_size)
1617 {
1618 offset -= iovp->iod_iovec[i].iov_size;
1619 i++;
1620 continue;
1621 }
1622 bytes = iovp->iod_iovec[i].iov_size - offset;
1623 if (bytes > count)
1624 bytes = count;
1625
1626 user_proc= iovp->iod_proc_nr;
1627 vir_user= iovp->iod_iovec[i].iov_addr + offset;
1628 if (odd_byte)
1629 {
1630 r= sys_vircopy(SELF, D, (vir_bytes)&two_bytes[1],
1631 user_proc, D, vir_user, 1);
1632 if (r != OK)
1633 {
1634 panic("DP8390",
1635 "dp_pio16_nic2user: sys_vircopy failed",
1636 r);
1637 }
1638 count--;
1639 offset++;
1640 bytes--;
1641 vir_user++;
1642 odd_byte= 0;
1643 if (!bytes)
1644 continue;
1645 }
1646 ecount= bytes & ~1;
1647 if (ecount != 0)
1648 {
1649 do_vir_insw(dep->de_data_port, user_proc, vir_user,
1650 ecount);
1651 count -= ecount;
1652 offset += ecount;
1653 bytes -= ecount;
1654 vir_user += ecount;
1655 }
1656 if (bytes)
1657 {
1658 assert(bytes == 1);
1659 *(u16_t *)two_bytes= inw(dep->de_data_port);
1660 r= sys_vircopy(SELF, D, (vir_bytes)&two_bytes[0],
1661 user_proc, D, vir_user, 1);
1662 if (r != OK)
1663 {
1664 panic("DP8390",
1665 "dp_pio16_nic2user: sys_vircopy failed",
1666 r);
1667 }
1668 count--;
1669 offset++;
1670 bytes--;
1671 vir_user++;
1672 odd_byte= 1;
1673 }
1674 }
1675 assert(count == 0);
1676 }
1677
1678 /*===========================================================================*
1679 * dp_next_iovec *
1680 *===========================================================================*/
1681 static void dp_next_iovec(iovp)
1682 iovec_dat_t *iovp;
1683 {
1684 assert(iovp->iod_iovec_s > IOVEC_NR);
1685
1686 iovp->iod_iovec_s -= IOVEC_NR;
1687
1688 iovp->iod_iovec_addr += IOVEC_NR * sizeof(iovec_t);
1689
1690 get_userdata(iovp->iod_proc_nr, iovp->iod_iovec_addr,
1691 (iovp->iod_iovec_s > IOVEC_NR ? IOVEC_NR : iovp->iod_iovec_s) *
1692 sizeof(iovec_t), iovp->iod_iovec);
1693 }
1694
1695 /*===========================================================================*
1696 * conf_hw *
1697 *===========================================================================*/
1698 static void conf_hw(dep)
1699 dpeth_t *dep;
1700 {
1701 static eth_stat_t empty_stat = {0, 0, 0, 0, 0, 0 /* ,... */ };
1702
1703 int ifnr;
1704 dp_conf_t *dcp;
1705
1706 dep->de_mode= DEM_DISABLED; /* Superfluous */
1707 ifnr= dep-de_table;
1708
1709 dcp= &dp_conf[ifnr];
1710 update_conf(dep, dcp);
1711 if (dep->de_mode != DEM_ENABLED)
1712 return;
1713 if (!wdeth_probe(dep) && !ne_probe(dep) && !el2_probe(dep))
1714 {
1715 printf("%s: No ethernet card found at 0x%x\n",
1716 dep->de_name, dep->de_base_port);
1717 dep->de_mode= DEM_DISABLED;
1718 return;
1719 }
1720
1721 /* XXX */ if (dep->de_linmem == 0) dep->de_linmem= 0xFFFF0000;
1722
1723 dep->de_flags = DEF_EMPTY;
1724 dep->de_stat = empty_stat;
1725 }
1726
1727 /*===========================================================================*
1728 * update_conf *
1729 *===========================================================================*/
1730 static void update_conf(dep, dcp)
1731 dpeth_t *dep;
1732 dp_conf_t *dcp;
1733 {
1734 long v;
1735 static char dpc_fmt[] = "x:d:x:x";
1736
1737 #if ENABLE_PCI
1738 if (dep->de_pci)
1739 {
1740 if (dep->de_pci == 1)
1741 {
1742 /* PCI device is present */
1743 dep->de_mode= DEM_ENABLED;
1744 }
1745 return; /* Already configured */
1746 }
1747 #endif
1748
1749 /* Get the default settings and modify them from the environment. */
1750 dep->de_mode= DEM_SINK;
1751 v= dcp->dpc_port;
1752 switch (env_parse(dcp->dpc_envvar, dpc_fmt, 0, &v, 0x0000L, 0xFFFFL)) {
1753 case EP_OFF:
1754 dep->de_mode= DEM_DISABLED;
1755 break;
1756 case EP_ON:
1757 case EP_SET:
1758 dep->de_mode= DEM_ENABLED; /* Might become disabled if
1759 * all probes fail */
1760 break;
1761 }
1762 dep->de_base_port= v;
1763
1764 v= dcp->dpc_irq | DEI_DEFAULT;
1765 (void) env_parse(dcp->dpc_envvar, dpc_fmt, 1, &v, 0L,
1766 (long) NR_IRQ_VECTORS - 1);
1767 dep->de_irq= v;
1768
1769 v= dcp->dpc_mem;
1770 (void) env_parse(dcp->dpc_envvar, dpc_fmt, 2, &v, 0L, 0xFFFFFL);
1771 dep->de_linmem= v;
1772
1773 v= 0;
1774 (void) env_parse(dcp->dpc_envvar, dpc_fmt, 3, &v, 0x2000L, 0x8000L);
1775 dep->de_ramsize= v;
1776 }
1777
1778 /*===========================================================================*
1779 * calc_iovec_size *
1780 *===========================================================================*/
1781 static int calc_iovec_size(iovp)
1782 iovec_dat_t *iovp;
1783 {
1784 /* Calculate the size of a request. Note that the iovec_dat
1785 * structure will be unusable after calc_iovec_size.
1786 */
1787 int size;
1788 int i;
1789
1790 size= 0;
1791 i= 0;
1792 while (i < iovp->iod_iovec_s)
1793 {
1794 if (i >= IOVEC_NR)
1795 {
1796 dp_next_iovec(iovp);
1797 i= 0;
1798 continue;
1799 }
1800 size += iovp->iod_iovec[i].iov_size;
1801 i++;
1802 }
1803 return size;
1804 }
1805
1806 /*===========================================================================*
1807 * reply *
1808 *===========================================================================*/
1809 static void reply(dep, err, may_block)
1810 dpeth_t *dep;
1811 int err;
1812 int may_block;
1813 {
1814 message reply;
1815 int status;
1816 int r;
1817
1818 status = 0;
1819 if (dep->de_flags & DEF_PACK_SEND)
1820 status |= DL_PACK_SEND;
1821 if (dep->de_flags & DEF_PACK_RECV)
1822 status |= DL_PACK_RECV;
1823
1824 reply.m_type = DL_TASK_REPLY;
1825 reply.DL_PORT = dep - de_table;
1826 reply.DL_PROC = dep->de_client;
1827 reply.DL_STAT = status | ((u32_t) err << 16);
1828 reply.DL_COUNT = dep->de_read_s;
1829 reply.DL_CLCK = 0; /* Don't know */
1830 r= send(dep->de_client, &reply);
1831
1832 if (r == ELOCKED && may_block)
1833 {
1834 #if 0
1835 printf("send locked\n");
1836 #endif
1837 return;
1838 }
1839
1840 if (r < 0)
1841 panic("", "dp8390: send failed:", r);
1842
1843 dep->de_read_s = 0;
1844 dep->de_flags &= ~(DEF_PACK_SEND | DEF_PACK_RECV);
1845 }
1846
1847 /*===========================================================================*
1848 * mess_reply *
1849 *===========================================================================*/
1850 static void mess_reply(req, reply_mess)
1851 message *req;
1852 message *reply_mess;
1853 {
1854 if (send(req->m_source, reply_mess) != OK)
1855 panic("", "dp8390: unable to mess_reply", NO_NUM);
1856 }
1857
1858 /*===========================================================================*
1859 * get_userdata *
1860 *===========================================================================*/
1861 static void get_userdata(user_proc, user_addr, count, loc_addr)
1862 int user_proc;
1863 vir_bytes user_addr;
1864 vir_bytes count;
1865 void *loc_addr;
1866 {
1867 int r;
1868
1869 r= sys_vircopy(user_proc, D, user_addr,
1870 SELF, D, (vir_bytes)loc_addr, count);
1871 if (r != OK)
1872 panic("DP8390", "get_userdata: sys_vircopy failed", r);
1873 }
1874
1875 /*===========================================================================*
1876 * put_userdata *
1877 *===========================================================================*/
1878 static void put_userdata(user_proc, user_addr, count, loc_addr)
1879 int user_proc;
1880 vir_bytes user_addr;
1881 vir_bytes count;
1882 void *loc_addr;
1883 {
1884 int r;
1885
1886 r= sys_vircopy(SELF, D, (vir_bytes)loc_addr,
1887 user_proc, D, user_addr, count);
1888 if (r != OK)
1889 panic("DP8390", "put_userdata: sys_vircopy failed", r);
1890 }
1891
1892 u8_t inb(port_t port)
1893 {
1894 int r;
1895 u32_t value;
1896
1897 r= sys_inb(port, &value);
1898 if (r != OK)
1899 panic("DP8390","sys_inb failed", r);
1900 return value;
1901 }
1902
1903 u16_t inw(port_t port)
1904 {
1905 int r;
1906 u16_t value;
1907
1908 r= sys_inw(port, &value);
1909 if (r != OK)
1910 panic("DP8390", "sys_inw failed", r);
1911 return value;
1912 }
1913
1914 void outb(port_t port, u8_t value)
1915 {
1916 int r;
1917
1918 r= sys_outb(port, value);
1919 if (r != OK)
1920 panic("DP8390", "sys_outb failed", r);
1921 }
1922
1923 void outw(port_t port, u16_t value)
1924 {
1925 int r;
1926
1927 r= sys_outw(port, value);
1928 if (r != OK)
1929 panic("DP8390", "sys_outw failed", r);
1930 }
1931
1932 static void insb(port_t port, void *buf, size_t size)
1933 {
1934 do_vir_insb(port, SELF, (vir_bytes)buf, size);
1935 }
1936
1937 static void insw(port_t port, void *buf, size_t size)
1938 {
1939 do_vir_insw(port, SELF, (vir_bytes)buf, size);
1940 }
1941
1942 static void do_vir_insb(port_t port, int proc, vir_bytes buf, size_t size)
1943 {
1944 int r;
1945
1946 r= sys_sdevio(DIO_INPUT, port, DIO_BYTE, proc, (void *)buf, size);
1947 if (r != OK)
1948 panic("DP8390", "sys_sdevio failed", r);
1949 }
1950
1951 static void do_vir_insw(port_t port, int proc, vir_bytes buf, size_t size)
1952 {
1953 int r;
1954
1955 r= sys_sdevio(DIO_INPUT, port, DIO_WORD, proc, (void *)buf, size);
1956 if (r != OK)
1957 panic("DP8390", "sys_sdevio failed", r);
1958 }
1959
1960 static void do_vir_outsb(port_t port, int proc, vir_bytes buf, size_t size)
1961 {
1962 int r;
1963
1964 r= sys_sdevio(DIO_OUTPUT, port, DIO_BYTE, proc, (void *)buf, size);
1965 if (r != OK)
1966 panic("DP8390", "sys_sdevio failed", r);
1967 }
1968
1969 static void do_vir_outsw(port_t port, int proc, vir_bytes buf, size_t size)
1970 {
1971 int r;
1972
1973 r= sys_sdevio(DIO_OUTPUT, port, DIO_WORD, proc, (void *)buf, size);
1974 if (r != OK)
1975 panic("DP8390", "sys_sdevio failed", r);
1976 }
1977
1978 /*
1979 * $PchId: dp8390.c,v 1.25 2005/02/10 17:32:07 philip Exp $
1980 */
Cache object: fc5888001bcb2291d6c1c7c6db917e97
|