4 * This file contains a ethernet device driver for NS dp8390 based ethernet
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>
20 #include <minix/com.h>
21 #include <minix/endpoint.h>
24 #include <net/gen/ether.h>
25 #include <net/gen/eth_io.h>
26 #include <machine/vm.h>
32 static dpeth_t de_state
;
33 static int de_instance
;
38 typedef struct dp_conf
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? */
57 #define wdeth_probe(dep) (0)
60 #define ne_probe(dep) (0)
63 #define el2_probe(dep) (0)
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
70 #define CR_EXTRA CR_STA
73 _PROTOTYPE( static void pci_conf
, (void) );
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
,
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
,
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
) );
138 EXTERN
char **env_argv
;
140 PRIVATE
void handle_hw_intr(void)
147 if (dep
->de_mode
!= DEM_ENABLED
)
149 assert(dep
->de_flags
& DEF_ENABLED
);
151 assert(irq
>= 0 && irq
< NR_IRQ_VECTORS
);
152 if (dep
->de_int_pending
|| 1)
154 dep
->de_int_pending
= 0;
157 r
= sys_irqenable(&dep
->de_hook
);
159 panic("unable enable interrupts: %d", r
);
164 /*===========================================================================*
166 *===========================================================================*/
167 int main(int argc
, char *argv
[])
173 /* SEF local startup. */
174 env_setargs(argc
, argv
);
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
)) {
188 printf("dp8390: notify from CLOCK\n");
191 panic("dp8390: illegal notify from: %d",
195 /* done, get a new message */
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;
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. */
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. */
241 system_hz
= sys_hz();
244 panic("A head which at this time has no name");
248 (void) env_parse("instance", "d", 0, &v
, 0, 255);
249 de_instance
= (int) v
;
253 strcpy(dep
->de_name
, "dp8390#0");
254 dep
->de_name
[7] += de_instance
;
256 /* Announce we are up! */
257 netdriver_announce();
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
)
275 /*===========================================================================*
277 *===========================================================================*/
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
);
293 if (dep
->de_mode
!= DEM_ENABLED
)
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
);
327 /*===========================================================================*
329 *===========================================================================*/
330 static void pci_conf()
335 static char envfmt
[] = "*:d.d.d";
337 static int first_time
= 1;
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 */
353 (void) env_parse(envvar
, envfmt
, 1, &v
, 0, 255);
356 (void) env_parse(envvar
, envfmt
, 2, &v
, 0, 255);
359 (void) env_parse(envvar
, envfmt
, 3, &v
, 0, 255);
363 printf("%s: no pci for instance %d\n", dep
->de_name
,
368 if (!rtl_probe(dep
, de_instance
))
371 #endif /* ENABLE_PCI */
373 /*===========================================================================*
375 *===========================================================================*/
376 static void do_vwrite_s(mp
, from_int
)
386 count
= mp
->DL_COUNT
;
387 dep
->de_client
= mp
->m_source
;
389 if (dep
->de_mode
== DEM_SINK
)
392 dep
->de_flags
|= DEF_PACK_SEND
;
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
)
405 panic("dp8390: should not be sending");
406 dep
->de_sendmsg
= *mp
;
407 dep
->de_flags
|= DEF_SEND_AVAIL
;
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
,
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.. */
441 dep
->de_sendq
[sendq_head
].sq_size
= size
;
443 if (++sendq_head
== dep
->de_sendq_nr
)
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.
457 assert(dep
->de_mode
== DEM_ENABLED
);
458 assert(dep
->de_flags
& DEF_ENABLED
);
461 /*===========================================================================*
463 *===========================================================================*/
464 static void do_vread_s(mp
)
473 count
= mp
->DL_COUNT
;
474 dep
->de_client
= mp
->m_source
;
475 if (dep
->de_mode
== DEM_SINK
)
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
;
504 if ((dep
->de_flags
& (DEF_READING
|DEF_STOPPED
)) ==
505 (DEF_READING
|DEF_STOPPED
))
507 /* The chip is stopped, and all arrived packets are
515 /*===========================================================================*
517 *===========================================================================*/
518 static void do_init(message
*mp
)
524 pci_conf(); /* Configure PCI devices. */
529 if (dep
->de_mode
== DEM_DISABLED
)
531 /* This is the default, try to (re)locate the device. */
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
);
541 if (dep
->de_mode
== DEM_ENABLED
)
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
;
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
);
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
;
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 /*===========================================================================*
579 *===========================================================================*/
580 static void do_int(dep
)
583 if (dep
->de_flags
& (DEF_PACK_SEND
| DEF_PACK_RECV
))
587 /*===========================================================================*
589 *===========================================================================*/
590 static void do_getstat_s(mp
)
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
);
606 panic("do_getstat: send failed: %d", r
);
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
);
622 panic("do_getstat: send failed: %d", r
);
625 /*===========================================================================*
627 *===========================================================================*/
628 static void dp_stop(dep
)
632 if (dep
->de_mode
== DEM_SINK
)
634 assert(dep
->de_mode
== DEM_ENABLED
);
636 if (!(dep
->de_flags
& DEF_ENABLED
))
639 outb_reg0(dep
, DP_CR
, CR_STP
| CR_DM_ABORT
);
640 (dep
->de_stopf
)(dep
);
642 dep
->de_flags
= DEF_EMPTY
;
645 /*===========================================================================*
647 *===========================================================================*/
648 static void dp_init(dep
)
654 /* General initialization */
655 dep
->de_flags
= DEF_EMPTY
;
656 (*dep
->de_initf
)(dep
);
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
],
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).
676 outb_reg0(dep
, DP_CR
, CR_PS_P0
| CR_STP
| CR_DM_ABORT
);
679 outb_reg0(dep
, DP_DCR
, DCR_WORDWIDE
| DCR_8BYTES
| DCR_BMS
);
681 outb_reg0(dep
, DP_DCR
, DCR_BYTEWIDE
| DCR_8BYTES
| DCR_BMS
);
683 outb_reg0(dep
, DP_RBCR0
, 0);
684 outb_reg0(dep
, DP_RBCR1
, 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
);
695 outb_reg0(dep
, DP_TCR
, TCR_INTERNAL
);
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
);
701 outb_reg0(dep
, DP_ISR
, 0xFF);
703 outb_reg0(dep
, DP_IMR
, IMR_PRXE
| IMR_PTXE
| IMR_RXEE
| IMR_TXEE
|
704 IMR_OVWE
| IMR_CNTE
);
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);
726 outb_reg0(dep
, DP_CR
, CR_DM_ABORT
| CR_STA
);
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
;
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
);
765 panic("sys_irqsetpolicy failed: %d", r
);
767 r
= sys_irqenable(&dep
->de_hook
);
770 panic("unable enable interrupts: %d", r
);
774 /*===========================================================================*
776 *===========================================================================*/
777 static void dp_confaddr(dep
)
782 static char eafmt
[]= "x:x:x:x:x:x";
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
)
796 dep
->de_address
.ea_addr
[i
]= v
;
799 if (i
!= 0 && i
!= 6) env_panic(eakey
); /* It's all or nothing */
802 /*===========================================================================*
804 *===========================================================================*/
805 static void dp_reinit(dep
)
810 outb_reg0(dep
, DP_CR
, CR_PS_P0
| CR_EXTRA
);
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 /*===========================================================================*
824 *===========================================================================*/
825 static void dp_reset(dep
)
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
++)
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
++)
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;
853 dep
->de_flags
&= ~DEF_STOPPED
;
856 /*===========================================================================*
858 *===========================================================================*/
859 static void dp_check_ints(dep
)
863 int size
, sendq_tail
;
865 if (!(dep
->de_flags
& DEF_ENABLED
))
866 panic("dp8390: got premature interrupt");
870 isr
= inb_reg0(dep
, DP_ISR
);
873 outb_reg0(dep
, DP_ISR
, isr
);
874 if (isr
& (ISR_PTX
|ISR_TXE
))
879 { printf("%s: got send Error\n", dep
->de_name
); }
881 dep
->de_stat
.ets_sendErr
++;
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
++;
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
++;
902 && ++dep
->de_stat
.ets_fifoUnder
<= 10)
904 printf("%s: fifo underrun\n",
908 && ++dep
->de_stat
.ets_CDheartbeat
<= 10)
910 printf("%s: CD heart beat failure\n",
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
))
922 /* Or hardware bug? */
924 "%s: transmit interrupt, but not sending\n",
928 dep
->de_sendq
[sendq_tail
].sq_filled
= 0;
929 if (++sendq_tail
== dep
->de_sendq_nr
)
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
)
947 /* Only call dp_recv if there is a read request */
948 if (dep
->de_flags
& DEF_READING
)
952 if (isr
& ISR_RXE
) dep
->de_stat
.ets_recvErr
++;
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
);
961 dep
->de_stat
.ets_OVW
++;
964 "%s: got overwrite warning\n", dep
->de_name
); }
966 if (dep
->de_flags
& DEF_READING
)
969 "dp_check_ints: strange: overwrite warning and pending read request\n");
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.
986 "%s: NIC stopped\n", dep
->de_name
); }
988 dep
->de_flags
|= DEF_STOPPED
;
992 if ((dep
->de_flags
& (DEF_READING
|DEF_STOPPED
)) ==
993 (DEF_READING
|DEF_STOPPED
))
995 /* The chip is stopped, and all arrived packets are
1002 /*===========================================================================*
1004 *===========================================================================*/
1005 static void dp_recv(dep
)
1009 unsigned pageno
, curr
, next
;
1011 int packet_processed
, r
;
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
),
1028 (dep
->de_getblockf
)(dep
, pageno
, sizeof(header
) +
1029 2*sizeof(ether_addr_t
), sizeof(eth_type
), ð_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
);
1041 else if (next
< dep
->de_startpage
|| next
>= dep
->de_stoppage
)
1043 printf("%s: strange next page\n", dep
->de_name
);
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",
1052 dep
->de_stat
.ets_fifoOver
++;
1055 else if ((header
.dr_status
& RSR_PRX
) &&
1056 (dep
->de_flags
& DEF_ENABLED
))
1058 r
= dp_pkt2user_s(dep
, pageno
, length
);
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);
1068 outb_reg0(dep
, DP_BNRY
, next
- 1);
1072 while (!packet_processed
);
1075 /*===========================================================================*
1077 *===========================================================================*/
1078 static void dp_send(dep
)
1081 if (!(dep
->de_flags
& DEF_SEND_AVAIL
))
1084 dep
->de_flags
&= ~DEF_SEND_AVAIL
;
1085 do_vwrite_s(&dep
->de_sendmsg
, TRUE
);
1088 /*===========================================================================*
1090 *===========================================================================*/
1091 static void dp_getblock(dep
, page
, offset
, size
, 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
)
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
)
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 /*===========================================================================*
1146 *===========================================================================*/
1147 static int dp_pkt2user_s(dpeth_t
*dep
, int page
, vir_bytes length
)
1151 if (!(dep
->de_flags
& DEF_READING
))
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
);
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
;
1180 /*===========================================================================*
1182 *===========================================================================*/
1183 static void dp_user2nic_s(dep
, iovp
, offset
, nic_addr
, count
)
1185 iovec_dat_s_t
*iovp
;
1193 vir_hw
= (vir_bytes
)dep
->de_locmem
+ nic_addr
;
1200 dp_next_iovec_s(iovp
);
1204 assert(i
< iovp
->iod_iovec_s
);
1205 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
1207 offset
-= iovp
->iod_iovec
[i
].iov_size
;
1211 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
1215 r
= sys_safecopyfrom(iovp
->iod_proc_nr
,
1216 iovp
->iod_iovec
[i
].iov_grant
, offset
,
1219 panic("dp_user2nic_s: sys_safecopyfrom failed: %d", r
);
1229 /*===========================================================================*
1230 * dp_pio8_user2nic_s *
1231 *===========================================================================*/
1232 static void dp_pio8_user2nic_s(dep
, iovp
, offset
, nic_addr
, count
)
1234 iovec_dat_s_t
*iovp
;
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
);
1254 dp_next_iovec_s(iovp
);
1258 assert(i
< iovp
->iod_iovec_s
);
1259 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
1261 offset
-= iovp
->iod_iovec
[i
].iov_size
;
1265 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
1269 r
= sys_safe_outsb(dep
->de_data_port
, iovp
->iod_proc_nr
,
1270 iovp
->iod_iovec
[i
].iov_grant
, offset
, bytes
);
1272 panic("dp_pio8_user2nic_s: sys_safe_outsb failed: %d",
1280 for (i
= 0; i
<100; i
++)
1282 if (inb_reg0(dep
, DP_ISR
) & ISR_RDC
)
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
)
1296 iovec_dat_s_t
*iovp
;
1303 int i
, r
, bytes
, user_proc
;
1307 ecount
= (count
+1) & ~1;
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
);
1322 dp_next_iovec_s(iovp
);
1326 assert(i
< iovp
->iod_iovec_s
);
1327 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
1329 offset
-= iovp
->iod_iovec
[i
].iov_size
;
1333 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
1337 user_proc
= iovp
->iod_proc_nr
;
1338 gid
= iovp
->iod_iovec
[i
].iov_grant
;
1341 r
= sys_safecopyfrom(user_proc
, gid
, offset
,
1342 (vir_bytes
)&two_bytes
[1], 1, D
);
1344 panic("dp_pio16_user2nic: sys_safecopyfrom failed: %d", r
);
1346 outw(dep
->de_data_port
, *(u16_t
*)two_bytes
);
1357 r
= sys_safe_outsw(dep
->de_data_port
, user_proc
,
1358 gid
, offset
, ecount
);
1360 panic("dp_pio16_user2nic: sys_safe_outsw failed: %d", r
);
1369 r
= sys_safecopyfrom(user_proc
, gid
, offset
,
1370 (vir_bytes
)&two_bytes
[0], 1, D
);
1372 panic("dp_pio16_user2nic: sys_safecopyfrom failed: %d", r
);
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
)
1392 panic("dp8390: remote dma failed to complete");
1396 /*===========================================================================*
1398 *===========================================================================*/
1399 static void dp_nic2user_s(dep
, nic_addr
, iovp
, offset
, count
)
1402 iovec_dat_s_t
*iovp
;
1409 vir_hw
= (vir_bytes
)dep
->de_locmem
+ nic_addr
;
1416 dp_next_iovec_s(iovp
);
1420 assert(i
< iovp
->iod_iovec_s
);
1421 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
1423 offset
-= iovp
->iod_iovec
[i
].iov_size
;
1427 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
1431 r
= sys_safecopyto(iovp
->iod_proc_nr
,
1432 iovp
->iod_iovec
[i
].iov_grant
, offset
,
1435 panic("dp_nic2user_s: sys_safecopyto failed: %d", r
);
1444 /*===========================================================================*
1445 * dp_pio8_nic2user_s *
1446 *===========================================================================*/
1447 static void dp_pio8_nic2user_s(dep
, nic_addr
, iovp
, offset
, count
)
1450 iovec_dat_s_t
*iovp
;
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
);
1467 dp_next_iovec_s(iovp
);
1471 assert(i
< iovp
->iod_iovec_s
);
1472 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
1474 offset
-= iovp
->iod_iovec
[i
].iov_size
;
1478 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
1482 r
= sys_safe_insb(dep
->de_data_port
, iovp
->iod_proc_nr
,
1483 iovp
->iod_iovec
[i
].iov_grant
, offset
, bytes
);
1485 panic("dp_pio8_nic2user_s: sys_safe_insb failed: %d", r
);
1493 /*===========================================================================*
1494 * dp_pio16_nic2user_s *
1495 *===========================================================================*/
1496 static void dp_pio16_nic2user_s(dep
, nic_addr
, iovp
, offset
, count
)
1499 iovec_dat_s_t
*iovp
;
1505 int i
, r
, bytes
, user_proc
;
1509 ecount
= (count
+1) & ~1;
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
);
1523 dp_next_iovec_s(iovp
);
1527 assert(i
< iovp
->iod_iovec_s
);
1528 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
1530 offset
-= iovp
->iod_iovec
[i
].iov_size
;
1534 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
1538 user_proc
= iovp
->iod_proc_nr
;
1539 gid
= iovp
->iod_iovec
[i
].iov_grant
;
1542 r
= sys_safecopyto(user_proc
, gid
, offset
,
1543 (vir_bytes
)&two_bytes
[1], 1, D
);
1545 panic("dp_pio16_nic2user: sys_safecopyto failed: %d", r
);
1557 r
= sys_safe_insw(dep
->de_data_port
, user_proc
, gid
,
1560 panic("dp_pio16_nic2user: sys_safe_insw failed: %d",
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
);
1575 panic("dp_pio16_nic2user: sys_safecopyto failed: %d",
1587 /*===========================================================================*
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 /*===========================================================================*
1607 *===========================================================================*/
1608 static void conf_hw(dep
)
1611 static eth_stat_t empty_stat
= {0, 0, 0, 0, 0, 0 /* ,... */ };
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
)
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
;
1633 /* XXX */ if (dep
->de_linmem
== 0) dep
->de_linmem
= 0xFFFF0000;
1635 dep
->de_flags
= DEF_EMPTY
;
1636 dep
->de_stat
= empty_stat
;
1639 /*===========================================================================*
1641 *===========================================================================*/
1642 static void update_conf(dep
, dcp
)
1647 static char dpc_fmt
[] = "x:d:x:x";
1653 if (dep
->de_pci
== 1)
1655 /* PCI device is present */
1656 dep
->de_mode
= DEM_ENABLED
;
1658 return; /* Already configured */
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
;
1668 switch (env_parse(eckey
, dpc_fmt
, 0, &v
, 0x0000L
, 0xFFFFL
)) {
1670 dep
->de_mode
= DEM_DISABLED
;
1674 dep
->de_mode
= DEM_ENABLED
; /* Might become disabled if
1675 * all probes fail */
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);
1685 (void) env_parse(eckey
, dpc_fmt
, 2, &v
, 0L, 0xFFFFFL
);
1689 (void) env_parse(eckey
, dpc_fmt
, 3, &v
, 0x2000L
, 0x8000L
);
1693 /*===========================================================================*
1695 *===========================================================================*/
1696 static void map_hw_buffer(dep
)
1703 if (dep
->de_prog_IO
)
1707 "map_hw_buffer: programmed I/O, no need to map buffer\n");
1709 dep
->de_locmem
= (char *)-dep
->de_ramsize
; /* trap errors */
1713 size
= dep
->de_ramsize
+ I386_PAGE_SIZE
; /* Add I386_PAGE_SIZE for
1718 panic("map_hw_buffer: cannot malloc size: %d", size
);
1719 o
= I386_PAGE_SIZE
- ((vir_bytes
)buf
% I386_PAGE_SIZE
);
1721 printf("buf at %p, abuf at %p\n", buf
, abuf
);
1724 r
= sys_vm_map(SELF
, 1 /* map */, (vir_bytes
)abuf
,
1725 dep
->de_ramsize
, (phys_bytes
)dep
->de_linmem
);
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.
1748 while (i
< iovp
->iod_iovec_s
)
1752 dp_next_iovec_s(iovp
);
1756 size
+= iovp
->iod_iovec
[i
].iov_size
;
1762 /*===========================================================================*
1764 *===========================================================================*/
1765 static void reply(dep
)
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
);
1784 panic("dp8390: send failed: %d", r
);
1787 dep
->de_flags
&= ~(DEF_PACK_SEND
| DEF_PACK_RECV
);
1790 /*===========================================================================*
1792 *===========================================================================*/
1793 static void mess_reply(req
, reply_mess
)
1795 message
*reply_mess
;
1797 if (send(req
->m_source
, reply_mess
) != OK
)
1798 panic("dp8390: unable to mess_reply");
1801 /*===========================================================================*
1803 *===========================================================================*/
1804 static void get_userdata_s(user_proc
, grant
, offset
, count
, loc_addr
)
1806 cp_grant_id_t grant
;
1813 r
= sys_safecopyfrom(user_proc
, grant
, offset
,
1814 (vir_bytes
)loc_addr
, count
, D
);
1816 panic("get_userdata: sys_safecopyfrom failed: %d", r
);
1819 /*===========================================================================*
1821 *===========================================================================*/
1822 static void put_userdata_s(user_proc
, grant
, count
, loc_addr
)
1824 cp_grant_id_t grant
;
1830 r
= sys_safecopyto(user_proc
, grant
, 0, (vir_bytes
)loc_addr
,
1833 panic("put_userdata: sys_safecopyto failed: %d", r
);
1836 u8_t
inb(port_t port
)
1841 r
= sys_inb(port
, &value
);
1844 printf("inb failed for port 0x%x\n", port
);
1845 panic("sys_inb failed: %d", r
);
1850 u16_t
inw(port_t port
)
1853 unsigned long value
;
1855 r
= sys_inw(port
, &value
);
1857 panic("sys_inw failed: %d", r
);
1858 return (u16_t
) value
;
1861 void outb(port_t port
, u8_t value
)
1865 r
= sys_outb(port
, value
);
1867 panic("sys_outb failed: %d", r
);
1870 void outw(port_t port
, u16_t value
)
1874 r
= sys_outw(port
, value
);
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
)
1893 r
= sys_insb(port
, proc
, (void *) buf
, size
);
1895 panic("sys_sdevio failed: %d", r
);
1898 static void do_vir_insw(port_t port
, int proc
, vir_bytes buf
, size_t size
)
1902 r
= sys_insw(port
, proc
, (void *) buf
, size
);
1904 panic("sys_sdevio failed: %d", r
);
1907 static void do_vir_outsb(port_t port
, int proc
, vir_bytes buf
, size_t size
)
1911 r
= sys_outsb(port
, proc
, (void *) buf
, size
);
1913 panic("sys_sdevio failed: %d", r
);
1916 static void do_vir_outsw(port_t port
, int proc
, vir_bytes buf
, size_t size
)
1920 r
= sys_outsw(port
, proc
, (void *) buf
, size
);
1922 panic("sys_sdevio failed: %d", r
);
1926 * $PchId: dp8390.c,v 1.25 2005/02/10 17:32:07 philip Exp $