xref: /plan9/sys/src/9/pc/ether8390.c (revision ca045b349d1e3b05eaae4b7fb24367eecc5b0e8b)
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
dp8390getea(Ether * ether,uchar * ea)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
dp8390setea(Ether * ether)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*
_dp8390read(Dp8390 * ctlr,void * to,ulong from,ulong len)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*
dp8390read(Dp8390 * ctlr,void * to,ulong from,ulong len)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*
dp8390write(Dp8390 * ctlr,ulong to,void * from,ulong len)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
ringinit(Dp8390 * ctlr)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
getcurr(Dp8390 * ctlr)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
receive(Ether * ether)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
txstart(Ether * ether)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
transmit(Ether * ether)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
overflow(Ether * ether)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
interrupt(Ureg *,void * arg)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
setfilter(Ether * ether,Dp8390 * ctlr)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
promiscuous(void * arg,int)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
setbit(Dp8390 * ctlr,int bit,int on)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
multicast(void * arg,uchar * addr,int on)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
attach(Ether * ether)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
disable(Dp8390 * ctlr)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 static void
shutdown(Ether * ether)756 shutdown(Ether *ether)
757 {
758 	Dp8390 *ctlr;
759 
760 	ctlr = ether->ctlr;
761 	disable(ctlr);
762 }
763 
764 int
dp8390reset(Ether * ether)765 dp8390reset(Ether* ether)
766 {
767 	Dp8390 *ctlr;
768 
769 	ctlr = ether->ctlr;
770 
771 	/*
772 	 * This is the initialisation procedure described
773 	 * as 'mandatory' in the datasheet, with references
774 	 * to the 3C503 technical reference manual.
775 	 */
776 	disable(ctlr);
777 	if(ctlr->width != 1)
778 		regw(ctlr, Dcr, Ft4WORD|Ls|Wts);
779 	else
780 		regw(ctlr, Dcr, Ft4WORD|Ls);
781 
782 	regw(ctlr, Rbcr0, 0);
783 	regw(ctlr, Rbcr1, 0);
784 
785 	regw(ctlr, Tcr, LpbkNIC);
786 	regw(ctlr, Rcr, Mon);
787 
788 	/*
789 	 * Init the ring hardware and software ring pointers.
790 	 * Can't initialise ethernet address as it may not be
791 	 * known yet.
792 	 */
793 	ringinit(ctlr);
794 	regw(ctlr, Tpsr, ctlr->tstart);
795 
796 	/*
797 	 * Clear any pending interrupts and mask then all off.
798 	 */
799 	regw(ctlr, Isr, 0xFF);
800 	regw(ctlr, Imr, 0);
801 
802 	/*
803 	 * Leave the chip initialised,
804 	 * but in monitor mode.
805 	 */
806 	regw(ctlr, Cr, Page0|RdABORT|Sta);
807 
808 	/*
809 	 * Set up the software configuration.
810 	 */
811 	ether->attach = attach;
812 	ether->transmit = transmit;
813 	ether->interrupt = interrupt;
814 	ether->shutdown = shutdown;
815 	ether->ifstat = 0;
816 
817 	ether->promiscuous = promiscuous;
818 	ether->multicast = multicast;
819 	ether->arg = ether;
820 
821 	return 0;
822 }
823