kernel: scheduling fix for ARM
[minix.git] / drivers / dp8390 / dp8390.c
bloba7ea8593e7e2c16a567d11f82bca6fd2724b97c9
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 <sys/mman.h>
28 #include "assert.h"
30 #include "local.h"
31 #include "dp8390.h"
33 static dpeth_t de_state;
34 static int de_instance;
36 u32_t system_hz;
38 /* Configuration */
39 typedef struct dp_conf
41 port_t dpc_port;
42 int dpc_irq;
43 phys_bytes dpc_mem;
44 } dp_conf_t;
46 #define DP_CONF_NR 4
47 static dp_conf_t dp_conf[DP_CONF_NR]= /* Card addresses */
49 /* I/O port, IRQ, Buffer address. */
50 { 0x280, 3, 0xD0000, },
51 { 0x300, 5, 0xC8000, },
52 { 0x380, 10, 0xD8000, },
53 { 0x000, 0, 0x00000, },
56 /* Card inits configured out? */
57 #if !ENABLE_WDETH
58 #define wdeth_probe(dep) (0)
59 #endif
60 #if !ENABLE_NE2000
61 #define ne_probe(dep) (0)
62 #endif
63 #if !ENABLE_3C503
64 #define el2_probe(dep) (0)
65 #endif
67 /* Some clones of the dp8390 and the PC emulator 'Bochs' require the CR_STA
68 * on writes to the CR register. Additional CR_STAs do not appear to hurt
69 * genuine dp8390s
71 #define CR_EXTRA CR_STA
73 #if ENABLE_PCI
74 static void pci_conf(void);
75 #endif
76 static void do_vwrite_s(message *mp, int from_int);
77 static void do_vread_s(message *mp);
78 static void do_init(message *mp);
79 static void do_int(dpeth_t *dep);
80 static void do_getstat_s(message *mp);
81 static void dp_stop(dpeth_t *dep);
82 static void dp_init(dpeth_t *dep);
83 static void dp_confaddr(dpeth_t *dep);
84 static void dp_reinit(dpeth_t *dep);
85 static void dp_reset(dpeth_t *dep);
86 static void dp_check_ints(dpeth_t *dep);
87 static void dp_recv(dpeth_t *dep);
88 static void dp_send(dpeth_t *dep);
89 static void dp_getblock(dpeth_t *dep, int page, size_t offset, size_t
90 size, void *dst);
91 static void dp_pio8_getblock(dpeth_t *dep, int page, size_t offset,
92 size_t size, void *dst);
93 static void dp_pio16_getblock(dpeth_t *dep, int page, size_t offset,
94 size_t size, void *dst);
95 static int dp_pkt2user_s(dpeth_t *dep, int page, vir_bytes length);
96 static void dp_user2nic_s(dpeth_t *dep, iovec_dat_s_t *iovp, vir_bytes
97 offset, int nic_addr, vir_bytes count);
98 static void dp_pio8_user2nic_s(dpeth_t *dep, iovec_dat_s_t *iovp,
99 vir_bytes offset, int nic_addr, vir_bytes count);
100 static void dp_pio16_user2nic_s(dpeth_t *dep, iovec_dat_s_t *iovp,
101 vir_bytes offset, int nic_addr, vir_bytes count);
102 static void dp_nic2user_s(dpeth_t *dep, int nic_addr, iovec_dat_s_t
103 *iovp, vir_bytes offset, vir_bytes count);
104 static void dp_pio8_nic2user_s(dpeth_t *dep, int nic_addr, iovec_dat_s_t
105 *iovp, vir_bytes offset, vir_bytes count);
106 static void dp_pio16_nic2user_s(dpeth_t *dep, int nic_addr,
107 iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count);
108 static void dp_next_iovec_s(iovec_dat_s_t *iovp);
109 static void conf_hw(dpeth_t *dep);
110 static void update_conf(dpeth_t *dep, dp_conf_t *dcp);
111 static void map_hw_buffer(dpeth_t *dep);
112 static int calc_iovec_size_s(iovec_dat_s_t *iovp);
113 static void reply(dpeth_t *dep);
114 static void mess_reply(message *req, message *reply);
115 static void get_userdata_s(int user_proc, cp_grant_id_t grant, vir_bytes
116 offset, vir_bytes count, void *loc_addr);
117 static void put_userdata_s(int user_proc, cp_grant_id_t grant, size_t
118 count, void *loc_addr);
119 static void insb(port_t port, void *buf, size_t size);
120 static void insw(port_t port, void *buf, size_t size);
121 static void do_vir_insb(port_t port, int proc, vir_bytes buf, size_t
122 size);
123 static void do_vir_insw(port_t port, int proc, vir_bytes buf, size_t
124 size);
126 /* SEF functions and variables. */
127 static void sef_local_startup(void);
128 static int sef_cb_init_fresh(int type, sef_init_info_t *info);
129 static void sef_cb_signal_handler(int signo);
131 static void handle_hw_intr(void)
133 int r, irq;
134 dpeth_t *dep;
136 dep = &de_state;
138 if (dep->de_mode != DEM_ENABLED)
139 return;
140 assert(dep->de_flags & DEF_ENABLED);
141 irq= dep->de_irq;
142 assert(irq >= 0 && irq < NR_IRQ_VECTORS);
143 if (dep->de_int_pending || 1)
145 dep->de_int_pending= 0;
146 dp_check_ints(dep);
147 do_int(dep);
148 r= sys_irqenable(&dep->de_hook);
149 if (r != OK) {
150 panic("unable enable interrupts: %d", r);
155 /*===========================================================================*
156 * dpeth_task *
157 *===========================================================================*/
158 int main(int argc, char *argv[])
160 message m;
161 int ipc_status;
162 int r;
164 /* SEF local startup. */
165 env_setargs(argc, argv);
166 sef_local_startup();
168 while (TRUE)
170 if ((r= netdriver_receive(ANY, &m, &ipc_status)) != OK)
171 panic("dp8390: netdriver_receive failed: %d", r);
173 if (is_ipc_notify(ipc_status)) {
174 switch (_ENDPOINT_P(m.m_source)) {
175 case HARDWARE:
176 handle_hw_intr();
177 break;
178 case CLOCK:
179 printf("dp8390: notify from CLOCK\n");
180 break;
181 default:
182 panic("dp8390: illegal notify from: %d",
183 m.m_source);
186 /* done, get a new message */
187 continue;
190 switch (m.m_type)
192 case DL_WRITEV_S: do_vwrite_s(&m, FALSE); break;
193 case DL_READV_S: do_vread_s(&m); break;
194 case DL_CONF: do_init(&m); break;
195 case DL_GETSTAT_S: do_getstat_s(&m); break;
196 default:
197 panic("dp8390: illegal message: %d", m.m_type);
202 /*===========================================================================*
203 * sef_local_startup *
204 *===========================================================================*/
205 static void sef_local_startup()
207 /* Register init callbacks. */
208 sef_setcb_init_fresh(sef_cb_init_fresh);
209 sef_setcb_init_lu(sef_cb_init_fresh);
210 sef_setcb_init_restart(sef_cb_init_fresh);
212 /* Register live update callbacks. */
213 sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
214 sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree);
216 /* Register signal callbacks. */
217 sef_setcb_signal_handler(sef_cb_signal_handler);
219 /* Let SEF perform startup. */
220 sef_startup();
223 /*===========================================================================*
224 * sef_cb_init_fresh *
225 *===========================================================================*/
226 static int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
228 /* Initialize the dp8390 driver. */
229 dpeth_t *dep;
230 long v;
232 system_hz = sys_hz();
234 if (env_argc < 1) {
235 panic("A head which at this time has no name");
238 v = 0;
239 (void) env_parse("instance", "d", 0, &v, 0, 255);
240 de_instance = (int) v;
242 dep = &de_state;
244 strlcpy(dep->de_name, "dp8390#0", sizeof(dep->de_name));
245 dep->de_name[7] += de_instance;
247 /* Announce we are up! */
248 netdriver_announce();
250 return(OK);
253 /*===========================================================================*
254 * sef_cb_signal_handler *
255 *===========================================================================*/
256 static void sef_cb_signal_handler(int signo)
258 /* Only check for termination signal, ignore anything else. */
259 if (signo != SIGTERM) return;
261 if (de_state.de_mode == DEM_ENABLED)
262 dp_stop(&de_state);
265 #if 0
266 /*===========================================================================*
267 * dp8390_dump *
268 *===========================================================================*/
269 void dp8390_dump()
271 dpeth_t *dep;
272 int isr;
274 dep = &de_state;
276 printf("\n");
277 #if XXX
278 if (dep->de_mode == DEM_DISABLED)
279 printf("dp8390 instance %d is disabled\n", de_instance);
280 else if (dep->de_mode == DEM_SINK)
281 printf("dp8390 instance %d is in sink mode\n", de_instance);
282 #endif
284 if (dep->de_mode != DEM_ENABLED)
285 return;
287 printf("dp8390 statistics of instance %d:\n", de_instance);
289 printf("recvErr :%8ld\t", dep->de_stat.ets_recvErr);
290 printf("sendErr :%8ld\t", dep->de_stat.ets_sendErr);
291 printf("OVW :%8ld\n", dep->de_stat.ets_OVW);
293 printf("CRCerr :%8ld\t", dep->de_stat.ets_CRCerr);
294 printf("frameAll :%8ld\t", dep->de_stat.ets_frameAll);
295 printf("missedP :%8ld\n", dep->de_stat.ets_missedP);
297 printf("packetR :%8ld\t", dep->de_stat.ets_packetR);
298 printf("packetT :%8ld\t", dep->de_stat.ets_packetT);
299 printf("transDef :%8ld\n", dep->de_stat.ets_transDef);
301 printf("collision :%8ld\t", dep->de_stat.ets_collision);
302 printf("transAb :%8ld\t", dep->de_stat.ets_transAb);
303 printf("carrSense :%8ld\n", dep->de_stat.ets_carrSense);
305 printf("fifoUnder :%8ld\t", dep->de_stat.ets_fifoUnder);
306 printf("fifoOver :%8ld\t", dep->de_stat.ets_fifoOver);
307 printf("CDheartbeat:%8ld\n", dep->de_stat.ets_CDheartbeat);
309 printf("OWC :%8ld\t", dep->de_stat.ets_OWC);
311 isr= inb_reg0(dep, DP_ISR);
312 printf("dp_isr = 0x%x + 0x%x, de_flags = 0x%x\n", isr,
313 inb_reg0(dep, DP_ISR), dep->de_flags);
315 #endif
317 #if ENABLE_PCI
318 /*===========================================================================*
319 * pci_conf *
320 *===========================================================================*/
321 static void pci_conf()
323 char envvar[16];
324 struct dpeth *dep;
325 int i, pci_instance;
326 static int first_time= 1;
328 if (!first_time)
329 return;
330 first_time= 0;
332 dep= &de_state;
334 strlcpy(envvar, "DPETH0", sizeof(envvar));
335 envvar[5] += de_instance;
336 if (!(dep->de_pci= env_prefix(envvar, "pci")))
337 return; /* no PCI config */
339 /* Count the number of dp instances before this one that are configured
340 * for PCI, so that we can skip that many when enumerating PCI devices.
342 pci_instance= 0;
343 for (i= 0; i < de_instance; i++) {
344 envvar[5]= i;
345 if (env_prefix(envvar, "pci"))
346 pci_instance++;
349 if (!rtl_probe(dep, pci_instance))
350 dep->de_pci= -1;
352 #endif /* ENABLE_PCI */
354 /*===========================================================================*
355 * do_vwrite_s *
356 *===========================================================================*/
357 static void do_vwrite_s(mp, from_int)
358 message *mp;
359 int from_int;
361 int count, size;
362 int sendq_head;
363 dpeth_t *dep;
365 dep= &de_state;
367 count = mp->DL_COUNT;
368 dep->de_client= mp->m_source;
370 if (dep->de_mode == DEM_SINK)
372 assert(!from_int);
373 dep->de_flags |= DEF_PACK_SEND;
374 reply(dep);
375 return;
377 assert(dep->de_mode == DEM_ENABLED);
378 assert(dep->de_flags & DEF_ENABLED);
379 if (dep->de_flags & DEF_SEND_AVAIL)
380 panic("dp8390: send already in progress");
382 sendq_head= dep->de_sendq_head;
383 if (dep->de_sendq[sendq_head].sq_filled)
385 if (from_int)
386 panic("dp8390: should not be sending");
387 dep->de_sendmsg= *mp;
388 dep->de_flags |= DEF_SEND_AVAIL;
389 reply(dep);
390 return;
392 assert(!(dep->de_flags & DEF_PACK_SEND));
394 get_userdata_s(mp->m_source, mp->DL_GRANT, 0,
395 (count > IOVEC_NR ? IOVEC_NR : count) *
396 sizeof(dep->de_write_iovec_s.iod_iovec[0]),
397 dep->de_write_iovec_s.iod_iovec);
398 dep->de_write_iovec_s.iod_iovec_s = count;
399 dep->de_write_iovec_s.iod_proc_nr = mp->m_source;
400 dep->de_write_iovec_s.iod_grant = mp->DL_GRANT;
401 dep->de_write_iovec_s.iod_iovec_offset = 0;
403 dep->de_tmp_iovec_s = dep->de_write_iovec_s;
404 size = calc_iovec_size_s(&dep->de_tmp_iovec_s);
406 if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED)
408 panic("dp8390: invalid packet size: %d", size);
410 (dep->de_user2nicf_s)(dep, &dep->de_write_iovec_s, 0,
411 dep->de_sendq[sendq_head].sq_sendpage * DP_PAGESIZE,
412 size);
413 dep->de_sendq[sendq_head].sq_filled= TRUE;
414 if (dep->de_sendq_tail == sendq_head)
416 outb_reg0(dep, DP_TPSR, dep->de_sendq[sendq_head].sq_sendpage);
417 outb_reg0(dep, DP_TBCR1, size >> 8);
418 outb_reg0(dep, DP_TBCR0, size & 0xff);
419 outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);/* there it goes.. */
421 else
422 dep->de_sendq[sendq_head].sq_size= size;
424 if (++sendq_head == dep->de_sendq_nr)
425 sendq_head= 0;
426 assert(sendq_head < SENDQ_NR);
427 dep->de_sendq_head= sendq_head;
429 dep->de_flags |= DEF_PACK_SEND;
431 /* If the interrupt handler called, don't send a reply. The reply
432 * will be sent after all interrupts are handled.
434 if (from_int)
435 return;
436 reply(dep);
438 assert(dep->de_mode == DEM_ENABLED);
439 assert(dep->de_flags & DEF_ENABLED);
442 /*===========================================================================*
443 * do_vread_s *
444 *===========================================================================*/
445 static void do_vread_s(mp)
446 message *mp;
448 int count;
449 int size;
450 dpeth_t *dep;
452 dep= &de_state;
454 count = mp->DL_COUNT;
455 dep->de_client= mp->m_source;
456 if (dep->de_mode == DEM_SINK)
458 reply(dep);
459 return;
461 assert(dep->de_mode == DEM_ENABLED);
462 assert(dep->de_flags & DEF_ENABLED);
464 if(dep->de_flags & DEF_READING)
465 panic("dp8390: read already in progress");
467 get_userdata_s(mp->m_source, mp->DL_GRANT, 0,
468 (count > IOVEC_NR ? IOVEC_NR : count) *
469 sizeof(dep->de_read_iovec_s.iod_iovec[0]),
470 dep->de_read_iovec_s.iod_iovec);
471 dep->de_read_iovec_s.iod_iovec_s = count;
472 dep->de_read_iovec_s.iod_proc_nr = mp->m_source;
473 dep->de_read_iovec_s.iod_grant = mp->DL_GRANT;
474 dep->de_read_iovec_s.iod_iovec_offset = 0;
476 dep->de_tmp_iovec_s = dep->de_read_iovec_s;
477 size= calc_iovec_size_s(&dep->de_tmp_iovec_s);
479 if (size < ETH_MAX_PACK_SIZE_TAGGED)
480 panic("dp8390: wrong packet size: %d", size);
481 dep->de_flags |= DEF_READING;
483 dp_recv(dep);
485 if ((dep->de_flags & (DEF_READING|DEF_STOPPED)) ==
486 (DEF_READING|DEF_STOPPED))
488 /* The chip is stopped, and all arrived packets are
489 * delivered.
491 dp_reset(dep);
493 reply(dep);
496 /*===========================================================================*
497 * do_init *
498 *===========================================================================*/
499 static void do_init(message *mp)
501 dpeth_t *dep;
502 message reply_mess;
504 #if ENABLE_PCI
505 pci_conf(); /* Configure PCI devices. */
506 #endif
508 dep= &de_state;
510 if (dep->de_mode == DEM_DISABLED)
512 /* This is the default, try to (re)locate the device. */
513 conf_hw(dep);
514 if (dep->de_mode == DEM_DISABLED)
516 /* Probe failed, or the device is configured off. */
517 reply_mess.m_type= DL_CONF_REPLY;
518 reply_mess.DL_STAT= ENXIO;
519 mess_reply(mp, &reply_mess);
520 return;
522 if (dep->de_mode == DEM_ENABLED)
523 dp_init(dep);
526 if (dep->de_mode == DEM_SINK)
528 strncpy((char *) dep->de_address.ea_addr, "ZDP", 6);
529 dep->de_address.ea_addr[5] = de_instance;
530 dp_confaddr(dep);
531 reply_mess.m_type = DL_CONF_REPLY;
532 reply_mess.DL_STAT = OK;
533 *(ether_addr_t *) reply_mess.DL_HWADDR = dep->de_address;
534 mess_reply(mp, &reply_mess);
535 return;
537 assert(dep->de_mode == DEM_ENABLED);
538 assert(dep->de_flags & DEF_ENABLED);
540 dep->de_flags &= ~(DEF_PROMISC | DEF_MULTI | DEF_BROAD);
542 if (mp->DL_MODE & DL_PROMISC_REQ)
543 dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD;
544 if (mp->DL_MODE & DL_MULTI_REQ)
545 dep->de_flags |= DEF_MULTI;
546 if (mp->DL_MODE & DL_BROAD_REQ)
547 dep->de_flags |= DEF_BROAD;
549 dp_reinit(dep);
551 reply_mess.m_type = DL_CONF_REPLY;
552 reply_mess.DL_STAT = OK;
553 *(ether_addr_t *) reply_mess.DL_HWADDR = dep->de_address;
555 mess_reply(mp, &reply_mess);
558 /*===========================================================================*
559 * do_int *
560 *===========================================================================*/
561 static void do_int(dep)
562 dpeth_t *dep;
564 if (dep->de_flags & (DEF_PACK_SEND | DEF_PACK_RECV))
565 reply(dep);
568 /*===========================================================================*
569 * do_getstat_s *
570 *===========================================================================*/
571 static void do_getstat_s(mp)
572 message *mp;
574 int r;
575 dpeth_t *dep;
577 dep= &de_state;
579 if (dep->de_mode == DEM_SINK)
581 put_userdata_s(mp->m_source, (vir_bytes) mp->DL_GRANT,
582 (vir_bytes) sizeof(dep->de_stat), &dep->de_stat);
584 mp->m_type= DL_STAT_REPLY;
585 r= send(mp->m_source, mp);
586 if (r != OK)
587 panic("do_getstat: send failed: %d", r);
588 return;
590 assert(dep->de_mode == DEM_ENABLED);
591 assert(dep->de_flags & DEF_ENABLED);
593 dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0);
594 dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1);
595 dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2);
597 put_userdata_s(mp->m_source, mp->DL_GRANT,
598 sizeof(dep->de_stat), &dep->de_stat);
600 mp->m_type= DL_STAT_REPLY;
601 r= send(mp->m_source, mp);
602 if (r != OK)
603 panic("do_getstat: send failed: %d", r);
606 /*===========================================================================*
607 * dp_stop *
608 *===========================================================================*/
609 static void dp_stop(dep)
610 dpeth_t *dep;
613 if (dep->de_mode == DEM_SINK)
614 return;
615 assert(dep->de_mode == DEM_ENABLED);
617 if (!(dep->de_flags & DEF_ENABLED))
618 return;
620 outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
621 (dep->de_stopf)(dep);
623 dep->de_flags= DEF_EMPTY;
626 /*===========================================================================*
627 * dp_init *
628 *===========================================================================*/
629 static void dp_init(dep)
630 dpeth_t *dep;
632 int dp_rcr_reg;
633 int i, r;
635 /* General initialization */
636 dep->de_flags = DEF_EMPTY;
637 (*dep->de_initf)(dep);
639 dp_confaddr(dep);
641 if (debug)
643 printf("%s: Ethernet address ", dep->de_name);
644 for (i= 0; i < 6; i++)
645 printf("%x%c", dep->de_address.ea_addr[i],
646 i < 5 ? ':' : '\n');
649 /* Map buffer */
650 map_hw_buffer(dep);
652 /* Initialization of the dp8390 following the mandatory procedure
653 * in reference manual ("DP8390D/NS32490D NIC Network Interface
654 * Controller", National Semiconductor, July 1995, Page 29).
656 /* Step 1: */
657 outb_reg0(dep, DP_CR, CR_PS_P0 | CR_STP | CR_DM_ABORT);
658 /* Step 2: */
659 if (dep->de_16bit)
660 outb_reg0(dep, DP_DCR, DCR_WORDWIDE | DCR_8BYTES | DCR_BMS);
661 else
662 outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES | DCR_BMS);
663 /* Step 3: */
664 outb_reg0(dep, DP_RBCR0, 0);
665 outb_reg0(dep, DP_RBCR1, 0);
666 /* Step 4: */
667 dp_rcr_reg = 0;
668 if (dep->de_flags & DEF_PROMISC)
669 dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM;
670 if (dep->de_flags & DEF_BROAD)
671 dp_rcr_reg |= RCR_AB;
672 if (dep->de_flags & DEF_MULTI)
673 dp_rcr_reg |= RCR_AM;
674 outb_reg0(dep, DP_RCR, dp_rcr_reg);
675 /* Step 5: */
676 outb_reg0(dep, DP_TCR, TCR_INTERNAL);
677 /* Step 6: */
678 outb_reg0(dep, DP_BNRY, dep->de_startpage);
679 outb_reg0(dep, DP_PSTART, dep->de_startpage);
680 outb_reg0(dep, DP_PSTOP, dep->de_stoppage);
681 /* Step 7: */
682 outb_reg0(dep, DP_ISR, 0xFF);
683 /* Step 8: */
684 outb_reg0(dep, DP_IMR, IMR_PRXE | IMR_PTXE | IMR_RXEE | IMR_TXEE |
685 IMR_OVWE | IMR_CNTE);
686 /* Step 9: */
687 outb_reg0(dep, DP_CR, CR_PS_P1 | CR_DM_ABORT | CR_STP);
689 outb_reg1(dep, DP_PAR0, dep->de_address.ea_addr[0]);
690 outb_reg1(dep, DP_PAR1, dep->de_address.ea_addr[1]);
691 outb_reg1(dep, DP_PAR2, dep->de_address.ea_addr[2]);
692 outb_reg1(dep, DP_PAR3, dep->de_address.ea_addr[3]);
693 outb_reg1(dep, DP_PAR4, dep->de_address.ea_addr[4]);
694 outb_reg1(dep, DP_PAR5, dep->de_address.ea_addr[5]);
696 outb_reg1(dep, DP_MAR0, 0xff);
697 outb_reg1(dep, DP_MAR1, 0xff);
698 outb_reg1(dep, DP_MAR2, 0xff);
699 outb_reg1(dep, DP_MAR3, 0xff);
700 outb_reg1(dep, DP_MAR4, 0xff);
701 outb_reg1(dep, DP_MAR5, 0xff);
702 outb_reg1(dep, DP_MAR6, 0xff);
703 outb_reg1(dep, DP_MAR7, 0xff);
705 outb_reg1(dep, DP_CURR, dep->de_startpage + 1);
706 /* Step 10: */
707 outb_reg0(dep, DP_CR, CR_DM_ABORT | CR_STA);
708 /* Step 11: */
709 outb_reg0(dep, DP_TCR, TCR_NORMAL);
711 inb_reg0(dep, DP_CNTR0); /* reset counters by reading */
712 inb_reg0(dep, DP_CNTR1);
713 inb_reg0(dep, DP_CNTR2);
715 /* Finish the initialization. */
716 dep->de_flags |= DEF_ENABLED;
717 for (i= 0; i<dep->de_sendq_nr; i++)
718 dep->de_sendq[i].sq_filled= 0;
719 dep->de_sendq_head= 0;
720 dep->de_sendq_tail= 0;
721 if (!dep->de_prog_IO)
723 dep->de_user2nicf_s= dp_user2nic_s;
724 dep->de_nic2userf_s= dp_nic2user_s;
725 dep->de_getblockf= dp_getblock;
727 else if (dep->de_16bit)
729 dep->de_user2nicf_s= dp_pio16_user2nic_s;
730 dep->de_nic2userf_s= dp_pio16_nic2user_s;
731 dep->de_getblockf= dp_pio16_getblock;
733 else
735 dep->de_user2nicf_s= dp_pio8_user2nic_s;
736 dep->de_nic2userf_s= dp_pio8_nic2user_s;
737 dep->de_getblockf= dp_pio8_getblock;
740 /* Set the interrupt handler and policy. Do not automatically
741 * reenable interrupts. Return the IRQ line number on interrupts.
743 dep->de_hook = dep->de_irq;
744 r= sys_irqsetpolicy(dep->de_irq, 0, &dep->de_hook);
745 if (r != OK)
746 panic("sys_irqsetpolicy failed: %d", r);
748 r= sys_irqenable(&dep->de_hook);
749 if (r != OK)
751 panic("unable enable interrupts: %d", r);
755 /*===========================================================================*
756 * dp_confaddr *
757 *===========================================================================*/
758 static void dp_confaddr(dep)
759 dpeth_t *dep;
761 int i;
762 char eakey[16];
763 static char eafmt[]= "x:x:x:x:x:x";
764 long v;
766 /* User defined ethernet address? */
767 strlcpy(eakey, "DPETH0_EA", sizeof(eakey));
768 eakey[5] += de_instance;
770 for (i= 0; i < 6; i++)
772 v= dep->de_address.ea_addr[i];
773 if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET)
775 break;
777 dep->de_address.ea_addr[i]= v;
780 if (i != 0 && i != 6) env_panic(eakey); /* It's all or nothing */
783 /*===========================================================================*
784 * dp_reinit *
785 *===========================================================================*/
786 static void dp_reinit(dep)
787 dpeth_t *dep;
789 int dp_rcr_reg;
791 outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
793 dp_rcr_reg = 0;
794 if (dep->de_flags & DEF_PROMISC)
795 dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM;
796 if (dep->de_flags & DEF_BROAD)
797 dp_rcr_reg |= RCR_AB;
798 if (dep->de_flags & DEF_MULTI)
799 dp_rcr_reg |= RCR_AM;
800 outb_reg0(dep, DP_RCR, dp_rcr_reg);
803 /*===========================================================================*
804 * dp_reset *
805 *===========================================================================*/
806 static void dp_reset(dep)
807 dpeth_t *dep;
809 int i;
811 /* Stop chip */
812 outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
813 outb_reg0(dep, DP_RBCR0, 0);
814 outb_reg0(dep, DP_RBCR1, 0);
815 for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RST) == 0); i++)
816 ; /* Do nothing */
817 outb_reg0(dep, DP_TCR, TCR_1EXTERNAL|TCR_OFST);
818 outb_reg0(dep, DP_CR, CR_STA|CR_DM_ABORT);
819 outb_reg0(dep, DP_TCR, TCR_NORMAL);
821 /* Acknowledge the ISR_RDC (remote dma) interrupt. */
822 for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RDC) == 0); i++)
823 ; /* Do nothing */
824 outb_reg0(dep, DP_ISR, inb_reg0(dep, DP_ISR) & ~ISR_RDC);
826 /* Reset the transmit ring. If we were transmitting a packet, we
827 * pretend that the packet is processed. Higher layers will
828 * retransmit if the packet wasn't actually sent.
830 dep->de_sendq_head= dep->de_sendq_tail= 0;
831 for (i= 0; i<dep->de_sendq_nr; i++)
832 dep->de_sendq[i].sq_filled= 0;
833 dp_send(dep);
834 dep->de_flags &= ~DEF_STOPPED;
837 /*===========================================================================*
838 * dp_check_ints *
839 *===========================================================================*/
840 static void dp_check_ints(dep)
841 dpeth_t *dep;
843 int isr, tsr;
844 int size, sendq_tail;
846 if (!(dep->de_flags & DEF_ENABLED))
847 panic("dp8390: got premature interrupt");
849 for(;;)
851 isr = inb_reg0(dep, DP_ISR);
852 if (!isr)
853 break;
854 outb_reg0(dep, DP_ISR, isr);
855 if (isr & (ISR_PTX|ISR_TXE))
857 if (isr & ISR_TXE)
859 #if DEBUG
860 { printf("%s: got send Error\n", dep->de_name); }
861 #endif
862 dep->de_stat.ets_sendErr++;
864 else
866 tsr = inb_reg0(dep, DP_TSR);
868 if (tsr & TSR_PTX) dep->de_stat.ets_packetT++;
869 #if 0 /* Reserved in later manuals, should be ignored */
870 if (!(tsr & TSR_DFR))
872 /* In most (all?) implementations of
873 * the dp8390, this bit is set
874 * when the packet is not deferred
876 dep->de_stat.ets_transDef++;
878 #endif
879 if (tsr & TSR_COL) dep->de_stat.ets_collision++;
880 if (tsr & TSR_ABT) dep->de_stat.ets_transAb++;
881 if (tsr & TSR_CRS) dep->de_stat.ets_carrSense++;
882 if (tsr & TSR_FU
883 && ++dep->de_stat.ets_fifoUnder <= 10)
885 printf("%s: fifo underrun\n",
886 dep->de_name);
888 if (tsr & TSR_CDH
889 && ++dep->de_stat.ets_CDheartbeat <= 10)
891 printf("%s: CD heart beat failure\n",
892 dep->de_name);
894 if (tsr & TSR_OWC) dep->de_stat.ets_OWC++;
896 sendq_tail= dep->de_sendq_tail;
898 if (!(dep->de_sendq[sendq_tail].sq_filled))
900 /* Software bug? */
901 assert(!debug);
903 /* Or hardware bug? */
904 printf(
905 "%s: transmit interrupt, but not sending\n",
906 dep->de_name);
907 continue;
909 dep->de_sendq[sendq_tail].sq_filled= 0;
910 if (++sendq_tail == dep->de_sendq_nr)
911 sendq_tail= 0;
912 dep->de_sendq_tail= sendq_tail;
913 if (dep->de_sendq[sendq_tail].sq_filled)
915 size= dep->de_sendq[sendq_tail].sq_size;
916 outb_reg0(dep, DP_TPSR,
917 dep->de_sendq[sendq_tail].sq_sendpage);
918 outb_reg0(dep, DP_TBCR1, size >> 8);
919 outb_reg0(dep, DP_TBCR0, size & 0xff);
920 outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);
922 if (dep->de_flags & DEF_SEND_AVAIL)
923 dp_send(dep);
926 if (isr & ISR_PRX)
928 /* Only call dp_recv if there is a read request */
929 if (dep->de_flags & DEF_READING)
930 dp_recv(dep);
933 if (isr & ISR_RXE) dep->de_stat.ets_recvErr++;
934 if (isr & ISR_CNT)
936 dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0);
937 dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1);
938 dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2);
940 if (isr & ISR_OVW)
942 dep->de_stat.ets_OVW++;
943 #if 0
944 { printW(); printf(
945 "%s: got overwrite warning\n", dep->de_name); }
946 #endif
947 if (dep->de_flags & DEF_READING)
949 printf(
950 "dp_check_ints: strange: overwrite warning and pending read request\n");
951 dp_recv(dep);
954 if (isr & ISR_RDC)
956 /* Nothing to do */
958 if (isr & ISR_RST)
960 /* this means we got an interrupt but the ethernet
961 * chip is shutdown. We set the flag DEF_STOPPED,
962 * and continue processing arrived packets. When the
963 * receive buffer is empty, we reset the dp8390.
965 #if 0
966 { printW(); printf(
967 "%s: NIC stopped\n", dep->de_name); }
968 #endif
969 dep->de_flags |= DEF_STOPPED;
970 break;
973 if ((dep->de_flags & (DEF_READING|DEF_STOPPED)) ==
974 (DEF_READING|DEF_STOPPED))
976 /* The chip is stopped, and all arrived packets are
977 * delivered.
979 dp_reset(dep);
983 /*===========================================================================*
984 * dp_recv *
985 *===========================================================================*/
986 static void dp_recv(dep)
987 dpeth_t *dep;
989 dp_rcvhdr_t header;
990 unsigned pageno, curr, next;
991 vir_bytes length;
992 int packet_processed, r;
993 u16_t eth_type;
995 packet_processed = FALSE;
996 pageno = inb_reg0(dep, DP_BNRY) + 1;
997 if (pageno == dep->de_stoppage) pageno = dep->de_startpage;
1001 outb_reg0(dep, DP_CR, CR_PS_P1 | CR_EXTRA);
1002 curr = inb_reg1(dep, DP_CURR);
1003 outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
1005 if (curr == pageno) break;
1007 (dep->de_getblockf)(dep, pageno, (size_t)0, sizeof(header),
1008 &header);
1009 (dep->de_getblockf)(dep, pageno, sizeof(header) +
1010 2*sizeof(ether_addr_t), sizeof(eth_type), &eth_type);
1012 length = (header.dr_rbcl | (header.dr_rbch << 8)) -
1013 sizeof(dp_rcvhdr_t);
1014 next = header.dr_next;
1015 if (length < ETH_MIN_PACK_SIZE ||
1016 length > ETH_MAX_PACK_SIZE_TAGGED)
1018 printf("%s: packet with strange length arrived: %d\n",
1019 dep->de_name, (int) length);
1020 next= curr;
1022 else if (next < dep->de_startpage || next >= dep->de_stoppage)
1024 printf("%s: strange next page\n", dep->de_name);
1025 next= curr;
1027 else if (header.dr_status & RSR_FO)
1029 /* This is very serious, so we issue a warning and
1030 * reset the buffers */
1031 printf("%s: fifo overrun, resetting receive buffer\n",
1032 dep->de_name);
1033 dep->de_stat.ets_fifoOver++;
1034 next = curr;
1036 else if ((header.dr_status & RSR_PRX) &&
1037 (dep->de_flags & DEF_ENABLED))
1039 r = dp_pkt2user_s(dep, pageno, length);
1040 if (r != OK)
1041 return;
1043 packet_processed = TRUE;
1044 dep->de_stat.ets_packetR++;
1046 if (next == dep->de_startpage)
1047 outb_reg0(dep, DP_BNRY, dep->de_stoppage - 1);
1048 else
1049 outb_reg0(dep, DP_BNRY, next - 1);
1051 pageno = next;
1053 while (!packet_processed);
1056 /*===========================================================================*
1057 * dp_send *
1058 *===========================================================================*/
1059 static void dp_send(dep)
1060 dpeth_t *dep;
1062 if (!(dep->de_flags & DEF_SEND_AVAIL))
1063 return;
1065 dep->de_flags &= ~DEF_SEND_AVAIL;
1066 do_vwrite_s(&dep->de_sendmsg, TRUE);
1069 /*===========================================================================*
1070 * dp_getblock *
1071 *===========================================================================*/
1072 static void dp_getblock(dep, page, offset, size, dst)
1073 dpeth_t *dep;
1074 int page;
1075 size_t offset;
1076 size_t size;
1077 void *dst;
1079 offset = page * DP_PAGESIZE + offset;
1081 memcpy(dst, dep->de_locmem + offset, size);
1084 /*===========================================================================*
1085 * dp_pio8_getblock *
1086 *===========================================================================*/
1087 static void dp_pio8_getblock(dep, page, offset, size, dst)
1088 dpeth_t *dep;
1089 int page;
1090 size_t offset;
1091 size_t size;
1092 void *dst;
1094 offset = page * DP_PAGESIZE + offset;
1095 outb_reg0(dep, DP_RBCR0, size & 0xFF);
1096 outb_reg0(dep, DP_RBCR1, size >> 8);
1097 outb_reg0(dep, DP_RSAR0, offset & 0xFF);
1098 outb_reg0(dep, DP_RSAR1, offset >> 8);
1099 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
1101 insb(dep->de_data_port, dst, size);
1104 /*===========================================================================*
1105 * dp_pio16_getblock *
1106 *===========================================================================*/
1107 static void dp_pio16_getblock(dep, page, offset, size, dst)
1108 dpeth_t *dep;
1109 int page;
1110 size_t offset;
1111 size_t size;
1112 void *dst;
1114 offset = page * DP_PAGESIZE + offset;
1115 outb_reg0(dep, DP_RBCR0, size & 0xFF);
1116 outb_reg0(dep, DP_RBCR1, size >> 8);
1117 outb_reg0(dep, DP_RSAR0, offset & 0xFF);
1118 outb_reg0(dep, DP_RSAR1, offset >> 8);
1119 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
1121 assert (!(size & 1));
1122 insw(dep->de_data_port, dst, size);
1125 /*===========================================================================*
1126 * dp_pkt2user_s *
1127 *===========================================================================*/
1128 static int dp_pkt2user_s(dpeth_t *dep, int page, vir_bytes length)
1130 int last, count;
1132 if (!(dep->de_flags & DEF_READING))
1133 return EGENERIC;
1135 last = page + (length - 1) / DP_PAGESIZE;
1136 if (last >= dep->de_stoppage)
1138 count = (dep->de_stoppage - page) * DP_PAGESIZE -
1139 sizeof(dp_rcvhdr_t);
1141 /* Save read_iovec since we need it twice. */
1142 dep->de_tmp_iovec_s = dep->de_read_iovec_s;
1143 (dep->de_nic2userf_s)(dep, page * DP_PAGESIZE +
1144 sizeof(dp_rcvhdr_t), &dep->de_tmp_iovec_s, 0, count);
1145 (dep->de_nic2userf_s)(dep, dep->de_startpage * DP_PAGESIZE,
1146 &dep->de_read_iovec_s, count, length - count);
1148 else
1150 (dep->de_nic2userf_s)(dep, page * DP_PAGESIZE +
1151 sizeof(dp_rcvhdr_t), &dep->de_read_iovec_s, 0, length);
1154 dep->de_read_s = length;
1155 dep->de_flags |= DEF_PACK_RECV;
1156 dep->de_flags &= ~DEF_READING;
1158 return OK;
1161 /*===========================================================================*
1162 * dp_user2nic_s *
1163 *===========================================================================*/
1164 static void dp_user2nic_s(dep, iovp, offset, nic_addr, count)
1165 dpeth_t *dep;
1166 iovec_dat_s_t *iovp;
1167 vir_bytes offset;
1168 int nic_addr;
1169 vir_bytes count;
1171 vir_bytes vir_hw;
1172 int bytes, i, r;
1174 vir_hw = (vir_bytes)dep->de_locmem + nic_addr;
1176 i= 0;
1177 while (count > 0)
1179 if (i >= IOVEC_NR)
1181 dp_next_iovec_s(iovp);
1182 i= 0;
1183 continue;
1185 assert(i < iovp->iod_iovec_s);
1186 if (offset >= iovp->iod_iovec[i].iov_size)
1188 offset -= iovp->iod_iovec[i].iov_size;
1189 i++;
1190 continue;
1192 bytes = iovp->iod_iovec[i].iov_size - offset;
1193 if (bytes > count)
1194 bytes = count;
1196 r= sys_safecopyfrom(iovp->iod_proc_nr,
1197 iovp->iod_iovec[i].iov_grant, offset,
1198 vir_hw, bytes);
1199 if (r != OK) {
1200 panic("dp_user2nic_s: sys_safecopyfrom failed: %d", r);
1203 count -= bytes;
1204 vir_hw += bytes;
1205 offset += bytes;
1207 assert(count == 0);
1210 /*===========================================================================*
1211 * dp_pio8_user2nic_s *
1212 *===========================================================================*/
1213 static void dp_pio8_user2nic_s(dep, iovp, offset, nic_addr, count)
1214 dpeth_t *dep;
1215 iovec_dat_s_t *iovp;
1216 vir_bytes offset;
1217 int nic_addr;
1218 vir_bytes count;
1220 int bytes, i, r;
1222 outb_reg0(dep, DP_ISR, ISR_RDC);
1224 outb_reg0(dep, DP_RBCR0, count & 0xFF);
1225 outb_reg0(dep, DP_RBCR1, count >> 8);
1226 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
1227 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
1228 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
1230 i= 0;
1231 while (count > 0)
1233 if (i >= IOVEC_NR)
1235 dp_next_iovec_s(iovp);
1236 i= 0;
1237 continue;
1239 assert(i < iovp->iod_iovec_s);
1240 if (offset >= iovp->iod_iovec[i].iov_size)
1242 offset -= iovp->iod_iovec[i].iov_size;
1243 i++;
1244 continue;
1246 bytes = iovp->iod_iovec[i].iov_size - offset;
1247 if (bytes > count)
1248 bytes = count;
1250 r= sys_safe_outsb(dep->de_data_port, iovp->iod_proc_nr,
1251 iovp->iod_iovec[i].iov_grant, offset, bytes);
1252 if (r != OK) {
1253 panic("dp_pio8_user2nic_s: sys_safe_outsb failed: %d",
1256 count -= bytes;
1257 offset += bytes;
1259 assert(count == 0);
1261 for (i= 0; i<100; i++)
1263 if (inb_reg0(dep, DP_ISR) & ISR_RDC)
1264 break;
1266 if (i == 100)
1268 panic("dp8390: remote dma failed to complete");
1272 /*===========================================================================*
1273 * dp_pio16_user2nic_s *
1274 *===========================================================================*/
1275 static void dp_pio16_user2nic_s(dep, iovp, offset, nic_addr, count)
1276 dpeth_t *dep;
1277 iovec_dat_s_t *iovp;
1278 vir_bytes offset;
1279 int nic_addr;
1280 vir_bytes count;
1282 vir_bytes ecount;
1283 cp_grant_id_t gid;
1284 int i, r, bytes, user_proc;
1285 u8_t two_bytes[2];
1286 int odd_byte;
1288 ecount= (count+1) & ~1;
1289 odd_byte= 0;
1291 outb_reg0(dep, DP_ISR, ISR_RDC);
1292 outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
1293 outb_reg0(dep, DP_RBCR1, ecount >> 8);
1294 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
1295 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
1296 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
1298 i= 0;
1299 while (count > 0)
1301 if (i >= IOVEC_NR)
1303 dp_next_iovec_s(iovp);
1304 i= 0;
1305 continue;
1307 assert(i < iovp->iod_iovec_s);
1308 if (offset >= iovp->iod_iovec[i].iov_size)
1310 offset -= iovp->iod_iovec[i].iov_size;
1311 i++;
1312 continue;
1314 bytes = iovp->iod_iovec[i].iov_size - offset;
1315 if (bytes > count)
1316 bytes = count;
1318 user_proc= iovp->iod_proc_nr;
1319 gid= iovp->iod_iovec[i].iov_grant;
1320 if (odd_byte)
1322 r= sys_safecopyfrom(user_proc, gid, offset,
1323 (vir_bytes)&two_bytes[1], 1);
1324 if (r != OK) {
1325 panic("dp_pio16_user2nic: sys_safecopyfrom failed: %d", r);
1327 outw(dep->de_data_port, *(u16_t *)two_bytes);
1328 count--;
1329 offset++;
1330 bytes--;
1331 odd_byte= 0;
1332 if (!bytes)
1333 continue;
1335 ecount= bytes & ~1;
1336 if (ecount != 0)
1338 r= sys_safe_outsw(dep->de_data_port, user_proc,
1339 gid, offset, ecount);
1340 if (r != OK) {
1341 panic("dp_pio16_user2nic: sys_safe_outsw failed: %d", r);
1343 count -= ecount;
1344 offset += ecount;
1345 bytes -= ecount;
1347 if (bytes)
1349 assert(bytes == 1);
1350 r= sys_safecopyfrom(user_proc, gid, offset,
1351 (vir_bytes)&two_bytes[0], 1);
1352 if (r != OK) {
1353 panic("dp_pio16_user2nic: sys_safecopyfrom failed: %d", r);
1355 count--;
1356 offset++;
1357 bytes--;
1358 odd_byte= 1;
1361 assert(count == 0);
1363 if (odd_byte)
1364 outw(dep->de_data_port, *(u16_t *)two_bytes);
1366 for (i= 0; i<100; i++)
1368 if (inb_reg0(dep, DP_ISR) & ISR_RDC)
1369 break;
1371 if (i == 100)
1373 panic("dp8390: remote dma failed to complete");
1377 /*===========================================================================*
1378 * dp_nic2user_s *
1379 *===========================================================================*/
1380 static void dp_nic2user_s(dep, nic_addr, iovp, offset, count)
1381 dpeth_t *dep;
1382 int nic_addr;
1383 iovec_dat_s_t *iovp;
1384 vir_bytes offset;
1385 vir_bytes count;
1387 vir_bytes vir_hw;
1388 int bytes, i, r;
1390 vir_hw = (vir_bytes)dep->de_locmem + nic_addr;
1392 i= 0;
1393 while (count > 0)
1395 if (i >= IOVEC_NR)
1397 dp_next_iovec_s(iovp);
1398 i= 0;
1399 continue;
1401 assert(i < iovp->iod_iovec_s);
1402 if (offset >= iovp->iod_iovec[i].iov_size)
1404 offset -= iovp->iod_iovec[i].iov_size;
1405 i++;
1406 continue;
1408 bytes = iovp->iod_iovec[i].iov_size - offset;
1409 if (bytes > count)
1410 bytes = count;
1412 r= sys_safecopyto(iovp->iod_proc_nr,
1413 iovp->iod_iovec[i].iov_grant, offset,
1414 vir_hw, bytes);
1415 if (r != OK)
1416 panic("dp_nic2user_s: sys_safecopyto failed: %d", r);
1418 count -= bytes;
1419 vir_hw += bytes;
1420 offset += bytes;
1422 assert(count == 0);
1425 /*===========================================================================*
1426 * dp_pio8_nic2user_s *
1427 *===========================================================================*/
1428 static void dp_pio8_nic2user_s(dep, nic_addr, iovp, offset, count)
1429 dpeth_t *dep;
1430 int nic_addr;
1431 iovec_dat_s_t *iovp;
1432 vir_bytes offset;
1433 vir_bytes count;
1435 int bytes, i, r;
1437 outb_reg0(dep, DP_RBCR0, count & 0xFF);
1438 outb_reg0(dep, DP_RBCR1, count >> 8);
1439 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
1440 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
1441 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
1443 i= 0;
1444 while (count > 0)
1446 if (i >= IOVEC_NR)
1448 dp_next_iovec_s(iovp);
1449 i= 0;
1450 continue;
1452 assert(i < iovp->iod_iovec_s);
1453 if (offset >= iovp->iod_iovec[i].iov_size)
1455 offset -= iovp->iod_iovec[i].iov_size;
1456 i++;
1457 continue;
1459 bytes = iovp->iod_iovec[i].iov_size - offset;
1460 if (bytes > count)
1461 bytes = count;
1463 r= sys_safe_insb(dep->de_data_port, iovp->iod_proc_nr,
1464 iovp->iod_iovec[i].iov_grant, offset, bytes);
1465 if (r != OK) {
1466 panic("dp_pio8_nic2user_s: sys_safe_insb failed: %d", r);
1468 count -= bytes;
1469 offset += bytes;
1471 assert(count == 0);
1474 /*===========================================================================*
1475 * dp_pio16_nic2user_s *
1476 *===========================================================================*/
1477 static void dp_pio16_nic2user_s(dep, nic_addr, iovp, offset, count)
1478 dpeth_t *dep;
1479 int nic_addr;
1480 iovec_dat_s_t *iovp;
1481 vir_bytes offset;
1482 vir_bytes count;
1484 vir_bytes ecount;
1485 cp_grant_id_t gid;
1486 int i, r, bytes, user_proc;
1487 u8_t two_bytes[2];
1488 int odd_byte;
1490 ecount= (count+1) & ~1;
1491 odd_byte= 0;
1493 outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
1494 outb_reg0(dep, DP_RBCR1, ecount >> 8);
1495 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
1496 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
1497 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
1499 i= 0;
1500 while (count > 0)
1502 if (i >= IOVEC_NR)
1504 dp_next_iovec_s(iovp);
1505 i= 0;
1506 continue;
1508 assert(i < iovp->iod_iovec_s);
1509 if (offset >= iovp->iod_iovec[i].iov_size)
1511 offset -= iovp->iod_iovec[i].iov_size;
1512 i++;
1513 continue;
1515 bytes = iovp->iod_iovec[i].iov_size - offset;
1516 if (bytes > count)
1517 bytes = count;
1519 user_proc= iovp->iod_proc_nr;
1520 gid= iovp->iod_iovec[i].iov_grant;
1521 if (odd_byte)
1523 r= sys_safecopyto(user_proc, gid, offset,
1524 (vir_bytes)&two_bytes[1], 1);
1525 if (r != OK) {
1526 panic("dp_pio16_nic2user: sys_safecopyto failed: %d", r);
1528 count--;
1529 offset++;
1530 bytes--;
1531 odd_byte= 0;
1532 if (!bytes)
1533 continue;
1535 ecount= bytes & ~1;
1536 if (ecount != 0)
1538 r= sys_safe_insw(dep->de_data_port, user_proc, gid,
1539 offset, ecount);
1540 if (r != OK) {
1541 panic("dp_pio16_nic2user: sys_safe_insw failed: %d",
1544 count -= ecount;
1545 offset += ecount;
1546 bytes -= ecount;
1548 if (bytes)
1550 assert(bytes == 1);
1551 *(u16_t *)two_bytes= inw(dep->de_data_port);
1552 r= sys_safecopyto(user_proc, gid, offset,
1553 (vir_bytes)&two_bytes[0], 1);
1554 if (r != OK)
1556 panic("dp_pio16_nic2user: sys_safecopyto failed: %d",
1559 count--;
1560 offset++;
1561 bytes--;
1562 odd_byte= 1;
1565 assert(count == 0);
1568 /*===========================================================================*
1569 * dp_next_iovec_s *
1570 *===========================================================================*/
1571 static void dp_next_iovec_s(iovp)
1572 iovec_dat_s_t *iovp;
1574 assert(iovp->iod_iovec_s > IOVEC_NR);
1576 iovp->iod_iovec_s -= IOVEC_NR;
1578 iovp->iod_iovec_offset += IOVEC_NR * sizeof(iovec_t);
1580 get_userdata_s(iovp->iod_proc_nr, iovp->iod_grant,
1581 iovp->iod_iovec_offset,
1582 (iovp->iod_iovec_s > IOVEC_NR ? IOVEC_NR : iovp->iod_iovec_s) *
1583 sizeof(iovp->iod_iovec[0]), iovp->iod_iovec);
1586 /*===========================================================================*
1587 * conf_hw *
1588 *===========================================================================*/
1589 static void conf_hw(dep)
1590 dpeth_t *dep;
1592 static eth_stat_t empty_stat = {0, 0, 0, 0, 0, 0 /* ,... */ };
1594 int confnr;
1595 dp_conf_t *dcp;
1597 dep->de_mode= DEM_DISABLED; /* Superfluous */
1599 /* Pick a default configuration for this instance. */
1600 confnr= MIN(de_instance, DP_CONF_NR-1);
1602 dcp= &dp_conf[confnr];
1603 update_conf(dep, dcp);
1604 if (dep->de_mode != DEM_ENABLED)
1605 return;
1606 if (!wdeth_probe(dep) && !ne_probe(dep) && !el2_probe(dep))
1608 printf("%s: No ethernet card found at 0x%x\n",
1609 dep->de_name, dep->de_base_port);
1610 dep->de_mode= DEM_DISABLED;
1611 return;
1614 /* XXX */ if (dep->de_linmem == 0) dep->de_linmem= 0xFFFF0000;
1616 dep->de_flags = DEF_EMPTY;
1617 dep->de_stat = empty_stat;
1620 /*===========================================================================*
1621 * update_conf *
1622 *===========================================================================*/
1623 static void update_conf(dep, dcp)
1624 dpeth_t *dep;
1625 dp_conf_t *dcp;
1627 long v;
1628 static char dpc_fmt[] = "x:d:x:x";
1629 char eckey[16];
1631 #if ENABLE_PCI
1632 if (dep->de_pci)
1634 if (dep->de_pci == 1)
1636 /* PCI device is present */
1637 dep->de_mode= DEM_ENABLED;
1639 return; /* Already configured */
1641 #endif
1643 strlcpy(eckey, "DPETH0", sizeof(eckey));
1644 eckey[5] += de_instance;
1646 /* Get the default settings and modify them from the environment. */
1647 dep->de_mode= DEM_SINK;
1648 v= dcp->dpc_port;
1649 switch (env_parse(eckey, dpc_fmt, 0, &v, 0x0000L, 0xFFFFL)) {
1650 case EP_OFF:
1651 dep->de_mode= DEM_DISABLED;
1652 break;
1653 case EP_ON:
1654 case EP_SET:
1655 dep->de_mode= DEM_ENABLED; /* Might become disabled if
1656 * all probes fail */
1657 break;
1659 dep->de_base_port= v;
1661 v= dcp->dpc_irq | DEI_DEFAULT;
1662 (void) env_parse(eckey, dpc_fmt, 1, &v, 0L, (long) NR_IRQ_VECTORS - 1);
1663 dep->de_irq= v;
1665 v= dcp->dpc_mem;
1666 (void) env_parse(eckey, dpc_fmt, 2, &v, 0L, 0xFFFFFL);
1667 dep->de_linmem= v;
1669 v= 0;
1670 (void) env_parse(eckey, dpc_fmt, 3, &v, 0x2000L, 0x8000L);
1671 dep->de_ramsize= v;
1674 /*===========================================================================*
1675 * map_hw_buffer *
1676 *===========================================================================*/
1677 static void map_hw_buffer(dep)
1678 dpeth_t *dep;
1681 if (dep->de_prog_IO)
1683 #if 0
1684 printf(
1685 "map_hw_buffer: programmed I/O, no need to map buffer\n");
1686 #endif
1687 dep->de_locmem = (char *)-dep->de_ramsize; /* trap errors */
1688 return;
1691 dep->de_locmem=
1692 vm_map_phys(SELF, (void *) dep->de_linmem, dep->de_ramsize);
1693 if (dep->de_locmem == MAP_FAILED)
1694 panic("map_hw_buffer: vm_map_phys failed");
1697 /*===========================================================================*
1698 * calc_iovec_size_s *
1699 *===========================================================================*/
1700 static int calc_iovec_size_s(iovp)
1701 iovec_dat_s_t *iovp;
1703 /* Calculate the size of a request. Note that the iovec_dat
1704 * structure will be unusable after calc_iovec_size_s.
1706 int size;
1707 int i;
1709 size= 0;
1710 i= 0;
1711 while (i < iovp->iod_iovec_s)
1713 if (i >= IOVEC_NR)
1715 dp_next_iovec_s(iovp);
1716 i= 0;
1717 continue;
1719 size += iovp->iod_iovec[i].iov_size;
1720 i++;
1722 return size;
1725 /*===========================================================================*
1726 * reply *
1727 *===========================================================================*/
1728 static void reply(dep)
1729 dpeth_t *dep;
1731 message reply;
1732 int flags;
1733 int r;
1735 flags = DL_NOFLAGS;
1736 if (dep->de_flags & DEF_PACK_SEND)
1737 flags |= DL_PACK_SEND;
1738 if (dep->de_flags & DEF_PACK_RECV)
1739 flags |= DL_PACK_RECV;
1741 reply.m_type = DL_TASK_REPLY;
1742 reply.DL_FLAGS = flags;
1743 reply.DL_COUNT = dep->de_read_s;
1744 r= send(dep->de_client, &reply);
1746 if (r < 0)
1747 panic("dp8390: send failed: %d", r);
1749 dep->de_read_s = 0;
1750 dep->de_flags &= ~(DEF_PACK_SEND | DEF_PACK_RECV);
1753 /*===========================================================================*
1754 * mess_reply *
1755 *===========================================================================*/
1756 static void mess_reply(req, reply_mess)
1757 message *req;
1758 message *reply_mess;
1760 if (send(req->m_source, reply_mess) != OK)
1761 panic("dp8390: unable to mess_reply");
1764 /*===========================================================================*
1765 * get_userdata_s *
1766 *===========================================================================*/
1767 static void get_userdata_s(user_proc, grant, offset, count, loc_addr)
1768 int user_proc;
1769 cp_grant_id_t grant;
1770 vir_bytes offset;
1771 vir_bytes count;
1772 void *loc_addr;
1774 int r;
1776 r= sys_safecopyfrom(user_proc, grant, offset,
1777 (vir_bytes)loc_addr, count);
1778 if (r != OK)
1779 panic("get_userdata: sys_safecopyfrom failed: %d", r);
1782 /*===========================================================================*
1783 * put_userdata_s *
1784 *===========================================================================*/
1785 static void put_userdata_s(user_proc, grant, count, loc_addr)
1786 int user_proc;
1787 cp_grant_id_t grant;
1788 size_t count;
1789 void *loc_addr;
1791 int r;
1793 r= sys_safecopyto(user_proc, grant, 0, (vir_bytes)loc_addr,
1794 count);
1795 if (r != OK)
1796 panic("put_userdata: sys_safecopyto failed: %d", r);
1799 u8_t inb(port_t port)
1801 int r;
1802 u32_t value;
1804 r= sys_inb(port, &value);
1805 if (r != OK)
1807 printf("inb failed for port 0x%x\n", port);
1808 panic("sys_inb failed: %d", r);
1810 return value;
1813 u16_t inw(port_t port)
1815 int r;
1816 u32_t value;
1818 r= sys_inw(port, &value);
1819 if (r != OK)
1820 panic("sys_inw failed: %d", r);
1821 return (u16_t) value;
1824 void outb(port_t port, u8_t value)
1826 int r;
1828 r= sys_outb(port, value);
1829 if (r != OK)
1830 panic("sys_outb failed: %d", r);
1833 void outw(port_t port, u16_t value)
1835 int r;
1837 r= sys_outw(port, value);
1838 if (r != OK)
1839 panic("sys_outw failed: %d", r);
1842 static void insb(port_t port, void *buf, size_t size)
1844 do_vir_insb(port, SELF, (vir_bytes)buf, size);
1847 static void insw(port_t port, void *buf, size_t size)
1849 do_vir_insw(port, SELF, (vir_bytes)buf, size);
1852 static void do_vir_insb(port_t port, int proc, vir_bytes buf, size_t size)
1854 int r;
1856 r= sys_insb(port, proc, (void *) buf, size);
1857 if (r != OK)
1858 panic("sys_sdevio failed: %d", r);
1861 static void do_vir_insw(port_t port, int proc, vir_bytes buf, size_t size)
1863 int r;
1865 r= sys_insw(port, proc, (void *) buf, size);
1866 if (r != OK)
1867 panic("sys_sdevio failed: %d", r);
1871 * $PchId: dp8390.c,v 1.25 2005/02/10 17:32:07 philip Exp $