4 * This file contains a ethernet device driver for NS dp8390 based ethernet
7 * The valid messages and their parameters are:
9 * m_type DL_PORT DL_PROC DL_COUNT DL_MODE DL_ADDR DL_GRANT
10 * |------------+----------+---------+----------+---------+---------+---------|
11 * | HARDINT | | | | | | |
12 * |------------|----------|---------|----------|---------|---------|---------|
13 * | DL_WRITE | port nr | proc nr | count | mode | address | |
14 * |------------|----------|---------|----------|---------|---------|---------|
15 * | DL_WRITEV | port nr | proc nr | count | mode | address | |
16 * |------------|----------|---------|----------|---------|---------|---------|
17 * | DL_WRITEV_S| port nr | proc nr | count | mode | | grant |
18 * |------------|----------|---------|----------|---------|---------|---------|
19 * | DL_READ | port nr | proc nr | count | | address | |
20 * |------------|----------|---------|----------|---------|---------|---------|
21 * | DL_READV | port nr | proc nr | count | | address | |
22 * |------------|----------|---------|----------|---------|---------|---------|
23 * | DL_READV_S | port nr | proc nr | count | | | grant |
24 * |------------|----------|---------|----------|---------|---------|---------|
25 * | DL_CONF | port nr | proc nr | | mode | address | |
26 * |------------|----------|---------|----------|---------|---------|---------|
27 * | DL_GETSTAT | port nr | proc nr | | | address | |
28 * |------------|----------|---------|----------|---------|---------|---------|
29 * |DL_GETSTAT_S| port nr | proc nr | | | | grant |
30 * |------------|----------|---------|----------|---------|---------|---------|
31 * | DL_STOP | port_nr | | | | | |
32 * |------------|----------|---------|----------|---------|---------|---------|
34 * The messages sent are:
36 * m-type DL_PORT DL_PROC DL_COUNT DL_STAT DL_CLCK
37 * |-------------+----------+---------+----------+---------+---------|
38 * |DL_TASK_REPLY| port nr | proc nr | rd-count | err|stat| clock |
39 * |-------------+----------+---------+----------+---------+---------|
41 * m_type m3_i1 m3_i2 m3_ca1
42 * |-------------+---------+-----------+---------------|
43 * |DL_CONF_REPLY| port nr | last port | ethernet addr |
44 * |-------------+---------+-----------+---------------|
46 * Created: before Dec 28, 1992 by Philip Homburg <philip@f-mnx.phicoh.com>
48 * Modified Mar 10 1994 by Philip Homburg
49 * Become a generic dp8390 driver.
51 * Modified Dec 20 1996 by G. Falzoni <falzoni@marina.scn.de>
52 * Added support for 3c503 boards.
55 #include "../drivers.h"
58 #include <minix/com.h>
59 #include <minix/endpoint.h>
61 #include <net/gen/ether.h>
62 #include <net/gen/eth_io.h>
63 #include <sys/vm_i386.h>
72 static dpeth_t de_table
[DE_PORT_NR
];
73 static u16_t eth_ign_proto
;
74 static char *progname
;
79 typedef struct dp_conf
87 dp_conf_t dp_conf
[]= /* Card addresses */
89 /* I/O port, IRQ, Buffer address, Env. var. */
90 { 0x280, 3, 0xD0000, "DPETH0" },
91 { 0x300, 5, 0xC8000, "DPETH1" },
92 { 0x380, 10, 0xD8000, "DPETH2" },
95 /* Test if dp_conf has exactly DE_PORT_NR entries. If not then you will see
96 * the error: "array size is negative".
98 extern int ___dummy
[DE_PORT_NR
== sizeof(dp_conf
)/sizeof(dp_conf
[0]) ? 1 : -1];
100 /* Card inits configured out? */
102 #define wdeth_probe(dep) (0)
105 #define ne_probe(dep) (0)
108 #define el2_probe(dep) (0)
111 /* Some clones of the dp8390 and the PC emulator 'Bochs' require the CR_STA
112 * on writes to the CR register. Additional CR_STAs do not appear to hurt
115 #define CR_EXTRA CR_STA
118 _PROTOTYPE( static void pci_conf
, (void) );
120 _PROTOTYPE( static void do_vwrite
, (message
*mp
, int from_int
,
122 _PROTOTYPE( static void do_vwrite_s
, (message
*mp
, int from_int
) );
123 _PROTOTYPE( static void do_vread
, (message
*mp
, int vectored
) );
124 _PROTOTYPE( static void do_vread_s
, (message
*mp
) );
125 _PROTOTYPE( static void do_init
, (message
*mp
) );
126 _PROTOTYPE( static void do_int
, (dpeth_t
*dep
) );
127 _PROTOTYPE( static void do_getstat
, (message
*mp
) );
128 _PROTOTYPE( static void do_getstat_s
, (message
*mp
) );
129 _PROTOTYPE( static void do_getname
, (message
*mp
) );
130 _PROTOTYPE( static void do_stop
, (message
*mp
) );
131 _PROTOTYPE( static void dp_init
, (dpeth_t
*dep
) );
132 _PROTOTYPE( static void dp_confaddr
, (dpeth_t
*dep
) );
133 _PROTOTYPE( static void dp_reinit
, (dpeth_t
*dep
) );
134 _PROTOTYPE( static void dp_reset
, (dpeth_t
*dep
) );
135 _PROTOTYPE( static void dp_check_ints
, (dpeth_t
*dep
) );
136 _PROTOTYPE( static void dp_recv
, (dpeth_t
*dep
) );
137 _PROTOTYPE( static void dp_send
, (dpeth_t
*dep
) );
138 _PROTOTYPE( static void dp8390_stop
, (void) );
139 _PROTOTYPE( static void dp_getblock
, (dpeth_t
*dep
, int page
,
140 size_t offset
, size_t size
, void *dst
) );
141 _PROTOTYPE( static void dp_pio8_getblock
, (dpeth_t
*dep
, int page
,
142 size_t offset
, size_t size
, void *dst
) );
143 _PROTOTYPE( static void dp_pio16_getblock
, (dpeth_t
*dep
, int page
,
144 size_t offset
, size_t size
, void *dst
) );
145 _PROTOTYPE( static int dp_pkt2user
, (dpeth_t
*dep
, int page
,
147 _PROTOTYPE( static int dp_pkt2user_s
, (dpeth_t
*dep
, int page
,
149 _PROTOTYPE( static void dp_user2nic
, (dpeth_t
*dep
, iovec_dat_t
*iovp
,
150 vir_bytes offset
, int nic_addr
, vir_bytes count
) );
151 _PROTOTYPE( static void dp_user2nic_s
, (dpeth_t
*dep
, iovec_dat_s_t
*iovp
,
152 vir_bytes offset
, int nic_addr
, vir_bytes count
) );
153 _PROTOTYPE( static void dp_pio8_user2nic
, (dpeth_t
*dep
,
154 iovec_dat_t
*iovp
, vir_bytes offset
,
155 int nic_addr
, vir_bytes count
) );
156 _PROTOTYPE( static void dp_pio8_user2nic_s
, (dpeth_t
*dep
,
157 iovec_dat_s_t
*iovp
, vir_bytes offset
,
158 int nic_addr
, vir_bytes count
) );
159 _PROTOTYPE( static void dp_pio16_user2nic
, (dpeth_t
*dep
,
160 iovec_dat_t
*iovp
, vir_bytes offset
,
161 int nic_addr
, vir_bytes count
) );
162 _PROTOTYPE( static void dp_pio16_user2nic_s
, (dpeth_t
*dep
,
163 iovec_dat_s_t
*iovp
, vir_bytes offset
,
164 int nic_addr
, vir_bytes count
) );
165 _PROTOTYPE( static void dp_nic2user
, (dpeth_t
*dep
, int nic_addr
,
166 iovec_dat_t
*iovp
, vir_bytes offset
, vir_bytes count
) );
167 _PROTOTYPE( static void dp_nic2user_s
, (dpeth_t
*dep
, int nic_addr
,
168 iovec_dat_s_t
*iovp
, vir_bytes offset
, vir_bytes count
) );
169 _PROTOTYPE( static void dp_pio8_nic2user
, (dpeth_t
*dep
, int nic_addr
,
170 iovec_dat_t
*iovp
, vir_bytes offset
, vir_bytes count
) );
171 _PROTOTYPE( static void dp_pio8_nic2user_s
, (dpeth_t
*dep
, int nic_addr
,
172 iovec_dat_s_t
*iovp
, vir_bytes offset
, vir_bytes count
) );
173 _PROTOTYPE( static void dp_pio16_nic2user
, (dpeth_t
*dep
, int nic_addr
,
174 iovec_dat_t
*iovp
, vir_bytes offset
, vir_bytes count
) );
175 _PROTOTYPE( static void dp_pio16_nic2user_s
, (dpeth_t
*dep
, int nic_addr
,
176 iovec_dat_s_t
*iovp
, vir_bytes offset
, vir_bytes count
) );
177 _PROTOTYPE( static void dp_next_iovec
, (iovec_dat_t
*iovp
) );
178 _PROTOTYPE( static void dp_next_iovec_s
, (iovec_dat_s_t
*iovp
) );
179 _PROTOTYPE( static void conf_hw
, (dpeth_t
*dep
) );
180 _PROTOTYPE( static void update_conf
, (dpeth_t
*dep
, dp_conf_t
*dcp
) );
181 _PROTOTYPE( static void map_hw_buffer
, (dpeth_t
*dep
) );
182 _PROTOTYPE( static int calc_iovec_size
, (iovec_dat_t
*iovp
) );
183 _PROTOTYPE( static int calc_iovec_size_s
, (iovec_dat_s_t
*iovp
) );
184 _PROTOTYPE( static void reply
, (dpeth_t
*dep
, int err
, int may_block
) );
185 _PROTOTYPE( static void mess_reply
, (message
*req
, message
*reply
) );
186 _PROTOTYPE( static void get_userdata
, (int user_proc
,
187 vir_bytes user_addr
, vir_bytes count
, void *loc_addr
) );
188 _PROTOTYPE( static void get_userdata_s
, (int user_proc
,
189 cp_grant_id_t grant
, vir_bytes offset
, vir_bytes count
,
191 _PROTOTYPE( static void put_userdata
, (int user_proc
,
192 vir_bytes user_addr
, vir_bytes count
, void *loc_addr
) );
193 _PROTOTYPE( static void put_userdata_s
, (int user_proc
,
194 cp_grant_id_t grant
, size_t count
, void *loc_addr
) );
195 _PROTOTYPE( static void insb
, (port_t port
, void *buf
, size_t size
) );
196 _PROTOTYPE( static void insw
, (port_t port
, void *buf
, size_t size
) );
197 _PROTOTYPE( static void do_vir_insb
, (port_t port
, int proc
,
198 vir_bytes buf
, size_t size
) );
199 _PROTOTYPE( static void do_vir_insw
, (port_t port
, int proc
,
200 vir_bytes buf
, size_t size
) );
201 _PROTOTYPE( static void do_vir_outsb
, (port_t port
, int proc
,
202 vir_bytes buf
, size_t size
) );
203 _PROTOTYPE( static void do_vir_outsw
, (port_t port
, int proc
,
204 vir_bytes buf
, size_t size
) );
206 PRIVATE
int handle_hw_intr(void)
211 for (i
= 0, dep
= &de_table
[0]; i
<DE_PORT_NR
; i
++, dep
++)
213 if (dep
->de_mode
!= DEM_ENABLED
)
215 assert(dep
->de_flags
& DEF_ENABLED
);
217 assert(irq
>= 0 && irq
< NR_IRQ_VECTORS
);
218 if (dep
->de_int_pending
|| 1)
220 dep
->de_int_pending
= 0;
223 r
= sys_irqenable(&dep
->de_hook
);
227 "unable enable interrupts", r
);
235 /* SEF functions and variables. */
236 FORWARD
_PROTOTYPE( void sef_local_startup
, (void) );
237 FORWARD
_PROTOTYPE( int sef_cb_init_fresh
, (int type
, sef_init_info_t
*info
) );
239 EXTERN
char **env_argv
;
241 /*===========================================================================*
243 *===========================================================================*/
244 int main(int argc
, char *argv
[])
249 /* SEF local startup. */
250 env_setargs(argc
, argv
);
255 if ((r
= sef_receive(ANY
, &m
)) != OK
)
256 panic("", "dp8390: sef_receive failed", r
);
258 if (is_notify(m
.m_type
)) {
259 switch (_ENDPOINT_P(m
.m_source
)) {
261 r
= handle_hw_intr();
267 if (getsigset(&set
) != 0) break;
269 if (sigismember(&set
, SIGTERM
))
275 printf("dp8390: notify from CLOCK\n");
278 panic("", "dp8390: illegal notify from",
282 /* done, get a new message */
288 case DL_WRITE
: do_vwrite(&m
, FALSE
, FALSE
); break;
289 case DL_WRITEV
: do_vwrite(&m
, FALSE
, TRUE
); break;
290 case DL_WRITEV_S
: do_vwrite_s(&m
, FALSE
); break;
291 case DL_READ
: do_vread(&m
, FALSE
); break;
292 case DL_READV
: do_vread(&m
, TRUE
); break;
293 case DL_READV_S
: do_vread_s(&m
); break;
294 case DL_CONF
: do_init(&m
); break;
295 case DL_GETSTAT
: do_getstat(&m
); break;
296 case DL_GETSTAT_S
: do_getstat_s(&m
); break;
297 case DL_GETNAME
: do_getname(&m
); break;
298 case DL_STOP
: do_stop(&m
); break;
300 panic("", "dp8390: illegal message", m
.m_type
);
305 /*===========================================================================*
306 * sef_local_startup *
307 *===========================================================================*/
308 PRIVATE
void sef_local_startup()
310 /* Register init callbacks. */
311 sef_setcb_init_fresh(sef_cb_init_fresh
);
312 sef_setcb_init_restart(sef_cb_init_fresh
);
314 /* No live update support for now. */
316 /* Let SEF perform startup. */
320 /*===========================================================================*
321 * sef_cb_init_fresh *
322 *===========================================================================*/
323 PRIVATE
int sef_cb_init_fresh(int type
, sef_init_info_t
*info
)
325 /* Initialize the dp8390 driver. */
330 system_hz
= sys_hz();
335 "A head which at this time has no name", NO_NUM
);
337 (progname
=strrchr(env_argv
[0],'/')) ? progname
++
338 : (progname
=env_argv
[0]);
340 for (i
= 0, dep
= de_table
; i
<DE_PORT_NR
; i
++, dep
++)
342 strcpy(dep
->de_name
, "dp8390#0");
343 dep
->de_name
[7] += i
;
347 (void) env_parse("ETH_IGN_PROTO", "x", 0, &v
, 0x0000L
, 0xFFFFL
);
348 eth_ign_proto
= htons((u16_t
) v
);
350 /* Try to notify inet that we are present (again) */
351 r
= _pm_findproc("inet", &tasknr
);
359 /*===========================================================================*
361 *===========================================================================*/
368 for (i
= 0, dep
= &de_table
[0]; i
<DE_PORT_NR
; i
++, dep
++)
371 if (dep
->de_mode
== DEM_DISABLED
)
372 printf("dp8390 port %d is disabled\n", i
);
373 else if (dep
->de_mode
== DEM_SINK
)
374 printf("dp8390 port %d is in sink mode\n", i
);
377 if (dep
->de_mode
!= DEM_ENABLED
)
380 printf("dp8390 statistics of port %d:\n", i
);
382 printf("recvErr :%8ld\t", dep
->de_stat
.ets_recvErr
);
383 printf("sendErr :%8ld\t", dep
->de_stat
.ets_sendErr
);
384 printf("OVW :%8ld\n", dep
->de_stat
.ets_OVW
);
386 printf("CRCerr :%8ld\t", dep
->de_stat
.ets_CRCerr
);
387 printf("frameAll :%8ld\t", dep
->de_stat
.ets_frameAll
);
388 printf("missedP :%8ld\n", dep
->de_stat
.ets_missedP
);
390 printf("packetR :%8ld\t", dep
->de_stat
.ets_packetR
);
391 printf("packetT :%8ld\t", dep
->de_stat
.ets_packetT
);
392 printf("transDef :%8ld\n", dep
->de_stat
.ets_transDef
);
394 printf("collision :%8ld\t", dep
->de_stat
.ets_collision
);
395 printf("transAb :%8ld\t", dep
->de_stat
.ets_transAb
);
396 printf("carrSense :%8ld\n", dep
->de_stat
.ets_carrSense
);
398 printf("fifoUnder :%8ld\t", dep
->de_stat
.ets_fifoUnder
);
399 printf("fifoOver :%8ld\t", dep
->de_stat
.ets_fifoOver
);
400 printf("CDheartbeat:%8ld\n", dep
->de_stat
.ets_CDheartbeat
);
402 printf("OWC :%8ld\t", dep
->de_stat
.ets_OWC
);
404 isr
= inb_reg0(dep
, DP_ISR
);
405 printf("dp_isr = 0x%x + 0x%x, de_flags = 0x%x\n", isr
,
406 inb_reg0(dep
, DP_ISR
), dep
->de_flags
);
411 /*===========================================================================*
413 *===========================================================================*/
414 static void dp8390_stop()
419 for (i
= 0; i
<DE_PORT_NR
; i
++)
421 if (de_table
[i
].de_mode
!= DEM_ENABLED
)
423 mess
.m_type
= DL_STOP
;
430 /*===========================================================================*
432 *===========================================================================*/
433 static void pci_conf()
438 static char envfmt
[] = "*:d.d.d";
440 static int first_time
= 1;
446 for (i
= 0, dep
= de_table
; i
<DE_PORT_NR
; i
++, dep
++)
448 envvar
= dp_conf
[i
].dpc_envvar
;
449 if (!(dep
->de_pci
= env_prefix(envvar
, "pci")))
450 continue; /* no PCI config */
452 (void) env_parse(envvar
, envfmt
, 1, &v
, 0, 255);
455 (void) env_parse(envvar
, envfmt
, 2, &v
, 0, 255);
458 (void) env_parse(envvar
, envfmt
, 3, &v
, 0, 255);
462 for (h
= 1; h
>= 0; h
--) {
463 for (i
= 0, dep
= de_table
; i
<DE_PORT_NR
; i
++, dep
++)
467 printf("pci: no pci for port %d\n", i
);
470 if (((dep
->de_pcibus
| dep
->de_pcidev
|
471 dep
->de_pcifunc
) != 0) != h
)
480 #endif /* ENABLE_PCI */
482 /*===========================================================================*
484 *===========================================================================*/
485 static void do_vwrite(mp
, from_int
, vectored
)
490 int port
, count
, size
;
495 count
= mp
->DL_COUNT
;
496 if (port
< 0 || port
>= DE_PORT_NR
)
497 panic("", "dp8390: illegal port", port
);
498 dep
= &de_table
[port
];
499 dep
->de_client
= mp
->DL_PROC
;
501 if (dep
->de_mode
== DEM_SINK
)
504 dep
->de_flags
|= DEF_PACK_SEND
;
505 reply(dep
, OK
, FALSE
);
508 assert(dep
->de_mode
== DEM_ENABLED
);
509 assert(dep
->de_flags
& DEF_ENABLED
);
510 if (dep
->de_flags
& DEF_SEND_AVAIL
)
511 panic("", "dp8390: send already in progress", NO_NUM
);
513 sendq_head
= dep
->de_sendq_head
;
514 if (dep
->de_sendq
[sendq_head
].sq_filled
)
517 panic("", "dp8390: should not be sending\n", NO_NUM
);
518 dep
->de_sendmsg
= *mp
;
519 dep
->de_flags
|= DEF_SEND_AVAIL
;
520 reply(dep
, OK
, FALSE
);
523 assert(!(dep
->de_flags
& DEF_PACK_SEND
));
527 get_userdata(mp
->DL_PROC
, (vir_bytes
) mp
->DL_ADDR
,
528 (count
> IOVEC_NR
? IOVEC_NR
: count
) *
529 sizeof(iovec_t
), dep
->de_write_iovec
.iod_iovec
);
530 dep
->de_write_iovec
.iod_iovec_s
= count
;
531 dep
->de_write_iovec
.iod_proc_nr
= mp
->DL_PROC
;
532 dep
->de_write_iovec
.iod_iovec_addr
= (vir_bytes
) mp
->DL_ADDR
;
534 dep
->de_tmp_iovec
= dep
->de_write_iovec
;
535 size
= calc_iovec_size(&dep
->de_tmp_iovec
);
539 dep
->de_write_iovec
.iod_iovec
[0].iov_addr
=
540 (vir_bytes
) mp
->DL_ADDR
;
541 dep
->de_write_iovec
.iod_iovec
[0].iov_size
=
543 dep
->de_write_iovec
.iod_iovec_s
= 1;
544 dep
->de_write_iovec
.iod_proc_nr
= mp
->DL_PROC
;
545 dep
->de_write_iovec
.iod_iovec_addr
= 0;
548 if (size
< ETH_MIN_PACK_SIZE
|| size
> ETH_MAX_PACK_SIZE_TAGGED
)
550 panic("", "dp8390: invalid packet size", size
);
552 (dep
->de_user2nicf
)(dep
, &dep
->de_write_iovec
, 0,
553 dep
->de_sendq
[sendq_head
].sq_sendpage
* DP_PAGESIZE
,
555 dep
->de_sendq
[sendq_head
].sq_filled
= TRUE
;
556 if (dep
->de_sendq_tail
== sendq_head
)
558 outb_reg0(dep
, DP_TPSR
, dep
->de_sendq
[sendq_head
].sq_sendpage
);
559 outb_reg0(dep
, DP_TBCR1
, size
>> 8);
560 outb_reg0(dep
, DP_TBCR0
, size
& 0xff);
561 outb_reg0(dep
, DP_CR
, CR_TXP
| CR_EXTRA
);/* there it goes.. */
564 dep
->de_sendq
[sendq_head
].sq_size
= size
;
566 if (++sendq_head
== dep
->de_sendq_nr
)
568 assert(sendq_head
< SENDQ_NR
);
569 dep
->de_sendq_head
= sendq_head
;
571 dep
->de_flags
|= DEF_PACK_SEND
;
573 /* If the interrupt handler called, don't send a reply. The reply
574 * will be sent after all interrupts are handled.
578 reply(dep
, OK
, FALSE
);
580 assert(dep
->de_mode
== DEM_ENABLED
);
581 assert(dep
->de_flags
& DEF_ENABLED
);
584 /*===========================================================================*
586 *===========================================================================*/
587 static void do_vwrite_s(mp
, from_int
)
591 int port
, count
, size
;
596 count
= mp
->DL_COUNT
;
597 if (port
< 0 || port
>= DE_PORT_NR
)
598 panic("", "dp8390: illegal port", port
);
599 dep
= &de_table
[port
];
600 dep
->de_client
= mp
->DL_PROC
;
602 if (dep
->de_mode
== DEM_SINK
)
605 dep
->de_flags
|= DEF_PACK_SEND
;
606 reply(dep
, OK
, FALSE
);
609 assert(dep
->de_mode
== DEM_ENABLED
);
610 assert(dep
->de_flags
& DEF_ENABLED
);
611 if (dep
->de_flags
& DEF_SEND_AVAIL
)
612 panic("", "dp8390: send already in progress", NO_NUM
);
614 sendq_head
= dep
->de_sendq_head
;
615 if (dep
->de_sendq
[sendq_head
].sq_filled
)
618 panic("", "dp8390: should not be sending\n", NO_NUM
);
619 dep
->de_sendmsg
= *mp
;
620 dep
->de_flags
|= DEF_SEND_AVAIL
;
621 reply(dep
, OK
, FALSE
);
624 assert(!(dep
->de_flags
& DEF_PACK_SEND
));
626 get_userdata_s(mp
->DL_PROC
, mp
->DL_GRANT
, 0,
627 (count
> IOVEC_NR
? IOVEC_NR
: count
) *
628 sizeof(dep
->de_write_iovec_s
.iod_iovec
[0]),
629 dep
->de_write_iovec_s
.iod_iovec
);
630 dep
->de_write_iovec_s
.iod_iovec_s
= count
;
631 dep
->de_write_iovec_s
.iod_proc_nr
= mp
->DL_PROC
;
632 dep
->de_write_iovec_s
.iod_grant
= mp
->DL_GRANT
;
633 dep
->de_write_iovec_s
.iod_iovec_offset
= 0;
635 dep
->de_tmp_iovec_s
= dep
->de_write_iovec_s
;
636 size
= calc_iovec_size_s(&dep
->de_tmp_iovec_s
);
638 if (size
< ETH_MIN_PACK_SIZE
|| size
> ETH_MAX_PACK_SIZE_TAGGED
)
640 panic("", "dp8390: invalid packet size", size
);
642 (dep
->de_user2nicf_s
)(dep
, &dep
->de_write_iovec_s
, 0,
643 dep
->de_sendq
[sendq_head
].sq_sendpage
* DP_PAGESIZE
,
645 dep
->de_sendq
[sendq_head
].sq_filled
= TRUE
;
646 if (dep
->de_sendq_tail
== sendq_head
)
648 outb_reg0(dep
, DP_TPSR
, dep
->de_sendq
[sendq_head
].sq_sendpage
);
649 outb_reg0(dep
, DP_TBCR1
, size
>> 8);
650 outb_reg0(dep
, DP_TBCR0
, size
& 0xff);
651 outb_reg0(dep
, DP_CR
, CR_TXP
| CR_EXTRA
);/* there it goes.. */
654 dep
->de_sendq
[sendq_head
].sq_size
= size
;
656 if (++sendq_head
== dep
->de_sendq_nr
)
658 assert(sendq_head
< SENDQ_NR
);
659 dep
->de_sendq_head
= sendq_head
;
661 dep
->de_flags
|= DEF_PACK_SEND
;
663 /* If the interrupt handler called, don't send a reply. The reply
664 * will be sent after all interrupts are handled.
668 reply(dep
, OK
, FALSE
);
670 assert(dep
->de_mode
== DEM_ENABLED
);
671 assert(dep
->de_flags
& DEF_ENABLED
);
674 /*===========================================================================*
676 *===========================================================================*/
677 static void do_vread(mp
, vectored
)
686 count
= mp
->DL_COUNT
;
687 if (port
< 0 || port
>= DE_PORT_NR
)
688 panic("", "dp8390: illegal port", port
);
689 dep
= &de_table
[port
];
690 dep
->de_client
= mp
->DL_PROC
;
691 if (dep
->de_mode
== DEM_SINK
)
693 reply(dep
, OK
, FALSE
);
696 assert(dep
->de_mode
== DEM_ENABLED
);
697 assert(dep
->de_flags
& DEF_ENABLED
);
699 if(dep
->de_flags
& DEF_READING
)
700 panic("", "dp8390: read already in progress", NO_NUM
);
702 dep
->de_safecopy_read
= 0;
706 get_userdata(mp
->DL_PROC
, (vir_bytes
) mp
->DL_ADDR
,
707 (count
> IOVEC_NR
? IOVEC_NR
: count
) *
708 sizeof(iovec_t
), dep
->de_read_iovec
.iod_iovec
);
709 dep
->de_read_iovec
.iod_iovec_s
= count
;
710 dep
->de_read_iovec
.iod_proc_nr
= mp
->DL_PROC
;
711 dep
->de_read_iovec
.iod_iovec_addr
= (vir_bytes
) mp
->DL_ADDR
;
713 dep
->de_tmp_iovec
= dep
->de_read_iovec
;
714 size
= calc_iovec_size(&dep
->de_tmp_iovec
);
718 dep
->de_read_iovec
.iod_iovec
[0].iov_addr
=
719 (vir_bytes
) mp
->DL_ADDR
;
720 dep
->de_read_iovec
.iod_iovec
[0].iov_size
=
722 dep
->de_read_iovec
.iod_iovec_s
= 1;
723 dep
->de_read_iovec
.iod_proc_nr
= mp
->DL_PROC
;
724 dep
->de_read_iovec
.iod_iovec_addr
= 0;
727 if (size
< ETH_MAX_PACK_SIZE_TAGGED
)
728 panic("", "dp8390: wrong packet size", size
);
729 dep
->de_flags
|= DEF_READING
;
733 if ((dep
->de_flags
& (DEF_READING
|DEF_STOPPED
)) ==
734 (DEF_READING
|DEF_STOPPED
))
736 /* The chip is stopped, and all arrived packets are
741 reply(dep
, OK
, FALSE
);
744 /*===========================================================================*
746 *===========================================================================*/
747 static void do_vread_s(mp
)
755 count
= mp
->DL_COUNT
;
756 if (port
< 0 || port
>= DE_PORT_NR
)
757 panic("", "dp8390: illegal port", port
);
758 dep
= &de_table
[port
];
759 dep
->de_client
= mp
->DL_PROC
;
760 if (dep
->de_mode
== DEM_SINK
)
762 reply(dep
, OK
, FALSE
);
765 assert(dep
->de_mode
== DEM_ENABLED
);
766 assert(dep
->de_flags
& DEF_ENABLED
);
768 dep
->de_safecopy_read
= 1;
770 if(dep
->de_flags
& DEF_READING
)
771 panic("", "dp8390: read already in progress", NO_NUM
);
773 get_userdata_s(mp
->DL_PROC
, mp
->DL_GRANT
, 0,
774 (count
> IOVEC_NR
? IOVEC_NR
: count
) *
775 sizeof(dep
->de_read_iovec_s
.iod_iovec
[0]),
776 dep
->de_read_iovec_s
.iod_iovec
);
777 dep
->de_read_iovec_s
.iod_iovec_s
= count
;
778 dep
->de_read_iovec_s
.iod_proc_nr
= mp
->DL_PROC
;
779 dep
->de_read_iovec_s
.iod_grant
= mp
->DL_GRANT
;
780 dep
->de_read_iovec_s
.iod_iovec_offset
= 0;
782 dep
->de_tmp_iovec_s
= dep
->de_read_iovec_s
;
783 size
= calc_iovec_size_s(&dep
->de_tmp_iovec_s
);
785 if (size
< ETH_MAX_PACK_SIZE_TAGGED
)
786 panic("", "dp8390: wrong packet size", size
);
787 dep
->de_flags
|= DEF_READING
;
791 if ((dep
->de_flags
& (DEF_READING
|DEF_STOPPED
)) ==
792 (DEF_READING
|DEF_STOPPED
))
794 /* The chip is stopped, and all arrived packets are
799 reply(dep
, OK
, FALSE
);
802 /*===========================================================================*
804 *===========================================================================*/
805 static void do_init(mp
)
813 pci_conf(); /* Configure PCI devices. */
817 if (port
< 0 || port
>= DE_PORT_NR
)
819 reply_mess
.m_type
= DL_CONF_REPLY
;
820 reply_mess
.m3_i1
= ENXIO
;
821 mess_reply(mp
, &reply_mess
);
824 dep
= &de_table
[port
];
825 if (dep
->de_mode
== DEM_DISABLED
)
827 /* This is the default, try to (re)locate the device. */
829 if (dep
->de_mode
== DEM_DISABLED
)
831 /* Probe failed, or the device is configured off. */
832 reply_mess
.m_type
= DL_CONF_REPLY
;
833 reply_mess
.m3_i1
= ENXIO
;
834 mess_reply(mp
, &reply_mess
);
837 if (dep
->de_mode
== DEM_ENABLED
)
841 if (dep
->de_mode
== DEM_SINK
)
843 strncpy((char *) dep
->de_address
.ea_addr
, "ZDP", 6);
844 dep
->de_address
.ea_addr
[5] = port
;
846 reply_mess
.m_type
= DL_CONF_REPLY
;
847 reply_mess
.m3_i1
= mp
->DL_PORT
;
848 reply_mess
.m3_i2
= DE_PORT_NR
;
849 *(ether_addr_t
*) reply_mess
.m3_ca1
= dep
->de_address
;
850 mess_reply(mp
, &reply_mess
);
853 assert(dep
->de_mode
== DEM_ENABLED
);
854 assert(dep
->de_flags
& DEF_ENABLED
);
856 dep
->de_flags
&= ~(DEF_PROMISC
| DEF_MULTI
| DEF_BROAD
);
858 if (mp
->DL_MODE
& DL_PROMISC_REQ
)
859 dep
->de_flags
|= DEF_PROMISC
| DEF_MULTI
| DEF_BROAD
;
860 if (mp
->DL_MODE
& DL_MULTI_REQ
)
861 dep
->de_flags
|= DEF_MULTI
;
862 if (mp
->DL_MODE
& DL_BROAD_REQ
)
863 dep
->de_flags
|= DEF_BROAD
;
865 dep
->de_client
= mp
->m_source
;
868 reply_mess
.m_type
= DL_CONF_REPLY
;
869 reply_mess
.m3_i1
= mp
->DL_PORT
;
870 reply_mess
.m3_i2
= DE_PORT_NR
;
871 *(ether_addr_t
*) reply_mess
.m3_ca1
= dep
->de_address
;
873 mess_reply(mp
, &reply_mess
);
876 /*===========================================================================*
878 *===========================================================================*/
879 static void do_int(dep
)
882 if (dep
->de_flags
& (DEF_PACK_SEND
| DEF_PACK_RECV
))
883 reply(dep
, OK
, TRUE
);
886 /*===========================================================================*
888 *===========================================================================*/
889 static void do_getstat(mp
)
896 if (port
< 0 || port
>= DE_PORT_NR
)
897 panic("", "dp8390: illegal port", port
);
898 dep
= &de_table
[port
];
899 dep
->de_client
= mp
->DL_PROC
;
900 if (dep
->de_mode
== DEM_SINK
)
902 put_userdata(mp
->DL_PROC
, (vir_bytes
) mp
->DL_ADDR
,
903 (vir_bytes
) sizeof(dep
->de_stat
), &dep
->de_stat
);
905 mp
->m_type
= DL_STAT_REPLY
;
908 r
= send(mp
->m_source
, mp
);
910 panic(__FILE__
, "do_getstat: send failed: %d\n", r
);
913 assert(dep
->de_mode
== DEM_ENABLED
);
914 assert(dep
->de_flags
& DEF_ENABLED
);
916 dep
->de_stat
.ets_CRCerr
+= inb_reg0(dep
, DP_CNTR0
);
917 dep
->de_stat
.ets_frameAll
+= inb_reg0(dep
, DP_CNTR1
);
918 dep
->de_stat
.ets_missedP
+= inb_reg0(dep
, DP_CNTR2
);
920 put_userdata(mp
->DL_PROC
, (vir_bytes
) mp
->DL_ADDR
,
921 (vir_bytes
) sizeof(dep
->de_stat
), &dep
->de_stat
);
923 mp
->m_type
= DL_STAT_REPLY
;
926 r
= send(mp
->m_source
, mp
);
928 panic(__FILE__
, "do_getstat: send failed: %d\n", r
);
931 /*===========================================================================*
933 *===========================================================================*/
934 static void do_getstat_s(mp
)
941 if (port
< 0 || port
>= DE_PORT_NR
)
942 panic("", "dp8390: illegal port", port
);
943 dep
= &de_table
[port
];
944 dep
->de_client
= mp
->DL_PROC
;
945 if (dep
->de_mode
== DEM_SINK
)
947 put_userdata(mp
->DL_PROC
, (vir_bytes
) mp
->DL_ADDR
,
948 (vir_bytes
) sizeof(dep
->de_stat
), &dep
->de_stat
);
950 mp
->m_type
= DL_STAT_REPLY
;
953 r
= send(mp
->m_source
, mp
);
955 panic(__FILE__
, "do_getstat: send failed: %d\n", r
);
958 assert(dep
->de_mode
== DEM_ENABLED
);
959 assert(dep
->de_flags
& DEF_ENABLED
);
961 dep
->de_stat
.ets_CRCerr
+= inb_reg0(dep
, DP_CNTR0
);
962 dep
->de_stat
.ets_frameAll
+= inb_reg0(dep
, DP_CNTR1
);
963 dep
->de_stat
.ets_missedP
+= inb_reg0(dep
, DP_CNTR2
);
965 put_userdata_s(mp
->DL_PROC
, mp
->DL_GRANT
,
966 sizeof(dep
->de_stat
), &dep
->de_stat
);
968 mp
->m_type
= DL_STAT_REPLY
;
971 r
= send(mp
->m_source
, mp
);
973 panic(__FILE__
, "do_getstat: send failed: %d\n", r
);
976 /*===========================================================================*
978 *===========================================================================*/
979 static void do_getname(mp
)
984 strncpy(mp
->DL_NAME
, progname
, sizeof(mp
->DL_NAME
));
985 mp
->DL_NAME
[sizeof(mp
->DL_NAME
)-1]= '\0';
986 mp
->m_type
= DL_NAME_REPLY
;
987 r
= send(mp
->m_source
, mp
);
989 panic("dp8390", "do_getname: send failed: %d\n", r
);
992 /*===========================================================================*
994 *===========================================================================*/
995 static void do_stop(mp
)
1003 if (port
< 0 || port
>= DE_PORT_NR
)
1004 panic("", "dp8390: illegal port", port
);
1005 dep
= &de_table
[port
];
1006 if (dep
->de_mode
== DEM_SINK
)
1008 assert(dep
->de_mode
== DEM_ENABLED
);
1010 if (!(dep
->de_flags
& DEF_ENABLED
))
1013 outb_reg0(dep
, DP_CR
, CR_STP
| CR_DM_ABORT
);
1014 (dep
->de_stopf
)(dep
);
1016 dep
->de_flags
= DEF_EMPTY
;
1019 /*===========================================================================*
1021 *===========================================================================*/
1022 static void dp_init(dep
)
1028 /* General initialization */
1029 dep
->de_flags
= DEF_EMPTY
;
1030 (*dep
->de_initf
)(dep
);
1036 printf("%s: Ethernet address ", dep
->de_name
);
1037 for (i
= 0; i
< 6; i
++)
1038 printf("%x%c", dep
->de_address
.ea_addr
[i
],
1039 i
< 5 ? ':' : '\n');
1045 /* Initialization of the dp8390 following the mandatory procedure
1046 * in reference manual ("DP8390D/NS32490D NIC Network Interface
1047 * Controller", National Semiconductor, July 1995, Page 29).
1050 outb_reg0(dep
, DP_CR
, CR_PS_P0
| CR_STP
| CR_DM_ABORT
);
1053 outb_reg0(dep
, DP_DCR
, DCR_WORDWIDE
| DCR_8BYTES
| DCR_BMS
);
1055 outb_reg0(dep
, DP_DCR
, DCR_BYTEWIDE
| DCR_8BYTES
| DCR_BMS
);
1057 outb_reg0(dep
, DP_RBCR0
, 0);
1058 outb_reg0(dep
, DP_RBCR1
, 0);
1061 if (dep
->de_flags
& DEF_PROMISC
)
1062 dp_rcr_reg
|= RCR_AB
| RCR_PRO
| RCR_AM
;
1063 if (dep
->de_flags
& DEF_BROAD
)
1064 dp_rcr_reg
|= RCR_AB
;
1065 if (dep
->de_flags
& DEF_MULTI
)
1066 dp_rcr_reg
|= RCR_AM
;
1067 outb_reg0(dep
, DP_RCR
, dp_rcr_reg
);
1069 outb_reg0(dep
, DP_TCR
, TCR_INTERNAL
);
1071 outb_reg0(dep
, DP_BNRY
, dep
->de_startpage
);
1072 outb_reg0(dep
, DP_PSTART
, dep
->de_startpage
);
1073 outb_reg0(dep
, DP_PSTOP
, dep
->de_stoppage
);
1075 outb_reg0(dep
, DP_ISR
, 0xFF);
1077 outb_reg0(dep
, DP_IMR
, IMR_PRXE
| IMR_PTXE
| IMR_RXEE
| IMR_TXEE
|
1078 IMR_OVWE
| IMR_CNTE
);
1080 outb_reg0(dep
, DP_CR
, CR_PS_P1
| CR_DM_ABORT
| CR_STP
);
1082 outb_reg1(dep
, DP_PAR0
, dep
->de_address
.ea_addr
[0]);
1083 outb_reg1(dep
, DP_PAR1
, dep
->de_address
.ea_addr
[1]);
1084 outb_reg1(dep
, DP_PAR2
, dep
->de_address
.ea_addr
[2]);
1085 outb_reg1(dep
, DP_PAR3
, dep
->de_address
.ea_addr
[3]);
1086 outb_reg1(dep
, DP_PAR4
, dep
->de_address
.ea_addr
[4]);
1087 outb_reg1(dep
, DP_PAR5
, dep
->de_address
.ea_addr
[5]);
1089 outb_reg1(dep
, DP_MAR0
, 0xff);
1090 outb_reg1(dep
, DP_MAR1
, 0xff);
1091 outb_reg1(dep
, DP_MAR2
, 0xff);
1092 outb_reg1(dep
, DP_MAR3
, 0xff);
1093 outb_reg1(dep
, DP_MAR4
, 0xff);
1094 outb_reg1(dep
, DP_MAR5
, 0xff);
1095 outb_reg1(dep
, DP_MAR6
, 0xff);
1096 outb_reg1(dep
, DP_MAR7
, 0xff);
1098 outb_reg1(dep
, DP_CURR
, dep
->de_startpage
+ 1);
1100 outb_reg0(dep
, DP_CR
, CR_DM_ABORT
| CR_STA
);
1102 outb_reg0(dep
, DP_TCR
, TCR_NORMAL
);
1104 inb_reg0(dep
, DP_CNTR0
); /* reset counters by reading */
1105 inb_reg0(dep
, DP_CNTR1
);
1106 inb_reg0(dep
, DP_CNTR2
);
1108 /* Finish the initialization. */
1109 dep
->de_flags
|= DEF_ENABLED
;
1110 for (i
= 0; i
<dep
->de_sendq_nr
; i
++)
1111 dep
->de_sendq
[i
].sq_filled
= 0;
1112 dep
->de_sendq_head
= 0;
1113 dep
->de_sendq_tail
= 0;
1114 if (!dep
->de_prog_IO
)
1116 dep
->de_user2nicf
= dp_user2nic
;
1117 dep
->de_user2nicf_s
= dp_user2nic_s
;
1118 dep
->de_nic2userf
= dp_nic2user
;
1119 dep
->de_nic2userf_s
= dp_nic2user_s
;
1120 dep
->de_getblockf
= dp_getblock
;
1122 else if (dep
->de_16bit
)
1124 dep
->de_user2nicf
= dp_pio16_user2nic
;
1125 dep
->de_user2nicf_s
= dp_pio16_user2nic_s
;
1126 dep
->de_nic2userf
= dp_pio16_nic2user
;
1127 dep
->de_nic2userf_s
= dp_pio16_nic2user_s
;
1128 dep
->de_getblockf
= dp_pio16_getblock
;
1132 dep
->de_user2nicf
= dp_pio8_user2nic
;
1133 dep
->de_user2nicf_s
= dp_pio8_user2nic_s
;
1134 dep
->de_nic2userf
= dp_pio8_nic2user
;
1135 dep
->de_nic2userf_s
= dp_pio8_nic2user_s
;
1136 dep
->de_getblockf
= dp_pio8_getblock
;
1139 /* Set the interrupt handler and policy. Do not automatically
1140 * reenable interrupts. Return the IRQ line number on interrupts.
1142 dep
->de_hook
= dep
->de_irq
;
1143 r
= sys_irqsetpolicy(dep
->de_irq
, 0, &dep
->de_hook
);
1145 panic("DP8390", "sys_irqsetpolicy failed", r
);
1147 r
= sys_irqenable(&dep
->de_hook
);
1150 panic("DP8390", "unable enable interrupts", r
);
1154 /*===========================================================================*
1156 *===========================================================================*/
1157 static void dp_confaddr(dep
)
1162 static char eafmt
[]= "x:x:x:x:x:x";
1165 /* User defined ethernet address? */
1166 strcpy(eakey
, dp_conf
[dep
-de_table
].dpc_envvar
);
1167 strcat(eakey
, "_EA");
1169 for (i
= 0; i
< 6; i
++)
1171 v
= dep
->de_address
.ea_addr
[i
];
1172 if (env_parse(eakey
, eafmt
, i
, &v
, 0x00L
, 0xFFL
) != EP_SET
)
1176 dep
->de_address
.ea_addr
[i
]= v
;
1179 if (i
!= 0 && i
!= 6) env_panic(eakey
); /* It's all or nothing */
1182 /*===========================================================================*
1184 *===========================================================================*/
1185 static void dp_reinit(dep
)
1190 outb_reg0(dep
, DP_CR
, CR_PS_P0
| CR_EXTRA
);
1193 if (dep
->de_flags
& DEF_PROMISC
)
1194 dp_rcr_reg
|= RCR_AB
| RCR_PRO
| RCR_AM
;
1195 if (dep
->de_flags
& DEF_BROAD
)
1196 dp_rcr_reg
|= RCR_AB
;
1197 if (dep
->de_flags
& DEF_MULTI
)
1198 dp_rcr_reg
|= RCR_AM
;
1199 outb_reg0(dep
, DP_RCR
, dp_rcr_reg
);
1202 /*===========================================================================*
1204 *===========================================================================*/
1205 static void dp_reset(dep
)
1211 outb_reg0(dep
, DP_CR
, CR_STP
| CR_DM_ABORT
);
1212 outb_reg0(dep
, DP_RBCR0
, 0);
1213 outb_reg0(dep
, DP_RBCR1
, 0);
1214 for (i
= 0; i
< 0x1000 && ((inb_reg0(dep
, DP_ISR
) & ISR_RST
) == 0); i
++)
1216 outb_reg0(dep
, DP_TCR
, TCR_1EXTERNAL
|TCR_OFST
);
1217 outb_reg0(dep
, DP_CR
, CR_STA
|CR_DM_ABORT
);
1218 outb_reg0(dep
, DP_TCR
, TCR_NORMAL
);
1220 /* Acknowledge the ISR_RDC (remote dma) interrupt. */
1221 for (i
= 0; i
< 0x1000 && ((inb_reg0(dep
, DP_ISR
) & ISR_RDC
) == 0); i
++)
1223 outb_reg0(dep
, DP_ISR
, inb_reg0(dep
, DP_ISR
) & ~ISR_RDC
);
1225 /* Reset the transmit ring. If we were transmitting a packet, we
1226 * pretend that the packet is processed. Higher layers will
1227 * retransmit if the packet wasn't actually sent.
1229 dep
->de_sendq_head
= dep
->de_sendq_tail
= 0;
1230 for (i
= 0; i
<dep
->de_sendq_nr
; i
++)
1231 dep
->de_sendq
[i
].sq_filled
= 0;
1233 dep
->de_flags
&= ~DEF_STOPPED
;
1236 /*===========================================================================*
1238 *===========================================================================*/
1239 static void dp_check_ints(dep
)
1243 int size
, sendq_tail
;
1245 if (!(dep
->de_flags
& DEF_ENABLED
))
1246 panic("", "dp8390: got premature interrupt", NO_NUM
);
1250 isr
= inb_reg0(dep
, DP_ISR
);
1253 outb_reg0(dep
, DP_ISR
, isr
);
1254 if (isr
& (ISR_PTX
|ISR_TXE
))
1259 { printf("%s: got send Error\n", dep
->de_name
); }
1261 dep
->de_stat
.ets_sendErr
++;
1265 tsr
= inb_reg0(dep
, DP_TSR
);
1267 if (tsr
& TSR_PTX
) dep
->de_stat
.ets_packetT
++;
1268 #if 0 /* Reserved in later manuals, should be ignored */
1269 if (!(tsr
& TSR_DFR
))
1271 /* In most (all?) implementations of
1272 * the dp8390, this bit is set
1273 * when the packet is not deferred
1275 dep
->de_stat
.ets_transDef
++;
1278 if (tsr
& TSR_COL
) dep
->de_stat
.ets_collision
++;
1279 if (tsr
& TSR_ABT
) dep
->de_stat
.ets_transAb
++;
1280 if (tsr
& TSR_CRS
) dep
->de_stat
.ets_carrSense
++;
1282 && ++dep
->de_stat
.ets_fifoUnder
<= 10)
1284 printf("%s: fifo underrun\n",
1288 && ++dep
->de_stat
.ets_CDheartbeat
<= 10)
1290 printf("%s: CD heart beat failure\n",
1293 if (tsr
& TSR_OWC
) dep
->de_stat
.ets_OWC
++;
1295 sendq_tail
= dep
->de_sendq_tail
;
1297 if (!(dep
->de_sendq
[sendq_tail
].sq_filled
))
1302 /* Or hardware bug? */
1304 "%s: transmit interrupt, but not sending\n",
1308 dep
->de_sendq
[sendq_tail
].sq_filled
= 0;
1309 if (++sendq_tail
== dep
->de_sendq_nr
)
1311 dep
->de_sendq_tail
= sendq_tail
;
1312 if (dep
->de_sendq
[sendq_tail
].sq_filled
)
1314 size
= dep
->de_sendq
[sendq_tail
].sq_size
;
1315 outb_reg0(dep
, DP_TPSR
,
1316 dep
->de_sendq
[sendq_tail
].sq_sendpage
);
1317 outb_reg0(dep
, DP_TBCR1
, size
>> 8);
1318 outb_reg0(dep
, DP_TBCR0
, size
& 0xff);
1319 outb_reg0(dep
, DP_CR
, CR_TXP
| CR_EXTRA
);
1321 if (dep
->de_flags
& DEF_SEND_AVAIL
)
1327 /* Only call dp_recv if there is a read request */
1328 if (dep
->de_flags
& DEF_READING
)
1332 if (isr
& ISR_RXE
) dep
->de_stat
.ets_recvErr
++;
1335 dep
->de_stat
.ets_CRCerr
+= inb_reg0(dep
, DP_CNTR0
);
1336 dep
->de_stat
.ets_frameAll
+= inb_reg0(dep
, DP_CNTR1
);
1337 dep
->de_stat
.ets_missedP
+= inb_reg0(dep
, DP_CNTR2
);
1341 dep
->de_stat
.ets_OVW
++;
1344 "%s: got overwrite warning\n", dep
->de_name
); }
1346 if (dep
->de_flags
& DEF_READING
)
1349 "dp_check_ints: strange: overwrite warning and pending read request\n");
1359 /* this means we got an interrupt but the ethernet
1360 * chip is shutdown. We set the flag DEF_STOPPED,
1361 * and continue processing arrived packets. When the
1362 * receive buffer is empty, we reset the dp8390.
1366 "%s: NIC stopped\n", dep
->de_name
); }
1368 dep
->de_flags
|= DEF_STOPPED
;
1372 if ((dep
->de_flags
& (DEF_READING
|DEF_STOPPED
)) ==
1373 (DEF_READING
|DEF_STOPPED
))
1375 /* The chip is stopped, and all arrived packets are
1382 /*===========================================================================*
1384 *===========================================================================*/
1385 static void dp_recv(dep
)
1389 unsigned pageno
, curr
, next
;
1391 int packet_processed
, r
;
1394 packet_processed
= FALSE
;
1395 pageno
= inb_reg0(dep
, DP_BNRY
) + 1;
1396 if (pageno
== dep
->de_stoppage
) pageno
= dep
->de_startpage
;
1400 outb_reg0(dep
, DP_CR
, CR_PS_P1
| CR_EXTRA
);
1401 curr
= inb_reg1(dep
, DP_CURR
);
1402 outb_reg0(dep
, DP_CR
, CR_PS_P0
| CR_EXTRA
);
1404 if (curr
== pageno
) break;
1406 (dep
->de_getblockf
)(dep
, pageno
, (size_t)0, sizeof(header
),
1408 (dep
->de_getblockf
)(dep
, pageno
, sizeof(header
) +
1409 2*sizeof(ether_addr_t
), sizeof(eth_type
), ð_type
);
1411 length
= (header
.dr_rbcl
| (header
.dr_rbch
<< 8)) -
1412 sizeof(dp_rcvhdr_t
);
1413 next
= header
.dr_next
;
1414 if (length
< ETH_MIN_PACK_SIZE
||
1415 length
> ETH_MAX_PACK_SIZE_TAGGED
)
1417 printf("%s: packet with strange length arrived: %d\n",
1418 dep
->de_name
, (int) length
);
1421 else if (next
< dep
->de_startpage
|| next
>= dep
->de_stoppage
)
1423 printf("%s: strange next page\n", dep
->de_name
);
1426 else if (eth_type
== eth_ign_proto
)
1428 /* Hack: ignore packets of a given protocol, useful
1429 * if you share a net with 80 computers sending
1430 * Amoeba FLIP broadcasts. (Protocol 0x8146.)
1432 static int first
= 1;
1436 printf("%s: dropping proto 0x%04x packets\n",
1438 ntohs(eth_ign_proto
));
1440 dep
->de_stat
.ets_packetR
++;
1442 else if (header
.dr_status
& RSR_FO
)
1444 /* This is very serious, so we issue a warning and
1445 * reset the buffers */
1446 printf("%s: fifo overrun, resetting receive buffer\n",
1448 dep
->de_stat
.ets_fifoOver
++;
1451 else if ((header
.dr_status
& RSR_PRX
) &&
1452 (dep
->de_flags
& DEF_ENABLED
))
1454 if (dep
->de_safecopy_read
)
1455 r
= dp_pkt2user_s(dep
, pageno
, length
);
1457 r
= dp_pkt2user(dep
, pageno
, length
);
1461 packet_processed
= TRUE
;
1462 dep
->de_stat
.ets_packetR
++;
1464 if (next
== dep
->de_startpage
)
1465 outb_reg0(dep
, DP_BNRY
, dep
->de_stoppage
- 1);
1467 outb_reg0(dep
, DP_BNRY
, next
- 1);
1471 while (!packet_processed
);
1474 /*===========================================================================*
1476 *===========================================================================*/
1477 static void dp_send(dep
)
1480 if (!(dep
->de_flags
& DEF_SEND_AVAIL
))
1483 dep
->de_flags
&= ~DEF_SEND_AVAIL
;
1484 switch(dep
->de_sendmsg
.m_type
)
1486 case DL_WRITE
: do_vwrite(&dep
->de_sendmsg
, TRUE
, FALSE
); break;
1487 case DL_WRITEV
: do_vwrite(&dep
->de_sendmsg
, TRUE
, TRUE
); break;
1488 case DL_WRITEV_S
: do_vwrite_s(&dep
->de_sendmsg
, TRUE
); break;
1490 panic("", "dp8390: wrong type", dep
->de_sendmsg
.m_type
);
1495 /*===========================================================================*
1497 *===========================================================================*/
1498 static void dp_getblock(dep
, page
, offset
, size
, dst
)
1505 offset
= page
* DP_PAGESIZE
+ offset
;
1507 memcpy(dst
, dep
->de_locmem
+ offset
, size
);
1510 /*===========================================================================*
1511 * dp_pio8_getblock *
1512 *===========================================================================*/
1513 static void dp_pio8_getblock(dep
, page
, offset
, size
, dst
)
1520 offset
= page
* DP_PAGESIZE
+ offset
;
1521 outb_reg0(dep
, DP_RBCR0
, size
& 0xFF);
1522 outb_reg0(dep
, DP_RBCR1
, size
>> 8);
1523 outb_reg0(dep
, DP_RSAR0
, offset
& 0xFF);
1524 outb_reg0(dep
, DP_RSAR1
, offset
>> 8);
1525 outb_reg0(dep
, DP_CR
, CR_DM_RR
| CR_PS_P0
| CR_STA
);
1527 insb(dep
->de_data_port
, dst
, size
);
1530 /*===========================================================================*
1531 * dp_pio16_getblock *
1532 *===========================================================================*/
1533 static void dp_pio16_getblock(dep
, page
, offset
, size
, dst
)
1540 offset
= page
* DP_PAGESIZE
+ offset
;
1541 outb_reg0(dep
, DP_RBCR0
, size
& 0xFF);
1542 outb_reg0(dep
, DP_RBCR1
, size
>> 8);
1543 outb_reg0(dep
, DP_RSAR0
, offset
& 0xFF);
1544 outb_reg0(dep
, DP_RSAR1
, offset
>> 8);
1545 outb_reg0(dep
, DP_CR
, CR_DM_RR
| CR_PS_P0
| CR_STA
);
1547 assert (!(size
& 1));
1548 insw(dep
->de_data_port
, dst
, size
);
1551 /*===========================================================================*
1553 *===========================================================================*/
1554 static int dp_pkt2user(dep
, page
, length
)
1560 if (!(dep
->de_flags
& DEF_READING
))
1563 last
= page
+ (length
- 1) / DP_PAGESIZE
;
1564 if (last
>= dep
->de_stoppage
)
1566 count
= (dep
->de_stoppage
- page
) * DP_PAGESIZE
-
1567 sizeof(dp_rcvhdr_t
);
1569 /* Save read_iovec since we need it twice. */
1570 dep
->de_tmp_iovec
= dep
->de_read_iovec
;
1571 (dep
->de_nic2userf
)(dep
, page
* DP_PAGESIZE
+
1572 sizeof(dp_rcvhdr_t
), &dep
->de_tmp_iovec
, 0, count
);
1573 (dep
->de_nic2userf
)(dep
, dep
->de_startpage
* DP_PAGESIZE
,
1574 &dep
->de_read_iovec
, count
, length
- count
);
1578 (dep
->de_nic2userf
)(dep
, page
* DP_PAGESIZE
+
1579 sizeof(dp_rcvhdr_t
), &dep
->de_read_iovec
, 0, length
);
1582 dep
->de_read_s
= length
;
1583 dep
->de_flags
|= DEF_PACK_RECV
;
1584 dep
->de_flags
&= ~DEF_READING
;
1589 /*===========================================================================*
1591 *===========================================================================*/
1592 static int dp_pkt2user_s(dep
, page
, length
)
1598 if (!(dep
->de_flags
& DEF_READING
))
1601 last
= page
+ (length
- 1) / DP_PAGESIZE
;
1602 if (last
>= dep
->de_stoppage
)
1604 count
= (dep
->de_stoppage
- page
) * DP_PAGESIZE
-
1605 sizeof(dp_rcvhdr_t
);
1607 /* Save read_iovec since we need it twice. */
1608 dep
->de_tmp_iovec_s
= dep
->de_read_iovec_s
;
1609 (dep
->de_nic2userf_s
)(dep
, page
* DP_PAGESIZE
+
1610 sizeof(dp_rcvhdr_t
), &dep
->de_tmp_iovec_s
, 0, count
);
1611 (dep
->de_nic2userf_s
)(dep
, dep
->de_startpage
* DP_PAGESIZE
,
1612 &dep
->de_read_iovec_s
, count
, length
- count
);
1616 (dep
->de_nic2userf_s
)(dep
, page
* DP_PAGESIZE
+
1617 sizeof(dp_rcvhdr_t
), &dep
->de_read_iovec_s
, 0, length
);
1620 dep
->de_read_s
= length
;
1621 dep
->de_flags
|= DEF_PACK_RECV
;
1622 dep
->de_flags
&= ~DEF_READING
;
1627 /*===========================================================================*
1629 *===========================================================================*/
1630 static void dp_user2nic(dep
, iovp
, offset
, nic_addr
, count
)
1640 vir_hw
= (vir_bytes
)dep
->de_locmem
+ nic_addr
;
1647 dp_next_iovec(iovp
);
1651 assert(i
< iovp
->iod_iovec_s
);
1652 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
1654 offset
-= iovp
->iod_iovec
[i
].iov_size
;
1658 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
1662 r
= sys_vircopy(iovp
->iod_proc_nr
, D
,
1663 iovp
->iod_iovec
[i
].iov_addr
+ offset
,
1664 SELF
, D
, vir_hw
, bytes
);
1666 panic("DP8390", "dp_user2nic: sys_vircopy failed", r
);
1675 /*===========================================================================*
1677 *===========================================================================*/
1678 static void dp_user2nic_s(dep
, iovp
, offset
, nic_addr
, count
)
1680 iovec_dat_s_t
*iovp
;
1688 vir_hw
= (vir_bytes
)dep
->de_locmem
+ nic_addr
;
1695 dp_next_iovec_s(iovp
);
1699 assert(i
< iovp
->iod_iovec_s
);
1700 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
1702 offset
-= iovp
->iod_iovec
[i
].iov_size
;
1706 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
1710 r
= sys_safecopyfrom(iovp
->iod_proc_nr
,
1711 iovp
->iod_iovec
[i
].iov_grant
, offset
,
1716 "dp_user2nic_s: sys_safecopyfrom failed", r
);
1726 /*===========================================================================*
1727 * dp_pio8_user2nic *
1728 *===========================================================================*/
1729 static void dp_pio8_user2nic(dep
, iovp
, offset
, nic_addr
, count
)
1738 outb_reg0(dep
, DP_ISR
, ISR_RDC
);
1740 outb_reg0(dep
, DP_RBCR0
, count
& 0xFF);
1741 outb_reg0(dep
, DP_RBCR1
, count
>> 8);
1742 outb_reg0(dep
, DP_RSAR0
, nic_addr
& 0xFF);
1743 outb_reg0(dep
, DP_RSAR1
, nic_addr
>> 8);
1744 outb_reg0(dep
, DP_CR
, CR_DM_RW
| CR_PS_P0
| CR_STA
);
1751 dp_next_iovec(iovp
);
1755 assert(i
< iovp
->iod_iovec_s
);
1756 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
1758 offset
-= iovp
->iod_iovec
[i
].iov_size
;
1762 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
1766 do_vir_outsb(dep
->de_data_port
, iovp
->iod_proc_nr
,
1767 iovp
->iod_iovec
[i
].iov_addr
+ offset
, bytes
);
1773 for (i
= 0; i
<100; i
++)
1775 if (inb_reg0(dep
, DP_ISR
) & ISR_RDC
)
1780 panic("", "dp8390: remote dma failed to complete", NO_NUM
);
1784 /*===========================================================================*
1785 * dp_pio8_user2nic_s *
1786 *===========================================================================*/
1787 static void dp_pio8_user2nic_s(dep
, iovp
, offset
, nic_addr
, count
)
1789 iovec_dat_s_t
*iovp
;
1796 outb_reg0(dep
, DP_ISR
, ISR_RDC
);
1798 outb_reg0(dep
, DP_RBCR0
, count
& 0xFF);
1799 outb_reg0(dep
, DP_RBCR1
, count
>> 8);
1800 outb_reg0(dep
, DP_RSAR0
, nic_addr
& 0xFF);
1801 outb_reg0(dep
, DP_RSAR1
, nic_addr
>> 8);
1802 outb_reg0(dep
, DP_CR
, CR_DM_RW
| CR_PS_P0
| CR_STA
);
1809 dp_next_iovec_s(iovp
);
1813 assert(i
< iovp
->iod_iovec_s
);
1814 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
1816 offset
-= iovp
->iod_iovec
[i
].iov_size
;
1820 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
1824 r
= sys_safe_outsb(dep
->de_data_port
, iovp
->iod_proc_nr
,
1825 iovp
->iod_iovec
[i
].iov_grant
, offset
, bytes
);
1829 "dp_pio8_user2nic_s: sys_safe_outsb failed",
1837 for (i
= 0; i
<100; i
++)
1839 if (inb_reg0(dep
, DP_ISR
) & ISR_RDC
)
1844 panic("", "dp8390: remote dma failed to complete", NO_NUM
);
1848 /*===========================================================================*
1849 * dp_pio16_user2nic *
1850 *===========================================================================*/
1851 static void dp_pio16_user2nic(dep
, iovp
, offset
, nic_addr
, count
)
1860 int i
, r
, bytes
, user_proc
;
1864 ecount
= (count
+1) & ~1;
1867 outb_reg0(dep
, DP_ISR
, ISR_RDC
);
1868 outb_reg0(dep
, DP_RBCR0
, ecount
& 0xFF);
1869 outb_reg0(dep
, DP_RBCR1
, ecount
>> 8);
1870 outb_reg0(dep
, DP_RSAR0
, nic_addr
& 0xFF);
1871 outb_reg0(dep
, DP_RSAR1
, nic_addr
>> 8);
1872 outb_reg0(dep
, DP_CR
, CR_DM_RW
| CR_PS_P0
| CR_STA
);
1879 dp_next_iovec(iovp
);
1883 assert(i
< iovp
->iod_iovec_s
);
1884 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
1886 offset
-= iovp
->iod_iovec
[i
].iov_size
;
1890 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
1894 user_proc
= iovp
->iod_proc_nr
;
1895 vir_user
= iovp
->iod_iovec
[i
].iov_addr
+ offset
;
1898 r
= sys_vircopy(user_proc
, D
, vir_user
,
1899 SELF
, D
, (vir_bytes
)&two_bytes
[1], 1);
1903 "dp_pio16_user2nic: sys_vircopy failed",
1906 outw(dep
->de_data_port
, *(u16_t
*)two_bytes
);
1918 do_vir_outsw(dep
->de_data_port
, user_proc
, vir_user
,
1928 r
= sys_vircopy(user_proc
, D
, vir_user
,
1929 SELF
, D
, (vir_bytes
)&two_bytes
[0], 1);
1933 "dp_pio16_user2nic: sys_vircopy failed",
1946 outw(dep
->de_data_port
, *(u16_t
*)two_bytes
);
1948 for (i
= 0; i
<100; i
++)
1950 if (inb_reg0(dep
, DP_ISR
) & ISR_RDC
)
1955 panic("", "dp8390: remote dma failed to complete", NO_NUM
);
1959 /*===========================================================================*
1960 * dp_pio16_user2nic_s *
1961 *===========================================================================*/
1962 static void dp_pio16_user2nic_s(dep
, iovp
, offset
, nic_addr
, count
)
1964 iovec_dat_s_t
*iovp
;
1971 int i
, r
, bytes
, user_proc
;
1975 ecount
= (count
+1) & ~1;
1978 outb_reg0(dep
, DP_ISR
, ISR_RDC
);
1979 outb_reg0(dep
, DP_RBCR0
, ecount
& 0xFF);
1980 outb_reg0(dep
, DP_RBCR1
, ecount
>> 8);
1981 outb_reg0(dep
, DP_RSAR0
, nic_addr
& 0xFF);
1982 outb_reg0(dep
, DP_RSAR1
, nic_addr
>> 8);
1983 outb_reg0(dep
, DP_CR
, CR_DM_RW
| CR_PS_P0
| CR_STA
);
1990 dp_next_iovec_s(iovp
);
1994 assert(i
< iovp
->iod_iovec_s
);
1995 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
1997 offset
-= iovp
->iod_iovec
[i
].iov_size
;
2001 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
2005 user_proc
= iovp
->iod_proc_nr
;
2006 gid
= iovp
->iod_iovec
[i
].iov_grant
;
2009 r
= sys_safecopyfrom(user_proc
, gid
, offset
,
2010 (vir_bytes
)&two_bytes
[1], 1, D
);
2014 "dp_pio16_user2nic: sys_safecopyfrom failed",
2017 outw(dep
->de_data_port
, *(u16_t
*)two_bytes
);
2028 r
= sys_safe_outsw(dep
->de_data_port
, user_proc
,
2029 gid
, offset
, ecount
);
2033 "dp_pio16_user2nic: sys_safe_outsw failed",
2043 r
= sys_safecopyfrom(user_proc
, gid
, offset
,
2044 (vir_bytes
)&two_bytes
[0], 1, D
);
2048 "dp_pio16_user2nic: sys_safecopyfrom failed",
2060 outw(dep
->de_data_port
, *(u16_t
*)two_bytes
);
2062 for (i
= 0; i
<100; i
++)
2064 if (inb_reg0(dep
, DP_ISR
) & ISR_RDC
)
2069 panic("", "dp8390: remote dma failed to complete", NO_NUM
);
2073 /*===========================================================================*
2075 *===========================================================================*/
2076 static void dp_nic2user(dep
, nic_addr
, iovp
, offset
, count
)
2085 vir_bytes vir_hw
= (vir_bytes
) (dep
->de_locmem
+ nic_addr
);
2092 dp_next_iovec(iovp
);
2096 assert(i
< iovp
->iod_iovec_s
);
2097 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
2099 offset
-= iovp
->iod_iovec
[i
].iov_size
;
2103 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
2107 r
= sys_vircopy(SELF
, D
, vir_hw
,
2108 iovp
->iod_proc_nr
, D
,
2109 iovp
->iod_iovec
[i
].iov_addr
+ offset
, bytes
);
2111 panic("DP8390", "dp_nic2user: sys_vircopy failed", r
);
2120 /*===========================================================================*
2122 *===========================================================================*/
2123 static void dp_nic2user_s(dep
, nic_addr
, iovp
, offset
, count
)
2126 iovec_dat_s_t
*iovp
;
2133 vir_hw
= (vir_bytes
)dep
->de_locmem
+ nic_addr
;
2140 dp_next_iovec_s(iovp
);
2144 assert(i
< iovp
->iod_iovec_s
);
2145 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
2147 offset
-= iovp
->iod_iovec
[i
].iov_size
;
2151 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
2155 r
= sys_safecopyto(iovp
->iod_proc_nr
,
2156 iovp
->iod_iovec
[i
].iov_grant
, offset
,
2160 "dp_nic2user_s: sys_safecopyto failed", r
);
2169 /*===========================================================================*
2170 * dp_pio8_nic2user *
2171 *===========================================================================*/
2172 static void dp_pio8_nic2user(dep
, nic_addr
, iovp
, offset
, count
)
2181 outb_reg0(dep
, DP_RBCR0
, count
& 0xFF);
2182 outb_reg0(dep
, DP_RBCR1
, count
>> 8);
2183 outb_reg0(dep
, DP_RSAR0
, nic_addr
& 0xFF);
2184 outb_reg0(dep
, DP_RSAR1
, nic_addr
>> 8);
2185 outb_reg0(dep
, DP_CR
, CR_DM_RR
| CR_PS_P0
| CR_STA
);
2192 dp_next_iovec(iovp
);
2196 assert(i
< iovp
->iod_iovec_s
);
2197 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
2199 offset
-= iovp
->iod_iovec
[i
].iov_size
;
2203 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
2207 do_vir_insb(dep
->de_data_port
, iovp
->iod_proc_nr
,
2208 iovp
->iod_iovec
[i
].iov_addr
+ offset
, bytes
);
2215 /*===========================================================================*
2216 * dp_pio8_nic2user_s *
2217 *===========================================================================*/
2218 static void dp_pio8_nic2user_s(dep
, nic_addr
, iovp
, offset
, count
)
2221 iovec_dat_s_t
*iovp
;
2227 outb_reg0(dep
, DP_RBCR0
, count
& 0xFF);
2228 outb_reg0(dep
, DP_RBCR1
, count
>> 8);
2229 outb_reg0(dep
, DP_RSAR0
, nic_addr
& 0xFF);
2230 outb_reg0(dep
, DP_RSAR1
, nic_addr
>> 8);
2231 outb_reg0(dep
, DP_CR
, CR_DM_RR
| CR_PS_P0
| CR_STA
);
2238 dp_next_iovec_s(iovp
);
2242 assert(i
< iovp
->iod_iovec_s
);
2243 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
2245 offset
-= iovp
->iod_iovec
[i
].iov_size
;
2249 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
2253 r
= sys_safe_insb(dep
->de_data_port
, iovp
->iod_proc_nr
,
2254 iovp
->iod_iovec
[i
].iov_grant
, offset
, bytes
);
2258 "dp_pio8_nic2user_s: sys_safe_insb failed", r
);
2266 /*===========================================================================*
2267 * dp_pio16_nic2user *
2268 *===========================================================================*/
2269 static void dp_pio16_nic2user(dep
, nic_addr
, iovp
, offset
, count
)
2278 int i
, r
, bytes
, user_proc
;
2282 ecount
= (count
+1) & ~1;
2285 outb_reg0(dep
, DP_RBCR0
, ecount
& 0xFF);
2286 outb_reg0(dep
, DP_RBCR1
, ecount
>> 8);
2287 outb_reg0(dep
, DP_RSAR0
, nic_addr
& 0xFF);
2288 outb_reg0(dep
, DP_RSAR1
, nic_addr
>> 8);
2289 outb_reg0(dep
, DP_CR
, CR_DM_RR
| CR_PS_P0
| CR_STA
);
2296 dp_next_iovec(iovp
);
2300 assert(i
< iovp
->iod_iovec_s
);
2301 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
2303 offset
-= iovp
->iod_iovec
[i
].iov_size
;
2307 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
2311 user_proc
= iovp
->iod_proc_nr
;
2312 vir_user
= iovp
->iod_iovec
[i
].iov_addr
+ offset
;
2315 r
= sys_vircopy(SELF
, D
, (vir_bytes
)&two_bytes
[1],
2316 user_proc
, D
, vir_user
, 1);
2320 "dp_pio16_nic2user: sys_vircopy failed",
2334 do_vir_insw(dep
->de_data_port
, user_proc
, vir_user
,
2344 *(u16_t
*)two_bytes
= inw(dep
->de_data_port
);
2345 r
= sys_vircopy(SELF
, D
, (vir_bytes
)&two_bytes
[0],
2346 user_proc
, D
, vir_user
, 1);
2350 "dp_pio16_nic2user: sys_vircopy failed",
2363 /*===========================================================================*
2364 * dp_pio16_nic2user_s *
2365 *===========================================================================*/
2366 static void dp_pio16_nic2user_s(dep
, nic_addr
, iovp
, offset
, count
)
2369 iovec_dat_s_t
*iovp
;
2375 int i
, r
, bytes
, user_proc
;
2379 ecount
= (count
+1) & ~1;
2382 outb_reg0(dep
, DP_RBCR0
, ecount
& 0xFF);
2383 outb_reg0(dep
, DP_RBCR1
, ecount
>> 8);
2384 outb_reg0(dep
, DP_RSAR0
, nic_addr
& 0xFF);
2385 outb_reg0(dep
, DP_RSAR1
, nic_addr
>> 8);
2386 outb_reg0(dep
, DP_CR
, CR_DM_RR
| CR_PS_P0
| CR_STA
);
2393 dp_next_iovec_s(iovp
);
2397 assert(i
< iovp
->iod_iovec_s
);
2398 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
2400 offset
-= iovp
->iod_iovec
[i
].iov_size
;
2404 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
2408 user_proc
= iovp
->iod_proc_nr
;
2409 gid
= iovp
->iod_iovec
[i
].iov_grant
;
2412 r
= sys_safecopyto(user_proc
, gid
, offset
,
2413 (vir_bytes
)&two_bytes
[1], 1, D
);
2417 "dp_pio16_nic2user: sys_safecopyto failed",
2430 r
= sys_safe_insw(dep
->de_data_port
, user_proc
, gid
,
2435 "dp_pio16_nic2user: sys_safe_insw failed",
2445 *(u16_t
*)two_bytes
= inw(dep
->de_data_port
);
2446 r
= sys_safecopyto(user_proc
, gid
, offset
,
2447 (vir_bytes
)&two_bytes
[0], 1, D
);
2451 "dp_pio16_nic2user: sys_safecopyto failed",
2463 /*===========================================================================*
2465 *===========================================================================*/
2466 static void dp_next_iovec(iovp
)
2469 assert(iovp
->iod_iovec_s
> IOVEC_NR
);
2471 iovp
->iod_iovec_s
-= IOVEC_NR
;
2473 iovp
->iod_iovec_addr
+= IOVEC_NR
* sizeof(iovec_t
);
2475 get_userdata(iovp
->iod_proc_nr
, iovp
->iod_iovec_addr
,
2476 (iovp
->iod_iovec_s
> IOVEC_NR
? IOVEC_NR
: iovp
->iod_iovec_s
) *
2477 sizeof(iovec_t
), iovp
->iod_iovec
);
2480 /*===========================================================================*
2482 *===========================================================================*/
2483 static void dp_next_iovec_s(iovp
)
2484 iovec_dat_s_t
*iovp
;
2486 assert(iovp
->iod_iovec_s
> IOVEC_NR
);
2488 iovp
->iod_iovec_s
-= IOVEC_NR
;
2490 iovp
->iod_iovec_offset
+= IOVEC_NR
* sizeof(iovec_t
);
2492 get_userdata_s(iovp
->iod_proc_nr
, iovp
->iod_grant
,
2493 iovp
->iod_iovec_offset
,
2494 (iovp
->iod_iovec_s
> IOVEC_NR
? IOVEC_NR
: iovp
->iod_iovec_s
) *
2495 sizeof(iovp
->iod_iovec
[0]), iovp
->iod_iovec
);
2498 /*===========================================================================*
2500 *===========================================================================*/
2501 static void conf_hw(dep
)
2504 static eth_stat_t empty_stat
= {0, 0, 0, 0, 0, 0 /* ,... */ };
2509 dep
->de_mode
= DEM_DISABLED
; /* Superfluous */
2512 dcp
= &dp_conf
[ifnr
];
2513 update_conf(dep
, dcp
);
2514 if (dep
->de_mode
!= DEM_ENABLED
)
2516 if (!wdeth_probe(dep
) && !ne_probe(dep
) && !el2_probe(dep
))
2518 printf("%s: No ethernet card found at 0x%x\n",
2519 dep
->de_name
, dep
->de_base_port
);
2520 dep
->de_mode
= DEM_DISABLED
;
2524 /* XXX */ if (dep
->de_linmem
== 0) dep
->de_linmem
= 0xFFFF0000;
2526 dep
->de_flags
= DEF_EMPTY
;
2527 dep
->de_stat
= empty_stat
;
2530 /*===========================================================================*
2532 *===========================================================================*/
2533 static void update_conf(dep
, dcp
)
2538 static char dpc_fmt
[] = "x:d:x:x";
2543 if (dep
->de_pci
== 1)
2545 /* PCI device is present */
2546 dep
->de_mode
= DEM_ENABLED
;
2548 return; /* Already configured */
2552 /* Get the default settings and modify them from the environment. */
2553 dep
->de_mode
= DEM_SINK
;
2555 switch (env_parse(dcp
->dpc_envvar
, dpc_fmt
, 0, &v
, 0x0000L
, 0xFFFFL
)) {
2557 dep
->de_mode
= DEM_DISABLED
;
2561 dep
->de_mode
= DEM_ENABLED
; /* Might become disabled if
2562 * all probes fail */
2565 dep
->de_base_port
= v
;
2567 v
= dcp
->dpc_irq
| DEI_DEFAULT
;
2568 (void) env_parse(dcp
->dpc_envvar
, dpc_fmt
, 1, &v
, 0L,
2569 (long) NR_IRQ_VECTORS
- 1);
2573 (void) env_parse(dcp
->dpc_envvar
, dpc_fmt
, 2, &v
, 0L, 0xFFFFFL
);
2577 (void) env_parse(dcp
->dpc_envvar
, dpc_fmt
, 3, &v
, 0x2000L
, 0x8000L
);
2581 /*===========================================================================*
2583 *===========================================================================*/
2584 static void map_hw_buffer(dep
)
2591 if (dep
->de_prog_IO
)
2595 "map_hw_buffer: programmed I/O, no need to map buffer\n");
2597 dep
->de_locmem
= (char *)-dep
->de_ramsize
; /* trap errors */
2601 size
= dep
->de_ramsize
+ I386_PAGE_SIZE
; /* Add I386_PAGE_SIZE for
2606 panic(__FILE__
, "map_hw_buffer: cannot malloc size", size
);
2607 o
= I386_PAGE_SIZE
- ((vir_bytes
)buf
% I386_PAGE_SIZE
);
2609 printf("buf at 0x%x, abuf at 0x%x\n", buf
, abuf
);
2612 r
= sys_vm_map(SELF
, 1 /* map */, (vir_bytes
)abuf
,
2613 dep
->de_ramsize
, (phys_bytes
)dep
->de_linmem
);
2618 panic(__FILE__
, "map_hw_buffer: sys_vm_map failed", r
);
2619 dep
->de_locmem
= abuf
;
2622 /*===========================================================================*
2624 *===========================================================================*/
2625 static int calc_iovec_size(iovp
)
2628 /* Calculate the size of a request. Note that the iovec_dat
2629 * structure will be unusable after calc_iovec_size.
2636 while (i
< iovp
->iod_iovec_s
)
2640 dp_next_iovec(iovp
);
2644 size
+= iovp
->iod_iovec
[i
].iov_size
;
2650 /*===========================================================================*
2651 * calc_iovec_size_s *
2652 *===========================================================================*/
2653 static int calc_iovec_size_s(iovp
)
2654 iovec_dat_s_t
*iovp
;
2656 /* Calculate the size of a request. Note that the iovec_dat
2657 * structure will be unusable after calc_iovec_size_s.
2664 while (i
< iovp
->iod_iovec_s
)
2668 dp_next_iovec_s(iovp
);
2672 size
+= iovp
->iod_iovec
[i
].iov_size
;
2678 /*===========================================================================*
2680 *===========================================================================*/
2681 static void reply(dep
, err
, may_block
)
2691 if (dep
->de_flags
& DEF_PACK_SEND
)
2692 status
|= DL_PACK_SEND
;
2693 if (dep
->de_flags
& DEF_PACK_RECV
)
2694 status
|= DL_PACK_RECV
;
2696 reply
.m_type
= DL_TASK_REPLY
;
2697 reply
.DL_PORT
= dep
- de_table
;
2698 reply
.DL_PROC
= dep
->de_client
;
2699 reply
.DL_STAT
= status
| ((u32_t
) err
<< 16);
2700 reply
.DL_COUNT
= dep
->de_read_s
;
2701 reply
.DL_CLCK
= 0; /* Don't know */
2702 r
= send(dep
->de_client
, &reply
);
2704 if (r
== ELOCKED
&& may_block
)
2707 printf("send locked\n");
2713 panic("", "dp8390: send failed:", r
);
2716 dep
->de_flags
&= ~(DEF_PACK_SEND
| DEF_PACK_RECV
);
2719 /*===========================================================================*
2721 *===========================================================================*/
2722 static void mess_reply(req
, reply_mess
)
2724 message
*reply_mess
;
2726 if (send(req
->m_source
, reply_mess
) != OK
)
2727 panic("", "dp8390: unable to mess_reply", NO_NUM
);
2730 /*===========================================================================*
2732 *===========================================================================*/
2733 static void get_userdata(user_proc
, user_addr
, count
, loc_addr
)
2735 vir_bytes user_addr
;
2741 r
= sys_vircopy(user_proc
, D
, user_addr
,
2742 SELF
, D
, (vir_bytes
)loc_addr
, count
);
2744 panic("DP8390", "get_userdata: sys_vircopy failed", r
);
2747 /*===========================================================================*
2749 *===========================================================================*/
2750 static void get_userdata_s(user_proc
, grant
, offset
, count
, loc_addr
)
2752 cp_grant_id_t grant
;
2759 r
= sys_safecopyfrom(user_proc
, grant
, offset
,
2760 (vir_bytes
)loc_addr
, count
, D
);
2762 panic("DP8390", "get_userdata: sys_safecopyfrom failed", r
);
2765 /*===========================================================================*
2767 *===========================================================================*/
2768 static void put_userdata(user_proc
, user_addr
, count
, loc_addr
)
2770 vir_bytes user_addr
;
2776 r
= sys_vircopy(SELF
, D
, (vir_bytes
)loc_addr
,
2777 user_proc
, D
, user_addr
, count
);
2779 panic("DP8390", "put_userdata: sys_vircopy failed", r
);
2782 /*===========================================================================*
2784 *===========================================================================*/
2785 static void put_userdata_s(user_proc
, grant
, count
, loc_addr
)
2787 cp_grant_id_t grant
;
2793 r
= sys_safecopyto(user_proc
, grant
, 0, (vir_bytes
)loc_addr
,
2796 panic("DP8390", "put_userdata: sys_safecopyto failed", r
);
2799 u8_t
inb(port_t port
)
2804 r
= sys_inb(port
, &value
);
2807 printf("inb failed for port 0x%x\n", port
);
2808 panic("DP8390","sys_inb failed", r
);
2813 u16_t
inw(port_t port
)
2816 unsigned long value
;
2818 r
= sys_inw(port
, &value
);
2820 panic("DP8390", "sys_inw failed", r
);
2821 return (u16_t
) value
;
2824 void outb(port_t port
, u8_t value
)
2828 r
= sys_outb(port
, value
);
2830 panic("DP8390", "sys_outb failed", r
);
2833 void outw(port_t port
, u16_t value
)
2837 r
= sys_outw(port
, value
);
2839 panic("DP8390", "sys_outw failed", r
);
2842 static void insb(port_t port
, void *buf
, size_t size
)
2844 do_vir_insb(port
, SELF
, (vir_bytes
)buf
, size
);
2847 static void insw(port_t port
, void *buf
, size_t size
)
2849 do_vir_insw(port
, SELF
, (vir_bytes
)buf
, size
);
2852 static void do_vir_insb(port_t port
, int proc
, vir_bytes buf
, size_t size
)
2856 r
= sys_insb(port
, proc
, (void *) buf
, size
);
2858 panic("DP8390", "sys_sdevio failed", r
);
2861 static void do_vir_insw(port_t port
, int proc
, vir_bytes buf
, size_t size
)
2865 r
= sys_insw(port
, proc
, (void *) buf
, size
);
2867 panic("DP8390", "sys_sdevio failed", r
);
2870 static void do_vir_outsb(port_t port
, int proc
, vir_bytes buf
, size_t size
)
2874 r
= sys_outsb(port
, proc
, (void *) buf
, size
);
2876 panic("DP8390", "sys_sdevio failed", r
);
2879 static void do_vir_outsw(port_t port
, int proc
, vir_bytes buf
, size_t size
)
2883 r
= sys_outsw(port
, proc
, (void *) buf
, size
);
2885 panic("DP8390", "sys_sdevio failed", r
);
2889 * $PchId: dp8390.c,v 1.25 2005/02/10 17:32:07 philip Exp $