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 <minix/drivers.h>
56 #include <minix/netdriver.h>
59 #include <minix/com.h>
60 #include <minix/endpoint.h>
63 #include <net/gen/ether.h>
64 #include <net/gen/eth_io.h>
65 #include <machine/vm.h>
73 static dpeth_t de_table
[DE_PORT_NR
];
74 static u16_t eth_ign_proto
;
75 static const char *progname
;
80 typedef struct dp_conf
88 PRIVATE dp_conf_t dp_conf
[]= /* Card addresses */
90 /* I/O port, IRQ, Buffer address, Env. var. */
91 { 0x280, 3, 0xD0000, "DPETH0" },
92 { 0x300, 5, 0xC8000, "DPETH1" },
93 { 0x380, 10, 0xD8000, "DPETH2" },
96 /* Test if dp_conf has exactly DE_PORT_NR entries. If not then you will see
97 * the error: "array size is negative".
99 extern int ___dummy
[DE_PORT_NR
== sizeof(dp_conf
)/sizeof(dp_conf
[0]) ? 1 : -1];
101 /* Card inits configured out? */
103 #define wdeth_probe(dep) (0)
106 #define ne_probe(dep) (0)
109 #define el2_probe(dep) (0)
112 /* Some clones of the dp8390 and the PC emulator 'Bochs' require the CR_STA
113 * on writes to the CR register. Additional CR_STAs do not appear to hurt
116 #define CR_EXTRA CR_STA
119 _PROTOTYPE( static void pci_conf
, (void) );
121 _PROTOTYPE( static void do_vwrite
, (message
*mp
, int from_int
,
123 _PROTOTYPE( static void do_vwrite_s
, (message
*mp
, int from_int
) );
124 _PROTOTYPE( static void do_vread
, (message
*mp
, int vectored
) );
125 _PROTOTYPE( static void do_vread_s
, (message
*mp
) );
126 _PROTOTYPE( static void do_init
, (message
*mp
) );
127 _PROTOTYPE( static void do_int
, (dpeth_t
*dep
) );
128 _PROTOTYPE( static void do_getstat
, (message
*mp
) );
129 _PROTOTYPE( static void do_getstat_s
, (message
*mp
) );
130 _PROTOTYPE( static void do_getname
, (message
*mp
) );
131 _PROTOTYPE( static void do_stop
, (message
*mp
) );
132 _PROTOTYPE( static void dp_init
, (dpeth_t
*dep
) );
133 _PROTOTYPE( static void dp_confaddr
, (dpeth_t
*dep
) );
134 _PROTOTYPE( static void dp_reinit
, (dpeth_t
*dep
) );
135 _PROTOTYPE( static void dp_reset
, (dpeth_t
*dep
) );
136 _PROTOTYPE( static void dp_check_ints
, (dpeth_t
*dep
) );
137 _PROTOTYPE( static void dp_recv
, (dpeth_t
*dep
) );
138 _PROTOTYPE( static void dp_send
, (dpeth_t
*dep
) );
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 /* SEF functions and variables. */
207 FORWARD
_PROTOTYPE( void sef_local_startup
, (void) );
208 FORWARD
_PROTOTYPE( int sef_cb_init_fresh
, (int type
, sef_init_info_t
*info
) );
209 FORWARD
_PROTOTYPE( void sef_cb_signal_handler
, (int signo
) );
211 EXTERN
char **env_argv
;
213 PRIVATE
int handle_hw_intr(void)
218 for (i
= 0, dep
= &de_table
[0]; i
<DE_PORT_NR
; i
++, dep
++)
220 if (dep
->de_mode
!= DEM_ENABLED
)
222 assert(dep
->de_flags
& DEF_ENABLED
);
224 assert(irq
>= 0 && irq
< NR_IRQ_VECTORS
);
225 if (dep
->de_int_pending
|| 1)
227 dep
->de_int_pending
= 0;
230 r
= sys_irqenable(&dep
->de_hook
);
232 panic("unable enable interrupts: %d", r
);
240 /*===========================================================================*
242 *===========================================================================*/
243 int main(int argc
, char *argv
[])
249 /* SEF local startup. */
250 env_setargs(argc
, argv
);
255 if ((r
= netdriver_receive(ANY
, &m
, &ipc_status
)) != OK
)
256 panic("dp8390: netdriver_receive failed: %d", r
);
258 if (is_ipc_notify(ipc_status
)) {
259 switch (_ENDPOINT_P(m
.m_source
)) {
261 r
= handle_hw_intr();
264 printf("dp8390: notify from CLOCK\n");
267 panic("dp8390: illegal notify from: %d",
271 /* done, get a new message */
277 case DL_WRITE
: do_vwrite(&m
, FALSE
, FALSE
); break;
278 case DL_WRITEV
: do_vwrite(&m
, FALSE
, TRUE
); break;
279 case DL_WRITEV_S
: do_vwrite_s(&m
, FALSE
); break;
280 case DL_READ
: do_vread(&m
, FALSE
); break;
281 case DL_READV
: do_vread(&m
, TRUE
); break;
282 case DL_READV_S
: do_vread_s(&m
); break;
283 case DL_CONF
: do_init(&m
); break;
284 case DL_GETSTAT
: do_getstat(&m
); break;
285 case DL_GETSTAT_S
: do_getstat_s(&m
); break;
286 case DL_GETNAME
: do_getname(&m
); break;
287 case DL_STOP
: do_stop(&m
); break;
289 panic("dp8390: illegal message: %d", m
.m_type
);
294 /*===========================================================================*
295 * sef_local_startup *
296 *===========================================================================*/
297 PRIVATE
void sef_local_startup()
299 /* Register init callbacks. */
300 sef_setcb_init_fresh(sef_cb_init_fresh
);
301 sef_setcb_init_lu(sef_cb_init_fresh
);
302 sef_setcb_init_restart(sef_cb_init_fresh
);
304 /* Register live update callbacks. */
305 sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready
);
306 sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree
);
308 /* Register signal callbacks. */
309 sef_setcb_signal_handler(sef_cb_signal_handler
);
311 /* Let SEF perform startup. */
315 /*===========================================================================*
316 * sef_cb_init_fresh *
317 *===========================================================================*/
318 PRIVATE
int sef_cb_init_fresh(int type
, sef_init_info_t
*UNUSED(info
))
320 /* Initialize the dp8390 driver. */
325 system_hz
= sys_hz();
328 panic("A head which at this time has no name");
330 (progname
=strrchr(env_argv
[0],'/')) ? progname
++
331 : (progname
=env_argv
[0]);
333 for (i
= 0, dep
= de_table
; i
<DE_PORT_NR
; i
++, dep
++)
335 strcpy(dep
->de_name
, "dp8390#0");
336 dep
->de_name
[7] += i
;
340 (void) env_parse("ETH_IGN_PROTO", "x", 0, &v
, 0x0000L
, 0xFFFFL
);
341 eth_ign_proto
= htons((u16_t
) v
);
343 /* Announce we are up! */
344 netdriver_announce();
349 /*===========================================================================*
350 * sef_cb_signal_handler *
351 *===========================================================================*/
352 PRIVATE
void sef_cb_signal_handler(int signo
)
357 /* Only check for termination signal, ignore anything else. */
358 if (signo
!= SIGTERM
) return;
360 for (i
= 0; i
<DE_PORT_NR
; i
++)
362 if (de_table
[i
].de_mode
!= DEM_ENABLED
)
364 mess
.m_type
= DL_STOP
;
371 /*===========================================================================*
373 *===========================================================================*/
380 for (i
= 0, dep
= &de_table
[0]; i
<DE_PORT_NR
; i
++, dep
++)
383 if (dep
->de_mode
== DEM_DISABLED
)
384 printf("dp8390 port %d is disabled\n", i
);
385 else if (dep
->de_mode
== DEM_SINK
)
386 printf("dp8390 port %d is in sink mode\n", i
);
389 if (dep
->de_mode
!= DEM_ENABLED
)
392 printf("dp8390 statistics of port %d:\n", i
);
394 printf("recvErr :%8ld\t", dep
->de_stat
.ets_recvErr
);
395 printf("sendErr :%8ld\t", dep
->de_stat
.ets_sendErr
);
396 printf("OVW :%8ld\n", dep
->de_stat
.ets_OVW
);
398 printf("CRCerr :%8ld\t", dep
->de_stat
.ets_CRCerr
);
399 printf("frameAll :%8ld\t", dep
->de_stat
.ets_frameAll
);
400 printf("missedP :%8ld\n", dep
->de_stat
.ets_missedP
);
402 printf("packetR :%8ld\t", dep
->de_stat
.ets_packetR
);
403 printf("packetT :%8ld\t", dep
->de_stat
.ets_packetT
);
404 printf("transDef :%8ld\n", dep
->de_stat
.ets_transDef
);
406 printf("collision :%8ld\t", dep
->de_stat
.ets_collision
);
407 printf("transAb :%8ld\t", dep
->de_stat
.ets_transAb
);
408 printf("carrSense :%8ld\n", dep
->de_stat
.ets_carrSense
);
410 printf("fifoUnder :%8ld\t", dep
->de_stat
.ets_fifoUnder
);
411 printf("fifoOver :%8ld\t", dep
->de_stat
.ets_fifoOver
);
412 printf("CDheartbeat:%8ld\n", dep
->de_stat
.ets_CDheartbeat
);
414 printf("OWC :%8ld\t", dep
->de_stat
.ets_OWC
);
416 isr
= inb_reg0(dep
, DP_ISR
);
417 printf("dp_isr = 0x%x + 0x%x, de_flags = 0x%x\n", isr
,
418 inb_reg0(dep
, DP_ISR
), dep
->de_flags
);
424 /*===========================================================================*
426 *===========================================================================*/
427 static void pci_conf()
432 static char envfmt
[] = "*:d.d.d";
434 static int first_time
= 1;
440 for (i
= 0, dep
= de_table
; i
<DE_PORT_NR
; i
++, dep
++)
442 envvar
= dp_conf
[i
].dpc_envvar
;
443 if (!(dep
->de_pci
= env_prefix(envvar
, "pci")))
444 continue; /* no PCI config */
446 (void) env_parse(envvar
, envfmt
, 1, &v
, 0, 255);
449 (void) env_parse(envvar
, envfmt
, 2, &v
, 0, 255);
452 (void) env_parse(envvar
, envfmt
, 3, &v
, 0, 255);
456 for (h
= 1; h
>= 0; h
--) {
457 for (i
= 0, dep
= de_table
; i
<DE_PORT_NR
; i
++, dep
++)
461 printf("pci: no pci for port %d\n", i
);
464 if (((dep
->de_pcibus
| dep
->de_pcidev
|
465 dep
->de_pcifunc
) != 0) != h
)
474 #endif /* ENABLE_PCI */
476 /*===========================================================================*
478 *===========================================================================*/
479 static void do_vwrite(mp
, from_int
, vectored
)
484 int port
, count
, size
;
489 count
= mp
->DL_COUNT
;
490 if (port
< 0 || port
>= DE_PORT_NR
)
491 panic("dp8390: illegal port: %d", port
);
492 dep
= &de_table
[port
];
493 dep
->de_client
= mp
->DL_PROC
;
495 if (dep
->de_mode
== DEM_SINK
)
498 dep
->de_flags
|= DEF_PACK_SEND
;
499 reply(dep
, OK
, FALSE
);
502 assert(dep
->de_mode
== DEM_ENABLED
);
503 assert(dep
->de_flags
& DEF_ENABLED
);
504 if (dep
->de_flags
& DEF_SEND_AVAIL
)
505 panic("dp8390: send already in progress");
507 sendq_head
= dep
->de_sendq_head
;
508 if (dep
->de_sendq
[sendq_head
].sq_filled
)
511 panic("dp8390: should not be sending");
512 dep
->de_sendmsg
= *mp
;
513 dep
->de_flags
|= DEF_SEND_AVAIL
;
514 reply(dep
, OK
, FALSE
);
517 assert(!(dep
->de_flags
& DEF_PACK_SEND
));
521 get_userdata(mp
->DL_PROC
, (vir_bytes
) mp
->DL_ADDR
,
522 (count
> IOVEC_NR
? IOVEC_NR
: count
) *
523 sizeof(iovec_t
), dep
->de_write_iovec
.iod_iovec
);
524 dep
->de_write_iovec
.iod_iovec_s
= count
;
525 dep
->de_write_iovec
.iod_proc_nr
= mp
->DL_PROC
;
526 dep
->de_write_iovec
.iod_iovec_addr
= (vir_bytes
) mp
->DL_ADDR
;
528 dep
->de_tmp_iovec
= dep
->de_write_iovec
;
529 size
= calc_iovec_size(&dep
->de_tmp_iovec
);
533 dep
->de_write_iovec
.iod_iovec
[0].iov_addr
=
534 (vir_bytes
) mp
->DL_ADDR
;
535 dep
->de_write_iovec
.iod_iovec
[0].iov_size
=
537 dep
->de_write_iovec
.iod_iovec_s
= 1;
538 dep
->de_write_iovec
.iod_proc_nr
= mp
->DL_PROC
;
539 dep
->de_write_iovec
.iod_iovec_addr
= 0;
542 if (size
< ETH_MIN_PACK_SIZE
|| size
> ETH_MAX_PACK_SIZE_TAGGED
)
544 panic("dp8390: invalid packet size: %d", size
);
546 (dep
->de_user2nicf
)(dep
, &dep
->de_write_iovec
, 0,
547 dep
->de_sendq
[sendq_head
].sq_sendpage
* DP_PAGESIZE
,
549 dep
->de_sendq
[sendq_head
].sq_filled
= TRUE
;
550 if (dep
->de_sendq_tail
== sendq_head
)
552 outb_reg0(dep
, DP_TPSR
, dep
->de_sendq
[sendq_head
].sq_sendpage
);
553 outb_reg0(dep
, DP_TBCR1
, size
>> 8);
554 outb_reg0(dep
, DP_TBCR0
, size
& 0xff);
555 outb_reg0(dep
, DP_CR
, CR_TXP
| CR_EXTRA
);/* there it goes.. */
558 dep
->de_sendq
[sendq_head
].sq_size
= size
;
560 if (++sendq_head
== dep
->de_sendq_nr
)
562 assert(sendq_head
< SENDQ_NR
);
563 dep
->de_sendq_head
= sendq_head
;
565 dep
->de_flags
|= DEF_PACK_SEND
;
567 /* If the interrupt handler called, don't send a reply. The reply
568 * will be sent after all interrupts are handled.
572 reply(dep
, OK
, FALSE
);
574 assert(dep
->de_mode
== DEM_ENABLED
);
575 assert(dep
->de_flags
& DEF_ENABLED
);
578 /*===========================================================================*
580 *===========================================================================*/
581 static void do_vwrite_s(mp
, from_int
)
585 int port
, count
, size
;
590 count
= mp
->DL_COUNT
;
591 if (port
< 0 || port
>= DE_PORT_NR
)
592 panic("dp8390: illegal port: %d", port
);
593 dep
= &de_table
[port
];
594 dep
->de_client
= mp
->DL_PROC
;
596 if (dep
->de_mode
== DEM_SINK
)
599 dep
->de_flags
|= DEF_PACK_SEND
;
600 reply(dep
, OK
, FALSE
);
603 assert(dep
->de_mode
== DEM_ENABLED
);
604 assert(dep
->de_flags
& DEF_ENABLED
);
605 if (dep
->de_flags
& DEF_SEND_AVAIL
)
606 panic("dp8390: send already in progress");
608 sendq_head
= dep
->de_sendq_head
;
609 if (dep
->de_sendq
[sendq_head
].sq_filled
)
612 panic("dp8390: should not be sending");
613 dep
->de_sendmsg
= *mp
;
614 dep
->de_flags
|= DEF_SEND_AVAIL
;
615 reply(dep
, OK
, FALSE
);
618 assert(!(dep
->de_flags
& DEF_PACK_SEND
));
620 get_userdata_s(mp
->DL_PROC
, mp
->DL_GRANT
, 0,
621 (count
> IOVEC_NR
? IOVEC_NR
: count
) *
622 sizeof(dep
->de_write_iovec_s
.iod_iovec
[0]),
623 dep
->de_write_iovec_s
.iod_iovec
);
624 dep
->de_write_iovec_s
.iod_iovec_s
= count
;
625 dep
->de_write_iovec_s
.iod_proc_nr
= mp
->DL_PROC
;
626 dep
->de_write_iovec_s
.iod_grant
= mp
->DL_GRANT
;
627 dep
->de_write_iovec_s
.iod_iovec_offset
= 0;
629 dep
->de_tmp_iovec_s
= dep
->de_write_iovec_s
;
630 size
= calc_iovec_size_s(&dep
->de_tmp_iovec_s
);
632 if (size
< ETH_MIN_PACK_SIZE
|| size
> ETH_MAX_PACK_SIZE_TAGGED
)
634 panic("dp8390: invalid packet size: %d", size
);
636 (dep
->de_user2nicf_s
)(dep
, &dep
->de_write_iovec_s
, 0,
637 dep
->de_sendq
[sendq_head
].sq_sendpage
* DP_PAGESIZE
,
639 dep
->de_sendq
[sendq_head
].sq_filled
= TRUE
;
640 if (dep
->de_sendq_tail
== sendq_head
)
642 outb_reg0(dep
, DP_TPSR
, dep
->de_sendq
[sendq_head
].sq_sendpage
);
643 outb_reg0(dep
, DP_TBCR1
, size
>> 8);
644 outb_reg0(dep
, DP_TBCR0
, size
& 0xff);
645 outb_reg0(dep
, DP_CR
, CR_TXP
| CR_EXTRA
);/* there it goes.. */
648 dep
->de_sendq
[sendq_head
].sq_size
= size
;
650 if (++sendq_head
== dep
->de_sendq_nr
)
652 assert(sendq_head
< SENDQ_NR
);
653 dep
->de_sendq_head
= sendq_head
;
655 dep
->de_flags
|= DEF_PACK_SEND
;
657 /* If the interrupt handler called, don't send a reply. The reply
658 * will be sent after all interrupts are handled.
662 reply(dep
, OK
, FALSE
);
664 assert(dep
->de_mode
== DEM_ENABLED
);
665 assert(dep
->de_flags
& DEF_ENABLED
);
668 /*===========================================================================*
670 *===========================================================================*/
671 static void do_vread(mp
, vectored
)
680 count
= mp
->DL_COUNT
;
681 if (port
< 0 || port
>= DE_PORT_NR
)
682 panic("dp8390: illegal port: %d", port
);
683 dep
= &de_table
[port
];
684 dep
->de_client
= mp
->DL_PROC
;
685 if (dep
->de_mode
== DEM_SINK
)
687 reply(dep
, OK
, FALSE
);
690 assert(dep
->de_mode
== DEM_ENABLED
);
691 assert(dep
->de_flags
& DEF_ENABLED
);
693 if(dep
->de_flags
& DEF_READING
)
694 panic("dp8390: read already in progress");
696 dep
->de_safecopy_read
= 0;
700 get_userdata(mp
->DL_PROC
, (vir_bytes
) mp
->DL_ADDR
,
701 (count
> IOVEC_NR
? IOVEC_NR
: count
) *
702 sizeof(iovec_t
), dep
->de_read_iovec
.iod_iovec
);
703 dep
->de_read_iovec
.iod_iovec_s
= count
;
704 dep
->de_read_iovec
.iod_proc_nr
= mp
->DL_PROC
;
705 dep
->de_read_iovec
.iod_iovec_addr
= (vir_bytes
) mp
->DL_ADDR
;
707 dep
->de_tmp_iovec
= dep
->de_read_iovec
;
708 size
= calc_iovec_size(&dep
->de_tmp_iovec
);
712 dep
->de_read_iovec
.iod_iovec
[0].iov_addr
=
713 (vir_bytes
) mp
->DL_ADDR
;
714 dep
->de_read_iovec
.iod_iovec
[0].iov_size
=
716 dep
->de_read_iovec
.iod_iovec_s
= 1;
717 dep
->de_read_iovec
.iod_proc_nr
= mp
->DL_PROC
;
718 dep
->de_read_iovec
.iod_iovec_addr
= 0;
721 if (size
< ETH_MAX_PACK_SIZE_TAGGED
)
722 panic("dp8390: wrong packet size: %d", size
);
723 dep
->de_flags
|= DEF_READING
;
727 if ((dep
->de_flags
& (DEF_READING
|DEF_STOPPED
)) ==
728 (DEF_READING
|DEF_STOPPED
))
730 /* The chip is stopped, and all arrived packets are
735 reply(dep
, OK
, FALSE
);
738 /*===========================================================================*
740 *===========================================================================*/
741 static void do_vread_s(mp
)
749 count
= mp
->DL_COUNT
;
750 if (port
< 0 || port
>= DE_PORT_NR
)
751 panic("dp8390: illegal port: %d", port
);
752 dep
= &de_table
[port
];
753 dep
->de_client
= mp
->DL_PROC
;
754 if (dep
->de_mode
== DEM_SINK
)
756 reply(dep
, OK
, FALSE
);
759 assert(dep
->de_mode
== DEM_ENABLED
);
760 assert(dep
->de_flags
& DEF_ENABLED
);
762 dep
->de_safecopy_read
= 1;
764 if(dep
->de_flags
& DEF_READING
)
765 panic("dp8390: read already in progress");
767 get_userdata_s(mp
->DL_PROC
, mp
->DL_GRANT
, 0,
768 (count
> IOVEC_NR
? IOVEC_NR
: count
) *
769 sizeof(dep
->de_read_iovec_s
.iod_iovec
[0]),
770 dep
->de_read_iovec_s
.iod_iovec
);
771 dep
->de_read_iovec_s
.iod_iovec_s
= count
;
772 dep
->de_read_iovec_s
.iod_proc_nr
= mp
->DL_PROC
;
773 dep
->de_read_iovec_s
.iod_grant
= mp
->DL_GRANT
;
774 dep
->de_read_iovec_s
.iod_iovec_offset
= 0;
776 dep
->de_tmp_iovec_s
= dep
->de_read_iovec_s
;
777 size
= calc_iovec_size_s(&dep
->de_tmp_iovec_s
);
779 if (size
< ETH_MAX_PACK_SIZE_TAGGED
)
780 panic("dp8390: wrong packet size: %d", size
);
781 dep
->de_flags
|= DEF_READING
;
785 if ((dep
->de_flags
& (DEF_READING
|DEF_STOPPED
)) ==
786 (DEF_READING
|DEF_STOPPED
))
788 /* The chip is stopped, and all arrived packets are
793 reply(dep
, OK
, FALSE
);
796 /*===========================================================================*
798 *===========================================================================*/
799 static void do_init(message
*mp
)
806 pci_conf(); /* Configure PCI devices. */
810 if (port
< 0 || port
>= DE_PORT_NR
)
812 reply_mess
.m_type
= DL_CONF_REPLY
;
813 reply_mess
.m3_i1
= ENXIO
;
814 mess_reply(mp
, &reply_mess
);
817 dep
= &de_table
[port
];
818 if (dep
->de_mode
== DEM_DISABLED
)
820 /* This is the default, try to (re)locate the device. */
822 if (dep
->de_mode
== DEM_DISABLED
)
824 /* Probe failed, or the device is configured off. */
825 reply_mess
.m_type
= DL_CONF_REPLY
;
826 reply_mess
.m3_i1
= ENXIO
;
827 mess_reply(mp
, &reply_mess
);
830 if (dep
->de_mode
== DEM_ENABLED
)
834 if (dep
->de_mode
== DEM_SINK
)
836 strncpy((char *) dep
->de_address
.ea_addr
, "ZDP", 6);
837 dep
->de_address
.ea_addr
[5] = port
;
839 reply_mess
.m_type
= DL_CONF_REPLY
;
840 reply_mess
.m3_i1
= mp
->DL_PORT
;
841 reply_mess
.m3_i2
= DE_PORT_NR
;
842 *(ether_addr_t
*) reply_mess
.m3_ca1
= dep
->de_address
;
843 mess_reply(mp
, &reply_mess
);
846 assert(dep
->de_mode
== DEM_ENABLED
);
847 assert(dep
->de_flags
& DEF_ENABLED
);
849 dep
->de_flags
&= ~(DEF_PROMISC
| DEF_MULTI
| DEF_BROAD
);
851 if (mp
->DL_MODE
& DL_PROMISC_REQ
)
852 dep
->de_flags
|= DEF_PROMISC
| DEF_MULTI
| DEF_BROAD
;
853 if (mp
->DL_MODE
& DL_MULTI_REQ
)
854 dep
->de_flags
|= DEF_MULTI
;
855 if (mp
->DL_MODE
& DL_BROAD_REQ
)
856 dep
->de_flags
|= DEF_BROAD
;
858 dep
->de_client
= mp
->m_source
;
861 reply_mess
.m_type
= DL_CONF_REPLY
;
862 reply_mess
.m3_i1
= mp
->DL_PORT
;
863 reply_mess
.m3_i2
= DE_PORT_NR
;
864 *(ether_addr_t
*) reply_mess
.m3_ca1
= dep
->de_address
;
866 mess_reply(mp
, &reply_mess
);
869 /*===========================================================================*
871 *===========================================================================*/
872 static void do_int(dep
)
875 if (dep
->de_flags
& (DEF_PACK_SEND
| DEF_PACK_RECV
))
876 reply(dep
, OK
, TRUE
);
879 /*===========================================================================*
881 *===========================================================================*/
882 static void do_getstat(message
*mp
)
888 if (port
< 0 || port
>= DE_PORT_NR
)
889 panic("dp8390: illegal port: %d", port
);
890 dep
= &de_table
[port
];
891 dep
->de_client
= mp
->DL_PROC
;
892 if (dep
->de_mode
== DEM_SINK
)
894 put_userdata(mp
->DL_PROC
, (vir_bytes
) mp
->DL_ADDR
,
895 (vir_bytes
) sizeof(dep
->de_stat
), &dep
->de_stat
);
897 mp
->m_type
= DL_STAT_REPLY
;
900 r
= send(mp
->m_source
, mp
);
902 panic("do_getstat: send failed: %d", r
);
905 assert(dep
->de_mode
== DEM_ENABLED
);
906 assert(dep
->de_flags
& DEF_ENABLED
);
908 dep
->de_stat
.ets_CRCerr
+= inb_reg0(dep
, DP_CNTR0
);
909 dep
->de_stat
.ets_frameAll
+= inb_reg0(dep
, DP_CNTR1
);
910 dep
->de_stat
.ets_missedP
+= inb_reg0(dep
, DP_CNTR2
);
912 put_userdata(mp
->DL_PROC
, (vir_bytes
) mp
->DL_ADDR
,
913 (vir_bytes
) sizeof(dep
->de_stat
), &dep
->de_stat
);
915 mp
->m_type
= DL_STAT_REPLY
;
918 r
= send(mp
->m_source
, mp
);
920 panic("do_getstat: send failed: %d", r
);
923 /*===========================================================================*
925 *===========================================================================*/
926 static void do_getstat_s(mp
)
933 if (port
< 0 || port
>= DE_PORT_NR
)
934 panic("dp8390: illegal port: %d", port
);
935 dep
= &de_table
[port
];
936 dep
->de_client
= mp
->DL_PROC
;
937 if (dep
->de_mode
== DEM_SINK
)
939 put_userdata(mp
->DL_PROC
, (vir_bytes
) mp
->DL_ADDR
,
940 (vir_bytes
) sizeof(dep
->de_stat
), &dep
->de_stat
);
942 mp
->m_type
= DL_STAT_REPLY
;
945 r
= send(mp
->m_source
, mp
);
947 panic("do_getstat: send failed: %d", r
);
950 assert(dep
->de_mode
== DEM_ENABLED
);
951 assert(dep
->de_flags
& DEF_ENABLED
);
953 dep
->de_stat
.ets_CRCerr
+= inb_reg0(dep
, DP_CNTR0
);
954 dep
->de_stat
.ets_frameAll
+= inb_reg0(dep
, DP_CNTR1
);
955 dep
->de_stat
.ets_missedP
+= inb_reg0(dep
, DP_CNTR2
);
957 put_userdata_s(mp
->DL_PROC
, mp
->DL_GRANT
,
958 sizeof(dep
->de_stat
), &dep
->de_stat
);
960 mp
->m_type
= DL_STAT_REPLY
;
963 r
= send(mp
->m_source
, mp
);
965 panic("do_getstat: send failed: %d", r
);
968 /*===========================================================================*
970 *===========================================================================*/
971 static void do_getname(mp
)
976 strncpy(mp
->DL_NAME
, progname
, sizeof(mp
->DL_NAME
));
977 mp
->DL_NAME
[sizeof(mp
->DL_NAME
)-1]= '\0';
978 mp
->m_type
= DL_NAME_REPLY
;
979 r
= send(mp
->m_source
, mp
);
981 panic("do_getname: send failed: %d", r
);
984 /*===========================================================================*
986 *===========================================================================*/
987 static void do_stop(mp
)
995 if (port
< 0 || port
>= DE_PORT_NR
)
996 panic("dp8390: illegal port: %d", port
);
997 dep
= &de_table
[port
];
998 if (dep
->de_mode
== DEM_SINK
)
1000 assert(dep
->de_mode
== DEM_ENABLED
);
1002 if (!(dep
->de_flags
& DEF_ENABLED
))
1005 outb_reg0(dep
, DP_CR
, CR_STP
| CR_DM_ABORT
);
1006 (dep
->de_stopf
)(dep
);
1008 dep
->de_flags
= DEF_EMPTY
;
1011 /*===========================================================================*
1013 *===========================================================================*/
1014 static void dp_init(dep
)
1020 /* General initialization */
1021 dep
->de_flags
= DEF_EMPTY
;
1022 (*dep
->de_initf
)(dep
);
1028 printf("%s: Ethernet address ", dep
->de_name
);
1029 for (i
= 0; i
< 6; i
++)
1030 printf("%x%c", dep
->de_address
.ea_addr
[i
],
1031 i
< 5 ? ':' : '\n');
1037 /* Initialization of the dp8390 following the mandatory procedure
1038 * in reference manual ("DP8390D/NS32490D NIC Network Interface
1039 * Controller", National Semiconductor, July 1995, Page 29).
1042 outb_reg0(dep
, DP_CR
, CR_PS_P0
| CR_STP
| CR_DM_ABORT
);
1045 outb_reg0(dep
, DP_DCR
, DCR_WORDWIDE
| DCR_8BYTES
| DCR_BMS
);
1047 outb_reg0(dep
, DP_DCR
, DCR_BYTEWIDE
| DCR_8BYTES
| DCR_BMS
);
1049 outb_reg0(dep
, DP_RBCR0
, 0);
1050 outb_reg0(dep
, DP_RBCR1
, 0);
1053 if (dep
->de_flags
& DEF_PROMISC
)
1054 dp_rcr_reg
|= RCR_AB
| RCR_PRO
| RCR_AM
;
1055 if (dep
->de_flags
& DEF_BROAD
)
1056 dp_rcr_reg
|= RCR_AB
;
1057 if (dep
->de_flags
& DEF_MULTI
)
1058 dp_rcr_reg
|= RCR_AM
;
1059 outb_reg0(dep
, DP_RCR
, dp_rcr_reg
);
1061 outb_reg0(dep
, DP_TCR
, TCR_INTERNAL
);
1063 outb_reg0(dep
, DP_BNRY
, dep
->de_startpage
);
1064 outb_reg0(dep
, DP_PSTART
, dep
->de_startpage
);
1065 outb_reg0(dep
, DP_PSTOP
, dep
->de_stoppage
);
1067 outb_reg0(dep
, DP_ISR
, 0xFF);
1069 outb_reg0(dep
, DP_IMR
, IMR_PRXE
| IMR_PTXE
| IMR_RXEE
| IMR_TXEE
|
1070 IMR_OVWE
| IMR_CNTE
);
1072 outb_reg0(dep
, DP_CR
, CR_PS_P1
| CR_DM_ABORT
| CR_STP
);
1074 outb_reg1(dep
, DP_PAR0
, dep
->de_address
.ea_addr
[0]);
1075 outb_reg1(dep
, DP_PAR1
, dep
->de_address
.ea_addr
[1]);
1076 outb_reg1(dep
, DP_PAR2
, dep
->de_address
.ea_addr
[2]);
1077 outb_reg1(dep
, DP_PAR3
, dep
->de_address
.ea_addr
[3]);
1078 outb_reg1(dep
, DP_PAR4
, dep
->de_address
.ea_addr
[4]);
1079 outb_reg1(dep
, DP_PAR5
, dep
->de_address
.ea_addr
[5]);
1081 outb_reg1(dep
, DP_MAR0
, 0xff);
1082 outb_reg1(dep
, DP_MAR1
, 0xff);
1083 outb_reg1(dep
, DP_MAR2
, 0xff);
1084 outb_reg1(dep
, DP_MAR3
, 0xff);
1085 outb_reg1(dep
, DP_MAR4
, 0xff);
1086 outb_reg1(dep
, DP_MAR5
, 0xff);
1087 outb_reg1(dep
, DP_MAR6
, 0xff);
1088 outb_reg1(dep
, DP_MAR7
, 0xff);
1090 outb_reg1(dep
, DP_CURR
, dep
->de_startpage
+ 1);
1092 outb_reg0(dep
, DP_CR
, CR_DM_ABORT
| CR_STA
);
1094 outb_reg0(dep
, DP_TCR
, TCR_NORMAL
);
1096 inb_reg0(dep
, DP_CNTR0
); /* reset counters by reading */
1097 inb_reg0(dep
, DP_CNTR1
);
1098 inb_reg0(dep
, DP_CNTR2
);
1100 /* Finish the initialization. */
1101 dep
->de_flags
|= DEF_ENABLED
;
1102 for (i
= 0; i
<dep
->de_sendq_nr
; i
++)
1103 dep
->de_sendq
[i
].sq_filled
= 0;
1104 dep
->de_sendq_head
= 0;
1105 dep
->de_sendq_tail
= 0;
1106 if (!dep
->de_prog_IO
)
1108 dep
->de_user2nicf
= dp_user2nic
;
1109 dep
->de_user2nicf_s
= dp_user2nic_s
;
1110 dep
->de_nic2userf
= dp_nic2user
;
1111 dep
->de_nic2userf_s
= dp_nic2user_s
;
1112 dep
->de_getblockf
= dp_getblock
;
1114 else if (dep
->de_16bit
)
1116 dep
->de_user2nicf
= dp_pio16_user2nic
;
1117 dep
->de_user2nicf_s
= dp_pio16_user2nic_s
;
1118 dep
->de_nic2userf
= dp_pio16_nic2user
;
1119 dep
->de_nic2userf_s
= dp_pio16_nic2user_s
;
1120 dep
->de_getblockf
= dp_pio16_getblock
;
1124 dep
->de_user2nicf
= dp_pio8_user2nic
;
1125 dep
->de_user2nicf_s
= dp_pio8_user2nic_s
;
1126 dep
->de_nic2userf
= dp_pio8_nic2user
;
1127 dep
->de_nic2userf_s
= dp_pio8_nic2user_s
;
1128 dep
->de_getblockf
= dp_pio8_getblock
;
1131 /* Set the interrupt handler and policy. Do not automatically
1132 * reenable interrupts. Return the IRQ line number on interrupts.
1134 dep
->de_hook
= dep
->de_irq
;
1135 r
= sys_irqsetpolicy(dep
->de_irq
, 0, &dep
->de_hook
);
1137 panic("sys_irqsetpolicy failed: %d", r
);
1139 r
= sys_irqenable(&dep
->de_hook
);
1142 panic("unable enable interrupts: %d", r
);
1146 /*===========================================================================*
1148 *===========================================================================*/
1149 static void dp_confaddr(dep
)
1154 static char eafmt
[]= "x:x:x:x:x:x";
1157 /* User defined ethernet address? */
1158 strcpy(eakey
, dp_conf
[dep
-de_table
].dpc_envvar
);
1159 strcat(eakey
, "_EA");
1161 for (i
= 0; i
< 6; i
++)
1163 v
= dep
->de_address
.ea_addr
[i
];
1164 if (env_parse(eakey
, eafmt
, i
, &v
, 0x00L
, 0xFFL
) != EP_SET
)
1168 dep
->de_address
.ea_addr
[i
]= v
;
1171 if (i
!= 0 && i
!= 6) env_panic(eakey
); /* It's all or nothing */
1174 /*===========================================================================*
1176 *===========================================================================*/
1177 static void dp_reinit(dep
)
1182 outb_reg0(dep
, DP_CR
, CR_PS_P0
| CR_EXTRA
);
1185 if (dep
->de_flags
& DEF_PROMISC
)
1186 dp_rcr_reg
|= RCR_AB
| RCR_PRO
| RCR_AM
;
1187 if (dep
->de_flags
& DEF_BROAD
)
1188 dp_rcr_reg
|= RCR_AB
;
1189 if (dep
->de_flags
& DEF_MULTI
)
1190 dp_rcr_reg
|= RCR_AM
;
1191 outb_reg0(dep
, DP_RCR
, dp_rcr_reg
);
1194 /*===========================================================================*
1196 *===========================================================================*/
1197 static void dp_reset(dep
)
1203 outb_reg0(dep
, DP_CR
, CR_STP
| CR_DM_ABORT
);
1204 outb_reg0(dep
, DP_RBCR0
, 0);
1205 outb_reg0(dep
, DP_RBCR1
, 0);
1206 for (i
= 0; i
< 0x1000 && ((inb_reg0(dep
, DP_ISR
) & ISR_RST
) == 0); i
++)
1208 outb_reg0(dep
, DP_TCR
, TCR_1EXTERNAL
|TCR_OFST
);
1209 outb_reg0(dep
, DP_CR
, CR_STA
|CR_DM_ABORT
);
1210 outb_reg0(dep
, DP_TCR
, TCR_NORMAL
);
1212 /* Acknowledge the ISR_RDC (remote dma) interrupt. */
1213 for (i
= 0; i
< 0x1000 && ((inb_reg0(dep
, DP_ISR
) & ISR_RDC
) == 0); i
++)
1215 outb_reg0(dep
, DP_ISR
, inb_reg0(dep
, DP_ISR
) & ~ISR_RDC
);
1217 /* Reset the transmit ring. If we were transmitting a packet, we
1218 * pretend that the packet is processed. Higher layers will
1219 * retransmit if the packet wasn't actually sent.
1221 dep
->de_sendq_head
= dep
->de_sendq_tail
= 0;
1222 for (i
= 0; i
<dep
->de_sendq_nr
; i
++)
1223 dep
->de_sendq
[i
].sq_filled
= 0;
1225 dep
->de_flags
&= ~DEF_STOPPED
;
1228 /*===========================================================================*
1230 *===========================================================================*/
1231 static void dp_check_ints(dep
)
1235 int size
, sendq_tail
;
1237 if (!(dep
->de_flags
& DEF_ENABLED
))
1238 panic("dp8390: got premature interrupt");
1242 isr
= inb_reg0(dep
, DP_ISR
);
1245 outb_reg0(dep
, DP_ISR
, isr
);
1246 if (isr
& (ISR_PTX
|ISR_TXE
))
1251 { printf("%s: got send Error\n", dep
->de_name
); }
1253 dep
->de_stat
.ets_sendErr
++;
1257 tsr
= inb_reg0(dep
, DP_TSR
);
1259 if (tsr
& TSR_PTX
) dep
->de_stat
.ets_packetT
++;
1260 #if 0 /* Reserved in later manuals, should be ignored */
1261 if (!(tsr
& TSR_DFR
))
1263 /* In most (all?) implementations of
1264 * the dp8390, this bit is set
1265 * when the packet is not deferred
1267 dep
->de_stat
.ets_transDef
++;
1270 if (tsr
& TSR_COL
) dep
->de_stat
.ets_collision
++;
1271 if (tsr
& TSR_ABT
) dep
->de_stat
.ets_transAb
++;
1272 if (tsr
& TSR_CRS
) dep
->de_stat
.ets_carrSense
++;
1274 && ++dep
->de_stat
.ets_fifoUnder
<= 10)
1276 printf("%s: fifo underrun\n",
1280 && ++dep
->de_stat
.ets_CDheartbeat
<= 10)
1282 printf("%s: CD heart beat failure\n",
1285 if (tsr
& TSR_OWC
) dep
->de_stat
.ets_OWC
++;
1287 sendq_tail
= dep
->de_sendq_tail
;
1289 if (!(dep
->de_sendq
[sendq_tail
].sq_filled
))
1294 /* Or hardware bug? */
1296 "%s: transmit interrupt, but not sending\n",
1300 dep
->de_sendq
[sendq_tail
].sq_filled
= 0;
1301 if (++sendq_tail
== dep
->de_sendq_nr
)
1303 dep
->de_sendq_tail
= sendq_tail
;
1304 if (dep
->de_sendq
[sendq_tail
].sq_filled
)
1306 size
= dep
->de_sendq
[sendq_tail
].sq_size
;
1307 outb_reg0(dep
, DP_TPSR
,
1308 dep
->de_sendq
[sendq_tail
].sq_sendpage
);
1309 outb_reg0(dep
, DP_TBCR1
, size
>> 8);
1310 outb_reg0(dep
, DP_TBCR0
, size
& 0xff);
1311 outb_reg0(dep
, DP_CR
, CR_TXP
| CR_EXTRA
);
1313 if (dep
->de_flags
& DEF_SEND_AVAIL
)
1319 /* Only call dp_recv if there is a read request */
1320 if (dep
->de_flags
& DEF_READING
)
1324 if (isr
& ISR_RXE
) dep
->de_stat
.ets_recvErr
++;
1327 dep
->de_stat
.ets_CRCerr
+= inb_reg0(dep
, DP_CNTR0
);
1328 dep
->de_stat
.ets_frameAll
+= inb_reg0(dep
, DP_CNTR1
);
1329 dep
->de_stat
.ets_missedP
+= inb_reg0(dep
, DP_CNTR2
);
1333 dep
->de_stat
.ets_OVW
++;
1336 "%s: got overwrite warning\n", dep
->de_name
); }
1338 if (dep
->de_flags
& DEF_READING
)
1341 "dp_check_ints: strange: overwrite warning and pending read request\n");
1351 /* this means we got an interrupt but the ethernet
1352 * chip is shutdown. We set the flag DEF_STOPPED,
1353 * and continue processing arrived packets. When the
1354 * receive buffer is empty, we reset the dp8390.
1358 "%s: NIC stopped\n", dep
->de_name
); }
1360 dep
->de_flags
|= DEF_STOPPED
;
1364 if ((dep
->de_flags
& (DEF_READING
|DEF_STOPPED
)) ==
1365 (DEF_READING
|DEF_STOPPED
))
1367 /* The chip is stopped, and all arrived packets are
1374 /*===========================================================================*
1376 *===========================================================================*/
1377 static void dp_recv(dep
)
1381 unsigned pageno
, curr
, next
;
1383 int packet_processed
, r
;
1386 packet_processed
= FALSE
;
1387 pageno
= inb_reg0(dep
, DP_BNRY
) + 1;
1388 if (pageno
== dep
->de_stoppage
) pageno
= dep
->de_startpage
;
1392 outb_reg0(dep
, DP_CR
, CR_PS_P1
| CR_EXTRA
);
1393 curr
= inb_reg1(dep
, DP_CURR
);
1394 outb_reg0(dep
, DP_CR
, CR_PS_P0
| CR_EXTRA
);
1396 if (curr
== pageno
) break;
1398 (dep
->de_getblockf
)(dep
, pageno
, (size_t)0, sizeof(header
),
1400 (dep
->de_getblockf
)(dep
, pageno
, sizeof(header
) +
1401 2*sizeof(ether_addr_t
), sizeof(eth_type
), ð_type
);
1403 length
= (header
.dr_rbcl
| (header
.dr_rbch
<< 8)) -
1404 sizeof(dp_rcvhdr_t
);
1405 next
= header
.dr_next
;
1406 if (length
< ETH_MIN_PACK_SIZE
||
1407 length
> ETH_MAX_PACK_SIZE_TAGGED
)
1409 printf("%s: packet with strange length arrived: %d\n",
1410 dep
->de_name
, (int) length
);
1413 else if (next
< dep
->de_startpage
|| next
>= dep
->de_stoppage
)
1415 printf("%s: strange next page\n", dep
->de_name
);
1418 else if (eth_type
== eth_ign_proto
)
1420 /* Hack: ignore packets of a given protocol, useful
1421 * if you share a net with 80 computers sending
1422 * Amoeba FLIP broadcasts. (Protocol 0x8146.)
1424 static int first
= 1;
1428 printf("%s: dropping proto 0x%04x packets\n",
1430 ntohs(eth_ign_proto
));
1432 dep
->de_stat
.ets_packetR
++;
1434 else if (header
.dr_status
& RSR_FO
)
1436 /* This is very serious, so we issue a warning and
1437 * reset the buffers */
1438 printf("%s: fifo overrun, resetting receive buffer\n",
1440 dep
->de_stat
.ets_fifoOver
++;
1443 else if ((header
.dr_status
& RSR_PRX
) &&
1444 (dep
->de_flags
& DEF_ENABLED
))
1446 if (dep
->de_safecopy_read
)
1447 r
= dp_pkt2user_s(dep
, pageno
, length
);
1449 r
= dp_pkt2user(dep
, pageno
, length
);
1453 packet_processed
= TRUE
;
1454 dep
->de_stat
.ets_packetR
++;
1456 if (next
== dep
->de_startpage
)
1457 outb_reg0(dep
, DP_BNRY
, dep
->de_stoppage
- 1);
1459 outb_reg0(dep
, DP_BNRY
, next
- 1);
1463 while (!packet_processed
);
1466 /*===========================================================================*
1468 *===========================================================================*/
1469 static void dp_send(dep
)
1472 if (!(dep
->de_flags
& DEF_SEND_AVAIL
))
1475 dep
->de_flags
&= ~DEF_SEND_AVAIL
;
1476 switch(dep
->de_sendmsg
.m_type
)
1478 case DL_WRITE
: do_vwrite(&dep
->de_sendmsg
, TRUE
, FALSE
); break;
1479 case DL_WRITEV
: do_vwrite(&dep
->de_sendmsg
, TRUE
, TRUE
); break;
1480 case DL_WRITEV_S
: do_vwrite_s(&dep
->de_sendmsg
, TRUE
); break;
1482 panic("dp8390: wrong type: %d", dep
->de_sendmsg
.m_type
);
1487 /*===========================================================================*
1489 *===========================================================================*/
1490 static void dp_getblock(dep
, page
, offset
, size
, dst
)
1497 offset
= page
* DP_PAGESIZE
+ offset
;
1499 memcpy(dst
, dep
->de_locmem
+ offset
, size
);
1502 /*===========================================================================*
1503 * dp_pio8_getblock *
1504 *===========================================================================*/
1505 static void dp_pio8_getblock(dep
, page
, offset
, size
, dst
)
1512 offset
= page
* DP_PAGESIZE
+ offset
;
1513 outb_reg0(dep
, DP_RBCR0
, size
& 0xFF);
1514 outb_reg0(dep
, DP_RBCR1
, size
>> 8);
1515 outb_reg0(dep
, DP_RSAR0
, offset
& 0xFF);
1516 outb_reg0(dep
, DP_RSAR1
, offset
>> 8);
1517 outb_reg0(dep
, DP_CR
, CR_DM_RR
| CR_PS_P0
| CR_STA
);
1519 insb(dep
->de_data_port
, dst
, size
);
1522 /*===========================================================================*
1523 * dp_pio16_getblock *
1524 *===========================================================================*/
1525 static void dp_pio16_getblock(dep
, page
, offset
, size
, dst
)
1532 offset
= page
* DP_PAGESIZE
+ offset
;
1533 outb_reg0(dep
, DP_RBCR0
, size
& 0xFF);
1534 outb_reg0(dep
, DP_RBCR1
, size
>> 8);
1535 outb_reg0(dep
, DP_RSAR0
, offset
& 0xFF);
1536 outb_reg0(dep
, DP_RSAR1
, offset
>> 8);
1537 outb_reg0(dep
, DP_CR
, CR_DM_RR
| CR_PS_P0
| CR_STA
);
1539 assert (!(size
& 1));
1540 insw(dep
->de_data_port
, dst
, size
);
1543 /*===========================================================================*
1545 *===========================================================================*/
1546 static int dp_pkt2user(dpeth_t
*dep
, int page
, vir_bytes length
)
1550 if (!(dep
->de_flags
& DEF_READING
))
1553 last
= page
+ (length
- 1) / DP_PAGESIZE
;
1554 if (last
>= dep
->de_stoppage
)
1556 count
= (dep
->de_stoppage
- page
) * DP_PAGESIZE
-
1557 sizeof(dp_rcvhdr_t
);
1559 /* Save read_iovec since we need it twice. */
1560 dep
->de_tmp_iovec
= dep
->de_read_iovec
;
1561 (dep
->de_nic2userf
)(dep
, page
* DP_PAGESIZE
+
1562 sizeof(dp_rcvhdr_t
), &dep
->de_tmp_iovec
, 0, count
);
1563 (dep
->de_nic2userf
)(dep
, dep
->de_startpage
* DP_PAGESIZE
,
1564 &dep
->de_read_iovec
, count
, length
- count
);
1568 (dep
->de_nic2userf
)(dep
, page
* DP_PAGESIZE
+
1569 sizeof(dp_rcvhdr_t
), &dep
->de_read_iovec
, 0, length
);
1572 dep
->de_read_s
= length
;
1573 dep
->de_flags
|= DEF_PACK_RECV
;
1574 dep
->de_flags
&= ~DEF_READING
;
1579 /*===========================================================================*
1581 *===========================================================================*/
1582 static int dp_pkt2user_s(dpeth_t
*dep
, int page
, vir_bytes length
)
1586 if (!(dep
->de_flags
& DEF_READING
))
1589 last
= page
+ (length
- 1) / DP_PAGESIZE
;
1590 if (last
>= dep
->de_stoppage
)
1592 count
= (dep
->de_stoppage
- page
) * DP_PAGESIZE
-
1593 sizeof(dp_rcvhdr_t
);
1595 /* Save read_iovec since we need it twice. */
1596 dep
->de_tmp_iovec_s
= dep
->de_read_iovec_s
;
1597 (dep
->de_nic2userf_s
)(dep
, page
* DP_PAGESIZE
+
1598 sizeof(dp_rcvhdr_t
), &dep
->de_tmp_iovec_s
, 0, count
);
1599 (dep
->de_nic2userf_s
)(dep
, dep
->de_startpage
* DP_PAGESIZE
,
1600 &dep
->de_read_iovec_s
, count
, length
- count
);
1604 (dep
->de_nic2userf_s
)(dep
, page
* DP_PAGESIZE
+
1605 sizeof(dp_rcvhdr_t
), &dep
->de_read_iovec_s
, 0, length
);
1608 dep
->de_read_s
= length
;
1609 dep
->de_flags
|= DEF_PACK_RECV
;
1610 dep
->de_flags
&= ~DEF_READING
;
1615 /*===========================================================================*
1617 *===========================================================================*/
1618 static void dp_user2nic(dep
, iovp
, offset
, nic_addr
, count
)
1629 vir_hw
= (vir_bytes
)dep
->de_locmem
+ nic_addr
;
1636 dp_next_iovec(iovp
);
1640 assert(i
< iovp
->iod_iovec_s
);
1641 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
1643 offset
-= iovp
->iod_iovec
[i
].iov_size
;
1647 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
1651 r
= sys_vircopy(iovp
->iod_proc_nr
, D
,
1652 iovp
->iod_iovec
[i
].iov_addr
+ offset
,
1653 SELF
, D
, vir_hw
, bytes
);
1655 panic("dp_user2nic: sys_vircopy failed: %d", r
);
1664 /*===========================================================================*
1666 *===========================================================================*/
1667 static void dp_user2nic_s(dep
, iovp
, offset
, nic_addr
, count
)
1669 iovec_dat_s_t
*iovp
;
1677 vir_hw
= (vir_bytes
)dep
->de_locmem
+ nic_addr
;
1684 dp_next_iovec_s(iovp
);
1688 assert(i
< iovp
->iod_iovec_s
);
1689 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
1691 offset
-= iovp
->iod_iovec
[i
].iov_size
;
1695 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
1699 r
= sys_safecopyfrom(iovp
->iod_proc_nr
,
1700 iovp
->iod_iovec
[i
].iov_grant
, offset
,
1703 panic("dp_user2nic_s: sys_safecopyfrom failed: %d", r
);
1713 /*===========================================================================*
1714 * dp_pio8_user2nic *
1715 *===========================================================================*/
1716 static void dp_pio8_user2nic(dep
, iovp
, offset
, nic_addr
, count
)
1725 outb_reg0(dep
, DP_ISR
, ISR_RDC
);
1727 outb_reg0(dep
, DP_RBCR0
, count
& 0xFF);
1728 outb_reg0(dep
, DP_RBCR1
, count
>> 8);
1729 outb_reg0(dep
, DP_RSAR0
, nic_addr
& 0xFF);
1730 outb_reg0(dep
, DP_RSAR1
, nic_addr
>> 8);
1731 outb_reg0(dep
, DP_CR
, CR_DM_RW
| CR_PS_P0
| CR_STA
);
1738 dp_next_iovec(iovp
);
1742 assert(i
< iovp
->iod_iovec_s
);
1743 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
1745 offset
-= iovp
->iod_iovec
[i
].iov_size
;
1749 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
1753 do_vir_outsb(dep
->de_data_port
, iovp
->iod_proc_nr
,
1754 iovp
->iod_iovec
[i
].iov_addr
+ offset
, bytes
);
1760 for (i
= 0; i
<100; i
++)
1762 if (inb_reg0(dep
, DP_ISR
) & ISR_RDC
)
1767 panic("dp8390: remote dma failed to complete");
1771 /*===========================================================================*
1772 * dp_pio8_user2nic_s *
1773 *===========================================================================*/
1774 static void dp_pio8_user2nic_s(dep
, iovp
, offset
, nic_addr
, count
)
1776 iovec_dat_s_t
*iovp
;
1783 outb_reg0(dep
, DP_ISR
, ISR_RDC
);
1785 outb_reg0(dep
, DP_RBCR0
, count
& 0xFF);
1786 outb_reg0(dep
, DP_RBCR1
, count
>> 8);
1787 outb_reg0(dep
, DP_RSAR0
, nic_addr
& 0xFF);
1788 outb_reg0(dep
, DP_RSAR1
, nic_addr
>> 8);
1789 outb_reg0(dep
, DP_CR
, CR_DM_RW
| CR_PS_P0
| CR_STA
);
1796 dp_next_iovec_s(iovp
);
1800 assert(i
< iovp
->iod_iovec_s
);
1801 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
1803 offset
-= iovp
->iod_iovec
[i
].iov_size
;
1807 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
1811 r
= sys_safe_outsb(dep
->de_data_port
, iovp
->iod_proc_nr
,
1812 iovp
->iod_iovec
[i
].iov_grant
, offset
, bytes
);
1814 panic("dp_pio8_user2nic_s: sys_safe_outsb failed: %d",
1822 for (i
= 0; i
<100; i
++)
1824 if (inb_reg0(dep
, DP_ISR
) & ISR_RDC
)
1829 panic("dp8390: remote dma failed to complete");
1833 /*===========================================================================*
1834 * dp_pio16_user2nic *
1835 *===========================================================================*/
1836 static void dp_pio16_user2nic(dep
, iovp
, offset
, nic_addr
, count
)
1845 int i
, r
, bytes
, user_proc
;
1849 ecount
= (count
+1) & ~1;
1852 outb_reg0(dep
, DP_ISR
, ISR_RDC
);
1853 outb_reg0(dep
, DP_RBCR0
, ecount
& 0xFF);
1854 outb_reg0(dep
, DP_RBCR1
, ecount
>> 8);
1855 outb_reg0(dep
, DP_RSAR0
, nic_addr
& 0xFF);
1856 outb_reg0(dep
, DP_RSAR1
, nic_addr
>> 8);
1857 outb_reg0(dep
, DP_CR
, CR_DM_RW
| CR_PS_P0
| CR_STA
);
1864 dp_next_iovec(iovp
);
1868 assert(i
< iovp
->iod_iovec_s
);
1869 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
1871 offset
-= iovp
->iod_iovec
[i
].iov_size
;
1875 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
1879 user_proc
= iovp
->iod_proc_nr
;
1880 vir_user
= iovp
->iod_iovec
[i
].iov_addr
+ offset
;
1883 r
= sys_vircopy(user_proc
, D
, vir_user
,
1884 SELF
, D
, (vir_bytes
)&two_bytes
[1], 1);
1886 panic("dp_pio16_user2nic: sys_vircopy failed: %d",
1889 outw(dep
->de_data_port
, *(u16_t
*)two_bytes
);
1901 do_vir_outsw(dep
->de_data_port
, user_proc
, vir_user
,
1911 r
= sys_vircopy(user_proc
, D
, vir_user
,
1912 SELF
, D
, (vir_bytes
)&two_bytes
[0], 1);
1914 panic("dp_pio16_user2nic: sys_vircopy failed: %d",
1927 outw(dep
->de_data_port
, *(u16_t
*)two_bytes
);
1929 for (i
= 0; i
<100; i
++)
1931 if (inb_reg0(dep
, DP_ISR
) & ISR_RDC
)
1936 panic("dp8390: remote dma failed to complete");
1940 /*===========================================================================*
1941 * dp_pio16_user2nic_s *
1942 *===========================================================================*/
1943 static void dp_pio16_user2nic_s(dep
, iovp
, offset
, nic_addr
, count
)
1945 iovec_dat_s_t
*iovp
;
1952 int i
, r
, bytes
, user_proc
;
1956 ecount
= (count
+1) & ~1;
1959 outb_reg0(dep
, DP_ISR
, ISR_RDC
);
1960 outb_reg0(dep
, DP_RBCR0
, ecount
& 0xFF);
1961 outb_reg0(dep
, DP_RBCR1
, ecount
>> 8);
1962 outb_reg0(dep
, DP_RSAR0
, nic_addr
& 0xFF);
1963 outb_reg0(dep
, DP_RSAR1
, nic_addr
>> 8);
1964 outb_reg0(dep
, DP_CR
, CR_DM_RW
| CR_PS_P0
| CR_STA
);
1971 dp_next_iovec_s(iovp
);
1975 assert(i
< iovp
->iod_iovec_s
);
1976 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
1978 offset
-= iovp
->iod_iovec
[i
].iov_size
;
1982 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
1986 user_proc
= iovp
->iod_proc_nr
;
1987 gid
= iovp
->iod_iovec
[i
].iov_grant
;
1990 r
= sys_safecopyfrom(user_proc
, gid
, offset
,
1991 (vir_bytes
)&two_bytes
[1], 1, D
);
1993 panic("dp_pio16_user2nic: sys_safecopyfrom failed: %d", r
);
1995 outw(dep
->de_data_port
, *(u16_t
*)two_bytes
);
2006 r
= sys_safe_outsw(dep
->de_data_port
, user_proc
,
2007 gid
, offset
, ecount
);
2009 panic("dp_pio16_user2nic: sys_safe_outsw failed: %d", r
);
2018 r
= sys_safecopyfrom(user_proc
, gid
, offset
,
2019 (vir_bytes
)&two_bytes
[0], 1, D
);
2021 panic("dp_pio16_user2nic: sys_safecopyfrom failed: %d", r
);
2032 outw(dep
->de_data_port
, *(u16_t
*)two_bytes
);
2034 for (i
= 0; i
<100; i
++)
2036 if (inb_reg0(dep
, DP_ISR
) & ISR_RDC
)
2041 panic("dp8390: remote dma failed to complete");
2045 /*===========================================================================*
2047 *===========================================================================*/
2048 static void dp_nic2user(dep
, nic_addr
, iovp
, offset
, count
)
2057 vir_bytes vir_hw
= (vir_bytes
) (dep
->de_locmem
+ nic_addr
);
2064 dp_next_iovec(iovp
);
2068 assert(i
< iovp
->iod_iovec_s
);
2069 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
2071 offset
-= iovp
->iod_iovec
[i
].iov_size
;
2075 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
2079 r
= sys_vircopy(SELF
, D
, vir_hw
,
2080 iovp
->iod_proc_nr
, D
,
2081 iovp
->iod_iovec
[i
].iov_addr
+ offset
, bytes
);
2083 panic("dp_nic2user: sys_vircopy failed: %d", r
);
2092 /*===========================================================================*
2094 *===========================================================================*/
2095 static void dp_nic2user_s(dep
, nic_addr
, iovp
, offset
, count
)
2098 iovec_dat_s_t
*iovp
;
2105 vir_hw
= (vir_bytes
)dep
->de_locmem
+ nic_addr
;
2112 dp_next_iovec_s(iovp
);
2116 assert(i
< iovp
->iod_iovec_s
);
2117 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
2119 offset
-= iovp
->iod_iovec
[i
].iov_size
;
2123 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
2127 r
= sys_safecopyto(iovp
->iod_proc_nr
,
2128 iovp
->iod_iovec
[i
].iov_grant
, offset
,
2131 panic("dp_nic2user_s: sys_safecopyto failed: %d", r
);
2140 /*===========================================================================*
2141 * dp_pio8_nic2user *
2142 *===========================================================================*/
2143 static void dp_pio8_nic2user(dep
, nic_addr
, iovp
, offset
, count
)
2152 outb_reg0(dep
, DP_RBCR0
, count
& 0xFF);
2153 outb_reg0(dep
, DP_RBCR1
, count
>> 8);
2154 outb_reg0(dep
, DP_RSAR0
, nic_addr
& 0xFF);
2155 outb_reg0(dep
, DP_RSAR1
, nic_addr
>> 8);
2156 outb_reg0(dep
, DP_CR
, CR_DM_RR
| CR_PS_P0
| CR_STA
);
2163 dp_next_iovec(iovp
);
2167 assert(i
< iovp
->iod_iovec_s
);
2168 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
2170 offset
-= iovp
->iod_iovec
[i
].iov_size
;
2174 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
2178 do_vir_insb(dep
->de_data_port
, iovp
->iod_proc_nr
,
2179 iovp
->iod_iovec
[i
].iov_addr
+ offset
, bytes
);
2186 /*===========================================================================*
2187 * dp_pio8_nic2user_s *
2188 *===========================================================================*/
2189 static void dp_pio8_nic2user_s(dep
, nic_addr
, iovp
, offset
, count
)
2192 iovec_dat_s_t
*iovp
;
2198 outb_reg0(dep
, DP_RBCR0
, count
& 0xFF);
2199 outb_reg0(dep
, DP_RBCR1
, count
>> 8);
2200 outb_reg0(dep
, DP_RSAR0
, nic_addr
& 0xFF);
2201 outb_reg0(dep
, DP_RSAR1
, nic_addr
>> 8);
2202 outb_reg0(dep
, DP_CR
, CR_DM_RR
| CR_PS_P0
| CR_STA
);
2209 dp_next_iovec_s(iovp
);
2213 assert(i
< iovp
->iod_iovec_s
);
2214 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
2216 offset
-= iovp
->iod_iovec
[i
].iov_size
;
2220 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
2224 r
= sys_safe_insb(dep
->de_data_port
, iovp
->iod_proc_nr
,
2225 iovp
->iod_iovec
[i
].iov_grant
, offset
, bytes
);
2227 panic("dp_pio8_nic2user_s: sys_safe_insb failed: %d", r
);
2235 /*===========================================================================*
2236 * dp_pio16_nic2user *
2237 *===========================================================================*/
2238 static void dp_pio16_nic2user(dep
, nic_addr
, iovp
, offset
, count
)
2247 int i
, r
, bytes
, user_proc
;
2251 ecount
= (count
+1) & ~1;
2254 outb_reg0(dep
, DP_RBCR0
, ecount
& 0xFF);
2255 outb_reg0(dep
, DP_RBCR1
, ecount
>> 8);
2256 outb_reg0(dep
, DP_RSAR0
, nic_addr
& 0xFF);
2257 outb_reg0(dep
, DP_RSAR1
, nic_addr
>> 8);
2258 outb_reg0(dep
, DP_CR
, CR_DM_RR
| CR_PS_P0
| CR_STA
);
2265 dp_next_iovec(iovp
);
2269 assert(i
< iovp
->iod_iovec_s
);
2270 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
2272 offset
-= iovp
->iod_iovec
[i
].iov_size
;
2276 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
2280 user_proc
= iovp
->iod_proc_nr
;
2281 vir_user
= iovp
->iod_iovec
[i
].iov_addr
+ offset
;
2284 r
= sys_vircopy(SELF
, D
, (vir_bytes
)&two_bytes
[1],
2285 user_proc
, D
, vir_user
, 1);
2287 panic("dp_pio16_nic2user: sys_vircopy failed: %d",
2301 do_vir_insw(dep
->de_data_port
, user_proc
, vir_user
,
2311 *(u16_t
*)two_bytes
= inw(dep
->de_data_port
);
2312 r
= sys_vircopy(SELF
, D
, (vir_bytes
)&two_bytes
[0],
2313 user_proc
, D
, vir_user
, 1);
2315 panic("dp_pio16_nic2user: sys_vircopy failed: %d", r
);
2327 /*===========================================================================*
2328 * dp_pio16_nic2user_s *
2329 *===========================================================================*/
2330 static void dp_pio16_nic2user_s(dep
, nic_addr
, iovp
, offset
, count
)
2333 iovec_dat_s_t
*iovp
;
2339 int i
, r
, bytes
, user_proc
;
2343 ecount
= (count
+1) & ~1;
2346 outb_reg0(dep
, DP_RBCR0
, ecount
& 0xFF);
2347 outb_reg0(dep
, DP_RBCR1
, ecount
>> 8);
2348 outb_reg0(dep
, DP_RSAR0
, nic_addr
& 0xFF);
2349 outb_reg0(dep
, DP_RSAR1
, nic_addr
>> 8);
2350 outb_reg0(dep
, DP_CR
, CR_DM_RR
| CR_PS_P0
| CR_STA
);
2357 dp_next_iovec_s(iovp
);
2361 assert(i
< iovp
->iod_iovec_s
);
2362 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
2364 offset
-= iovp
->iod_iovec
[i
].iov_size
;
2368 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
2372 user_proc
= iovp
->iod_proc_nr
;
2373 gid
= iovp
->iod_iovec
[i
].iov_grant
;
2376 r
= sys_safecopyto(user_proc
, gid
, offset
,
2377 (vir_bytes
)&two_bytes
[1], 1, D
);
2379 panic("dp_pio16_nic2user: sys_safecopyto failed: %d", r
);
2391 r
= sys_safe_insw(dep
->de_data_port
, user_proc
, gid
,
2394 panic("dp_pio16_nic2user: sys_safe_insw failed: %d",
2404 *(u16_t
*)two_bytes
= inw(dep
->de_data_port
);
2405 r
= sys_safecopyto(user_proc
, gid
, offset
,
2406 (vir_bytes
)&two_bytes
[0], 1, D
);
2409 panic("dp_pio16_nic2user: sys_safecopyto failed: %d",
2421 /*===========================================================================*
2423 *===========================================================================*/
2424 static void dp_next_iovec(iovp
)
2427 assert(iovp
->iod_iovec_s
> IOVEC_NR
);
2429 iovp
->iod_iovec_s
-= IOVEC_NR
;
2431 iovp
->iod_iovec_addr
+= IOVEC_NR
* sizeof(iovec_t
);
2433 get_userdata(iovp
->iod_proc_nr
, iovp
->iod_iovec_addr
,
2434 (iovp
->iod_iovec_s
> IOVEC_NR
? IOVEC_NR
: iovp
->iod_iovec_s
) *
2435 sizeof(iovec_t
), iovp
->iod_iovec
);
2438 /*===========================================================================*
2440 *===========================================================================*/
2441 static void dp_next_iovec_s(iovp
)
2442 iovec_dat_s_t
*iovp
;
2444 assert(iovp
->iod_iovec_s
> IOVEC_NR
);
2446 iovp
->iod_iovec_s
-= IOVEC_NR
;
2448 iovp
->iod_iovec_offset
+= IOVEC_NR
* sizeof(iovec_t
);
2450 get_userdata_s(iovp
->iod_proc_nr
, iovp
->iod_grant
,
2451 iovp
->iod_iovec_offset
,
2452 (iovp
->iod_iovec_s
> IOVEC_NR
? IOVEC_NR
: iovp
->iod_iovec_s
) *
2453 sizeof(iovp
->iod_iovec
[0]), iovp
->iod_iovec
);
2456 /*===========================================================================*
2458 *===========================================================================*/
2459 static void conf_hw(dep
)
2462 static eth_stat_t empty_stat
= {0, 0, 0, 0, 0, 0 /* ,... */ };
2467 dep
->de_mode
= DEM_DISABLED
; /* Superfluous */
2470 dcp
= &dp_conf
[ifnr
];
2471 update_conf(dep
, dcp
);
2472 if (dep
->de_mode
!= DEM_ENABLED
)
2474 if (!wdeth_probe(dep
) && !ne_probe(dep
) && !el2_probe(dep
))
2476 printf("%s: No ethernet card found at 0x%x\n",
2477 dep
->de_name
, dep
->de_base_port
);
2478 dep
->de_mode
= DEM_DISABLED
;
2482 /* XXX */ if (dep
->de_linmem
== 0) dep
->de_linmem
= 0xFFFF0000;
2484 dep
->de_flags
= DEF_EMPTY
;
2485 dep
->de_stat
= empty_stat
;
2488 /*===========================================================================*
2490 *===========================================================================*/
2491 static void update_conf(dep
, dcp
)
2496 static char dpc_fmt
[] = "x:d:x:x";
2501 if (dep
->de_pci
== 1)
2503 /* PCI device is present */
2504 dep
->de_mode
= DEM_ENABLED
;
2506 return; /* Already configured */
2510 /* Get the default settings and modify them from the environment. */
2511 dep
->de_mode
= DEM_SINK
;
2513 switch (env_parse(dcp
->dpc_envvar
, dpc_fmt
, 0, &v
, 0x0000L
, 0xFFFFL
)) {
2515 dep
->de_mode
= DEM_DISABLED
;
2519 dep
->de_mode
= DEM_ENABLED
; /* Might become disabled if
2520 * all probes fail */
2523 dep
->de_base_port
= v
;
2525 v
= dcp
->dpc_irq
| DEI_DEFAULT
;
2526 (void) env_parse(dcp
->dpc_envvar
, dpc_fmt
, 1, &v
, 0L,
2527 (long) NR_IRQ_VECTORS
- 1);
2531 (void) env_parse(dcp
->dpc_envvar
, dpc_fmt
, 2, &v
, 0L, 0xFFFFFL
);
2535 (void) env_parse(dcp
->dpc_envvar
, dpc_fmt
, 3, &v
, 0x2000L
, 0x8000L
);
2539 /*===========================================================================*
2541 *===========================================================================*/
2542 static void map_hw_buffer(dep
)
2549 if (dep
->de_prog_IO
)
2553 "map_hw_buffer: programmed I/O, no need to map buffer\n");
2555 dep
->de_locmem
= (char *)-dep
->de_ramsize
; /* trap errors */
2559 size
= dep
->de_ramsize
+ I386_PAGE_SIZE
; /* Add I386_PAGE_SIZE for
2564 panic("map_hw_buffer: cannot malloc size: %d", size
);
2565 o
= I386_PAGE_SIZE
- ((vir_bytes
)buf
% I386_PAGE_SIZE
);
2567 printf("buf at 0x%x, abuf at 0x%x\n", buf
, abuf
);
2570 r
= sys_vm_map(SELF
, 1 /* map */, (vir_bytes
)abuf
,
2571 dep
->de_ramsize
, (phys_bytes
)dep
->de_linmem
);
2576 panic("map_hw_buffer: sys_vm_map failed: %d", r
);
2577 dep
->de_locmem
= abuf
;
2580 /*===========================================================================*
2582 *===========================================================================*/
2583 static int calc_iovec_size(iovp
)
2586 /* Calculate the size of a request. Note that the iovec_dat
2587 * structure will be unusable after calc_iovec_size.
2594 while (i
< iovp
->iod_iovec_s
)
2598 dp_next_iovec(iovp
);
2602 size
+= iovp
->iod_iovec
[i
].iov_size
;
2608 /*===========================================================================*
2609 * calc_iovec_size_s *
2610 *===========================================================================*/
2611 static int calc_iovec_size_s(iovp
)
2612 iovec_dat_s_t
*iovp
;
2614 /* Calculate the size of a request. Note that the iovec_dat
2615 * structure will be unusable after calc_iovec_size_s.
2622 while (i
< iovp
->iod_iovec_s
)
2626 dp_next_iovec_s(iovp
);
2630 size
+= iovp
->iod_iovec
[i
].iov_size
;
2636 /*===========================================================================*
2638 *===========================================================================*/
2639 static void reply(dep
, err
, may_block
)
2649 if (dep
->de_flags
& DEF_PACK_SEND
)
2650 status
|= DL_PACK_SEND
;
2651 if (dep
->de_flags
& DEF_PACK_RECV
)
2652 status
|= DL_PACK_RECV
;
2654 reply
.m_type
= DL_TASK_REPLY
;
2655 reply
.DL_PORT
= dep
- de_table
;
2656 reply
.DL_PROC
= dep
->de_client
;
2657 reply
.DL_STAT
= status
| ((u32_t
) err
<< 16);
2658 reply
.DL_COUNT
= dep
->de_read_s
;
2659 reply
.DL_CLCK
= 0; /* Don't know */
2660 r
= send(dep
->de_client
, &reply
);
2662 if (r
== ELOCKED
&& may_block
)
2665 printf("send locked\n");
2671 panic("dp8390: send failed: %d", r
);
2674 dep
->de_flags
&= ~(DEF_PACK_SEND
| DEF_PACK_RECV
);
2677 /*===========================================================================*
2679 *===========================================================================*/
2680 static void mess_reply(req
, reply_mess
)
2682 message
*reply_mess
;
2684 if (send(req
->m_source
, reply_mess
) != OK
)
2685 panic("dp8390: unable to mess_reply");
2688 /*===========================================================================*
2690 *===========================================================================*/
2691 static void get_userdata(user_proc
, user_addr
, count
, loc_addr
)
2693 vir_bytes user_addr
;
2699 r
= sys_vircopy(user_proc
, D
, user_addr
,
2700 SELF
, D
, (vir_bytes
)loc_addr
, count
);
2702 panic("get_userdata: sys_vircopy failed: %d", r
);
2705 /*===========================================================================*
2707 *===========================================================================*/
2708 static void get_userdata_s(user_proc
, grant
, offset
, count
, loc_addr
)
2710 cp_grant_id_t grant
;
2717 r
= sys_safecopyfrom(user_proc
, grant
, offset
,
2718 (vir_bytes
)loc_addr
, count
, D
);
2720 panic("get_userdata: sys_safecopyfrom failed: %d", r
);
2723 /*===========================================================================*
2725 *===========================================================================*/
2726 static void put_userdata(user_proc
, user_addr
, count
, loc_addr
)
2728 vir_bytes user_addr
;
2734 r
= sys_vircopy(SELF
, D
, (vir_bytes
)loc_addr
,
2735 user_proc
, D
, user_addr
, count
);
2737 panic("put_userdata: sys_vircopy failed: %d", r
);
2740 /*===========================================================================*
2742 *===========================================================================*/
2743 static void put_userdata_s(user_proc
, grant
, count
, loc_addr
)
2745 cp_grant_id_t grant
;
2751 r
= sys_safecopyto(user_proc
, grant
, 0, (vir_bytes
)loc_addr
,
2754 panic("put_userdata: sys_safecopyto failed: %d", r
);
2757 u8_t
inb(port_t port
)
2762 r
= sys_inb(port
, &value
);
2765 printf("inb failed for port 0x%x\n", port
);
2766 panic("sys_inb failed: %d", r
);
2771 u16_t
inw(port_t port
)
2774 unsigned long value
;
2776 r
= sys_inw(port
, &value
);
2778 panic("sys_inw failed: %d", r
);
2779 return (u16_t
) value
;
2782 void outb(port_t port
, u8_t value
)
2786 r
= sys_outb(port
, value
);
2788 panic("sys_outb failed: %d", r
);
2791 void outw(port_t port
, u16_t value
)
2795 r
= sys_outw(port
, value
);
2797 panic("sys_outw failed: %d", r
);
2800 static void insb(port_t port
, void *buf
, size_t size
)
2802 do_vir_insb(port
, SELF
, (vir_bytes
)buf
, size
);
2805 static void insw(port_t port
, void *buf
, size_t size
)
2807 do_vir_insw(port
, SELF
, (vir_bytes
)buf
, size
);
2810 static void do_vir_insb(port_t port
, int proc
, vir_bytes buf
, size_t size
)
2814 r
= sys_insb(port
, proc
, (void *) buf
, size
);
2816 panic("sys_sdevio failed: %d", r
);
2819 static void do_vir_insw(port_t port
, int proc
, vir_bytes buf
, size_t size
)
2823 r
= sys_insw(port
, proc
, (void *) buf
, size
);
2825 panic("sys_sdevio failed: %d", r
);
2828 static void do_vir_outsb(port_t port
, int proc
, vir_bytes buf
, size_t size
)
2832 r
= sys_outsb(port
, proc
, (void *) buf
, size
);
2834 panic("sys_sdevio failed: %d", r
);
2837 static void do_vir_outsw(port_t port
, int proc
, vir_bytes buf
, size_t size
)
2841 r
= sys_outsw(port
, proc
, (void *) buf
, size
);
2843 panic("sys_sdevio failed: %d", r
);
2847 * $PchId: dp8390.c,v 1.25 2005/02/10 17:32:07 philip Exp $