1 /*
2 * ethernet
3 */
4
5 #include "u.h"
6 #include "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 "ethermii.h"
15 #include "etherif.h"
16 #include "ureg.h"
17
18 /*
19 * TO DO:
20 * - test EMAC1
21 */
22
23 #define DBG if(0)iprint
24 #define MIIDBG if(0)iprint
25
26 enum {
27 Nrdre = 64, /* receive descriptor ring entries */
28 Ntdre = 32, /* transmit descriptor ring entries */
29 Nrxchan = 2,
30 Ntxchan = 2, /* there are actually 4 but we only use 2 now */
31
32 Rbsize = ETHERMAXTU, /* ring buffer size */
33 Bufsize = (Rbsize+CACHELINESZ-1)&~(CACHELINESZ-1), /* aligned */
34 };
35
36 enum {
37 /* emac-specific Rx BD bits */
38 RxOverrun= 1<<9, /* not enough empty space in FIFO */
39 RxPause= 1<<8, /* control pause packet */
40 RxBad= 1<<7, /* packet error */
41 RxRunt= 1<<6,
42 RxShort= 1<<5,
43 RxAlign= 1<<4,
44 RxFCS= 1<<3,
45 RxLong= 1<<2,
46 RxRange= 1<<1, /* out of range error */
47 RxInRange= 1<<0, /* in range error */
48 RxError= (0x3FF & ~RxPause), /* error flags */
49
50 /* emac-specific Tx BD bits */
51 /* write access */
52 TxFCS= 1<<9, /* generate FCS */
53 TxPad= 1<<8, /* pad short frames */
54 TxInsSA= 1<<7, /* insert source address */
55 TxRepSA= 1<<6, /* replace source address */
56 TxInsVLAN= 1<<5, /* insert VLAN tag */
57 TxRepVLAN= 1<<4, /* replace VLAN tag */
58
59 /* read access (status) */
60 TxBadFCS= 1<<9,
61 TxBadPrev= 1<<8, /* bad previous packet in dependent mode */
62 TxLostCarrier= 1<<7,
63 TxEDef= 1<<6, /* excessive deferral */
64 TxECol= 1<<5, /* excessive collisions */
65 TxLateCol= 1<<4, /* late collision (half-duplex only) */
66 TxManyCol= 1<<3, /* more than 1 but less than 16 collisions */
67 TxCollision= 1<<2, /* single collision */
68 TxUnderrun= 1<<1, /* didn't fill FIFO in time */
69 TxSQE= 1<<0, /* signal quality test failed (10mbit half-duplex only) */
70 TxError= 0x3FF, /* error flags */
71 };
72
73 typedef struct Emac Emac;
74 struct Emac {
75 ulong mr0; /* mode register 0 [see 19-48] */
76 ulong mr1; /* mode register 1 [Reset] */
77 ulong tmr0; /* transmit mode register 0 [see 19-28] */
78 ulong tmr1; /* transmit mode register 1 [see 19-28] */
79 ulong rmr; /* receive mode register [Reset] */
80 ulong isr; /* interrupt status register [Always] */
81 ulong iser; /* interrupt status enable register [Reset] */
82 ulong iahr; /* individual address high [Reset, R, T]*/
83 ulong ialr; /* individual address low [Reset, R, T] */
84 ulong vtpid; /* VLAN Tag Protocol Identifier [Reset, R, T] */
85 ulong vtci; /* VLAN Tag Control Information [Reset, R, T] */
86 ulong ptr; /* pause timer [Reset, T] */
87 ulong iaht[4]; /* individual address hash table [Reset, R] */
88 ulong gaht[4]; /* group address hash table [Reset, R] */
89 ulong lsah; /* last source address high */
90 ulong lsal; /* last source address low */
91 ulong ipgvr; /* inter-packet gap value [Reset, T] */
92 ulong stacr; /* STA control register [see 19-41] */
93 ulong trtr; /* transmit request threshold register [see 19-42] */
94 ulong rwmr; /* receive low/high water mark [Reset] */
95 ulong octx; /* bytes transmitted */
96 ulong ocrx; /* bytes received */
97 };
98
99 enum {
100 /* mode register 0 */
101 Mr0Rxi= 1<<31, /* receive MAC idle */
102 Mr0Txi= 1<<30, /* transmit MAC idle */
103 Mr0Srst= 1<<29, /* soft reset; soft reset in progress */
104 Mr0Txe= 1<<28, /* tx MAC enable */
105 Mr0Rxe= 1<<27, /* rx MAC enable */
106 Mr0Wke= 1<<26, /* enable wake-up packets */
107
108 /* mode register 1 */
109 Mr1Fde= 1<<31, /* full-duplex enable */
110 Mr1Ile= 1<<30, /* internal loop-back enable */
111 Mr1Vle= 1<<29, /* VLAN enable */
112 Mr1Eifc= 1<<28, /* enable integrated flow control */
113 Mr1App= 1<<27, /* allow pause packets */
114 Mr1Ist= 1<<24, /* ignore sqe test (all but half-duplex 10m/bit) */
115 Mr1Mf10= 0<<22, /* medium [MII] frequency is 10 mbps */
116 Mr1Mf100= 1<<22, /* medium frequency is 100 mbps */
117 Mr1Rfs512= 0<<20, /* RX FIFO size (512 bytes) */
118 Mr1Rfs1024= 1<<20,
119 Mr1Rfs2048= 2<<20,
120 Mr1Rfs4096= 3<<20,
121 Mr1Tfs1024= 1<<18, /* TX FIFO size (1024 bytes) */
122 Mr1Tfs2048= 2<<18,
123 Mr1Tr0sp= 0<<15, /* transmit request 0: single packet */
124 Mr1Tr0mp= 1<<15, /* multiple packets */
125 Mr1Tr0dm= 2<<15, /* dependent mode */
126 Mr1Tr1sp= 0<<13, /* transmit request 1: single packet */
127 Mr1Tr1mp= 1<<13, /* multiple packets */
128 Mr1Tr1dm= 2<<13, /* dependent mode */
129
130 /* transmit mode register 0 */
131 Tmr0Gnp0= 1<<31, /* get new packet channel 0 */
132 Tmr0Gnp1= 1<<30, /* get new packet channel 1 */
133 Tmr0Gnpd= 1<<29, /* get new packet dependent mode */
134 Tmr0Fc= 1<<28, /* first channel (dependent mode) */
135
136 /* transmit mode register 1 */
137 Tmr1Trl_s= 27, /* transmit low request (shift) */
138 Tmr1Tur_s= 16, /* transmit urgent request (shift) */
139
140 /* receive mode register */
141 RmrSp= 1<<31, /* strip pad/FCS bytes */
142 RmrSfcs= 1<<30, /* strip FCS */
143 RmrRrp= 1<<29, /* receive runt packets */
144 RmrRfp= 1<<28, /* receive packets with FCS error */
145 RmrRop= 1<<27, /* receive oversize packets */
146 RmrRpir= 1<<26, /* receive packets with in range error */
147 RmrPpp= 1<<25, /* propagate pause packet */
148 RmrPme= 1<<24, /* promiscuous mode enable */
149 RmrPmme= 1<<23, /* promiscuous mode multicast enable */
150 RmrIae= 1<<22, /* individual address enable */
151 RmrMiae= 1<<21, /* multiple individual address enable */
152 RmrBae= 1<<20, /* broadcast address enable */
153 RmrMae= 1<<19, /* multicast address enable */
154
155 /* interrupt status register */
156 IsrOvr= 1<<25, /* overrun error */
157 IsrPp= 1<<24, /* pause packet */
158 IsrBp= 1<<23, /* bad packet */
159 IsrRp= 1<<22, /* runt packet */
160 IsrSe= 1<<21, /* short event */
161 IsrAle= 1<<20, /* alignment error */
162 IsrBfcs= 1<<19, /* bad FCS */
163 IsrPtle= 1<<18, /* packet too long error */
164 IsrOre= 1<<17, /* out of range error */
165 IsrIre= 1<<16, /* in range error */
166 IsrDbdm= 1<<9, /* dead bit dependent mode */
167 IsrDb0= 1<<8, /* dead bit 0 */
168 IsrSe0= 1<<7, /* sqe 0 */
169 IsrTe0= 1<<6, /* tx error 0 */
170 IsrDb1= 1<<5, /* dead bit 1 */
171 IsrSe1= 1<<4, /* sqe 1 */
172 IsrTe1= 1<<3, /* tx error 1 */
173 IsrMos= 1<<1, /* MMA operation succeeded */
174 IsrMof= 1<<0, /* MMA operation failed */
175
176 /* STA control register */
177 StaOc= 1<<15, /* operation complete */
178 StaPhye= 1<<14, /* PHY error */
179 StaRead= 1<<12, /* STA read */
180 StaWrite= 2<<12, /* STA write */
181 StaOpb50= 0<<10, /* OPB frequency */
182 StaOpb66= 1<<10,
183 StaOpb83= 2<<10,
184 StaOpb100= 3<<10,
185
186 /* transmit request threshold */
187 TrtrTrt_s= 27, /* threshold (shift) -- and the value is (threshold/64)-1 */
188
189 /* receive low/high water mark register */
190 RwmrRlwm_s= 23, /* low water mark (shift) */
191 RwmrRhwm_s= 7, /* high water mark (shift) */
192 };
193
194 typedef struct {
195 Lock;
196 int port;
197 int init;
198 int active;
199 Emac *regs;
200 Emac *miiregs;
201 Mal* rx;
202 Mal* tx;
203
204 Mii *mii;
205
206 Ring;
207
208 ulong interrupts; /* statistics */
209 ulong deferred;
210 ulong heartbeat;
211 ulong latecoll;
212 ulong retrylim;
213 ulong underrun;
214 ulong overrun;
215 ulong carrierlost;
216 ulong retrycount;
217 } Ctlr;
218
219 static void dumpemac(Emac*);
220
221 static void
attach(Ether * ether)222 attach(Ether *ether)
223 {
224 Ctlr *ctlr;
225
226 ctlr = ether->ctlr;
227 ilock(ctlr);
228 if(!ctlr->active){
229 malrxenable(ctlr->rx);
230 maltxenable(ctlr->tx);
231 eieio();
232 ctlr->regs->mr0 = Mr0Txe | Mr0Rxe;
233 eieio();
234 ctlr->active = 1;
235 }
236 iunlock(ctlr);
237 }
238
239 static void
closed(Ether * ether)240 closed(Ether *ether)
241 {
242 Ctlr *ctlr;
243
244 ctlr = ether->ctlr;
245 if(ctlr->active){
246 ilock(ctlr);
247 iprint("ether closed\n");
248 ctlr->regs->mr0 &= ~(Mr0Txe | Mr0Rxe); /* reset enable bits */
249 /* TO DO: reset ring */
250 /* TO DO: could wait */
251 ctlr->active = 0;
252 iunlock(ctlr);
253 }
254 }
255
256 static void
promiscuous(void * arg,int on)257 promiscuous(void* arg, int on)
258 {
259 Ether *ether;
260 Ctlr *ctlr;
261
262 ether = (Ether*)arg;
263 ctlr = ether->ctlr;
264
265 ilock(ctlr);
266 if(on || ether->nmaddr)
267 ctlr->regs->rmr |= RmrPme | RmrPmme;
268 else
269 ctlr->regs->rmr &= ~(RmrPme | RmrPmme);
270 iunlock(ctlr);
271 }
272
273 static void
multicast(void * arg,uchar * addr,int on)274 multicast(void* arg, uchar *addr, int on)
275 {
276 Ether *ether;
277 Ctlr *ctlr;
278
279 USED(addr, on); /* if on, could SetGroupAddress; if !on, it's hard */
280
281 ether = (Ether*)arg;
282 ctlr = ether->ctlr;
283
284 ilock(ctlr);
285 if(ether->prom || ether->nmaddr)
286 ctlr->regs->rmr |= RmrPmme;
287 else
288 ctlr->regs->rmr &= ~RmrPmme;
289 iunlock(ctlr);
290 }
291
292 static void
txstart(Ether * ether)293 txstart(Ether *ether)
294 {
295 int len;
296 Ctlr *ctlr;
297 Block *b;
298 BD *dre;
299
300 ctlr = ether->ctlr;
301 while(ctlr->ntq < ctlr->ntdre-1){
302 b = qget(ether->oq);
303 if(b == 0)
304 break;
305
306 dre = &ctlr->tdr[ctlr->tdrh];
307 if(dre->status & BDReady)
308 panic("ether: txstart");
309
310 /*
311 * Give ownership of the descriptor to the chip, increment the
312 * software ring descriptor pointer and tell the chip to poll.
313 */
314 len = BLEN(b);
315 if(ctlr->txb[ctlr->tdrh] != nil)
316 panic("etheremac: txstart");
317 ctlr->txb[ctlr->tdrh] = b;
318 dre->addr = PADDR(b->rp);
319 dre->length = len;
320 dcflush(b->rp, len);
321 eieio();
322 dre->status = (dre->status & BDWrap) | BDReady|BDInt|BDLast|TxFCS|TxPad;
323 eieio();
324 ctlr->regs->tmr0 = Tmr0Gnp0; /* TO DO: several channels */
325 eieio();
326 ctlr->ntq++;
327 ctlr->tdrh = NEXT(ctlr->tdrh, ctlr->ntdre);
328 }
329 }
330
331 static void
transmit(Ether * ether)332 transmit(Ether* ether)
333 {
334 Ctlr *ctlr;
335
336 ctlr = ether->ctlr;
337 ilock(ctlr);
338 txstart(ether);
339 iunlock(ctlr);
340 }
341
342 /*
343 * allocate receive buffer space on cache-line boundaries
344 */
345 static Block*
clallocb(void)346 clallocb(void)
347 {
348 Block *b;
349
350 b = iallocb(Bufsize+CACHELINESZ-1);
351 if(b == nil)
352 return b;
353 dcflush(b->base, BALLOC(b));
354 b->wp = b->rp = (uchar*)(((ulong)b->base + CACHELINESZ - 1) & ~(CACHELINESZ-1));
355 return b;
356 }
357
358
359 static void
rxring(Ureg *,void * arg)360 rxring(Ureg*, void *arg)
361 {
362 Ether *ether;
363 ulong status;
364 Ctlr *ctlr;
365 BD *dre;
366 Block *b, *rb;
367
368 ether = arg;
369 ctlr = ether->ctlr;
370 ctlr->interrupts++;
371
372 /*
373 * Receiver interrupt: run round the descriptor ring logging
374 * errors and passing valid receive data up to the higher levels
375 * until we encounter a descriptor still owned by the chip.
376 * We rely on the descriptor accesses being uncached.
377 */
378 dre = &ctlr->rdr[ctlr->rdrx];
379 while(((status = dre->status) & BDEmpty) == 0){
380 if(status & RxError || (status & (BDFirst|BDLast)) != (BDFirst|BDLast)){
381 if(status & (RxShort|RxLong))
382 ether->buffs++;
383 if(status & (RxBad|RxAlign|RxRange|RxInRange))
384 ether->frames++;
385 if(status & RxFCS)
386 ether->crcs++;
387 if(status & RxOverrun)
388 ether->overflows++;
389 iprint("eth rx: %lux\n", status);
390 }else if((status & RxPause) == 0){
391 /*
392 * We have a packet. Read it in.
393 */
394 b = clallocb();
395 if(b != nil){
396 rb = ctlr->rxb[ctlr->rdrx];
397 rb->wp += dre->length;
398 ctlr->rxb[ctlr->rdrx] = b;
399 ctlr->rdr[ctlr->rdrx].addr = PADDR(b->wp);
400 etheriq(ether, rb, 1);
401 }else
402 ether->soverflows++;
403 }
404
405 /*
406 * Finished with this descriptor, reinitialise it,
407 * give it back to the chip, then on to the next...
408 */
409 dre->status = (status & BDWrap) | BDEmpty | BDInt;
410 eieio();
411
412 ctlr->rdrx = NEXT(ctlr->rdrx, ctlr->nrdre);
413 dre = &ctlr->rdr[ctlr->rdrx];
414 }
415 }
416
417 static void
txring(Ureg *,void * arg)418 txring(Ureg*, void *arg)
419 {
420 Ether *ether;
421 ulong status;
422 Ctlr *ctlr;
423 BD *dre;
424 Block *b;
425
426 ether = arg;
427 ctlr = ether->ctlr;
428 ctlr->interrupts++;
429
430 /*
431 * Transmitter interrupt: handle anything queued for a free descriptor.
432 */
433 lock(ctlr);
434 while(ctlr->ntq){
435 dre = &ctlr->tdr[ctlr->tdri];
436 status = dre->status;
437 if(status & BDReady)
438 break;
439 if(status & TxEDef)
440 ctlr->deferred++;
441 if(status & TxLateCol)
442 ctlr->latecoll++;
443 if(status & TxECol)
444 ctlr->retrylim++;
445 if(status & TxUnderrun)
446 ctlr->underrun++;
447 if(status & (TxManyCol|TxCollision))
448 ctlr->retrycount++;
449 b = ctlr->txb[ctlr->tdri];
450 if(b == nil)
451 panic("etheremac: bufp");
452 ctlr->txb[ctlr->tdri] = nil;
453 freeb(b);
454 ctlr->ntq--;
455 ctlr->tdri = NEXT(ctlr->tdri, ctlr->ntdre);
456 }
457 txstart(ether);
458 unlock(ctlr);
459 }
460
461 static void
interrupt(Ureg *,void * arg)462 interrupt(Ureg*, void *arg)
463 {
464 Ether *ether;
465 ulong events;
466 Ctlr *ctlr;
467
468 ether = arg;
469 ctlr = ether->ctlr;
470
471 events = ctlr->regs->isr;
472 eieio();
473 ctlr->regs->isr = events;
474 eieio();
475 ctlr->interrupts++;
476 //iprint("eth: %8.8lux\n", events);
477 if(!ctlr->active || events == 0)
478 return;
479
480 if(events & IsrOvr)
481 ctlr->overrun++;
482 if(events & (IsrTe0|IsrTe1))
483 ether->oerrs++;
484
485 rxring(nil, arg);
486 txring(nil, arg);
487 ctlr->interrupts -= 2;
488
489 /* TO DO: restart tx/rx on error */
490 }
491
492 static long
ifstat(Ether * ether,void * a,long n,ulong offset)493 ifstat(Ether* ether, void* a, long n, ulong offset)
494 {
495 char *p;
496 int len;
497 Ctlr *ctlr;
498
499 if(n == 0)
500 return 0;
501
502 ctlr = ether->ctlr;
503
504 p = malloc(READSTR);
505 len = snprint(p, READSTR, "interrupts: %lud\n", ctlr->interrupts);
506 len += snprint(p+len, READSTR-len, "carrierlost: %lud\n", ctlr->carrierlost);
507 len += snprint(p+len, READSTR-len, "heartbeat: %lud\n", ctlr->heartbeat);
508 len += snprint(p+len, READSTR-len, "retrylimit: %lud\n", ctlr->retrylim);
509 len += snprint(p+len, READSTR-len, "retrycount: %lud\n", ctlr->retrycount);
510 len += snprint(p+len, READSTR-len, "latecollisions: %lud\n", ctlr->latecoll);
511 len += snprint(p+len, READSTR-len, "rxoverruns: %lud\n", ctlr->overrun);
512 len += snprint(p+len, READSTR-len, "txunderruns: %lud\n", ctlr->underrun);
513 snprint(p+len, READSTR-len, "framesdeferred: %lud\n", ctlr->deferred);
514 n = readstr(offset, a, n, p);
515 free(p);
516
517 return n;
518 }
519
520 static QLock miilock; /* the PHY are both on EMAC0's MII bus */
521
522 static int
miird(Mii * mii,int pa,int ra)523 miird(Mii *mii, int pa, int ra)
524 {
525 Ctlr *ctlr;
526 Emac *em;
527 ulong r;
528 int i;
529
530 if(up)
531 qlock(&miilock);
532 ctlr = mii->ctlr;
533 em = ctlr->miiregs;
534 MIIDBG("r: %x.%x:", pa, ra);
535 if((em->stacr & StaOc) == 0)
536 iprint("mii-not oc\n");
537 em->stacr = StaRead | StaOpb66 | (pa<<5) | ra;
538 for(i=0; i<100 && (em->stacr & StaOc) == 0; i++)
539 microdelay(1);
540 r = em->stacr;
541 if(up)
542 qunlock(&miilock);
543 if((r & StaOc) == 0)
544 iprint("mii'-not oc\n");
545 if(r & StaPhye)
546 return -1;
547 MIIDBG(" %8.8lux\n", r);
548 return r >> 16;
549 }
550
551 static int
miiwr(Mii * mii,int pa,int ra,int v)552 miiwr(Mii *mii, int pa, int ra, int v)
553 {
554 Ctlr *ctlr;
555 Emac *em;
556 ulong r;
557 int i;
558
559 if(up)
560 qlock(&miilock);
561 ctlr = mii->ctlr;
562 em = ctlr->miiregs;
563 if((em->stacr & StaOc) == 0)
564 iprint("miiw-not oc\n");
565 em->stacr = (v<<16) | StaWrite | StaOpb66 | (pa<<5) | ra;
566 for(i=0; i<100 && (em->stacr & StaOc) == 0; i++)
567 microdelay(1);
568 r = em->stacr;
569 if(up)
570 qunlock(&miilock);
571 if((r & StaOc) == 0)
572 iprint("miiw'-not oc\n");
573 if(r & StaPhye)
574 return -1;
575 MIIDBG("w: %x.%x: %8.8lux\n", pa, ra, r);
576 return 0;
577 }
578
579 static int
emacmii(Ctlr * ctlr)580 emacmii(Ctlr *ctlr)
581 {
582 MiiPhy *phy;
583 int i;
584
585 MIIDBG("mii\n");
586 if((ctlr->mii = malloc(sizeof(Mii))) == nil)
587 return -1;
588 ctlr->mii->ctlr = ctlr;
589 ctlr->mii->mir = miird;
590 ctlr->mii->miw = miiwr;
591
592 if(mii(ctlr->mii, 1<<(ctlr->port+1)) == 0 || (phy = ctlr->mii->curphy) == nil){
593 free(ctlr->mii);
594 ctlr->mii = nil;
595 return -1;
596 }
597
598 iprint("oui %X phyno %d\n", phy->oui, phy->phyno);
599 if(miistatus(ctlr->mii) < 0){
600
601 miireset(ctlr->mii);
602 MIIDBG("miireset\n");
603 if(miiane(ctlr->mii, ~0, 0, ~0) < 0){
604 iprint("miiane failed\n");
605 return -1;
606 }
607 MIIDBG("miistatus...\n");
608 miistatus(ctlr->mii);
609 if(miird(ctlr->mii, phy->phyno, Bmsr) & BmsrLs){
610 for(i=0;; i++){
611 if(i > 600){
612 iprint("emac%d: autonegotiation failed\n", ctlr->port);
613 break;
614 }
615 if(miird(ctlr->mii, phy->phyno, Bmsr) & BmsrAnc)
616 break;
617 delay(10);
618 }
619 if(miistatus(ctlr->mii) < 0)
620 iprint("miistatus failed\n");
621 }else{
622 iprint("emac%d: no link\n", ctlr->port);
623 phy->speed = 10; /* simple default */
624 }
625 }
626
627 iprint("emac%d mii: fd=%d speed=%d tfc=%d rfc=%d\n", ctlr->port, phy->fd, phy->speed, phy->tfc, phy->rfc);
628
629 MIIDBG("mii done\n");
630
631 return 0;
632 }
633
634 static void
emacsetup(Ctlr * ctlr,Ether * ether)635 emacsetup(Ctlr *ctlr, Ether *ether)
636 {
637 int i;
638 Emac *em;
639 ulong mode;
640 MiiPhy *phy;
641
642 /* apparently don't need to set any Alt1 in GPIO */
643
644 em = ctlr->regs;
645
646 /* errata emac_8 */
647 if(em->mr0 & Mr0Rxe){ /* probably never happens in our config */
648 em->mr0 &= ~Mr0Rxe;
649 eieio();
650 for(i=0; (em->mr0 & Mr0Rxi) == 0; i++){
651 if(i > 100){
652 iprint("ethermac: Rxe->Rxi timed out\n");
653 break; /* we'll try soft reset anyway */
654 }
655 microdelay(100);
656 }
657 }
658
659 /* soft reset */
660 em->mr0 = Mr0Srst;
661 eieio();
662 for(i=0; em->mr0 & Mr0Srst; i++){
663 if(i > 20){
664 iprint("ethermac: reset (PHY clocks not running?)");
665 i=0;
666 }
667 microdelay(100);
668 }
669 iprint("%d: rx=%8.8lux tx=%8.8lux\n", ctlr->port, PADDR(ctlr->rdr), PADDR(ctlr->tdr));
670 //if(ctlr->port)return;
671
672 malrxinit(ctlr->rx, ctlr, Bufsize/16);
673 maltxinit(ctlr->tx, ctlr);
674 malrxreset(ctlr->rx);
675 maltxreset(ctlr->tx);
676
677 em->mr0 = 0;
678 mode = Mr1Rfs4096 | Mr1Tfs2048 | Mr1Tr0mp;
679 if(ctlr->mii != nil && (phy = ctlr->mii->curphy) != nil){
680 if(phy->speed == 10){
681 mode |= Mr1Mf10;
682 if(phy->fd)
683 mode |= Mr1Ist;
684 }else
685 mode |= Mr1Mf100 | Mr1Ist;
686 if(phy->fd)
687 mode |= Mr1Fde;
688 /* errata emac_9 suggests not using integrated flow control (it's broken); so don't negotiate it */
689 if(0 && (phy->rfc || phy->tfc))
690 mode |= Mr1App | Mr1Eifc;
691 ether->mbps = phy->speed;
692 ether->fullduplex = phy->fd;
693 }else{
694 iprint("mii: didn't work: default 100FD\n");
695 mode |= Mr1Mf100 | Mr1Ist | Mr1Fde;
696 ether->mbps = 100;
697 ether->fullduplex = 1;
698 }
699
700 em->mr1 = mode;
701 em->tmr1 = (9<<Tmr1Trl_s) | (256<<Tmr1Tur_s); /* TO DO: validate these sizes */
702 em->rmr = RmrSp | RmrSfcs | RmrIae | RmrBae;
703 em->iahr = (ether->ea[0]<<8) | ether->ea[1];
704 em->ialr = (ether->ea[2]<<24) | (ether->ea[3]<<16) | (ether->ea[4]<<8) | ether->ea[5];
705 em->vtpid = 0;
706 em->vtci = 0;
707 em->ptr = 1; /* pause timer [Reset, T] */
708 for(i=0; i<4; i++){
709 em->iaht[i] = 0; /* individual address hash table */
710 em->gaht[i] = 0; /* group address hash table */
711 }
712 em->ipgvr = (96/8)/3; /* minimise bit times between packets */
713 em->trtr = ((256/64)-1)<<TrtrTrt_s; /* transmission threshold (probably could be smaller) */
714 em->rwmr = (32<<RwmrRlwm_s) | (128<<RwmrRhwm_s); /* receive low/high water mark (TO DO: check) */
715 /* 0x0f002000? */
716 //dumpemac(em);
717 //dumpmal();
718 eieio();
719 em->isr = em->isr; /* clear all events */
720 eieio();
721 em->iser = IsrOvr | IsrBp | IsrSe | IsrSe0 | IsrTe0 | IsrSe1 | IsrTe1; /* enable various error interrupts */
722 /* packet tx/rx interrupts come from MAL */
723 eieio();
724
725 /* tx/rx enable is deferred until attach */
726 }
727
728 static int
reset(Ether * ether)729 reset(Ether* ether)
730 {
731 uchar ea[Eaddrlen];
732 Ctlr *ctlr;
733 int i;
734
735 ioringreserve(Nrxchan, Nrdre, Ntxchan, Ntdre);
736
737 /*
738 * Insist that the platform-specific code provide the Ethernet address
739 */
740 memset(ea, 0, Eaddrlen);
741 if(memcmp(ea, ether->ea, Eaddrlen) == 0){
742 print("no ether address");
743 return -1;
744 }
745
746 ctlr = malloc(sizeof(*ctlr));
747 ctlr->port = ether->port;
748
749 switch(ether->port){
750 case 0:
751 ctlr->regs = KADDR(PHYSEMAC0);
752 ctlr->miiregs = ctlr->regs;
753 ctlr->rx = malchannel(0, 0, rxring, ether);
754 ctlr->tx = malchannel(0, 1, txring, ether);
755 ether->irq = VectorEMAC0;
756 break;
757 case 1:
758 ctlr->regs = KADDR(PHYSEMAC1);
759 ctlr->miiregs = KADDR(PHYSEMAC0); /* p. 19-41: ``only the MDIO interface for EMAC0 is pinned out'' */
760 ctlr->rx = malchannel(1, 0, rxring, ether);
761 ctlr->tx = malchannel(2, 1, txring, ether);
762 ether->irq = VectorEMAC1;
763 break;
764 default:
765 print("%s ether: no port %lud\n", ether->type, ether->port);
766 free(ctlr);
767 return -1;
768 }
769
770 if(emacmii(ctlr) < 0){
771 free(ctlr);
772 return -1;
773 }
774
775 ether->ctlr = ctlr;
776
777 if(ioringinit(ctlr, Nrdre, Ntdre) < 0) /* TO DO: there are two transmit rings*/
778 panic("etheremac initring");
779
780 for(i = 0; i < ctlr->nrdre; i++){
781 ctlr->rxb[i] = clallocb();
782 ctlr->rdr[i].addr = PADDR(ctlr->rxb[i]->wp);
783 }
784
785 emacsetup(ctlr, ether);
786
787 ether->attach = attach;
788 ether->closed = closed;
789 ether->transmit = transmit;
790 ether->interrupt = interrupt; /* oddly, it's only error interrupts; see malchannel call above for tx/rx */
791 ether->ifstat = ifstat;
792
793 ether->arg = ether;
794 ether->promiscuous = promiscuous;
795 ether->multicast = multicast;
796
797 return 0;
798 }
799
800 void
etheremaclink(void)801 etheremaclink(void)
802 {
803 addethercard("EMAC", reset);
804 }
805
806 static void
dumpemac(Emac * r)807 dumpemac(Emac *r)
808 {
809 iprint("mr0=%8.8lux\n", r->mr0); /* mode register 0 [see 19-48] */
810 iprint("mr1=%8.8lux\n", r->mr1); /* mode register 1 [Reset] */
811 iprint("tmr0=%8.8lux\n", r->tmr0); /* transmit mode register 0 [see 19-28] */
812 iprint("tmr1=%8.8lux\n", r->tmr1); /* transmit mode register 1 [see 19-28] */
813 iprint("rmr=%8.8lux\n", r->rmr); /* receive mode register [Reset] */
814 iprint("isr=%8.8lux\n", r->isr); /* interrupt status register [Always] */
815 iprint("iser=%8.8lux\n", r->iser); /* interrupt status enable register [Reset] */
816 iprint("iahr=%8.8lux\n", r->iahr); /* individual address high [Reset, R, T]*/
817 iprint("ialr=%8.8lux\n", r->ialr); /* individual address low [Reset, R, T] */
818 iprint("vtpid=%8.8lux\n", r->vtpid); /* VLAN Tag Protocol Identifier [Reset, R, T] */
819 iprint("vtci=%8.8lux\n", r->vtci); /* VLAN Tag Control Information [Reset, R, T] */
820 iprint("ptr=%8.8lux\n", r->ptr); /* pause timer [Reset, T] */
821 iprint("lsah=%8.8lux\n", r->lsah); /* last source address high */
822 iprint("lsal=%8.8lux\n", r->lsal); /* last source address low */
823 iprint("ipgvr=%8.8lux\n", r->ipgvr); /* inter-packet gap value [Reset, T] */
824 iprint("stacr=%8.8lux\n", r->stacr); /* STA control register [see 19-41] */
825 iprint("trtr=%8.8lux\n", r->trtr); /* transmit request threshold register [see 19-42] */
826 iprint("rwmr=%8.8lux\n", r->rwmr); /* receive low/high water mark [Reset] */
827 iprint("octx=%8.8lux\n", r->octx); /* bytes transmitted */
828 iprint("ocrx=%8.8lux\n", r->ocrx); /* bytes received */
829 }
830