xref: /minix/minix/drivers/net/dp8390/dp8390.c (revision fb9c64b2)
1 /*
2  * dp8390.c
3  *
4  * This file contains a ethernet device driver for NS dp8390 based ethernet
5  * cards.
6  *
7  * Created:	before Dec 28, 1992 by Philip Homburg <philip@f-mnx.phicoh.com>
8  *
9  * Modified Mar 10 1994 by Philip Homburg
10  *	Become a generic dp8390 driver.
11  *
12  * Modified Dec 20 1996 by G. Falzoni <falzoni@marina.scn.de>
13  *	Added support for 3c503 boards.
14  */
15 
16 #include <minix/drivers.h>
17 #include <minix/netdriver.h>
18 
19 #include <sys/mman.h>
20 #include "assert.h"
21 
22 #include "local.h"
23 #include "dp8390.h"
24 
25 static dpeth_t de_state;
26 
27 u32_t system_hz;
28 
29 /* Configuration */
30 typedef struct dp_conf
31 {
32 	port_t dpc_port;
33 	int dpc_irq;
34 	phys_bytes dpc_mem;
35 } dp_conf_t;
36 
37 #define DP_CONF_NR 4
38 static dp_conf_t dp_conf[DP_CONF_NR]=	/* Card addresses */
39 {
40 	/* I/O port, IRQ,  Buffer address. */
41 	{  0x280,     3,    0xD0000,       },
42 	{  0x300,     5,    0xC8000,       },
43 	{  0x380,    10,    0xD8000,       },
44 	{  0x000,     0,    0x00000,       },
45 };
46 
47 /* Card inits configured out? */
48 #if !ENABLE_WDETH
49 #define wdeth_probe(dep)	(0)
50 #endif
51 #if !ENABLE_NE2000
52 #define ne_probe(dep)		(0)
53 #endif
54 #if !ENABLE_3C503
55 #define el2_probe(dep)		(0)
56 #endif
57 
58 /* Some clones of the dp8390 and the PC emulator 'Bochs' require the CR_STA
59  * on writes to the CR register. Additional CR_STAs do not appear to hurt
60  * genuine dp8390s
61  */
62 #define CR_EXTRA	CR_STA
63 
64 static int do_init(unsigned int instance, netdriver_addr_t *addr,
65 	uint32_t *caps, unsigned int *ticks);
66 static void pci_conf(unsigned int instance);
67 static int do_send(struct netdriver_data *data, size_t size);
68 static ssize_t do_recv(struct netdriver_data *data, size_t max);
69 static void do_set_mode(unsigned int mode, const netdriver_addr_t *mcast_list,
70 	unsigned int mcast_count);
71 static void do_stop(void);
72 static void dp_init(dpeth_t *dep, unsigned int instance);
73 static void dp_confaddr(dpeth_t *dep, unsigned int instance);
74 static void dp_reset(dpeth_t *dep);
75 static void do_intr(unsigned int mask);
76 static void do_tick(void);
77 static void dp_getblock(dpeth_t *dep, int page, size_t offset, size_t
78 	size, void *dst);
79 static void dp_pio8_getblock(dpeth_t *dep, int page, size_t offset,
80 	size_t size, void *dst);
81 static void dp_pio16_getblock(dpeth_t *dep, int page, size_t offset,
82 	size_t size, void *dst);
83 static void dp_pkt2user_s(dpeth_t *dep, struct netdriver_data *data, int page,
84 	size_t length);
85 static void dp_user2nic_s(dpeth_t *dep, struct netdriver_data *data,
86 	int nic_addr, size_t offset, size_t count);
87 static void dp_pio8_user2nic_s(dpeth_t *dep, struct netdriver_data *data,
88 	int nic_addr, size_t offset, size_t count);
89 static void dp_pio16_user2nic_s(dpeth_t *dep, struct netdriver_data *data,
90 	int nic_addr, size_t offset, size_t count);
91 static void dp_nic2user_s(dpeth_t *dep, struct netdriver_data *data,
92 	int nic_addr, size_t offset, size_t count);
93 static void dp_pio8_nic2user_s(dpeth_t *dep, struct netdriver_data *data,
94 	int nic_addr, size_t offset, size_t count);
95 static void dp_pio16_nic2user_s(dpeth_t *dep, struct netdriver_data *data,
96 	int nic_addr, size_t offset, size_t count);
97 static void conf_hw(dpeth_t *dep, unsigned int instance);
98 static void update_conf(dpeth_t *dep, dp_conf_t *dcp, unsigned int instance);
99 static void map_hw_buffer(dpeth_t *dep);
100 static void insb(port_t port, void *buf, size_t size);
101 static void insw(port_t port, void *buf, size_t size);
102 
103 static const struct netdriver dp_table = {
104 	.ndr_name	= "dp",
105 	.ndr_init	= do_init,
106 	.ndr_stop	= do_stop,
107 	.ndr_set_mode	= do_set_mode,
108 	.ndr_recv	= do_recv,
109 	.ndr_send	= do_send,
110 	.ndr_intr	= do_intr,
111 	.ndr_tick	= do_tick
112 };
113 
114 /*===========================================================================*
115  *				main					     *
116  *===========================================================================*/
117 int main(int argc, char *argv[])
118 {
119 	env_setargs(argc, argv);
120 
121 	netdriver_task(&dp_table);
122 
123 	return 0;
124 }
125 
126 /*===========================================================================*
127  *				do_init					     *
128  *===========================================================================*/
129 static int do_init(unsigned int instance, netdriver_addr_t *addr,
130 	uint32_t *caps, unsigned int *ticks)
131 {
132 /* Initialize the dp8390 driver. */
133 	dpeth_t *dep;
134 
135 	system_hz = sys_hz();
136 
137 	dep = &de_state;
138 	memset(dep, 0, sizeof(*dep));
139 
140 	pci_conf(instance); /* Configure PCI devices. */
141 
142 	/* This is the default, try to (re)locate the device. */
143 	conf_hw(dep, instance);
144 
145 	dp_init(dep, instance);
146 
147 	memcpy(addr, dep->de_address.na_addr, sizeof(*addr));
148 	*caps = NDEV_CAP_MCAST | NDEV_CAP_BCAST;
149 	*ticks = sys_hz(); /* update statistics once a second */
150 	return OK;
151 }
152 
153 #if 0
154 /*===========================================================================*
155  *				dp8390_dump				     *
156  *===========================================================================*/
157 void dp8390_dump(void)
158 {
159 	dpeth_t *dep;
160 	int isr;
161 
162 	dep = &de_state;
163 
164 	printf("\n");
165 	printf("dp8390 statistics of %s:\n", netdriver_name());
166 
167 	isr= inb_reg0(dep, DP_ISR);
168 	printf("dp_isr = 0x%x + 0x%x, de_flags = 0x%x\n", isr,
169 				inb_reg0(dep, DP_ISR), dep->de_flags);
170 }
171 #endif
172 
173 /*===========================================================================*
174  *				pci_env					     *
175  *===========================================================================*/
176 static int pci_env(unsigned int instance)
177 {
178 	char envvar[16], value[EP_BUF_SIZE];
179 	const char punct[] = ":,;.";
180 
181 	strlcpy(envvar, "DPETH0", sizeof(envvar));
182 	envvar[5] += instance;
183 
184 	/* If no setting with this name is present, default to PCI. */
185 	if (env_get_param(envvar, value, sizeof(value)) != 0)
186 		return TRUE;
187 
188 	/* Legacy support: check for a "pci" prefix. */
189 	return (strncmp(value, "pci", 3) == 0 &&
190 	    strchr(punct, value[3]) != NULL);
191 }
192 
193 /*===========================================================================*
194  *				pci_conf				     *
195  *===========================================================================*/
196 static void pci_conf(unsigned int instance)
197 {
198 	struct dpeth *dep;
199 	unsigned int i, pci_instance;
200 
201 	dep= &de_state;
202 
203 	if (!(dep->de_pci= pci_env(instance)))
204 		return;	/* no PCI config */
205 
206 	/* Count the number of dp instances before this one that are configured
207 	 * for PCI, so that we can skip that many when enumerating PCI devices.
208 	 */
209 	pci_instance= 0;
210 	for (i= 0; i < instance; i++) {
211 		if (pci_env(i))
212 			pci_instance++;
213 	}
214 
215 	if (!rtl_probe(dep, pci_instance))
216 		panic("no matching PCI device found");
217 }
218 
219 /*===========================================================================*
220  *				do_send					     *
221  *===========================================================================*/
222 static int do_send(struct netdriver_data *data, size_t size)
223 {
224 	int sendq_head;
225 	dpeth_t *dep;
226 
227 	dep= &de_state;
228 
229 	sendq_head= dep->de_sendq_head;
230 	if (dep->de_sendq[sendq_head].sq_filled)
231 		return SUSPEND;
232 
233 	(dep->de_user2nicf_s)(dep, data,
234 		dep->de_sendq[sendq_head].sq_sendpage * DP_PAGESIZE, 0, size);
235 
236 	dep->de_sendq[sendq_head].sq_filled= TRUE;
237 	if (dep->de_sendq_tail == sendq_head)
238 	{
239 		outb_reg0(dep, DP_TPSR, dep->de_sendq[sendq_head].sq_sendpage);
240 		outb_reg0(dep, DP_TBCR1, size >> 8);
241 		outb_reg0(dep, DP_TBCR0, size & 0xff);
242 		outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);/* there it goes.. */
243 	}
244 	else
245 		dep->de_sendq[sendq_head].sq_size= size;
246 
247 	if (++sendq_head == dep->de_sendq_nr)
248 		sendq_head= 0;
249 	assert(sendq_head < SENDQ_NR);
250 	dep->de_sendq_head= sendq_head;
251 
252 	return OK;
253 }
254 
255 /*===========================================================================*
256  *				do_set_mode				     *
257  *===========================================================================*/
258 static void do_set_mode(unsigned int mode,
259 	const netdriver_addr_t * mcast_list __unused,
260 	unsigned int mcast_count __unused)
261 {
262 	dpeth_t *dep;
263 	int dp_rcr_reg;
264 
265 	dep = &de_state;
266 
267 	outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
268 
269 	dp_rcr_reg = 0;
270 	if (mode & NDEV_MODE_PROMISC)
271 		dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM;
272 	if (mode & NDEV_MODE_BCAST)
273 		dp_rcr_reg |= RCR_AB;
274 	if (mode & (NDEV_MODE_MCAST_LIST | NDEV_MODE_MCAST_ALL))
275 		dp_rcr_reg |= RCR_AM;
276 	outb_reg0(dep, DP_RCR, dp_rcr_reg);
277 }
278 
279 /*===========================================================================*
280  *				dp_update_stats				     *
281  *===========================================================================*/
282 static void dp_update_stats(dpeth_t * dep)
283 {
284 
285 	netdriver_stat_ierror(inb_reg0(dep, DP_CNTR0));
286 	netdriver_stat_ierror(inb_reg0(dep, DP_CNTR1));
287 	netdriver_stat_ierror(inb_reg0(dep, DP_CNTR2));
288 }
289 
290 /*===========================================================================*
291  *				do_tick					     *
292  *===========================================================================*/
293 static void do_tick(void)
294 {
295 
296 	dp_update_stats(&de_state);
297 }
298 
299 /*===========================================================================*
300  *				do_stop					     *
301  *===========================================================================*/
302 static void do_stop(void)
303 {
304 	dpeth_t *dep;
305 
306 	dep = &de_state;
307 
308 	outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
309 	(dep->de_stopf)(dep);
310 }
311 
312 /*===========================================================================*
313  *				dp_init					     *
314  *===========================================================================*/
315 static void dp_init(dpeth_t *dep, unsigned int instance)
316 {
317 	int i, r;
318 
319 	/* General initialization */
320 	dep->de_flags = DEF_EMPTY;
321 	(*dep->de_initf)(dep);
322 
323 	dp_confaddr(dep, instance);
324 
325 	if (debug)
326 	{
327 		printf("%s: Ethernet address ", netdriver_name());
328 		for (i= 0; i < 6; i++)
329 			printf("%x%c", dep->de_address.na_addr[i],
330 							i < 5 ? ':' : '\n');
331 	}
332 
333 	/* Map buffer */
334 	map_hw_buffer(dep);
335 
336 	/* Initialization of the dp8390 following the mandatory procedure
337 	 * in reference manual ("DP8390D/NS32490D NIC Network Interface
338 	 * Controller", National Semiconductor, July 1995, Page 29).
339 	 */
340 	/* Step 1: */
341 	outb_reg0(dep, DP_CR, CR_PS_P0 | CR_STP | CR_DM_ABORT);
342 	/* Step 2: */
343 	if (dep->de_16bit)
344 		outb_reg0(dep, DP_DCR, DCR_WORDWIDE | DCR_8BYTES | DCR_BMS);
345 	else
346 		outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES | DCR_BMS);
347 	/* Step 3: */
348 	outb_reg0(dep, DP_RBCR0, 0);
349 	outb_reg0(dep, DP_RBCR1, 0);
350 	/* Step 4: */
351 	outb_reg0(dep, DP_RCR, 0);
352 	/* Step 5: */
353 	outb_reg0(dep, DP_TCR, TCR_INTERNAL);
354 	/* Step 6: */
355 	outb_reg0(dep, DP_BNRY, dep->de_startpage);
356 	outb_reg0(dep, DP_PSTART, dep->de_startpage);
357 	outb_reg0(dep, DP_PSTOP, dep->de_stoppage);
358 	/* Step 7: */
359 	outb_reg0(dep, DP_ISR, 0xFF);
360 	/* Step 8: */
361 	outb_reg0(dep, DP_IMR, IMR_PRXE | IMR_PTXE | IMR_RXEE | IMR_TXEE |
362 		IMR_OVWE | IMR_CNTE);
363 	/* Step 9: */
364 	outb_reg0(dep, DP_CR, CR_PS_P1 | CR_DM_ABORT | CR_STP);
365 
366 	outb_reg1(dep, DP_PAR0, dep->de_address.na_addr[0]);
367 	outb_reg1(dep, DP_PAR1, dep->de_address.na_addr[1]);
368 	outb_reg1(dep, DP_PAR2, dep->de_address.na_addr[2]);
369 	outb_reg1(dep, DP_PAR3, dep->de_address.na_addr[3]);
370 	outb_reg1(dep, DP_PAR4, dep->de_address.na_addr[4]);
371 	outb_reg1(dep, DP_PAR5, dep->de_address.na_addr[5]);
372 
373 	outb_reg1(dep, DP_MAR0, 0xff);
374 	outb_reg1(dep, DP_MAR1, 0xff);
375 	outb_reg1(dep, DP_MAR2, 0xff);
376 	outb_reg1(dep, DP_MAR3, 0xff);
377 	outb_reg1(dep, DP_MAR4, 0xff);
378 	outb_reg1(dep, DP_MAR5, 0xff);
379 	outb_reg1(dep, DP_MAR6, 0xff);
380 	outb_reg1(dep, DP_MAR7, 0xff);
381 
382 	outb_reg1(dep, DP_CURR, dep->de_startpage + 1);
383 	/* Step 10: */
384 	outb_reg0(dep, DP_CR, CR_DM_ABORT | CR_STA);
385 	/* Step 11: */
386 	outb_reg0(dep, DP_TCR, TCR_NORMAL);
387 
388 	inb_reg0(dep, DP_CNTR0);		/* reset counters by reading */
389 	inb_reg0(dep, DP_CNTR1);
390 	inb_reg0(dep, DP_CNTR2);
391 
392 	/* Finish the initialization. */
393 	for (i= 0; i<dep->de_sendq_nr; i++)
394 		dep->de_sendq[i].sq_filled= 0;
395 	dep->de_sendq_head= 0;
396 	dep->de_sendq_tail= 0;
397 	if (!dep->de_prog_IO)
398 	{
399 		dep->de_user2nicf_s= dp_user2nic_s;
400 		dep->de_nic2userf_s= dp_nic2user_s;
401 		dep->de_getblockf= dp_getblock;
402 	}
403 	else if (dep->de_16bit)
404 	{
405 		dep->de_user2nicf_s= dp_pio16_user2nic_s;
406 		dep->de_nic2userf_s= dp_pio16_nic2user_s;
407 		dep->de_getblockf= dp_pio16_getblock;
408 	}
409 	else
410 	{
411 		dep->de_user2nicf_s= dp_pio8_user2nic_s;
412 		dep->de_nic2userf_s= dp_pio8_nic2user_s;
413 		dep->de_getblockf= dp_pio8_getblock;
414 	}
415 
416 	/* Set the interrupt handler and policy. Do not automatically
417 	 * reenable interrupts. Return the IRQ line number on interrupts.
418  	 */
419  	dep->de_hook = dep->de_irq;
420 	r= sys_irqsetpolicy(dep->de_irq, 0, &dep->de_hook);
421 	if (r != OK)
422 		panic("sys_irqsetpolicy failed: %d", r);
423 
424 	r= sys_irqenable(&dep->de_hook);
425 	if (r != OK)
426 		panic("unable to enable interrupts: %d", r);
427 }
428 
429 /*===========================================================================*
430  *				dp_confaddr				     *
431  *===========================================================================*/
432 static void dp_confaddr(dpeth_t *dep, unsigned int instance)
433 {
434 	int i;
435 	char eakey[16];
436 	static char eafmt[]= "x:x:x:x:x:x";
437 	long v;
438 
439 	/* User defined ethernet address? */
440 	strlcpy(eakey, "DPETH0_EA", sizeof(eakey));
441 	eakey[5] += instance;
442 
443 	for (i= 0; i < 6; i++)
444 	{
445 		v= dep->de_address.na_addr[i];
446 		if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET)
447 		{
448 			break;
449 		}
450 		dep->de_address.na_addr[i]= v;
451 	}
452 
453 	if (i != 0 && i != 6) env_panic(eakey);	/* It's all or nothing */
454 }
455 
456 /*===========================================================================*
457  *				dp_reset				     *
458  *===========================================================================*/
459 static void dp_reset(dpeth_t *dep)
460 {
461 	int i;
462 
463 	/* Stop chip */
464 	outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
465 	outb_reg0(dep, DP_RBCR0, 0);
466 	outb_reg0(dep, DP_RBCR1, 0);
467 	for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RST) == 0); i++)
468 		; /* Do nothing */
469 	outb_reg0(dep, DP_TCR, TCR_1EXTERNAL|TCR_OFST);
470 	outb_reg0(dep, DP_CR, CR_STA|CR_DM_ABORT);
471 	outb_reg0(dep, DP_TCR, TCR_NORMAL);
472 
473 	/* Acknowledge the ISR_RDC (remote dma) interrupt. */
474 	for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RDC) == 0); i++)
475 		; /* Do nothing */
476 	outb_reg0(dep, DP_ISR, inb_reg0(dep, DP_ISR) & ~ISR_RDC);
477 
478 	/* Reset the transmit ring. If we were transmitting a packet, we
479 	 * pretend that the packet is processed. Higher layers will
480 	 * retransmit if the packet wasn't actually sent.
481 	 */
482 	dep->de_sendq_head= dep->de_sendq_tail= 0;
483 	for (i= 0; i<dep->de_sendq_nr; i++)
484 		dep->de_sendq[i].sq_filled= 0;
485 	netdriver_send();
486 	dep->de_flags &= ~DEF_STOPPED;
487 }
488 
489 /*===========================================================================*
490  *				do_intr					     *
491  *===========================================================================*/
492 static void do_intr(unsigned int __unused mask)
493 {
494 	dpeth_t *dep;
495 	int isr, tsr;
496 	int r, size, sendq_tail;
497 
498 	dep = &de_state;
499 
500 	for(;;)
501 	{
502 		isr = inb_reg0(dep, DP_ISR);
503 		if (!isr)
504 			break;
505 		outb_reg0(dep, DP_ISR, isr);
506 		if (isr & (ISR_PTX|ISR_TXE))
507 		{
508 			if (isr & ISR_TXE)
509 			{
510 #if DEBUG
511 				printf("%s: got send error\n",
512 				    netdriver_name());
513 #endif
514 				netdriver_stat_oerror(1);
515 			}
516 			else
517 			{
518 				tsr = inb_reg0(dep, DP_TSR);
519 
520 				if (tsr & TSR_PTX) {
521 					/* Transmission was successful. */
522 				}
523 #if 0	/* Reserved in later manuals, should be ignored */
524 				if (!(tsr & TSR_DFR))
525 				{
526 					/* In most (all?) implementations of
527 					 * the dp8390, this bit is set
528 					 * when the packet is not deferred
529 					 */
530 				}
531 #endif
532 				if (tsr & TSR_COL) netdriver_stat_coll(1);
533 			}
534 			sendq_tail= dep->de_sendq_tail;
535 
536 			if (!(dep->de_sendq[sendq_tail].sq_filled))
537 			{
538 				/* Software bug? */
539 				assert(!debug);
540 
541 				/* Or hardware bug? */
542 				printf(
543 				"%s: transmit interrupt, but not sending\n",
544 					netdriver_name());
545 				continue;
546 			}
547 			dep->de_sendq[sendq_tail].sq_filled= 0;
548 			if (++sendq_tail == dep->de_sendq_nr)
549 				sendq_tail= 0;
550 			dep->de_sendq_tail= sendq_tail;
551 			if (dep->de_sendq[sendq_tail].sq_filled)
552 			{
553 				size= dep->de_sendq[sendq_tail].sq_size;
554 				outb_reg0(dep, DP_TPSR,
555 					dep->de_sendq[sendq_tail].sq_sendpage);
556 				outb_reg0(dep, DP_TBCR1, size >> 8);
557 				outb_reg0(dep, DP_TBCR0, size & 0xff);
558 				outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);
559 			}
560 			netdriver_send();
561 		}
562 
563 		if (isr & ISR_PRX)
564 			netdriver_recv();
565 
566 		if (isr & ISR_RXE)
567 			netdriver_stat_ierror(1);
568 		if (isr & ISR_CNT)
569 			dp_update_stats(dep);
570 		if (isr & ISR_RDC)
571 		{
572 			/* Nothing to do */
573 		}
574 		if (isr & ISR_RST)
575 		{
576 			/* this means we got an interrupt but the ethernet
577 			 * chip is shutdown. We set the flag DEF_STOPPED,
578 			 * and continue processing arrived packets. When the
579 			 * receive buffer is empty, we reset the dp8390.
580 			 */
581 #if 0
582 			 { printW(); printf(
583 				"%s: NIC stopped\n", netdriver_name()); }
584 #endif
585 			dep->de_flags |= DEF_STOPPED;
586 			netdriver_recv(); /* see if we can reset right now */
587 			break;
588 		}
589 	}
590 
591 	if ((r = sys_irqenable(&dep->de_hook)) != OK)
592 		panic("unable enable interrupts: %d", r);
593 }
594 
595 /*===========================================================================*
596  *				do_recv					     *
597  *===========================================================================*/
598 static ssize_t do_recv(struct netdriver_data *data, size_t max)
599 {
600 	dpeth_t *dep;
601 	dp_rcvhdr_t header;
602 	unsigned pageno, curr, next;
603 	size_t length;
604 	int packet_processed;
605 	u16_t eth_type;
606 
607 	dep = &de_state;
608 
609 	packet_processed = FALSE;
610 	pageno = inb_reg0(dep, DP_BNRY) + 1;
611 	if (pageno == dep->de_stoppage) pageno = dep->de_startpage;
612 
613 	do
614 	{
615 		outb_reg0(dep, DP_CR, CR_PS_P1 | CR_EXTRA);
616 		curr = inb_reg1(dep, DP_CURR);
617 		outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
618 
619 		if (curr == pageno) {
620 			if (dep->de_flags & DEF_STOPPED) {
621 				/* The chip is stopped, and all arrived packets
622 				 * are delivered.
623 				 */
624 				dp_reset(dep);
625 			}
626 
627 			return SUSPEND;
628 		}
629 
630 		(dep->de_getblockf)(dep, pageno, (size_t)0, sizeof(header),
631 			&header);
632 		(dep->de_getblockf)(dep, pageno, sizeof(header) +
633 			2*sizeof(netdriver_addr_t), sizeof(eth_type),
634 			&eth_type);
635 
636 		length = (header.dr_rbcl | (header.dr_rbch << 8)) -
637 			sizeof(dp_rcvhdr_t);
638 		next = header.dr_next;
639 		if (length < NDEV_ETH_PACKET_MIN || length > max)
640 		{
641 			printf("%s: packet with strange length arrived: %d\n",
642 				netdriver_name(), (int) length);
643 			next= curr;
644 		}
645 		else if (next < dep->de_startpage || next >= dep->de_stoppage)
646 		{
647 			printf("%s: strange next page\n", netdriver_name());
648 			next= curr;
649 		}
650 		else if (header.dr_status & RSR_FO)
651 		{
652 			/* This is very serious, so we issue a warning and
653 			 * reset the buffers */
654 			printf("%s: fifo overrun, resetting receive buffer\n",
655 				netdriver_name());
656 			netdriver_stat_ierror(1);
657 			next = curr;
658 		}
659 		else if (header.dr_status & RSR_PRX)
660 		{
661 			dp_pkt2user_s(dep, data, pageno, length);
662 
663 			packet_processed = TRUE;
664 		}
665 		if (next == dep->de_startpage)
666 			outb_reg0(dep, DP_BNRY, dep->de_stoppage - 1);
667 		else
668 			outb_reg0(dep, DP_BNRY, next - 1);
669 
670 		pageno = next;
671 	} while (!packet_processed);
672 
673 	return length;
674 }
675 
676 /*===========================================================================*
677  *				dp_getblock				     *
678  *===========================================================================*/
679 static void dp_getblock(dpeth_t *dep, int page, size_t offset, size_t size,
680 	void *dst)
681 {
682 	offset = page * DP_PAGESIZE + offset;
683 
684 	memcpy(dst, dep->de_locmem + offset, size);
685 }
686 
687 /*===========================================================================*
688  *				dp_pio8_getblock			     *
689  *===========================================================================*/
690 static void dp_pio8_getblock(dpeth_t *dep, int page, size_t offset,
691 	size_t size, void *dst)
692 {
693 	offset = page * DP_PAGESIZE + offset;
694 	outb_reg0(dep, DP_RBCR0, size & 0xFF);
695 	outb_reg0(dep, DP_RBCR1, size >> 8);
696 	outb_reg0(dep, DP_RSAR0, offset & 0xFF);
697 	outb_reg0(dep, DP_RSAR1, offset >> 8);
698 	outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
699 
700 	insb(dep->de_data_port, dst, size);
701 }
702 
703 /*===========================================================================*
704  *				dp_pio16_getblock			     *
705  *===========================================================================*/
706 static void dp_pio16_getblock(dpeth_t *dep, int page, size_t offset,
707 	size_t size, void *dst)
708 {
709 	offset = page * DP_PAGESIZE + offset;
710 	outb_reg0(dep, DP_RBCR0, size & 0xFF);
711 	outb_reg0(dep, DP_RBCR1, size >> 8);
712 	outb_reg0(dep, DP_RSAR0, offset & 0xFF);
713 	outb_reg0(dep, DP_RSAR1, offset >> 8);
714 	outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
715 
716 	assert (!(size & 1));
717 	insw(dep->de_data_port, dst, size);
718 }
719 
720 /*===========================================================================*
721  *				dp_pkt2user_s				     *
722  *===========================================================================*/
723 static void dp_pkt2user_s(dpeth_t *dep, struct netdriver_data *data, int page,
724 	size_t length)
725 {
726 	unsigned int last, count;
727 
728 	last = page + (length - 1) / DP_PAGESIZE;
729 	if (last >= dep->de_stoppage)
730 	{
731 		count = (dep->de_stoppage - page) * DP_PAGESIZE -
732 			sizeof(dp_rcvhdr_t);
733 
734 		(dep->de_nic2userf_s)(dep, data,
735 		    page * DP_PAGESIZE + sizeof(dp_rcvhdr_t), 0, count);
736 		(dep->de_nic2userf_s)(dep, data,
737 		    dep->de_startpage * DP_PAGESIZE, count, length - count);
738 	}
739 	else
740 	{
741 		(dep->de_nic2userf_s)(dep, data,
742 		    page * DP_PAGESIZE + sizeof(dp_rcvhdr_t), 0, length);
743 	}
744 }
745 
746 /*===========================================================================*
747  *				dp_user2nic_s				     *
748  *===========================================================================*/
749 static void dp_user2nic_s(dpeth_t *dep, struct netdriver_data *data,
750 	int nic_addr, size_t offset, size_t count)
751 {
752 	netdriver_copyin(data, offset, dep->de_locmem + nic_addr, count);
753 }
754 
755 /*===========================================================================*
756  *				dp_pio8_user2nic_s			     *
757  *===========================================================================*/
758 static void dp_pio8_user2nic_s(dpeth_t *dep, struct netdriver_data *data,
759 	int nic_addr, size_t offset, size_t count)
760 {
761 	int i;
762 
763 	outb_reg0(dep, DP_ISR, ISR_RDC);
764 
765 	outb_reg0(dep, DP_RBCR0, count & 0xFF);
766 	outb_reg0(dep, DP_RBCR1, count >> 8);
767 	outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
768 	outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
769 	outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
770 
771 	netdriver_portoutb(data, offset, dep->de_data_port, count);
772 
773 	for (i= 0; i<100; i++)
774 	{
775 		if (inb_reg0(dep, DP_ISR) & ISR_RDC)
776 			break;
777 	}
778 	if (i == 100)
779 	{
780 		panic("dp8390: remote dma failed to complete");
781 	}
782 }
783 
784 /*===========================================================================*
785  *				dp_pio16_user2nic_s			     *
786  *===========================================================================*/
787 static void dp_pio16_user2nic_s(dpeth_t *dep, struct netdriver_data *data,
788 	int nic_addr, size_t offset, size_t count)
789 {
790 	size_t ecount;
791 	int i;
792 
793 	ecount= (count+1) & ~1;
794 
795 	outb_reg0(dep, DP_ISR, ISR_RDC);
796 	outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
797 	outb_reg0(dep, DP_RBCR1, ecount >> 8);
798 	outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
799 	outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
800 	outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
801 
802 	netdriver_portoutw(data, offset, dep->de_data_port, count);
803 
804 	for (i= 0; i<100; i++)
805 	{
806 		if (inb_reg0(dep, DP_ISR) & ISR_RDC)
807 			break;
808 	}
809 	if (i == 100)
810 	{
811 		panic("dp8390: remote dma failed to complete");
812 	}
813 }
814 
815 /*===========================================================================*
816  *				dp_nic2user_s				     *
817  *===========================================================================*/
818 static void dp_nic2user_s(dpeth_t *dep, struct netdriver_data *data,
819 	int nic_addr, size_t offset, size_t count)
820 {
821 	netdriver_copyout(data, offset, dep->de_locmem + nic_addr, count);
822 }
823 
824 /*===========================================================================*
825  *				dp_pio8_nic2user_s			     *
826  *===========================================================================*/
827 static void dp_pio8_nic2user_s(dpeth_t *dep, struct netdriver_data *data,
828 	int nic_addr, size_t offset, size_t count)
829 {
830 	outb_reg0(dep, DP_RBCR0, count & 0xFF);
831 	outb_reg0(dep, DP_RBCR1, count >> 8);
832 	outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
833 	outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
834 	outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
835 
836 	netdriver_portinb(data, offset, dep->de_data_port, count);
837 }
838 
839 /*===========================================================================*
840  *				dp_pio16_nic2user_s			     *
841  *===========================================================================*/
842 static void dp_pio16_nic2user_s(dpeth_t *dep, struct netdriver_data *data,
843 	int nic_addr, size_t offset, size_t count)
844 {
845 	size_t ecount;
846 
847 	ecount= (count+1) & ~1;
848 
849 	outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
850 	outb_reg0(dep, DP_RBCR1, ecount >> 8);
851 	outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
852 	outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
853 	outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
854 
855 	netdriver_portinw(data, offset, dep->de_data_port, count);
856 }
857 
858 /*===========================================================================*
859  *				conf_hw					     *
860  *===========================================================================*/
861 static void conf_hw(dpeth_t *dep, unsigned int instance)
862 {
863 	int confnr;
864 	dp_conf_t *dcp;
865 
866 	/* Pick a default configuration for this instance. */
867 	confnr= MIN(instance, DP_CONF_NR-1);
868 
869 	dcp= &dp_conf[confnr];
870 	update_conf(dep, dcp, instance);
871 	if (!wdeth_probe(dep) && !ne_probe(dep) && !el2_probe(dep))
872 		panic("no ethernet card found at 0x%x\n", dep->de_base_port);
873 
874 /* XXX */ if (dep->de_linmem == 0) dep->de_linmem= 0xFFFF0000;
875 }
876 
877 /*===========================================================================*
878  *				update_conf				     *
879  *===========================================================================*/
880 static void update_conf(dpeth_t *dep, dp_conf_t *dcp, unsigned int instance)
881 {
882 	long v;
883 	static char dpc_fmt[] = "x:d:x:x";
884 	char eckey[16];
885 
886 	if (dep->de_pci)
887 	{
888 		/* PCI device is present */
889 		return;		/* Already configured */
890 	}
891 
892 	strlcpy(eckey, "DPETH0", sizeof(eckey));
893 	eckey[5] += instance;
894 
895 	/* Get the default settings and modify them from the environment. */
896 	v= dcp->dpc_port;
897 	(void) env_parse(eckey, dpc_fmt, 0, &v, 0x0000L, 0xFFFFL);
898 	dep->de_base_port= v;
899 
900 	v= dcp->dpc_irq | DEI_DEFAULT;
901 	(void) env_parse(eckey, dpc_fmt, 1, &v, 0L, (long) NR_IRQ_VECTORS - 1);
902 	dep->de_irq= v;
903 
904 	v= dcp->dpc_mem;
905 	(void) env_parse(eckey, dpc_fmt, 2, &v, 0L, 0xFFFFFL);
906 	dep->de_linmem= v;
907 
908 	v= 0;
909 	(void) env_parse(eckey, dpc_fmt, 3, &v, 0x2000L, 0x8000L);
910 	dep->de_ramsize= v;
911 }
912 
913 /*===========================================================================*
914  *				map_hw_buffer				     *
915  *===========================================================================*/
916 static void map_hw_buffer(dpeth_t *dep)
917 {
918 
919 	if (dep->de_prog_IO)
920 	{
921 #if 0
922 		printf(
923 		"map_hw_buffer: programmed I/O, no need to map buffer\n");
924 #endif
925 		dep->de_locmem = (char *)-dep->de_ramsize; /* trap errors */
926 		return;
927 	}
928 
929 	dep->de_locmem=
930 		vm_map_phys(SELF, (void *) dep->de_linmem, dep->de_ramsize);
931 	if (dep->de_locmem == MAP_FAILED)
932 		panic("map_hw_buffer: vm_map_phys failed");
933 }
934 
935 u8_t inb(port_t port)
936 {
937 	int r;
938 	u32_t value;
939 
940 	r= sys_inb(port, &value);
941 	if (r != OK)
942 	{
943 		printf("inb failed for port 0x%x\n", port);
944 		panic("sys_inb failed: %d", r);
945 	}
946 	return value;
947 }
948 
949 u16_t inw(port_t port)
950 {
951 	int r;
952 	u32_t value;
953 
954 	r= sys_inw(port, &value);
955 	if (r != OK)
956 		panic("sys_inw failed: %d", r);
957 	return (u16_t) value;
958 }
959 
960 void outb(port_t port, u8_t value)
961 {
962 	int r;
963 
964 	r= sys_outb(port, value);
965 	if (r != OK)
966 		panic("sys_outb failed: %d", r);
967 }
968 
969 void outw(port_t port, u16_t value)
970 {
971 	int r;
972 
973 	r= sys_outw(port, value);
974 	if (r != OK)
975 		panic("sys_outw failed: %d", r);
976 }
977 
978 static void insb(port_t port, void *buf, size_t size)
979 {
980 	int r;
981 
982 	r= sys_insb(port, SELF, buf, size);
983 	if (r != OK)
984 		panic("sys_sdevio failed: %d", r);
985 }
986 
987 static void insw(port_t port, void *buf, size_t size)
988 {
989 	int r;
990 
991 	r= sys_insw(port, SELF, buf, size);
992 	if (r != OK)
993 		panic("sys_sdevio failed: %d", r);
994 }
995 
996 /*
997  * $PchId: dp8390.c,v 1.25 2005/02/10 17:32:07 philip Exp $
998  */
999