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 *===========================================================================*/
main(int argc,char * argv[])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 *===========================================================================*/
do_init(unsigned int instance,netdriver_addr_t * addr,uint32_t * caps,unsigned int * ticks)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 *===========================================================================*/
pci_env(unsigned int instance)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 *===========================================================================*/
pci_conf(unsigned int instance)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 *===========================================================================*/
do_send(struct netdriver_data * data,size_t size)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 *===========================================================================*/
do_set_mode(unsigned int mode,const netdriver_addr_t * mcast_list __unused,unsigned int mcast_count __unused)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 *===========================================================================*/
dp_update_stats(dpeth_t * dep)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 *===========================================================================*/
do_tick(void)293 static void do_tick(void)
294 {
295
296 dp_update_stats(&de_state);
297 }
298
299 /*===========================================================================*
300 * do_stop *
301 *===========================================================================*/
do_stop(void)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 *===========================================================================*/
dp_init(dpeth_t * dep,unsigned int instance)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 *===========================================================================*/
dp_confaddr(dpeth_t * dep,unsigned int instance)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 *===========================================================================*/
dp_reset(dpeth_t * dep)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 *===========================================================================*/
do_intr(unsigned int __unused mask)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 *===========================================================================*/
do_recv(struct netdriver_data * data,size_t max)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 ð_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 *===========================================================================*/
dp_getblock(dpeth_t * dep,int page,size_t offset,size_t size,void * dst)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 *===========================================================================*/
dp_pio8_getblock(dpeth_t * dep,int page,size_t offset,size_t size,void * dst)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 *===========================================================================*/
dp_pio16_getblock(dpeth_t * dep,int page,size_t offset,size_t size,void * dst)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 *===========================================================================*/
dp_pkt2user_s(dpeth_t * dep,struct netdriver_data * data,int page,size_t length)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 *===========================================================================*/
dp_user2nic_s(dpeth_t * dep,struct netdriver_data * data,int nic_addr,size_t offset,size_t count)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 *===========================================================================*/
dp_pio8_user2nic_s(dpeth_t * dep,struct netdriver_data * data,int nic_addr,size_t offset,size_t count)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 *===========================================================================*/
dp_pio16_user2nic_s(dpeth_t * dep,struct netdriver_data * data,int nic_addr,size_t offset,size_t count)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 *===========================================================================*/
dp_nic2user_s(dpeth_t * dep,struct netdriver_data * data,int nic_addr,size_t offset,size_t count)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 *===========================================================================*/
dp_pio8_nic2user_s(dpeth_t * dep,struct netdriver_data * data,int nic_addr,size_t offset,size_t count)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 *===========================================================================*/
dp_pio16_nic2user_s(dpeth_t * dep,struct netdriver_data * data,int nic_addr,size_t offset,size_t count)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 *===========================================================================*/
conf_hw(dpeth_t * dep,unsigned int instance)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 *===========================================================================*/
update_conf(dpeth_t * dep,dp_conf_t * dcp,unsigned int instance)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 *===========================================================================*/
map_hw_buffer(dpeth_t * dep)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
inb(port_t port)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
inw(port_t port)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
outb(port_t port,u8_t value)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
outw(port_t port,u16_t value)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
insb(port_t port,void * buf,size_t size)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
insw(port_t port,void * buf,size_t size)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