3.1.7 branch.
[minix.git] / drivers / dp8390 / dp8390.c
blob78803c5d8fcd3c571cfa1dc4087953092bb37f4c
1 /*
2 * dp8390.c
4 * This file contains a ethernet device driver for NS dp8390 based ethernet
5 * cards.
7 * Created: before Dec 28, 1992 by Philip Homburg <philip@f-mnx.phicoh.com>
9 * Modified Mar 10 1994 by Philip Homburg
10 * Become a generic dp8390 driver.
12 * Modified Dec 20 1996 by G. Falzoni <falzoni@marina.scn.de>
13 * Added support for 3c503 boards.
16 #include <minix/drivers.h>
17 #include <minix/netdriver.h>
19 #include <stdlib.h>
20 #include <minix/com.h>
21 #include <minix/endpoint.h>
22 #include <minix/ds.h>
23 #include <net/hton.h>
24 #include <net/gen/ether.h>
25 #include <net/gen/eth_io.h>
26 #include <machine/vm.h>
27 #include "assert.h"
29 #include "local.h"
30 #include "dp8390.h"
32 static dpeth_t de_state;
33 static int de_instance;
35 u32_t system_hz;
37 /* Configuration */
38 typedef struct dp_conf
40 port_t dpc_port;
41 int dpc_irq;
42 phys_bytes dpc_mem;
43 } dp_conf_t;
45 #define DP_CONF_NR 4
46 PRIVATE dp_conf_t dp_conf[DP_CONF_NR]= /* Card addresses */
48 /* I/O port, IRQ, Buffer address. */
49 { 0x280, 3, 0xD0000, },
50 { 0x300, 5, 0xC8000, },
51 { 0x380, 10, 0xD8000, },
52 { 0x000, 0, 0x00000, },
55 /* Card inits configured out? */
56 #if !ENABLE_WDETH
57 #define wdeth_probe(dep) (0)
58 #endif
59 #if !ENABLE_NE2000
60 #define ne_probe(dep) (0)
61 #endif
62 #if !ENABLE_3C503
63 #define el2_probe(dep) (0)
64 #endif
66 /* Some clones of the dp8390 and the PC emulator 'Bochs' require the CR_STA
67 * on writes to the CR register. Additional CR_STAs do not appear to hurt
68 * genuine dp8390s
70 #define CR_EXTRA CR_STA
72 #if ENABLE_PCI
73 _PROTOTYPE( static void pci_conf, (void) );
74 #endif
75 _PROTOTYPE( static void do_vwrite_s, (message *mp, int from_int) );
76 _PROTOTYPE( static void do_vread_s, (message *mp) );
77 _PROTOTYPE( static void do_init, (message *mp) );
78 _PROTOTYPE( static void do_int, (dpeth_t *dep) );
79 _PROTOTYPE( static void do_getstat_s, (message *mp) );
80 _PROTOTYPE( static void dp_stop, (dpeth_t *dep) );
81 _PROTOTYPE( static void dp_init, (dpeth_t *dep) );
82 _PROTOTYPE( static void dp_confaddr, (dpeth_t *dep) );
83 _PROTOTYPE( static void dp_reinit, (dpeth_t *dep) );
84 _PROTOTYPE( static void dp_reset, (dpeth_t *dep) );
85 _PROTOTYPE( static void dp_check_ints, (dpeth_t *dep) );
86 _PROTOTYPE( static void dp_recv, (dpeth_t *dep) );
87 _PROTOTYPE( static void dp_send, (dpeth_t *dep) );
88 _PROTOTYPE( static void dp_getblock, (dpeth_t *dep, int page,
89 size_t offset, size_t size, void *dst) );
90 _PROTOTYPE( static void dp_pio8_getblock, (dpeth_t *dep, int page,
91 size_t offset, size_t size, void *dst) );
92 _PROTOTYPE( static void dp_pio16_getblock, (dpeth_t *dep, int page,
93 size_t offset, size_t size, void *dst) );
94 _PROTOTYPE( static int dp_pkt2user_s, (dpeth_t *dep, int page,
95 vir_bytes length) );
96 _PROTOTYPE( static void dp_user2nic_s, (dpeth_t *dep, iovec_dat_s_t *iovp,
97 vir_bytes offset, int nic_addr, vir_bytes count) );
98 _PROTOTYPE( static void dp_pio8_user2nic_s, (dpeth_t *dep,
99 iovec_dat_s_t *iovp, vir_bytes offset,
100 int nic_addr, vir_bytes count) );
101 _PROTOTYPE( static void dp_pio16_user2nic_s, (dpeth_t *dep,
102 iovec_dat_s_t *iovp, vir_bytes offset,
103 int nic_addr, vir_bytes count) );
104 _PROTOTYPE( static void dp_nic2user_s, (dpeth_t *dep, int nic_addr,
105 iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
106 _PROTOTYPE( static void dp_pio8_nic2user_s, (dpeth_t *dep, int nic_addr,
107 iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
108 _PROTOTYPE( static void dp_pio16_nic2user_s, (dpeth_t *dep, int nic_addr,
109 iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
110 _PROTOTYPE( static void dp_next_iovec_s, (iovec_dat_s_t *iovp) );
111 _PROTOTYPE( static void conf_hw, (dpeth_t *dep) );
112 _PROTOTYPE( static void update_conf, (dpeth_t *dep, dp_conf_t *dcp) );
113 _PROTOTYPE( static void map_hw_buffer, (dpeth_t *dep) );
114 _PROTOTYPE( static int calc_iovec_size_s, (iovec_dat_s_t *iovp) );
115 _PROTOTYPE( static void reply, (dpeth_t *dep) );
116 _PROTOTYPE( static void mess_reply, (message *req, message *reply) );
117 _PROTOTYPE( static void get_userdata_s, (int user_proc,
118 cp_grant_id_t grant, vir_bytes offset, vir_bytes count,
119 void *loc_addr) );
120 _PROTOTYPE( static void put_userdata_s, (int user_proc,
121 cp_grant_id_t grant, size_t count, void *loc_addr) );
122 _PROTOTYPE( static void insb, (port_t port, void *buf, size_t size) );
123 _PROTOTYPE( static void insw, (port_t port, void *buf, size_t size) );
124 _PROTOTYPE( static void do_vir_insb, (port_t port, int proc,
125 vir_bytes buf, size_t size) );
126 _PROTOTYPE( static void do_vir_insw, (port_t port, int proc,
127 vir_bytes buf, size_t size) );
128 _PROTOTYPE( static void do_vir_outsb, (port_t port, int proc,
129 vir_bytes buf, size_t size) );
130 _PROTOTYPE( static void do_vir_outsw, (port_t port, int proc,
131 vir_bytes buf, size_t size) );
133 /* SEF functions and variables. */
134 FORWARD _PROTOTYPE( void sef_local_startup, (void) );
135 FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
136 FORWARD _PROTOTYPE( void sef_cb_signal_handler, (int signo) );
137 EXTERN int env_argc;
138 EXTERN char **env_argv;
140 PRIVATE void handle_hw_intr(void)
142 int r, irq;
143 dpeth_t *dep;
145 dep = &de_state;
147 if (dep->de_mode != DEM_ENABLED)
148 return;
149 assert(dep->de_flags & DEF_ENABLED);
150 irq= dep->de_irq;
151 assert(irq >= 0 && irq < NR_IRQ_VECTORS);
152 if (dep->de_int_pending || 1)
154 dep->de_int_pending= 0;
155 dp_check_ints(dep);
156 do_int(dep);
157 r= sys_irqenable(&dep->de_hook);
158 if (r != OK) {
159 panic("unable enable interrupts: %d", r);
164 /*===========================================================================*
165 * dpeth_task *
166 *===========================================================================*/
167 int main(int argc, char *argv[])
169 message m;
170 int ipc_status;
171 int r;
173 /* SEF local startup. */
174 env_setargs(argc, argv);
175 sef_local_startup();
177 while (TRUE)
179 if ((r= netdriver_receive(ANY, &m, &ipc_status)) != OK)
180 panic("dp8390: netdriver_receive failed: %d", r);
182 if (is_ipc_notify(ipc_status)) {
183 switch (_ENDPOINT_P(m.m_source)) {
184 case HARDWARE:
185 handle_hw_intr();
186 break;
187 case CLOCK:
188 printf("dp8390: notify from CLOCK\n");
189 break;
190 default:
191 panic("dp8390: illegal notify from: %d",
192 m.m_source);
195 /* done, get a new message */
196 continue;
199 switch (m.m_type)
201 case DL_WRITEV_S: do_vwrite_s(&m, FALSE); break;
202 case DL_READV_S: do_vread_s(&m); break;
203 case DL_CONF: do_init(&m); break;
204 case DL_GETSTAT_S: do_getstat_s(&m); break;
205 default:
206 panic("dp8390: illegal message: %d", m.m_type);
211 /*===========================================================================*
212 * sef_local_startup *
213 *===========================================================================*/
214 PRIVATE void sef_local_startup()
216 /* Register init callbacks. */
217 sef_setcb_init_fresh(sef_cb_init_fresh);
218 sef_setcb_init_lu(sef_cb_init_fresh);
219 sef_setcb_init_restart(sef_cb_init_fresh);
221 /* Register live update callbacks. */
222 sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
223 sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree);
225 /* Register signal callbacks. */
226 sef_setcb_signal_handler(sef_cb_signal_handler);
228 /* Let SEF perform startup. */
229 sef_startup();
232 /*===========================================================================*
233 * sef_cb_init_fresh *
234 *===========================================================================*/
235 PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
237 /* Initialize the dp8390 driver. */
238 dpeth_t *dep;
239 long v;
241 system_hz = sys_hz();
243 if (env_argc < 1) {
244 panic("A head which at this time has no name");
247 v = 0;
248 (void) env_parse("instance", "d", 0, &v, 0, 255);
249 de_instance = (int) v;
251 dep = &de_state;
253 strcpy(dep->de_name, "dp8390#0");
254 dep->de_name[7] += de_instance;
256 /* Announce we are up! */
257 netdriver_announce();
259 return(OK);
262 /*===========================================================================*
263 * sef_cb_signal_handler *
264 *===========================================================================*/
265 PRIVATE void sef_cb_signal_handler(int signo)
267 /* Only check for termination signal, ignore anything else. */
268 if (signo != SIGTERM) return;
270 if (de_state.de_mode == DEM_ENABLED)
271 dp_stop(&de_state);
274 #if 0
275 /*===========================================================================*
276 * dp8390_dump *
277 *===========================================================================*/
278 void dp8390_dump()
280 dpeth_t *dep;
281 int isr;
283 dep = &de_state;
285 printf("\n");
286 #if XXX
287 if (dep->de_mode == DEM_DISABLED)
288 printf("dp8390 instance %d is disabled\n", de_instance);
289 else if (dep->de_mode == DEM_SINK)
290 printf("dp8390 instance %d is in sink mode\n", de_instance);
291 #endif
293 if (dep->de_mode != DEM_ENABLED)
294 return;
296 printf("dp8390 statistics of instance %d:\n", de_instance);
298 printf("recvErr :%8ld\t", dep->de_stat.ets_recvErr);
299 printf("sendErr :%8ld\t", dep->de_stat.ets_sendErr);
300 printf("OVW :%8ld\n", dep->de_stat.ets_OVW);
302 printf("CRCerr :%8ld\t", dep->de_stat.ets_CRCerr);
303 printf("frameAll :%8ld\t", dep->de_stat.ets_frameAll);
304 printf("missedP :%8ld\n", dep->de_stat.ets_missedP);
306 printf("packetR :%8ld\t", dep->de_stat.ets_packetR);
307 printf("packetT :%8ld\t", dep->de_stat.ets_packetT);
308 printf("transDef :%8ld\n", dep->de_stat.ets_transDef);
310 printf("collision :%8ld\t", dep->de_stat.ets_collision);
311 printf("transAb :%8ld\t", dep->de_stat.ets_transAb);
312 printf("carrSense :%8ld\n", dep->de_stat.ets_carrSense);
314 printf("fifoUnder :%8ld\t", dep->de_stat.ets_fifoUnder);
315 printf("fifoOver :%8ld\t", dep->de_stat.ets_fifoOver);
316 printf("CDheartbeat:%8ld\n", dep->de_stat.ets_CDheartbeat);
318 printf("OWC :%8ld\t", dep->de_stat.ets_OWC);
320 isr= inb_reg0(dep, DP_ISR);
321 printf("dp_isr = 0x%x + 0x%x, de_flags = 0x%x\n", isr,
322 inb_reg0(dep, DP_ISR), dep->de_flags);
324 #endif
326 #if ENABLE_PCI
327 /*===========================================================================*
328 * pci_conf *
329 *===========================================================================*/
330 static void pci_conf()
332 int confnr;
333 char envvar[16];
334 struct dpeth *dep;
335 static char envfmt[] = "*:d.d.d";
336 long v;
337 static int first_time= 1;
339 if (!first_time)
340 return;
341 first_time= 0;
343 dep= &de_state;
345 /* Pick a default configuration for this instance. */
346 confnr= MIN(de_instance, DP_CONF_NR-1);
348 strcpy(envvar, "DPETH0");
349 envvar[5] += de_instance;
350 if (!(dep->de_pci= env_prefix(envvar, "pci")))
351 return; /* no PCI config */
352 v= 0;
353 (void) env_parse(envvar, envfmt, 1, &v, 0, 255);
354 dep->de_pcibus= v;
355 v= 0;
356 (void) env_parse(envvar, envfmt, 2, &v, 0, 255);
357 dep->de_pcidev= v;
358 v= 0;
359 (void) env_parse(envvar, envfmt, 3, &v, 0, 255);
360 dep->de_pcifunc= v;
362 if (!dep->de_pci) {
363 printf("%s: no pci for instance %d\n", dep->de_name,
364 de_instance);
365 return;
368 if (!rtl_probe(dep, de_instance))
369 dep->de_pci= -1;
371 #endif /* ENABLE_PCI */
373 /*===========================================================================*
374 * do_vwrite_s *
375 *===========================================================================*/
376 static void do_vwrite_s(mp, from_int)
377 message *mp;
378 int from_int;
380 int count, size;
381 int sendq_head;
382 dpeth_t *dep;
384 dep= &de_state;
386 count = mp->DL_COUNT;
387 dep->de_client= mp->m_source;
389 if (dep->de_mode == DEM_SINK)
391 assert(!from_int);
392 dep->de_flags |= DEF_PACK_SEND;
393 reply(dep);
394 return;
396 assert(dep->de_mode == DEM_ENABLED);
397 assert(dep->de_flags & DEF_ENABLED);
398 if (dep->de_flags & DEF_SEND_AVAIL)
399 panic("dp8390: send already in progress");
401 sendq_head= dep->de_sendq_head;
402 if (dep->de_sendq[sendq_head].sq_filled)
404 if (from_int)
405 panic("dp8390: should not be sending");
406 dep->de_sendmsg= *mp;
407 dep->de_flags |= DEF_SEND_AVAIL;
408 reply(dep);
409 return;
411 assert(!(dep->de_flags & DEF_PACK_SEND));
413 get_userdata_s(mp->DL_ENDPT, mp->DL_GRANT, 0,
414 (count > IOVEC_NR ? IOVEC_NR : count) *
415 sizeof(dep->de_write_iovec_s.iod_iovec[0]),
416 dep->de_write_iovec_s.iod_iovec);
417 dep->de_write_iovec_s.iod_iovec_s = count;
418 dep->de_write_iovec_s.iod_proc_nr = mp->DL_ENDPT;
419 dep->de_write_iovec_s.iod_grant = mp->DL_GRANT;
420 dep->de_write_iovec_s.iod_iovec_offset = 0;
422 dep->de_tmp_iovec_s = dep->de_write_iovec_s;
423 size = calc_iovec_size_s(&dep->de_tmp_iovec_s);
425 if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED)
427 panic("dp8390: invalid packet size: %d", size);
429 (dep->de_user2nicf_s)(dep, &dep->de_write_iovec_s, 0,
430 dep->de_sendq[sendq_head].sq_sendpage * DP_PAGESIZE,
431 size);
432 dep->de_sendq[sendq_head].sq_filled= TRUE;
433 if (dep->de_sendq_tail == sendq_head)
435 outb_reg0(dep, DP_TPSR, dep->de_sendq[sendq_head].sq_sendpage);
436 outb_reg0(dep, DP_TBCR1, size >> 8);
437 outb_reg0(dep, DP_TBCR0, size & 0xff);
438 outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);/* there it goes.. */
440 else
441 dep->de_sendq[sendq_head].sq_size= size;
443 if (++sendq_head == dep->de_sendq_nr)
444 sendq_head= 0;
445 assert(sendq_head < SENDQ_NR);
446 dep->de_sendq_head= sendq_head;
448 dep->de_flags |= DEF_PACK_SEND;
450 /* If the interrupt handler called, don't send a reply. The reply
451 * will be sent after all interrupts are handled.
453 if (from_int)
454 return;
455 reply(dep);
457 assert(dep->de_mode == DEM_ENABLED);
458 assert(dep->de_flags & DEF_ENABLED);
461 /*===========================================================================*
462 * do_vread_s *
463 *===========================================================================*/
464 static void do_vread_s(mp)
465 message *mp;
467 int count;
468 int size;
469 dpeth_t *dep;
471 dep= &de_state;
473 count = mp->DL_COUNT;
474 dep->de_client= mp->m_source;
475 if (dep->de_mode == DEM_SINK)
477 reply(dep);
478 return;
480 assert(dep->de_mode == DEM_ENABLED);
481 assert(dep->de_flags & DEF_ENABLED);
483 if(dep->de_flags & DEF_READING)
484 panic("dp8390: read already in progress");
486 get_userdata_s(mp->DL_ENDPT, mp->DL_GRANT, 0,
487 (count > IOVEC_NR ? IOVEC_NR : count) *
488 sizeof(dep->de_read_iovec_s.iod_iovec[0]),
489 dep->de_read_iovec_s.iod_iovec);
490 dep->de_read_iovec_s.iod_iovec_s = count;
491 dep->de_read_iovec_s.iod_proc_nr = mp->DL_ENDPT;
492 dep->de_read_iovec_s.iod_grant = mp->DL_GRANT;
493 dep->de_read_iovec_s.iod_iovec_offset = 0;
495 dep->de_tmp_iovec_s = dep->de_read_iovec_s;
496 size= calc_iovec_size_s(&dep->de_tmp_iovec_s);
498 if (size < ETH_MAX_PACK_SIZE_TAGGED)
499 panic("dp8390: wrong packet size: %d", size);
500 dep->de_flags |= DEF_READING;
502 dp_recv(dep);
504 if ((dep->de_flags & (DEF_READING|DEF_STOPPED)) ==
505 (DEF_READING|DEF_STOPPED))
507 /* The chip is stopped, and all arrived packets are
508 * delivered.
510 dp_reset(dep);
512 reply(dep);
515 /*===========================================================================*
516 * do_init *
517 *===========================================================================*/
518 static void do_init(message *mp)
520 dpeth_t *dep;
521 message reply_mess;
523 #if ENABLE_PCI
524 pci_conf(); /* Configure PCI devices. */
525 #endif
527 dep= &de_state;
529 if (dep->de_mode == DEM_DISABLED)
531 /* This is the default, try to (re)locate the device. */
532 conf_hw(dep);
533 if (dep->de_mode == DEM_DISABLED)
535 /* Probe failed, or the device is configured off. */
536 reply_mess.m_type= DL_CONF_REPLY;
537 reply_mess.DL_STAT= ENXIO;
538 mess_reply(mp, &reply_mess);
539 return;
541 if (dep->de_mode == DEM_ENABLED)
542 dp_init(dep);
545 if (dep->de_mode == DEM_SINK)
547 strncpy((char *) dep->de_address.ea_addr, "ZDP", 6);
548 dep->de_address.ea_addr[5] = de_instance;
549 dp_confaddr(dep);
550 reply_mess.m_type = DL_CONF_REPLY;
551 reply_mess.DL_STAT = OK;
552 *(ether_addr_t *) reply_mess.DL_HWADDR = dep->de_address;
553 mess_reply(mp, &reply_mess);
554 return;
556 assert(dep->de_mode == DEM_ENABLED);
557 assert(dep->de_flags & DEF_ENABLED);
559 dep->de_flags &= ~(DEF_PROMISC | DEF_MULTI | DEF_BROAD);
561 if (mp->DL_MODE & DL_PROMISC_REQ)
562 dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD;
563 if (mp->DL_MODE & DL_MULTI_REQ)
564 dep->de_flags |= DEF_MULTI;
565 if (mp->DL_MODE & DL_BROAD_REQ)
566 dep->de_flags |= DEF_BROAD;
568 dp_reinit(dep);
570 reply_mess.m_type = DL_CONF_REPLY;
571 reply_mess.DL_STAT = OK;
572 *(ether_addr_t *) reply_mess.DL_HWADDR = dep->de_address;
574 mess_reply(mp, &reply_mess);
577 /*===========================================================================*
578 * do_int *
579 *===========================================================================*/
580 static void do_int(dep)
581 dpeth_t *dep;
583 if (dep->de_flags & (DEF_PACK_SEND | DEF_PACK_RECV))
584 reply(dep);
587 /*===========================================================================*
588 * do_getstat_s *
589 *===========================================================================*/
590 static void do_getstat_s(mp)
591 message *mp;
593 int r;
594 dpeth_t *dep;
596 dep= &de_state;
598 if (dep->de_mode == DEM_SINK)
600 put_userdata_s(mp->DL_ENDPT, (vir_bytes) mp->DL_GRANT,
601 (vir_bytes) sizeof(dep->de_stat), &dep->de_stat);
603 mp->m_type= DL_STAT_REPLY;
604 r= send(mp->m_source, mp);
605 if (r != OK)
606 panic("do_getstat: send failed: %d", r);
607 return;
609 assert(dep->de_mode == DEM_ENABLED);
610 assert(dep->de_flags & DEF_ENABLED);
612 dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0);
613 dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1);
614 dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2);
616 put_userdata_s(mp->DL_ENDPT, mp->DL_GRANT,
617 sizeof(dep->de_stat), &dep->de_stat);
619 mp->m_type= DL_STAT_REPLY;
620 r= send(mp->m_source, mp);
621 if (r != OK)
622 panic("do_getstat: send failed: %d", r);
625 /*===========================================================================*
626 * dp_stop *
627 *===========================================================================*/
628 static void dp_stop(dep)
629 dpeth_t *dep;
632 if (dep->de_mode == DEM_SINK)
633 return;
634 assert(dep->de_mode == DEM_ENABLED);
636 if (!(dep->de_flags & DEF_ENABLED))
637 return;
639 outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
640 (dep->de_stopf)(dep);
642 dep->de_flags= DEF_EMPTY;
645 /*===========================================================================*
646 * dp_init *
647 *===========================================================================*/
648 static void dp_init(dep)
649 dpeth_t *dep;
651 int dp_rcr_reg;
652 int i, r;
654 /* General initialization */
655 dep->de_flags = DEF_EMPTY;
656 (*dep->de_initf)(dep);
658 dp_confaddr(dep);
660 if (debug)
662 printf("%s: Ethernet address ", dep->de_name);
663 for (i= 0; i < 6; i++)
664 printf("%x%c", dep->de_address.ea_addr[i],
665 i < 5 ? ':' : '\n');
668 /* Map buffer */
669 map_hw_buffer(dep);
671 /* Initialization of the dp8390 following the mandatory procedure
672 * in reference manual ("DP8390D/NS32490D NIC Network Interface
673 * Controller", National Semiconductor, July 1995, Page 29).
675 /* Step 1: */
676 outb_reg0(dep, DP_CR, CR_PS_P0 | CR_STP | CR_DM_ABORT);
677 /* Step 2: */
678 if (dep->de_16bit)
679 outb_reg0(dep, DP_DCR, DCR_WORDWIDE | DCR_8BYTES | DCR_BMS);
680 else
681 outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES | DCR_BMS);
682 /* Step 3: */
683 outb_reg0(dep, DP_RBCR0, 0);
684 outb_reg0(dep, DP_RBCR1, 0);
685 /* Step 4: */
686 dp_rcr_reg = 0;
687 if (dep->de_flags & DEF_PROMISC)
688 dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM;
689 if (dep->de_flags & DEF_BROAD)
690 dp_rcr_reg |= RCR_AB;
691 if (dep->de_flags & DEF_MULTI)
692 dp_rcr_reg |= RCR_AM;
693 outb_reg0(dep, DP_RCR, dp_rcr_reg);
694 /* Step 5: */
695 outb_reg0(dep, DP_TCR, TCR_INTERNAL);
696 /* Step 6: */
697 outb_reg0(dep, DP_BNRY, dep->de_startpage);
698 outb_reg0(dep, DP_PSTART, dep->de_startpage);
699 outb_reg0(dep, DP_PSTOP, dep->de_stoppage);
700 /* Step 7: */
701 outb_reg0(dep, DP_ISR, 0xFF);
702 /* Step 8: */
703 outb_reg0(dep, DP_IMR, IMR_PRXE | IMR_PTXE | IMR_RXEE | IMR_TXEE |
704 IMR_OVWE | IMR_CNTE);
705 /* Step 9: */
706 outb_reg0(dep, DP_CR, CR_PS_P1 | CR_DM_ABORT | CR_STP);
708 outb_reg1(dep, DP_PAR0, dep->de_address.ea_addr[0]);
709 outb_reg1(dep, DP_PAR1, dep->de_address.ea_addr[1]);
710 outb_reg1(dep, DP_PAR2, dep->de_address.ea_addr[2]);
711 outb_reg1(dep, DP_PAR3, dep->de_address.ea_addr[3]);
712 outb_reg1(dep, DP_PAR4, dep->de_address.ea_addr[4]);
713 outb_reg1(dep, DP_PAR5, dep->de_address.ea_addr[5]);
715 outb_reg1(dep, DP_MAR0, 0xff);
716 outb_reg1(dep, DP_MAR1, 0xff);
717 outb_reg1(dep, DP_MAR2, 0xff);
718 outb_reg1(dep, DP_MAR3, 0xff);
719 outb_reg1(dep, DP_MAR4, 0xff);
720 outb_reg1(dep, DP_MAR5, 0xff);
721 outb_reg1(dep, DP_MAR6, 0xff);
722 outb_reg1(dep, DP_MAR7, 0xff);
724 outb_reg1(dep, DP_CURR, dep->de_startpage + 1);
725 /* Step 10: */
726 outb_reg0(dep, DP_CR, CR_DM_ABORT | CR_STA);
727 /* Step 11: */
728 outb_reg0(dep, DP_TCR, TCR_NORMAL);
730 inb_reg0(dep, DP_CNTR0); /* reset counters by reading */
731 inb_reg0(dep, DP_CNTR1);
732 inb_reg0(dep, DP_CNTR2);
734 /* Finish the initialization. */
735 dep->de_flags |= DEF_ENABLED;
736 for (i= 0; i<dep->de_sendq_nr; i++)
737 dep->de_sendq[i].sq_filled= 0;
738 dep->de_sendq_head= 0;
739 dep->de_sendq_tail= 0;
740 if (!dep->de_prog_IO)
742 dep->de_user2nicf_s= dp_user2nic_s;
743 dep->de_nic2userf_s= dp_nic2user_s;
744 dep->de_getblockf= dp_getblock;
746 else if (dep->de_16bit)
748 dep->de_user2nicf_s= dp_pio16_user2nic_s;
749 dep->de_nic2userf_s= dp_pio16_nic2user_s;
750 dep->de_getblockf= dp_pio16_getblock;
752 else
754 dep->de_user2nicf_s= dp_pio8_user2nic_s;
755 dep->de_nic2userf_s= dp_pio8_nic2user_s;
756 dep->de_getblockf= dp_pio8_getblock;
759 /* Set the interrupt handler and policy. Do not automatically
760 * reenable interrupts. Return the IRQ line number on interrupts.
762 dep->de_hook = dep->de_irq;
763 r= sys_irqsetpolicy(dep->de_irq, 0, &dep->de_hook);
764 if (r != OK)
765 panic("sys_irqsetpolicy failed: %d", r);
767 r= sys_irqenable(&dep->de_hook);
768 if (r != OK)
770 panic("unable enable interrupts: %d", r);
774 /*===========================================================================*
775 * dp_confaddr *
776 *===========================================================================*/
777 static void dp_confaddr(dep)
778 dpeth_t *dep;
780 int i;
781 char eakey[16];
782 static char eafmt[]= "x:x:x:x:x:x";
783 long v;
785 /* User defined ethernet address? */
786 strcpy(eakey, "DPETH0_EA");
787 eakey[5] += de_instance;
789 for (i= 0; i < 6; i++)
791 v= dep->de_address.ea_addr[i];
792 if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET)
794 break;
796 dep->de_address.ea_addr[i]= v;
799 if (i != 0 && i != 6) env_panic(eakey); /* It's all or nothing */
802 /*===========================================================================*
803 * dp_reinit *
804 *===========================================================================*/
805 static void dp_reinit(dep)
806 dpeth_t *dep;
808 int dp_rcr_reg;
810 outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
812 dp_rcr_reg = 0;
813 if (dep->de_flags & DEF_PROMISC)
814 dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM;
815 if (dep->de_flags & DEF_BROAD)
816 dp_rcr_reg |= RCR_AB;
817 if (dep->de_flags & DEF_MULTI)
818 dp_rcr_reg |= RCR_AM;
819 outb_reg0(dep, DP_RCR, dp_rcr_reg);
822 /*===========================================================================*
823 * dp_reset *
824 *===========================================================================*/
825 static void dp_reset(dep)
826 dpeth_t *dep;
828 int i;
830 /* Stop chip */
831 outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
832 outb_reg0(dep, DP_RBCR0, 0);
833 outb_reg0(dep, DP_RBCR1, 0);
834 for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RST) == 0); i++)
835 ; /* Do nothing */
836 outb_reg0(dep, DP_TCR, TCR_1EXTERNAL|TCR_OFST);
837 outb_reg0(dep, DP_CR, CR_STA|CR_DM_ABORT);
838 outb_reg0(dep, DP_TCR, TCR_NORMAL);
840 /* Acknowledge the ISR_RDC (remote dma) interrupt. */
841 for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RDC) == 0); i++)
842 ; /* Do nothing */
843 outb_reg0(dep, DP_ISR, inb_reg0(dep, DP_ISR) & ~ISR_RDC);
845 /* Reset the transmit ring. If we were transmitting a packet, we
846 * pretend that the packet is processed. Higher layers will
847 * retransmit if the packet wasn't actually sent.
849 dep->de_sendq_head= dep->de_sendq_tail= 0;
850 for (i= 0; i<dep->de_sendq_nr; i++)
851 dep->de_sendq[i].sq_filled= 0;
852 dp_send(dep);
853 dep->de_flags &= ~DEF_STOPPED;
856 /*===========================================================================*
857 * dp_check_ints *
858 *===========================================================================*/
859 static void dp_check_ints(dep)
860 dpeth_t *dep;
862 int isr, tsr;
863 int size, sendq_tail;
865 if (!(dep->de_flags & DEF_ENABLED))
866 panic("dp8390: got premature interrupt");
868 for(;;)
870 isr = inb_reg0(dep, DP_ISR);
871 if (!isr)
872 break;
873 outb_reg0(dep, DP_ISR, isr);
874 if (isr & (ISR_PTX|ISR_TXE))
876 if (isr & ISR_TXE)
878 #if DEBUG
879 { printf("%s: got send Error\n", dep->de_name); }
880 #endif
881 dep->de_stat.ets_sendErr++;
883 else
885 tsr = inb_reg0(dep, DP_TSR);
887 if (tsr & TSR_PTX) dep->de_stat.ets_packetT++;
888 #if 0 /* Reserved in later manuals, should be ignored */
889 if (!(tsr & TSR_DFR))
891 /* In most (all?) implementations of
892 * the dp8390, this bit is set
893 * when the packet is not deferred
895 dep->de_stat.ets_transDef++;
897 #endif
898 if (tsr & TSR_COL) dep->de_stat.ets_collision++;
899 if (tsr & TSR_ABT) dep->de_stat.ets_transAb++;
900 if (tsr & TSR_CRS) dep->de_stat.ets_carrSense++;
901 if (tsr & TSR_FU
902 && ++dep->de_stat.ets_fifoUnder <= 10)
904 printf("%s: fifo underrun\n",
905 dep->de_name);
907 if (tsr & TSR_CDH
908 && ++dep->de_stat.ets_CDheartbeat <= 10)
910 printf("%s: CD heart beat failure\n",
911 dep->de_name);
913 if (tsr & TSR_OWC) dep->de_stat.ets_OWC++;
915 sendq_tail= dep->de_sendq_tail;
917 if (!(dep->de_sendq[sendq_tail].sq_filled))
919 /* Software bug? */
920 assert(!debug);
922 /* Or hardware bug? */
923 printf(
924 "%s: transmit interrupt, but not sending\n",
925 dep->de_name);
926 continue;
928 dep->de_sendq[sendq_tail].sq_filled= 0;
929 if (++sendq_tail == dep->de_sendq_nr)
930 sendq_tail= 0;
931 dep->de_sendq_tail= sendq_tail;
932 if (dep->de_sendq[sendq_tail].sq_filled)
934 size= dep->de_sendq[sendq_tail].sq_size;
935 outb_reg0(dep, DP_TPSR,
936 dep->de_sendq[sendq_tail].sq_sendpage);
937 outb_reg0(dep, DP_TBCR1, size >> 8);
938 outb_reg0(dep, DP_TBCR0, size & 0xff);
939 outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);
941 if (dep->de_flags & DEF_SEND_AVAIL)
942 dp_send(dep);
945 if (isr & ISR_PRX)
947 /* Only call dp_recv if there is a read request */
948 if (dep->de_flags & DEF_READING)
949 dp_recv(dep);
952 if (isr & ISR_RXE) dep->de_stat.ets_recvErr++;
953 if (isr & ISR_CNT)
955 dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0);
956 dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1);
957 dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2);
959 if (isr & ISR_OVW)
961 dep->de_stat.ets_OVW++;
962 #if 0
963 { printW(); printf(
964 "%s: got overwrite warning\n", dep->de_name); }
965 #endif
966 if (dep->de_flags & DEF_READING)
968 printf(
969 "dp_check_ints: strange: overwrite warning and pending read request\n");
970 dp_recv(dep);
973 if (isr & ISR_RDC)
975 /* Nothing to do */
977 if (isr & ISR_RST)
979 /* this means we got an interrupt but the ethernet
980 * chip is shutdown. We set the flag DEF_STOPPED,
981 * and continue processing arrived packets. When the
982 * receive buffer is empty, we reset the dp8390.
984 #if 0
985 { printW(); printf(
986 "%s: NIC stopped\n", dep->de_name); }
987 #endif
988 dep->de_flags |= DEF_STOPPED;
989 break;
992 if ((dep->de_flags & (DEF_READING|DEF_STOPPED)) ==
993 (DEF_READING|DEF_STOPPED))
995 /* The chip is stopped, and all arrived packets are
996 * delivered.
998 dp_reset(dep);
1002 /*===========================================================================*
1003 * dp_recv *
1004 *===========================================================================*/
1005 static void dp_recv(dep)
1006 dpeth_t *dep;
1008 dp_rcvhdr_t header;
1009 unsigned pageno, curr, next;
1010 vir_bytes length;
1011 int packet_processed, r;
1012 u16_t eth_type;
1014 packet_processed = FALSE;
1015 pageno = inb_reg0(dep, DP_BNRY) + 1;
1016 if (pageno == dep->de_stoppage) pageno = dep->de_startpage;
1020 outb_reg0(dep, DP_CR, CR_PS_P1 | CR_EXTRA);
1021 curr = inb_reg1(dep, DP_CURR);
1022 outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
1024 if (curr == pageno) break;
1026 (dep->de_getblockf)(dep, pageno, (size_t)0, sizeof(header),
1027 &header);
1028 (dep->de_getblockf)(dep, pageno, sizeof(header) +
1029 2*sizeof(ether_addr_t), sizeof(eth_type), &eth_type);
1031 length = (header.dr_rbcl | (header.dr_rbch << 8)) -
1032 sizeof(dp_rcvhdr_t);
1033 next = header.dr_next;
1034 if (length < ETH_MIN_PACK_SIZE ||
1035 length > ETH_MAX_PACK_SIZE_TAGGED)
1037 printf("%s: packet with strange length arrived: %d\n",
1038 dep->de_name, (int) length);
1039 next= curr;
1041 else if (next < dep->de_startpage || next >= dep->de_stoppage)
1043 printf("%s: strange next page\n", dep->de_name);
1044 next= curr;
1046 else if (header.dr_status & RSR_FO)
1048 /* This is very serious, so we issue a warning and
1049 * reset the buffers */
1050 printf("%s: fifo overrun, resetting receive buffer\n",
1051 dep->de_name);
1052 dep->de_stat.ets_fifoOver++;
1053 next = curr;
1055 else if ((header.dr_status & RSR_PRX) &&
1056 (dep->de_flags & DEF_ENABLED))
1058 r = dp_pkt2user_s(dep, pageno, length);
1059 if (r != OK)
1060 return;
1062 packet_processed = TRUE;
1063 dep->de_stat.ets_packetR++;
1065 if (next == dep->de_startpage)
1066 outb_reg0(dep, DP_BNRY, dep->de_stoppage - 1);
1067 else
1068 outb_reg0(dep, DP_BNRY, next - 1);
1070 pageno = next;
1072 while (!packet_processed);
1075 /*===========================================================================*
1076 * dp_send *
1077 *===========================================================================*/
1078 static void dp_send(dep)
1079 dpeth_t *dep;
1081 if (!(dep->de_flags & DEF_SEND_AVAIL))
1082 return;
1084 dep->de_flags &= ~DEF_SEND_AVAIL;
1085 do_vwrite_s(&dep->de_sendmsg, TRUE);
1088 /*===========================================================================*
1089 * dp_getblock *
1090 *===========================================================================*/
1091 static void dp_getblock(dep, page, offset, size, dst)
1092 dpeth_t *dep;
1093 int page;
1094 size_t offset;
1095 size_t size;
1096 void *dst;
1098 offset = page * DP_PAGESIZE + offset;
1100 memcpy(dst, dep->de_locmem + offset, size);
1103 /*===========================================================================*
1104 * dp_pio8_getblock *
1105 *===========================================================================*/
1106 static void dp_pio8_getblock(dep, page, offset, size, dst)
1107 dpeth_t *dep;
1108 int page;
1109 size_t offset;
1110 size_t size;
1111 void *dst;
1113 offset = page * DP_PAGESIZE + offset;
1114 outb_reg0(dep, DP_RBCR0, size & 0xFF);
1115 outb_reg0(dep, DP_RBCR1, size >> 8);
1116 outb_reg0(dep, DP_RSAR0, offset & 0xFF);
1117 outb_reg0(dep, DP_RSAR1, offset >> 8);
1118 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
1120 insb(dep->de_data_port, dst, size);
1123 /*===========================================================================*
1124 * dp_pio16_getblock *
1125 *===========================================================================*/
1126 static void dp_pio16_getblock(dep, page, offset, size, dst)
1127 dpeth_t *dep;
1128 int page;
1129 size_t offset;
1130 size_t size;
1131 void *dst;
1133 offset = page * DP_PAGESIZE + offset;
1134 outb_reg0(dep, DP_RBCR0, size & 0xFF);
1135 outb_reg0(dep, DP_RBCR1, size >> 8);
1136 outb_reg0(dep, DP_RSAR0, offset & 0xFF);
1137 outb_reg0(dep, DP_RSAR1, offset >> 8);
1138 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
1140 assert (!(size & 1));
1141 insw(dep->de_data_port, dst, size);
1144 /*===========================================================================*
1145 * dp_pkt2user_s *
1146 *===========================================================================*/
1147 static int dp_pkt2user_s(dpeth_t *dep, int page, vir_bytes length)
1149 int last, count;
1151 if (!(dep->de_flags & DEF_READING))
1152 return EGENERIC;
1154 last = page + (length - 1) / DP_PAGESIZE;
1155 if (last >= dep->de_stoppage)
1157 count = (dep->de_stoppage - page) * DP_PAGESIZE -
1158 sizeof(dp_rcvhdr_t);
1160 /* Save read_iovec since we need it twice. */
1161 dep->de_tmp_iovec_s = dep->de_read_iovec_s;
1162 (dep->de_nic2userf_s)(dep, page * DP_PAGESIZE +
1163 sizeof(dp_rcvhdr_t), &dep->de_tmp_iovec_s, 0, count);
1164 (dep->de_nic2userf_s)(dep, dep->de_startpage * DP_PAGESIZE,
1165 &dep->de_read_iovec_s, count, length - count);
1167 else
1169 (dep->de_nic2userf_s)(dep, page * DP_PAGESIZE +
1170 sizeof(dp_rcvhdr_t), &dep->de_read_iovec_s, 0, length);
1173 dep->de_read_s = length;
1174 dep->de_flags |= DEF_PACK_RECV;
1175 dep->de_flags &= ~DEF_READING;
1177 return OK;
1180 /*===========================================================================*
1181 * dp_user2nic_s *
1182 *===========================================================================*/
1183 static void dp_user2nic_s(dep, iovp, offset, nic_addr, count)
1184 dpeth_t *dep;
1185 iovec_dat_s_t *iovp;
1186 vir_bytes offset;
1187 int nic_addr;
1188 vir_bytes count;
1190 vir_bytes vir_hw;
1191 int bytes, i, r;
1193 vir_hw = (vir_bytes)dep->de_locmem + nic_addr;
1195 i= 0;
1196 while (count > 0)
1198 if (i >= IOVEC_NR)
1200 dp_next_iovec_s(iovp);
1201 i= 0;
1202 continue;
1204 assert(i < iovp->iod_iovec_s);
1205 if (offset >= iovp->iod_iovec[i].iov_size)
1207 offset -= iovp->iod_iovec[i].iov_size;
1208 i++;
1209 continue;
1211 bytes = iovp->iod_iovec[i].iov_size - offset;
1212 if (bytes > count)
1213 bytes = count;
1215 r= sys_safecopyfrom(iovp->iod_proc_nr,
1216 iovp->iod_iovec[i].iov_grant, offset,
1217 vir_hw, bytes, D);
1218 if (r != OK) {
1219 panic("dp_user2nic_s: sys_safecopyfrom failed: %d", r);
1222 count -= bytes;
1223 vir_hw += bytes;
1224 offset += bytes;
1226 assert(count == 0);
1229 /*===========================================================================*
1230 * dp_pio8_user2nic_s *
1231 *===========================================================================*/
1232 static void dp_pio8_user2nic_s(dep, iovp, offset, nic_addr, count)
1233 dpeth_t *dep;
1234 iovec_dat_s_t *iovp;
1235 vir_bytes offset;
1236 int nic_addr;
1237 vir_bytes count;
1239 int bytes, i, r;
1241 outb_reg0(dep, DP_ISR, ISR_RDC);
1243 outb_reg0(dep, DP_RBCR0, count & 0xFF);
1244 outb_reg0(dep, DP_RBCR1, count >> 8);
1245 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
1246 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
1247 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
1249 i= 0;
1250 while (count > 0)
1252 if (i >= IOVEC_NR)
1254 dp_next_iovec_s(iovp);
1255 i= 0;
1256 continue;
1258 assert(i < iovp->iod_iovec_s);
1259 if (offset >= iovp->iod_iovec[i].iov_size)
1261 offset -= iovp->iod_iovec[i].iov_size;
1262 i++;
1263 continue;
1265 bytes = iovp->iod_iovec[i].iov_size - offset;
1266 if (bytes > count)
1267 bytes = count;
1269 r= sys_safe_outsb(dep->de_data_port, iovp->iod_proc_nr,
1270 iovp->iod_iovec[i].iov_grant, offset, bytes);
1271 if (r != OK) {
1272 panic("dp_pio8_user2nic_s: sys_safe_outsb failed: %d",
1275 count -= bytes;
1276 offset += bytes;
1278 assert(count == 0);
1280 for (i= 0; i<100; i++)
1282 if (inb_reg0(dep, DP_ISR) & ISR_RDC)
1283 break;
1285 if (i == 100)
1287 panic("dp8390: remote dma failed to complete");
1291 /*===========================================================================*
1292 * dp_pio16_user2nic_s *
1293 *===========================================================================*/
1294 static void dp_pio16_user2nic_s(dep, iovp, offset, nic_addr, count)
1295 dpeth_t *dep;
1296 iovec_dat_s_t *iovp;
1297 vir_bytes offset;
1298 int nic_addr;
1299 vir_bytes count;
1301 vir_bytes ecount;
1302 cp_grant_id_t gid;
1303 int i, r, bytes, user_proc;
1304 u8_t two_bytes[2];
1305 int odd_byte;
1307 ecount= (count+1) & ~1;
1308 odd_byte= 0;
1310 outb_reg0(dep, DP_ISR, ISR_RDC);
1311 outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
1312 outb_reg0(dep, DP_RBCR1, ecount >> 8);
1313 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
1314 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
1315 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
1317 i= 0;
1318 while (count > 0)
1320 if (i >= IOVEC_NR)
1322 dp_next_iovec_s(iovp);
1323 i= 0;
1324 continue;
1326 assert(i < iovp->iod_iovec_s);
1327 if (offset >= iovp->iod_iovec[i].iov_size)
1329 offset -= iovp->iod_iovec[i].iov_size;
1330 i++;
1331 continue;
1333 bytes = iovp->iod_iovec[i].iov_size - offset;
1334 if (bytes > count)
1335 bytes = count;
1337 user_proc= iovp->iod_proc_nr;
1338 gid= iovp->iod_iovec[i].iov_grant;
1339 if (odd_byte)
1341 r= sys_safecopyfrom(user_proc, gid, offset,
1342 (vir_bytes)&two_bytes[1], 1, D);
1343 if (r != OK) {
1344 panic("dp_pio16_user2nic: sys_safecopyfrom failed: %d", r);
1346 outw(dep->de_data_port, *(u16_t *)two_bytes);
1347 count--;
1348 offset++;
1349 bytes--;
1350 odd_byte= 0;
1351 if (!bytes)
1352 continue;
1354 ecount= bytes & ~1;
1355 if (ecount != 0)
1357 r= sys_safe_outsw(dep->de_data_port, user_proc,
1358 gid, offset, ecount);
1359 if (r != OK) {
1360 panic("dp_pio16_user2nic: sys_safe_outsw failed: %d", r);
1362 count -= ecount;
1363 offset += ecount;
1364 bytes -= ecount;
1366 if (bytes)
1368 assert(bytes == 1);
1369 r= sys_safecopyfrom(user_proc, gid, offset,
1370 (vir_bytes)&two_bytes[0], 1, D);
1371 if (r != OK) {
1372 panic("dp_pio16_user2nic: sys_safecopyfrom failed: %d", r);
1374 count--;
1375 offset++;
1376 bytes--;
1377 odd_byte= 1;
1380 assert(count == 0);
1382 if (odd_byte)
1383 outw(dep->de_data_port, *(u16_t *)two_bytes);
1385 for (i= 0; i<100; i++)
1387 if (inb_reg0(dep, DP_ISR) & ISR_RDC)
1388 break;
1390 if (i == 100)
1392 panic("dp8390: remote dma failed to complete");
1396 /*===========================================================================*
1397 * dp_nic2user_s *
1398 *===========================================================================*/
1399 static void dp_nic2user_s(dep, nic_addr, iovp, offset, count)
1400 dpeth_t *dep;
1401 int nic_addr;
1402 iovec_dat_s_t *iovp;
1403 vir_bytes offset;
1404 vir_bytes count;
1406 vir_bytes vir_hw;
1407 int bytes, i, r;
1409 vir_hw = (vir_bytes)dep->de_locmem + nic_addr;
1411 i= 0;
1412 while (count > 0)
1414 if (i >= IOVEC_NR)
1416 dp_next_iovec_s(iovp);
1417 i= 0;
1418 continue;
1420 assert(i < iovp->iod_iovec_s);
1421 if (offset >= iovp->iod_iovec[i].iov_size)
1423 offset -= iovp->iod_iovec[i].iov_size;
1424 i++;
1425 continue;
1427 bytes = iovp->iod_iovec[i].iov_size - offset;
1428 if (bytes > count)
1429 bytes = count;
1431 r= sys_safecopyto(iovp->iod_proc_nr,
1432 iovp->iod_iovec[i].iov_grant, offset,
1433 vir_hw, bytes, D);
1434 if (r != OK)
1435 panic("dp_nic2user_s: sys_safecopyto failed: %d", r);
1437 count -= bytes;
1438 vir_hw += bytes;
1439 offset += bytes;
1441 assert(count == 0);
1444 /*===========================================================================*
1445 * dp_pio8_nic2user_s *
1446 *===========================================================================*/
1447 static void dp_pio8_nic2user_s(dep, nic_addr, iovp, offset, count)
1448 dpeth_t *dep;
1449 int nic_addr;
1450 iovec_dat_s_t *iovp;
1451 vir_bytes offset;
1452 vir_bytes count;
1454 int bytes, i, r;
1456 outb_reg0(dep, DP_RBCR0, count & 0xFF);
1457 outb_reg0(dep, DP_RBCR1, count >> 8);
1458 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
1459 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
1460 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
1462 i= 0;
1463 while (count > 0)
1465 if (i >= IOVEC_NR)
1467 dp_next_iovec_s(iovp);
1468 i= 0;
1469 continue;
1471 assert(i < iovp->iod_iovec_s);
1472 if (offset >= iovp->iod_iovec[i].iov_size)
1474 offset -= iovp->iod_iovec[i].iov_size;
1475 i++;
1476 continue;
1478 bytes = iovp->iod_iovec[i].iov_size - offset;
1479 if (bytes > count)
1480 bytes = count;
1482 r= sys_safe_insb(dep->de_data_port, iovp->iod_proc_nr,
1483 iovp->iod_iovec[i].iov_grant, offset, bytes);
1484 if (r != OK) {
1485 panic("dp_pio8_nic2user_s: sys_safe_insb failed: %d", r);
1487 count -= bytes;
1488 offset += bytes;
1490 assert(count == 0);
1493 /*===========================================================================*
1494 * dp_pio16_nic2user_s *
1495 *===========================================================================*/
1496 static void dp_pio16_nic2user_s(dep, nic_addr, iovp, offset, count)
1497 dpeth_t *dep;
1498 int nic_addr;
1499 iovec_dat_s_t *iovp;
1500 vir_bytes offset;
1501 vir_bytes count;
1503 vir_bytes ecount;
1504 cp_grant_id_t gid;
1505 int i, r, bytes, user_proc;
1506 u8_t two_bytes[2];
1507 int odd_byte;
1509 ecount= (count+1) & ~1;
1510 odd_byte= 0;
1512 outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
1513 outb_reg0(dep, DP_RBCR1, ecount >> 8);
1514 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
1515 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
1516 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
1518 i= 0;
1519 while (count > 0)
1521 if (i >= IOVEC_NR)
1523 dp_next_iovec_s(iovp);
1524 i= 0;
1525 continue;
1527 assert(i < iovp->iod_iovec_s);
1528 if (offset >= iovp->iod_iovec[i].iov_size)
1530 offset -= iovp->iod_iovec[i].iov_size;
1531 i++;
1532 continue;
1534 bytes = iovp->iod_iovec[i].iov_size - offset;
1535 if (bytes > count)
1536 bytes = count;
1538 user_proc= iovp->iod_proc_nr;
1539 gid= iovp->iod_iovec[i].iov_grant;
1540 if (odd_byte)
1542 r= sys_safecopyto(user_proc, gid, offset,
1543 (vir_bytes)&two_bytes[1], 1, D);
1544 if (r != OK) {
1545 panic("dp_pio16_nic2user: sys_safecopyto failed: %d", r);
1547 count--;
1548 offset++;
1549 bytes--;
1550 odd_byte= 0;
1551 if (!bytes)
1552 continue;
1554 ecount= bytes & ~1;
1555 if (ecount != 0)
1557 r= sys_safe_insw(dep->de_data_port, user_proc, gid,
1558 offset, ecount);
1559 if (r != OK) {
1560 panic("dp_pio16_nic2user: sys_safe_insw failed: %d",
1563 count -= ecount;
1564 offset += ecount;
1565 bytes -= ecount;
1567 if (bytes)
1569 assert(bytes == 1);
1570 *(u16_t *)two_bytes= inw(dep->de_data_port);
1571 r= sys_safecopyto(user_proc, gid, offset,
1572 (vir_bytes)&two_bytes[0], 1, D);
1573 if (r != OK)
1575 panic("dp_pio16_nic2user: sys_safecopyto failed: %d",
1578 count--;
1579 offset++;
1580 bytes--;
1581 odd_byte= 1;
1584 assert(count == 0);
1587 /*===========================================================================*
1588 * dp_next_iovec_s *
1589 *===========================================================================*/
1590 static void dp_next_iovec_s(iovp)
1591 iovec_dat_s_t *iovp;
1593 assert(iovp->iod_iovec_s > IOVEC_NR);
1595 iovp->iod_iovec_s -= IOVEC_NR;
1597 iovp->iod_iovec_offset += IOVEC_NR * sizeof(iovec_t);
1599 get_userdata_s(iovp->iod_proc_nr, iovp->iod_grant,
1600 iovp->iod_iovec_offset,
1601 (iovp->iod_iovec_s > IOVEC_NR ? IOVEC_NR : iovp->iod_iovec_s) *
1602 sizeof(iovp->iod_iovec[0]), iovp->iod_iovec);
1605 /*===========================================================================*
1606 * conf_hw *
1607 *===========================================================================*/
1608 static void conf_hw(dep)
1609 dpeth_t *dep;
1611 static eth_stat_t empty_stat = {0, 0, 0, 0, 0, 0 /* ,... */ };
1613 int confnr;
1614 dp_conf_t *dcp;
1616 dep->de_mode= DEM_DISABLED; /* Superfluous */
1618 /* Pick a default configuration for this instance. */
1619 confnr= MIN(de_instance, DP_CONF_NR-1);
1621 dcp= &dp_conf[confnr];
1622 update_conf(dep, dcp);
1623 if (dep->de_mode != DEM_ENABLED)
1624 return;
1625 if (!wdeth_probe(dep) && !ne_probe(dep) && !el2_probe(dep))
1627 printf("%s: No ethernet card found at 0x%x\n",
1628 dep->de_name, dep->de_base_port);
1629 dep->de_mode= DEM_DISABLED;
1630 return;
1633 /* XXX */ if (dep->de_linmem == 0) dep->de_linmem= 0xFFFF0000;
1635 dep->de_flags = DEF_EMPTY;
1636 dep->de_stat = empty_stat;
1639 /*===========================================================================*
1640 * update_conf *
1641 *===========================================================================*/
1642 static void update_conf(dep, dcp)
1643 dpeth_t *dep;
1644 dp_conf_t *dcp;
1646 long v;
1647 static char dpc_fmt[] = "x:d:x:x";
1648 char eckey[16];
1650 #if ENABLE_PCI
1651 if (dep->de_pci)
1653 if (dep->de_pci == 1)
1655 /* PCI device is present */
1656 dep->de_mode= DEM_ENABLED;
1658 return; /* Already configured */
1660 #endif
1662 strcpy(eckey, "DPETH0");
1663 eckey[5] += de_instance;
1665 /* Get the default settings and modify them from the environment. */
1666 dep->de_mode= DEM_SINK;
1667 v= dcp->dpc_port;
1668 switch (env_parse(eckey, dpc_fmt, 0, &v, 0x0000L, 0xFFFFL)) {
1669 case EP_OFF:
1670 dep->de_mode= DEM_DISABLED;
1671 break;
1672 case EP_ON:
1673 case EP_SET:
1674 dep->de_mode= DEM_ENABLED; /* Might become disabled if
1675 * all probes fail */
1676 break;
1678 dep->de_base_port= v;
1680 v= dcp->dpc_irq | DEI_DEFAULT;
1681 (void) env_parse(eckey, dpc_fmt, 1, &v, 0L, (long) NR_IRQ_VECTORS - 1);
1682 dep->de_irq= v;
1684 v= dcp->dpc_mem;
1685 (void) env_parse(eckey, dpc_fmt, 2, &v, 0L, 0xFFFFFL);
1686 dep->de_linmem= v;
1688 v= 0;
1689 (void) env_parse(eckey, dpc_fmt, 3, &v, 0x2000L, 0x8000L);
1690 dep->de_ramsize= v;
1693 /*===========================================================================*
1694 * map_hw_buffer *
1695 *===========================================================================*/
1696 static void map_hw_buffer(dep)
1697 dpeth_t *dep;
1699 int r;
1700 size_t o, size;
1701 char *buf, *abuf;
1703 if (dep->de_prog_IO)
1705 #if 0
1706 printf(
1707 "map_hw_buffer: programmed I/O, no need to map buffer\n");
1708 #endif
1709 dep->de_locmem = (char *)-dep->de_ramsize; /* trap errors */
1710 return;
1713 size = dep->de_ramsize + I386_PAGE_SIZE; /* Add I386_PAGE_SIZE for
1714 * alignment
1716 buf= malloc(size);
1717 if (buf == NULL)
1718 panic("map_hw_buffer: cannot malloc size: %d", size);
1719 o= I386_PAGE_SIZE - ((vir_bytes)buf % I386_PAGE_SIZE);
1720 abuf= buf + o;
1721 printf("buf at %p, abuf at %p\n", buf, abuf);
1723 #if 0
1724 r= sys_vm_map(SELF, 1 /* map */, (vir_bytes)abuf,
1725 dep->de_ramsize, (phys_bytes)dep->de_linmem);
1726 #else
1727 r = ENOSYS;
1728 #endif
1729 if (r != OK)
1730 panic("map_hw_buffer: sys_vm_map failed: %d", r);
1731 dep->de_locmem = abuf;
1734 /*===========================================================================*
1735 * calc_iovec_size_s *
1736 *===========================================================================*/
1737 static int calc_iovec_size_s(iovp)
1738 iovec_dat_s_t *iovp;
1740 /* Calculate the size of a request. Note that the iovec_dat
1741 * structure will be unusable after calc_iovec_size_s.
1743 int size;
1744 int i;
1746 size= 0;
1747 i= 0;
1748 while (i < iovp->iod_iovec_s)
1750 if (i >= IOVEC_NR)
1752 dp_next_iovec_s(iovp);
1753 i= 0;
1754 continue;
1756 size += iovp->iod_iovec[i].iov_size;
1757 i++;
1759 return size;
1762 /*===========================================================================*
1763 * reply *
1764 *===========================================================================*/
1765 static void reply(dep)
1766 dpeth_t *dep;
1768 message reply;
1769 int flags;
1770 int r;
1772 flags = DL_NOFLAGS;
1773 if (dep->de_flags & DEF_PACK_SEND)
1774 flags |= DL_PACK_SEND;
1775 if (dep->de_flags & DEF_PACK_RECV)
1776 flags |= DL_PACK_RECV;
1778 reply.m_type = DL_TASK_REPLY;
1779 reply.DL_FLAGS = flags;
1780 reply.DL_COUNT = dep->de_read_s;
1781 r= send(dep->de_client, &reply);
1783 if (r < 0)
1784 panic("dp8390: send failed: %d", r);
1786 dep->de_read_s = 0;
1787 dep->de_flags &= ~(DEF_PACK_SEND | DEF_PACK_RECV);
1790 /*===========================================================================*
1791 * mess_reply *
1792 *===========================================================================*/
1793 static void mess_reply(req, reply_mess)
1794 message *req;
1795 message *reply_mess;
1797 if (send(req->m_source, reply_mess) != OK)
1798 panic("dp8390: unable to mess_reply");
1801 /*===========================================================================*
1802 * get_userdata_s *
1803 *===========================================================================*/
1804 static void get_userdata_s(user_proc, grant, offset, count, loc_addr)
1805 int user_proc;
1806 cp_grant_id_t grant;
1807 vir_bytes offset;
1808 vir_bytes count;
1809 void *loc_addr;
1811 int r;
1813 r= sys_safecopyfrom(user_proc, grant, offset,
1814 (vir_bytes)loc_addr, count, D);
1815 if (r != OK)
1816 panic("get_userdata: sys_safecopyfrom failed: %d", r);
1819 /*===========================================================================*
1820 * put_userdata_s *
1821 *===========================================================================*/
1822 static void put_userdata_s(user_proc, grant, count, loc_addr)
1823 int user_proc;
1824 cp_grant_id_t grant;
1825 size_t count;
1826 void *loc_addr;
1828 int r;
1830 r= sys_safecopyto(user_proc, grant, 0, (vir_bytes)loc_addr,
1831 count, D);
1832 if (r != OK)
1833 panic("put_userdata: sys_safecopyto failed: %d", r);
1836 u8_t inb(port_t port)
1838 int r;
1839 u32_t value;
1841 r= sys_inb(port, &value);
1842 if (r != OK)
1844 printf("inb failed for port 0x%x\n", port);
1845 panic("sys_inb failed: %d", r);
1847 return value;
1850 u16_t inw(port_t port)
1852 int r;
1853 unsigned long value;
1855 r= sys_inw(port, &value);
1856 if (r != OK)
1857 panic("sys_inw failed: %d", r);
1858 return (u16_t) value;
1861 void outb(port_t port, u8_t value)
1863 int r;
1865 r= sys_outb(port, value);
1866 if (r != OK)
1867 panic("sys_outb failed: %d", r);
1870 void outw(port_t port, u16_t value)
1872 int r;
1874 r= sys_outw(port, value);
1875 if (r != OK)
1876 panic("sys_outw failed: %d", r);
1879 static void insb(port_t port, void *buf, size_t size)
1881 do_vir_insb(port, SELF, (vir_bytes)buf, size);
1884 static void insw(port_t port, void *buf, size_t size)
1886 do_vir_insw(port, SELF, (vir_bytes)buf, size);
1889 static void do_vir_insb(port_t port, int proc, vir_bytes buf, size_t size)
1891 int r;
1893 r= sys_insb(port, proc, (void *) buf, size);
1894 if (r != OK)
1895 panic("sys_sdevio failed: %d", r);
1898 static void do_vir_insw(port_t port, int proc, vir_bytes buf, size_t size)
1900 int r;
1902 r= sys_insw(port, proc, (void *) buf, size);
1903 if (r != OK)
1904 panic("sys_sdevio failed: %d", r);
1907 static void do_vir_outsb(port_t port, int proc, vir_bytes buf, size_t size)
1909 int r;
1911 r= sys_outsb(port, proc, (void *) buf, size);
1912 if (r != OK)
1913 panic("sys_sdevio failed: %d", r);
1916 static void do_vir_outsw(port_t port, int proc, vir_bytes buf, size_t size)
1918 int r;
1920 r= sys_outsw(port, proc, (void *) buf, size);
1921 if (r != OK)
1922 panic("sys_sdevio failed: %d", r);
1926 * $PchId: dp8390.c,v 1.25 2005/02/10 17:32:07 philip Exp $