FreeBSD/Linux Kernel Cross Reference
sys/pc/ether8390.c
1 /*
2 * National Semiconductor DP8390 and clone
3 * Network Interface Controller.
4 */
5 #include "u.h"
6 #include "../port/lib.h"
7 #include "mem.h"
8 #include "dat.h"
9 #include "fns.h"
10 #include "io.h"
11 #include "../port/error.h"
12 #include "../port/netif.h"
13
14 #include "etherif.h"
15 #include "ether8390.h"
16
17 enum { /* NIC core registers */
18 Cr = 0x00, /* command register, all pages */
19
20 /* Page 0, read */
21 Clda0 = 0x01, /* current local DMA address 0 */
22 Clda1 = 0x02, /* current local DMA address 1 */
23 Bnry = 0x03, /* boundary pointer (R/W) */
24 Tsr = 0x04, /* transmit status register */
25 Ncr = 0x05, /* number of collisions register */
26 Fifo = 0x06, /* FIFO */
27 Isr = 0x07, /* interrupt status register (R/W) */
28 Crda0 = 0x08, /* current remote DMA address 0 */
29 Crda1 = 0x09, /* current remote DMA address 1 */
30 Rsr = 0x0C, /* receive status register */
31 Ref0 = 0x0D, /* frame alignment errors */
32 Ref1 = 0x0E, /* CRC errors */
33 Ref2 = 0x0F, /* missed packet errors */
34
35 /* Page 0, write */
36 Pstart = 0x01, /* page start register */
37 Pstop = 0x02, /* page stop register */
38 Tpsr = 0x04, /* transmit page start address */
39 Tbcr0 = 0x05, /* transmit byte count register 0 */
40 Tbcr1 = 0x06, /* transmit byte count register 1 */
41 Rsar0 = 0x08, /* remote start address register 0 */
42 Rsar1 = 0x09, /* remote start address register 1 */
43 Rbcr0 = 0x0A, /* remote byte count register 0 */
44 Rbcr1 = 0x0B, /* remote byte count register 1 */
45 Rcr = 0x0C, /* receive configuration register */
46 Tcr = 0x0D, /* transmit configuration register */
47 Dcr = 0x0E, /* data configuration register */
48 Imr = 0x0F, /* interrupt mask */
49
50 /* Page 1, read/write */
51 Par0 = 0x01, /* physical address register 0 */
52 Curr = 0x07, /* current page register */
53 Mar0 = 0x08, /* multicast address register 0 */
54 };
55
56 enum { /* Cr */
57 Stp = 0x01, /* stop */
58 Sta = 0x02, /* start */
59 Txp = 0x04, /* transmit packet */
60 Rd0 = 0x08, /* remote DMA command */
61 Rd1 = 0x10,
62 Rd2 = 0x20,
63 RdREAD = Rd0, /* remote read */
64 RdWRITE = Rd1, /* remote write */
65 RdSEND = Rd1|Rd0, /* send packet */
66 RdABORT = Rd2, /* abort/complete remote DMA */
67 Ps0 = 0x40, /* page select */
68 Ps1 = 0x80,
69 Page0 = 0x00,
70 Page1 = Ps0,
71 Page2 = Ps1,
72 };
73
74 enum { /* Isr/Imr */
75 Prx = 0x01, /* packet received */
76 Ptx = 0x02, /* packet transmitted */
77 Rxe = 0x04, /* receive error */
78 Txe = 0x08, /* transmit error */
79 Ovw = 0x10, /* overwrite warning */
80 Cnt = 0x20, /* counter overflow */
81 Rdc = 0x40, /* remote DMA complete */
82 Rst = 0x80, /* reset status */
83 };
84
85 enum { /* Dcr */
86 Wts = 0x01, /* word transfer select */
87 Bos = 0x02, /* byte order select */
88 Las = 0x04, /* long address select */
89 Ls = 0x08, /* loopback select */
90 Arm = 0x10, /* auto-initialise remote */
91 Ft0 = 0x20, /* FIFO threshold select */
92 Ft1 = 0x40,
93 Ft1WORD = 0x00,
94 Ft2WORD = Ft0,
95 Ft4WORD = Ft1,
96 Ft6WORD = Ft1|Ft0,
97 };
98
99 enum { /* Tcr */
100 Crc = 0x01, /* inhibit CRC */
101 Lb0 = 0x02, /* encoded loopback control */
102 Lb1 = 0x04,
103 LpbkNORMAL = 0x00, /* normal operation */
104 LpbkNIC = Lb0, /* internal NIC module loopback */
105 LpbkENDEC = Lb1, /* internal ENDEC module loopback */
106 LpbkEXTERNAL = Lb1|Lb0, /* external loopback */
107 Atd = 0x08, /* auto transmit disable */
108 Ofst = 0x10, /* collision offset enable */
109 };
110
111 enum { /* Tsr */
112 Ptxok = 0x01, /* packet transmitted */
113 Col = 0x04, /* transmit collided */
114 Abt = 0x08, /* tranmit aborted */
115 Crs = 0x10, /* carrier sense lost */
116 Fu = 0x20, /* FIFO underrun */
117 Cdh = 0x40, /* CD heartbeat */
118 Owc = 0x80, /* out of window collision */
119 };
120
121 enum { /* Rcr */
122 Sep = 0x01, /* save errored packets */
123 Ar = 0x02, /* accept runt packets */
124 Ab = 0x04, /* accept broadcast */
125 Am = 0x08, /* accept multicast */
126 Pro = 0x10, /* promiscuous physical */
127 Mon = 0x20, /* monitor mode */
128 };
129
130 enum { /* Rsr */
131 Prxok = 0x01, /* packet received intact */
132 Crce = 0x02, /* CRC error */
133 Fae = 0x04, /* frame alignment error */
134 Fo = 0x08, /* FIFO overrun */
135 Mpa = 0x10, /* missed packet */
136 Phy = 0x20, /* physical/multicast address */
137 Dis = 0x40, /* receiver disabled */
138 Dfr = 0x80, /* deferring */
139 };
140
141 typedef struct Hdr Hdr;
142 struct Hdr {
143 uchar status;
144 uchar next;
145 uchar len0;
146 uchar len1;
147 };
148
149 void
150 dp8390getea(Ether* ether, uchar* ea)
151 {
152 Dp8390 *ctlr;
153 uchar cr;
154 int i;
155
156 ctlr = ether->ctlr;
157
158 /*
159 * Get the ethernet address from the chip.
160 * Take care to restore the command register
161 * afterwards.
162 */
163 ilock(ctlr);
164 cr = regr(ctlr, Cr) & ~Txp;
165 regw(ctlr, Cr, Page1|(~(Ps1|Ps0) & cr));
166 for(i = 0; i < Eaddrlen; i++)
167 ea[i] = regr(ctlr, Par0+i);
168 regw(ctlr, Cr, cr);
169 iunlock(ctlr);
170 }
171
172 void
173 dp8390setea(Ether* ether)
174 {
175 int i;
176 uchar cr;
177 Dp8390 *ctlr;
178
179 ctlr = ether->ctlr;
180
181 /*
182 * Set the ethernet address into the chip.
183 * Take care to restore the command register
184 * afterwards. Don't care about multicast
185 * addresses as multicast is never enabled
186 * (currently).
187 */
188 ilock(ctlr);
189 cr = regr(ctlr, Cr) & ~Txp;
190 regw(ctlr, Cr, Page1|(~(Ps1|Ps0) & cr));
191 for(i = 0; i < Eaddrlen; i++)
192 regw(ctlr, Par0+i, ether->ea[i]);
193 regw(ctlr, Cr, cr);
194 iunlock(ctlr);
195 }
196
197 static void*
198 _dp8390read(Dp8390* ctlr, void* to, ulong from, ulong len)
199 {
200 uchar cr;
201 int timo;
202
203 /*
204 * Read some data at offset 'from' in the card's memory
205 * using the DP8390 remote DMA facility, and place it at
206 * 'to' in main memory, via the I/O data port.
207 */
208 cr = regr(ctlr, Cr) & ~Txp;
209 regw(ctlr, Cr, Page0|RdABORT|Sta);
210 regw(ctlr, Isr, Rdc);
211
212 /*
213 * Set up the remote DMA address and count.
214 */
215 len = ROUNDUP(len, ctlr->width);
216 regw(ctlr, Rbcr0, len & 0xFF);
217 regw(ctlr, Rbcr1, (len>>8) & 0xFF);
218 regw(ctlr, Rsar0, from & 0xFF);
219 regw(ctlr, Rsar1, (from>>8) & 0xFF);
220
221 /*
222 * Start the remote DMA read and suck the data
223 * out of the I/O port.
224 */
225 regw(ctlr, Cr, Page0|RdREAD|Sta);
226 rdread(ctlr, to, len);
227
228 /*
229 * Wait for the remote DMA to complete. The timeout
230 * is necessary because this routine may be called on
231 * a non-existent chip during initialisation and, due
232 * to the miracles of the bus, it's possible to get this
233 * far and still be talking to a slot full of nothing.
234 */
235 for(timo = 10000; (regr(ctlr, Isr) & Rdc) == 0 && timo; timo--)
236 ;
237
238 regw(ctlr, Isr, Rdc);
239 regw(ctlr, Cr, cr);
240
241 return to;
242 }
243
244 void*
245 dp8390read(Dp8390* ctlr, void* to, ulong from, ulong len)
246 {
247 void *v;
248
249 ilock(ctlr);
250 v = _dp8390read(ctlr, to, from, len);
251 iunlock(ctlr);
252
253 return v;
254 }
255
256 static void*
257 dp8390write(Dp8390* ctlr, ulong to, void* from, ulong len)
258 {
259 ulong crda;
260 uchar cr;
261 int timo, width;
262
263 top:
264 /*
265 * Write some data to offset 'to' in the card's memory
266 * using the DP8390 remote DMA facility, reading it at
267 * 'from' in main memory, via the I/O data port.
268 */
269 cr = regr(ctlr, Cr) & ~Txp;
270 regw(ctlr, Cr, Page0|RdABORT|Sta);
271 regw(ctlr, Isr, Rdc);
272
273 len = ROUNDUP(len, ctlr->width);
274
275 /*
276 * Set up the remote DMA address and count.
277 * This is straight from the DP8390[12D] datasheet,
278 * hence the initial set up for read.
279 * Assumption here that the A7000 EtherV card will
280 * never need a dummyrr.
281 */
282 if(ctlr->dummyrr && (ctlr->width == 1 || ctlr->width == 2)){
283 if(ctlr->width == 2)
284 width = 1;
285 else
286 width = 0;
287 crda = to-1-width;
288 regw(ctlr, Rbcr0, (len+1+width) & 0xFF);
289 regw(ctlr, Rbcr1, ((len+1+width)>>8) & 0xFF);
290 regw(ctlr, Rsar0, crda & 0xFF);
291 regw(ctlr, Rsar1, (crda>>8) & 0xFF);
292 regw(ctlr, Cr, Page0|RdREAD|Sta);
293
294 for(timo=0;; timo++){
295 if(timo > 10000){
296 print("ether8390: dummyrr timeout; assuming nodummyrr\n");
297 ctlr->dummyrr = 0;
298 goto top;
299 }
300 crda = regr(ctlr, Crda0);
301 crda |= regr(ctlr, Crda1)<<8;
302 if(crda == to){
303 /*
304 * Start the remote DMA write and make sure
305 * the registers are correct.
306 */
307 regw(ctlr, Cr, Page0|RdWRITE|Sta);
308
309 crda = regr(ctlr, Crda0);
310 crda |= regr(ctlr, Crda1)<<8;
311 if(crda != to)
312 panic("crda write %lud to %lud\n", crda, to);
313
314 break;
315 }
316 }
317 }
318 else{
319 regw(ctlr, Rsar0, to & 0xFF);
320 regw(ctlr, Rsar1, (to>>8) & 0xFF);
321 regw(ctlr, Rbcr0, len & 0xFF);
322 regw(ctlr, Rbcr1, (len>>8) & 0xFF);
323 regw(ctlr, Cr, Page0|RdWRITE|Sta);
324 }
325
326 /*
327 * Pump the data into the I/O port
328 * then wait for the remote DMA to finish.
329 */
330 rdwrite(ctlr, from, len);
331 for(timo = 10000; (regr(ctlr, Isr) & Rdc) == 0 && timo; timo--)
332 ;
333
334 regw(ctlr, Isr, Rdc);
335 regw(ctlr, Cr, cr);
336
337 return (void*)to;
338 }
339
340 static void
341 ringinit(Dp8390* ctlr)
342 {
343 regw(ctlr, Pstart, ctlr->pstart);
344 regw(ctlr, Pstop, ctlr->pstop);
345 regw(ctlr, Bnry, ctlr->pstop-1);
346
347 regw(ctlr, Cr, Page1|RdABORT|Stp);
348 regw(ctlr, Curr, ctlr->pstart);
349 regw(ctlr, Cr, Page0|RdABORT|Stp);
350
351 ctlr->nxtpkt = ctlr->pstart;
352 }
353
354 static uchar
355 getcurr(Dp8390* ctlr)
356 {
357 uchar cr, curr;
358
359 cr = regr(ctlr, Cr) & ~Txp;
360 regw(ctlr, Cr, Page1|(~(Ps1|Ps0) & cr));
361 curr = regr(ctlr, Curr);
362 regw(ctlr, Cr, cr);
363
364 return curr;
365 }
366
367 static void
368 receive(Ether* ether)
369 {
370 Dp8390 *ctlr;
371 uchar curr, *p;
372 Hdr hdr;
373 ulong count, data, len;
374 Block *bp;
375
376 ctlr = ether->ctlr;
377 for(curr = getcurr(ctlr); ctlr->nxtpkt != curr; curr = getcurr(ctlr)){
378 data = ctlr->nxtpkt*Dp8390BufSz;
379 if(ctlr->ram)
380 memmove(&hdr, (void*)(ether->mem+data), sizeof(Hdr));
381 else
382 _dp8390read(ctlr, &hdr, data, sizeof(Hdr));
383
384 /*
385 * Don't believe the upper byte count, work it
386 * out from the software next-page pointer and
387 * the current next-page pointer.
388 */
389 if(hdr.next > ctlr->nxtpkt)
390 len = hdr.next - ctlr->nxtpkt - 1;
391 else
392 len = (ctlr->pstop-ctlr->nxtpkt) + (hdr.next-ctlr->pstart) - 1;
393 if(hdr.len0 > (Dp8390BufSz-sizeof(Hdr)))
394 len--;
395
396 len = ((len<<8)|hdr.len0)-4;
397
398 /*
399 * Chip is badly scrogged, reinitialise the ring.
400 */
401 if(hdr.next < ctlr->pstart || hdr.next >= ctlr->pstop
402 || len < 60 || len > sizeof(Etherpkt)){
403 print("dp8390: H%2.2ux+%2.2ux+%2.2ux+%2.2ux,%lud\n",
404 hdr.status, hdr.next, hdr.len0, hdr.len1, len);
405 regw(ctlr, Cr, Page0|RdABORT|Stp);
406 ringinit(ctlr);
407 regw(ctlr, Cr, Page0|RdABORT|Sta);
408
409 return;
410 }
411
412 /*
413 * If it's a good packet read it in to the software buffer.
414 * If the packet wraps round the hardware ring, read it in
415 * two pieces.
416 */
417 if((hdr.status & (Fo|Fae|Crce|Prxok)) == Prxok && (bp = iallocb(len))){
418 p = bp->rp;
419 bp->wp = p+len;
420 data += sizeof(Hdr);
421
422 if((data+len) >= ctlr->pstop*Dp8390BufSz){
423 count = ctlr->pstop*Dp8390BufSz - data;
424 if(ctlr->ram)
425 memmove(p, (void*)(ether->mem+data), count);
426 else
427 _dp8390read(ctlr, p, data, count);
428 p += count;
429 data = ctlr->pstart*Dp8390BufSz;
430 len -= count;
431 }
432 if(len){
433 if(ctlr->ram)
434 memmove(p, (void*)(ether->mem+data), len);
435 else
436 _dp8390read(ctlr, p, data, len);
437 }
438
439 /*
440 * Copy the packet to whoever wants it.
441 */
442 etheriq(ether, bp, 1);
443 }
444
445 /*
446 * Finished with this packet, update the
447 * hardware and software ring pointers.
448 */
449 ctlr->nxtpkt = hdr.next;
450
451 hdr.next--;
452 if(hdr.next < ctlr->pstart)
453 hdr.next = ctlr->pstop-1;
454 regw(ctlr, Bnry, hdr.next);
455 }
456 }
457
458 static void
459 txstart(Ether* ether)
460 {
461 int len;
462 Dp8390 *ctlr;
463 Block *bp;
464 uchar minpkt[ETHERMINTU], *rp;
465
466 ctlr = ether->ctlr;
467
468 /*
469 * This routine is called both from the top level and from interrupt
470 * level and expects to be called with ctlr already locked.
471 */
472 if(ctlr->txbusy)
473 return;
474 bp = qget(ether->oq);
475 if(bp == nil)
476 return;
477
478 /*
479 * Make sure the packet is of minimum length;
480 * copy it to the card's memory by the appropriate means;
481 * start the transmission.
482 */
483 len = BLEN(bp);
484 rp = bp->rp;
485 if(len < ETHERMINTU){
486 rp = minpkt;
487 memmove(rp, bp->rp, len);
488 memset(rp+len, 0, ETHERMINTU-len);
489 len = ETHERMINTU;
490 }
491
492 if(ctlr->ram)
493 memmove((void*)(ether->mem+ctlr->tstart*Dp8390BufSz), rp, len);
494 else
495 dp8390write(ctlr, ctlr->tstart*Dp8390BufSz, rp, len);
496 freeb(bp);
497
498 regw(ctlr, Tbcr0, len & 0xFF);
499 regw(ctlr, Tbcr1, (len>>8) & 0xFF);
500 regw(ctlr, Cr, Page0|RdABORT|Txp|Sta);
501
502 ether->outpackets++;
503 ctlr->txbusy = 1;
504 }
505
506 static void
507 transmit(Ether* ether)
508 {
509 Dp8390 *ctlr;
510
511 ctlr = ether->ctlr;
512
513 ilock(ctlr);
514 txstart(ether);
515 iunlock(ctlr);
516 }
517
518 static void
519 overflow(Ether *ether)
520 {
521 Dp8390 *ctlr;
522 uchar txp;
523 int resend;
524
525 ctlr = ether->ctlr;
526
527 /*
528 * The following procedure is taken from the DP8390[12D] datasheet,
529 * it seems pretty adamant that this is what has to be done.
530 */
531 txp = regr(ctlr, Cr) & Txp;
532 regw(ctlr, Cr, Page0|RdABORT|Stp);
533 delay(2);
534 regw(ctlr, Rbcr0, 0);
535 regw(ctlr, Rbcr1, 0);
536
537 resend = 0;
538 if(txp && (regr(ctlr, Isr) & (Txe|Ptx)) == 0)
539 resend = 1;
540
541 regw(ctlr, Tcr, LpbkNIC);
542 regw(ctlr, Cr, Page0|RdABORT|Sta);
543 receive(ether);
544 regw(ctlr, Isr, Ovw);
545 regw(ctlr, Tcr, LpbkNORMAL);
546
547 if(resend)
548 regw(ctlr, Cr, Page0|RdABORT|Txp|Sta);
549 }
550
551 static void
552 interrupt(Ureg*, void* arg)
553 {
554 Ether *ether;
555 Dp8390 *ctlr;
556 uchar isr, r;
557
558 ether = arg;
559 ctlr = ether->ctlr;
560
561 /*
562 * While there is something of interest,
563 * clear all the interrupts and process.
564 */
565 ilock(ctlr);
566 regw(ctlr, Imr, 0x00);
567 while(isr = (regr(ctlr, Isr) & (Cnt|Ovw|Txe|Rxe|Ptx|Prx))){
568 if(isr & Ovw){
569 overflow(ether);
570 regw(ctlr, Isr, Ovw);
571 ether->overflows++;
572 }
573
574 /*
575 * Packets have been received.
576 * Take a spin round the ring.
577 */
578 if(isr & (Rxe|Prx)){
579 receive(ether);
580 regw(ctlr, Isr, Rxe|Prx);
581 }
582
583 /*
584 * A packet completed transmission, successfully or
585 * not. Start transmission on the next buffered packet,
586 * and wake the output routine.
587 */
588 if(isr & (Txe|Ptx)){
589 r = regr(ctlr, Tsr);
590 if((isr & Txe) && (r & (Cdh|Fu|Crs|Abt))){
591 print("dp8390: Tsr %#2.2ux", r);
592 ether->oerrs++;
593 }
594
595 regw(ctlr, Isr, Txe|Ptx);
596
597 if(isr & Ptx)
598 ether->outpackets++;
599 ctlr->txbusy = 0;
600 txstart(ether);
601 }
602
603 if(isr & Cnt){
604 ether->frames += regr(ctlr, Ref0);
605 ether->crcs += regr(ctlr, Ref1);
606 ether->buffs += regr(ctlr, Ref2);
607 regw(ctlr, Isr, Cnt);
608 }
609 }
610 regw(ctlr, Imr, Cnt|Ovw|Txe|Rxe|Ptx|Prx);
611 iunlock(ctlr);
612 }
613
614 static uchar allmar[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
615
616 static void
617 setfilter(Ether *ether, Dp8390 *ctlr)
618 {
619 uchar r, cr;
620 int i;
621 uchar *mar;
622
623 r = Ab;
624 mar = 0;
625 if(ether->prom){
626 r |= Pro|Am;
627 mar = allmar;
628 } else if(ether->nmaddr){
629 r |= Am;
630 mar = ctlr->mar;
631 }
632 if(mar){
633 cr = regr(ctlr, Cr) & ~Txp;
634 regw(ctlr, Cr, Page1|(~(Ps1|Ps0) & cr));
635 for(i = 0; i < 8; i++)
636 regw(ctlr, Mar0+i, *(mar++));
637 regw(ctlr, Cr, cr);
638 }
639 regw(ctlr, Rcr, r);
640 }
641
642 static void
643 promiscuous(void *arg, int )
644 {
645 Ether *ether;
646 Dp8390 *ctlr;
647
648 ether = arg;
649 ctlr = ether->ctlr;
650
651 ilock(ctlr);
652 setfilter(ether, ctlr);
653 iunlock(ctlr);
654 }
655
656 static void
657 setbit(Dp8390 *ctlr, int bit, int on)
658 {
659 int i, h;
660
661 i = bit/8;
662 h = bit%8;
663 if(on){
664 if(++(ctlr->mref[bit]) == 1)
665 ctlr->mar[i] |= 1<<h;
666 } else {
667 if(--(ctlr->mref[bit]) <= 0){
668 ctlr->mref[bit] = 0;
669 ctlr->mar[i] &= ~(1<<h);
670 }
671 }
672 }
673
674 static uchar reverse[64];
675
676 static void
677 multicast(void* arg, uchar *addr, int on)
678 {
679 Ether *ether;
680 Dp8390 *ctlr;
681 int i;
682 ulong h;
683
684 ether = arg;
685 ctlr = ether->ctlr;
686 if(reverse[1] == 0){
687 for(i = 0; i < 64; i++)
688 reverse[i] = ((i&1)<<5) | ((i&2)<<3) | ((i&4)<<1)
689 | ((i&8)>>1) | ((i&16)>>3) | ((i&32)>>5);
690 }
691
692 /*
693 * change filter bits
694 */
695 h = ethercrc(addr, 6);
696 ilock(ctlr);
697 setbit(ctlr, reverse[h&0x3f], on);
698 setfilter(ether, ctlr);
699 iunlock(ctlr);
700 }
701
702 static void
703 attach(Ether* ether)
704 {
705 Dp8390 *ctlr;
706 uchar r;
707
708 ctlr = ether->ctlr;
709
710 /*
711 * Enable the chip for transmit/receive.
712 * The init routine leaves the chip in monitor
713 * mode. Clear the missed-packet counter, it
714 * increments while in monitor mode.
715 * Sometimes there's an interrupt pending at this
716 * point but there's nothing in the Isr, so
717 * any pending interrupts are cleared and the
718 * mask of acceptable interrupts is enabled here.
719 */
720 r = Ab;
721 if(ether->prom)
722 r |= Pro;
723 if(ether->nmaddr)
724 r |= Am;
725 ilock(ctlr);
726 regw(ctlr, Isr, 0xFF);
727 regw(ctlr, Imr, Cnt|Ovw|Txe|Rxe|Ptx|Prx);
728 regw(ctlr, Rcr, r);
729 r = regr(ctlr, Ref2);
730 regw(ctlr, Tcr, LpbkNORMAL);
731 iunlock(ctlr);
732 USED(r);
733 }
734
735 static void
736 disable(Dp8390* ctlr)
737 {
738 int timo;
739
740 /*
741 * Stop the chip. Set the Stp bit and wait for the chip
742 * to finish whatever was on its tiny mind before it sets
743 * the Rst bit.
744 * The timeout is needed because there may not be a real
745 * chip there if this is called when probing for a device
746 * at boot.
747 */
748 regw(ctlr, Cr, Page0|RdABORT|Stp);
749 regw(ctlr, Rbcr0, 0);
750 regw(ctlr, Rbcr1, 0);
751 for(timo = 10000; (regr(ctlr, Isr) & Rst) == 0 && timo; timo--)
752 ;
753 }
754
755 int
756 dp8390reset(Ether* ether)
757 {
758 Dp8390 *ctlr;
759
760 ctlr = ether->ctlr;
761
762 /*
763 * This is the initialisation procedure described
764 * as 'mandatory' in the datasheet, with references
765 * to the 3C503 technical reference manual.
766 */
767 disable(ctlr);
768 if(ctlr->width != 1)
769 regw(ctlr, Dcr, Ft4WORD|Ls|Wts);
770 else
771 regw(ctlr, Dcr, Ft4WORD|Ls);
772
773 regw(ctlr, Rbcr0, 0);
774 regw(ctlr, Rbcr1, 0);
775
776 regw(ctlr, Tcr, LpbkNIC);
777 regw(ctlr, Rcr, Mon);
778
779 /*
780 * Init the ring hardware and software ring pointers.
781 * Can't initialise ethernet address as it may not be
782 * known yet.
783 */
784 ringinit(ctlr);
785 regw(ctlr, Tpsr, ctlr->tstart);
786
787 /*
788 * Clear any pending interrupts and mask then all off.
789 */
790 regw(ctlr, Isr, 0xFF);
791 regw(ctlr, Imr, 0);
792
793 /*
794 * Leave the chip initialised,
795 * but in monitor mode.
796 */
797 regw(ctlr, Cr, Page0|RdABORT|Sta);
798
799 /*
800 * Set up the software configuration.
801 */
802 ether->attach = attach;
803 ether->transmit = transmit;
804 ether->interrupt = interrupt;
805 ether->ifstat = 0;
806
807 ether->promiscuous = promiscuous;
808 ether->multicast = multicast;
809 ether->arg = ether;
810
811 return 0;
812 }
Cache object: 0e1093ae42accf71b3fe0e0838e99724
|