]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/kw/ether1116.c
devusb: fix format print warnings for ep->ntds and ep->uframes
[plan9front.git] / sys / src / 9 / kw / ether1116.c
1 /*
2  * marvell kirkwood gigabit ethernet (88e1116 and 88e1121) driver
3  * (as found in the sheevaplug, openrd and guruplug).
4  * the main difference is the flavour of phy kludgery necessary.
5  *
6  * from /public/doc/marvell/88f61xx.kirkwood.pdf,
7  *      /public/doc/marvell/88e1116.pdf, and
8  *      /public/doc/marvell/88e1121r.pdf.
9  */
10
11 #include "u.h"
12 #include "../port/lib.h"
13 #include "mem.h"
14 #include "dat.h"
15 #include "fns.h"
16 #include "io.h"
17 #include "../port/error.h"
18 #include "../port/netif.h"
19 #include "../port/etherif.h"
20
21 #include "ethermii.h"
22 #include "../ip/ip.h"
23
24 #define MIIDBG  if(0)iprint
25
26 #define WINATTR(v)      (((v) & MASK(8)) << 8)
27 #define WINSIZE(v)      (((v)/(64*1024) - 1) << 16)
28
29 enum {
30         Nrx             = 512,
31         Ntx             = 32,
32         Nrxblks         = 1024,
33         Rxblklen        = 2+1522,  /* ifc. supplies first 2 bytes as padding */
34
35         Maxrxintrsec    = 20*1000,      /* max. rx intrs. / sec */
36         Etherstuck      = 70,   /* must send or receive a packet in this many sec.s */
37
38         Descralign      = 16,
39         Bufalign        = 8,
40
41         Pass            = 1,            /* accept packets */
42
43         Qno             = 0,            /* do everything on queue zero */
44 };
45
46 typedef struct Ctlr Ctlr;
47 typedef struct Gbereg Gbereg;
48 typedef struct Mibstats Mibstats;
49 typedef struct Rx Rx;
50 typedef struct Tx Tx;
51
52 static struct {
53         Lock;
54         Block   *head;
55 } freeblocks;
56
57 /* hardware receive buffer descriptor */
58 struct Rx {
59         ulong   cs;
60         ulong   countsize;      /* bytes, buffer size */
61         ulong   buf;            /* phys. addr. of packet buffer */
62         ulong   next;           /* phys. addr. of next Rx */
63 };
64
65 /* hardware transmit buffer descriptor */
66 struct Tx {
67         ulong   cs;
68         ulong   countchk;       /* bytes, checksum */
69         ulong   buf;            /* phys. addr. of packet buffer */
70         ulong   next;           /* phys. addr. of next Tx */
71 };
72
73 /* fixed by hw; part of Gberegs */
74 struct Mibstats {
75         union {
76                 uvlong  rxby;           /* good bytes rcv'd */
77                 struct {
78                         ulong   rxbylo;
79                         ulong   rxbyhi;
80                 };
81         };
82         ulong   badrxby;                /* bad bytes rcv'd */
83         ulong   mactxerr;               /* tx err pkts */
84         ulong   rxpkt;                  /* good pkts rcv'd */
85         ulong   badrxpkt;               /* bad pkts rcv'd */
86         ulong   rxbcastpkt;             /* b'cast pkts rcv'd */
87         ulong   rxmcastpkt;             /* m'cast pkts rcv'd */
88
89         ulong   rx64;                   /* pkts <= 64 bytes */
90         ulong   rx65_127;               /* pkts 65—127 bytes */
91         ulong   rx128_255;              /* pkts 128—255 bytes */
92         ulong   rx256_511;              /* pkts 256—511 bytes */
93         ulong   rx512_1023;             /* pkts 512—1023 bytes */
94         ulong   rx1024_max;             /* pkts >= 1024 bytes */
95
96         union {
97                 uvlong  txby;           /* good bytes sent */
98                 struct {
99                         ulong   txbylo;
100                         ulong   txbyhi;
101                 };
102         };
103         ulong   txpkt;                  /* good pkts sent */
104         /* half-duplex: pkts dropped due to excessive collisions */
105         ulong   txcollpktdrop;
106         ulong   txmcastpkt;             /* m'cast pkts sent */
107         ulong   txbcastpkt;             /* b'cast pkts sent */
108
109         ulong   badmacctlpkts;          /* bad mac ctl pkts */
110         ulong   txflctl;                /* flow-control pkts sent */
111         ulong   rxflctl;                /* good flow-control pkts rcv'd */
112         ulong   badrxflctl;             /* bad flow-control pkts rcv'd */
113
114         ulong   rxundersized;           /* runts */
115         ulong   rxfrags;                /* fragments rcv'd */
116         ulong   rxtoobig;               /* oversized pkts rcv'd */
117         ulong   rxjabber;               /* jabber pkts rcv'd */
118         ulong   rxerr;                  /* rx error events */
119         ulong   crcerr;                 /* crc error events */
120         ulong   collisions;             /* collision events */
121         ulong   latecoll;               /* late collisions */
122 };
123
124 struct Ctlr {
125         Lock;
126         Ether   *ether;
127         Gbereg  *reg;
128
129         Lock    initlock;
130         int     init;
131
132         Rx      *rx;            /* receive descriptors */
133         Block   *rxb[Nrx];      /* blocks belonging to the descriptors */
134         int     rxhead;         /* descr ethernet will write to next */
135         int     rxtail;         /* next descr that might need a buffer */
136         Rendez  rrendez;        /* interrupt wakes up read process */
137         int     haveinput;
138
139         Tx      *tx;
140         Block   *txb[Ntx];
141         int     txhead;         /* next descr we can use for new packet */
142         int     txtail;         /* next descr to reclaim on tx complete */
143
144         Mii     *mii;
145         int     port;
146
147         int     linkchg;                /* link status changed? */
148         uvlong  starttime;              /* last activity time */
149
150         /* stats */
151         ulong   intrs;
152         ulong   newintrs;
153         ulong   txunderrun;
154         ulong   txringfull;
155         ulong   rxdiscard;
156         ulong   rxoverrun;
157         ulong   nofirstlast;
158
159         Mibstats;
160 };
161
162 #define Rxqon(q)        (1<<(q))
163 #define Txqon(q)        (1<<(q))
164
165 enum {
166         /* euc bits */
167         Portreset       = 1 << 20,
168
169         /* sdma config, sdc bits */
170         Burst1          = 0,
171         Burst2,
172         Burst4,
173         Burst8,
174         Burst16,
175         SDCrifb         = 1<<0,         /* rx intr on pkt boundaries */
176 #define SDCrxburst(v)   ((v)<<1)
177         SDCrxnobyteswap = 1<<4,
178         SDCtxnobyteswap = 1<<5,
179         SDCswap64byte   = 1<<6,
180 #define SDCtxburst(v)   ((v)<<22)
181         /* rx intr ipg (inter packet gap) */
182 #define SDCipgintrx(v)  ((((v)>>15) & 1)<<25) | (((v) & MASK(15))<<7)
183
184         /* portcfg bits */
185         PCFGupromisc            = 1<<0, /* unicast promiscuous mode */
186 #define Rxqdefault(q)   ((q)<<1)
187 #define Rxqarp(q)       ((q)<<4)
188         PCFGbcrejectnoiparp     = 1<<7,
189         PCFGbcrejectip          = 1<<8,
190         PCFGbcrejectarp         = 1<<9,
191         PCFGamnotxes            = 1<<12, /* auto mode, no summary update on tx */
192         PCFGtcpq        = 1<<14,        /* capture tcp frames to tcpq */
193         PCFGudpq        = 1<<15,        /* capture udp frames to udpq */
194 #define Rxqtcp(q)       ((q)<<16)
195 #define Rxqudp(q)       ((q)<<19)
196 #define Rxqbpdu(q)      ((q)<<22)
197         PCFGrxcs        = 1<<25,        /* rx tcp checksum mode with header */
198
199         /* portcfgx bits */
200         PCFGXspanq      = 1<<1,
201         PCFGXcrcoff     = 1<<2,         /* no ethernet crc */
202
203         /* port serial control0, psc0 bits */
204         PSC0porton              = 1<<0,
205         PSC0forcelinkup         = 1<<1,
206         PSC0an_dplxoff          = 1<<2, /* an_ = auto. negotiate */
207         PSC0an_flctloff         = 1<<3,
208         PSC0an_pauseadv         = 1<<4,
209         PSC0nofrclinkdown       = 1<<10,
210         PSC0an_spdoff           = 1<<13,
211         PSC0dteadv              = 1<<14,        /* dte advertise */
212
213         /* max. input pkt size */
214 #define PSC0mru(v)      ((v)<<17)
215         PSC0mrumask     = PSC0mru(MASK(3)),
216         PSC0mru1518     = 0,            /* 1500+2* 6(addrs) +2 + 4(crc) */
217         PSC0mru1522,                    /* 1518 + 4(vlan tags) */
218         PSC0mru1552,                    /* `baby giant' */
219         PSC0mru9022,                    /* `jumbo' */
220         PSC0mru9192,                    /* bigger jumbo */
221         PSC0mru9700,                    /* still bigger jumbo */
222
223         PSC0fd_frc              = 1<<21,        /* force full duplex */
224         PSC0flctlfrc            = 1<<22,
225         PSC0gmiispd_gbfrc       = 1<<23,
226         PSC0miispdfrc100mbps    = 1<<24,
227
228         /* port status 0, ps0 bits */
229         PS0linkup       = 1<<1,
230         PS0fd           = 1<<2,                 /* full duplex */
231         PS0flctl        = 1<<3,
232         PS0gmii_gb      = 1<<4,
233         PS0mii100mbps   = 1<<5,
234         PS0txbusy       = 1<<7,
235         PS0txfifoempty  = 1<<10,
236         PS0rxfifo1empty = 1<<11,
237         PS0rxfifo2empty = 1<<12,
238
239         /* port serial control 1, psc1 bits */
240         PSC1loopback    = 1<<1,
241         PSC1mii         = 0<<2,
242         PSC1rgmii       = 1<<3,                 /* enable RGMII */
243         PSC1portreset   = 1<<4,
244         PSC1clockbypass = 1<<5,
245         PSC1iban        = 1<<6,
246         PSC1iban_bypass = 1<<7,
247         PSC1iban_restart= 1<<8,
248         PSC1_gbonly     = 1<<11,
249         PSC1encolonbp   = 1<<15, /* "collision during back-pressure mib counting" */
250         PSC1coldomlimmask= MASK(6)<<16,
251 #define PSC1coldomlim(v) (((v) & MASK(6))<<16)
252         PSC1miiallowoddpreamble = 1<<22,
253
254         /* port status 1, ps1 bits */
255         PS1rxpause      = 1<<0,
256         PS1txpause      = 1<<1,
257         PS1pressure     = 1<<2,
258         PS1syncfail10ms = 1<<3,
259         PS1an_done      = 1<<4,
260         PS1inbandan_bypassed    = 1<<5,
261         PS1serdesplllocked      = 1<<6,
262         PS1syncok       = 1<<7,
263         PS1nosquelch    = 1<<8,
264
265         /* irq bits */
266         /* rx buf returned to cpu ownership, or frame reception finished */
267         Irx             = 1<<0,
268         Iextend         = 1<<1,         /* IEsum of irqe set */
269 #define Irxbufferq(q)   (1<<((q)+2))    /* rx buf returned to cpu ownership */
270         Irxerr          = 1<<10,        /* input ring full, usually */
271 #define Irxerrq(q)      (1<<((q)+11))
272 #define Itxendq(q)      (1<<((q)+19))   /* tx dma stopped for q */
273         Isum            = 1<<31,
274
275         /* irq extended, irqe bits */
276 #define IEtxbufferq(q)  (1<<((q)+0))    /* tx buf returned to cpu ownership */
277 #define IEtxerrq(q)     (1<<((q)+8))
278         IEphystschg     = 1<<16,
279         IEptp           = 1<<17,
280         IErxoverrun     = 1<<18,
281         IEtxunderrun    = 1<<19,
282         IElinkchg       = 1<<20,
283         IEintaddrerr    = 1<<23,
284         IEprbserr       = 1<<25,
285         IEsum           = 1<<31,
286
287         /* tx fifo urgent threshold (tx interrupt coalescing), pxtfut */
288 #define TFUTipginttx(v) (((v) & MASK(16))<<4);
289
290         /* minimal frame size, mfs */
291         MFS40by = 10<<2,
292         MFS44by = 11<<2,
293         MFS48by = 12<<2,
294         MFS52by = 13<<2,
295         MFS56by = 14<<2,
296         MFS60by = 15<<2,
297         MFS64by = 16<<2,
298
299         /* receive descriptor status */
300         RCSmacerr       = 1<<0,
301         RCSmacmask      = 3<<1,
302         RCSmacce        = 0<<1,
303         RCSmacor        = 1<<1,
304         RCSmacmf        = 2<<1,
305         RCSl4chkshift   = 3,
306         RCSl4chkmask    = MASK(16),
307         RCSvlan         = 1<<17,
308         RCSbpdu         = 1<<18,
309         RCSl4mask       = 3<<21,
310         RCSl4tcp4       = 0<<21,
311         RCSl4udp4       = 1<<21,
312         RCSl4other      = 2<<21,
313         RCSl4rsvd       = 3<<21,
314         RCSl2ev2        = 1<<23,
315         RCSl3ip4        = 1<<24,
316         RCSip4headok    = 1<<25,
317         RCSlast         = 1<<26,
318         RCSfirst        = 1<<27,
319         RCSunknownaddr  = 1<<28,
320         RCSenableintr   = 1<<29,
321         RCSl4chkok      = 1<<30,
322         RCSdmaown       = 1<<31,
323
324         /* transmit descriptor status */
325         TCSmacerr       = 1<<0,
326         TCSmacmask      = 3<<1,
327         TCSmaclc        = 0<<1,
328         TCSmacur        = 1<<1,
329         TCSmacrl        = 2<<1,
330         TCSllc          = 1<<9,
331         TCSl4chkmode    = 1<<10,
332         TCSipv4hdlenshift= 11,
333         TCSvlan         = 1<<15,
334         TCSl4type       = 1<<16,
335         TCSgl4chk       = 1<<17,
336         TCSgip4chk      = 1<<18,
337         TCSpadding      = 1<<19,
338         TCSlast         = 1<<20,
339         TCSfirst        = 1<<21,
340         TCSenableintr   = 1<<23,
341         TCSautomode     = 1<<30,
342         TCSdmaown       = 1<<31,
343 };
344
345 enum {
346         /* SMI regs */
347         PhysmiTimeout   = 10000,        /* what units? in ms. */
348         Physmidataoff   = 0,            /* Data */
349         Physmidatamask  = 0xffff<<Physmidataoff,
350
351         Physmiaddroff   = 16,           /* PHY device addr */
352         Physmiaddrmask  = 0x1f << Physmiaddroff,
353
354         Physmiop        = 26,
355         Physmiopmask    = 3<<Physmiop,
356         PhysmiopWr      = 0<<Physmiop,
357         PhysmiopRd      = 1<<Physmiop,
358
359         PhysmiReadok    = 1<<27,
360         PhysmiBusy      = 1<<28,
361
362         SmiRegaddroff   = 21,           /* PHY device register addr */
363         SmiRegaddrmask  = 0x1f << SmiRegaddroff,
364 };
365
366 struct Gbereg {
367         ulong   phy;                    /* PHY address */
368         ulong   smi;                    /* serial mgmt. interface */
369         ulong   euda;                   /* ether default address */
370         ulong   eudid;                  /* ether default id */
371         uchar   _pad0[0x80-0x10];
372
373         /* dma stuff */
374         ulong   euirq;                  /* interrupt cause */
375         ulong   euirqmask;              /* interrupt mask */
376         uchar   _pad1[0x94-0x88];
377         ulong   euea;                   /* error address */
378         ulong   euiae;                  /* internal error address */
379         uchar   _pad2[0xb0-0x9c];
380         ulong   euc;                    /* control */
381         uchar   _pad3[0x200-0xb4];
382         struct {
383                 ulong   base;           /* window base */
384                 ulong   size;           /* window size */
385         } base[6];
386         uchar   _pad4[0x280-0x230];
387         ulong   harr[4];                /* high address remap */
388         ulong   bare;                   /* base address enable */
389         ulong   epap;                   /* port access protect */
390         uchar   _pad5[0x400-0x298];
391
392         ulong   portcfg;                /* port configuration */
393         ulong   portcfgx;               /* port config. extend */
394         ulong   mii;                    /* mii serial parameters */
395         ulong   _pad6;
396         ulong   evlane;                 /* vlan ether type */
397         ulong   macal;                  /* mac address low */
398         ulong   macah;                  /* mac address high */
399         ulong   sdc;                    /* sdma config. */
400         ulong   dscp[7];                /* ip diff. serv. code point -> pri */
401         ulong   psc0;                   /* port serial control 0 */
402         ulong   vpt2p;                  /* vlan priority tag -> pri */
403         ulong   ps0;                    /* ether port status 0 */
404         ulong   tqc;                    /* transmit queue command */
405         ulong   psc1;                   /* port serial control 1 */
406         ulong   ps1;                    /* ether port status 1 */
407         ulong   mvhdr;                  /* marvell header */
408         ulong   _pad8[2];
409
410         /* interrupts */
411         ulong   irq;                    /* interrupt cause; some rw0c bits */
412         ulong   irqe;                   /* " " extended; some rw0c bits */
413         ulong   irqmask;                /* interrupt mask (actually enable) */
414         ulong   irqemask;               /* " " extended */
415
416         ulong   _pad9;
417         ulong   pxtfut;                 /* port tx fifo urgent threshold */
418         ulong   _pad10;
419         ulong   pxmfs;                  /* port rx minimum frame size */
420         ulong   _pad11;
421
422         /*
423          * # of input frames discarded by addr filtering or lack of resources;
424          * zeroed upon read.
425          */
426         ulong   pxdfc;                  /* port rx discard frame counter */
427         ulong   pxofc;                  /* port overrun frame counter */
428         ulong   _pad12[2];
429         ulong   piae;                   /* port internal address error */
430         uchar   _pad13[0x4bc-0x498];
431         ulong   etherprio;              /* ether type priority */
432         uchar   _pad14[0x4dc-0x4c0];
433         ulong   tqfpc;                  /* tx queue fixed priority config. */
434         ulong   pttbrc;                 /* port tx token-bucket rate config. */
435         ulong   tqc1;                   /* tx queue command 1 */
436         ulong   pmtu;                   /* port maximum transmit unit */
437         ulong   pmtbs;                  /* port maximum token bucket size */
438         uchar   _pad15[0x600-0x4f0];
439
440         struct {
441                 ulong   _pad[3];
442                 ulong   r;              /* phys. addr.: cur. rx desc. ptrs */
443         } crdp[8];
444         ulong   rqc;                    /* rx queue command */
445         ulong   tcsdp;                  /* phys. addr.: cur. tx desc. ptr */
446         uchar   _pad16[0x6c0-0x688];
447
448         ulong   tcqdp[8];               /* phys. addr.: cur. tx q. desc. ptr */
449         uchar   _pad17[0x700-0x6e0];
450
451         struct {
452                 ulong   tbctr;          /* queue tx token-bucket counter */
453                 ulong   tbcfg;          /* tx queue token-bucket config. */
454                 ulong   acfg;           /* tx queue arbiter config. */
455                 ulong   _pad;
456         } tq[8];
457         ulong   pttbc;                  /* port tx token-bucket counter */
458         uchar   _pad18[0x7a8-0x784];
459
460         ulong   ipg2;                   /* tx queue ipg */
461         ulong   _pad19[3];
462         ulong   ipg3;
463         ulong   _pad20;
464         ulong   htlp;                   /* high token in low packet */
465         ulong   htap;                   /* high token in async packet */
466         ulong   ltap;                   /* low token in async packet */
467         ulong   _pad21;
468         ulong   ts;                     /* tx speed */
469         uchar   _pad22[0x1000-0x7d4];
470
471         /* mac mib counters: statistics */
472         Mibstats;
473         uchar   _pad23[0x1400-0x1080];
474
475         /* multicast filtering; each byte: Qno<<1 | Pass */
476         ulong   dfsmt[64];      /* dest addr filter special m'cast table */
477         ulong   dfomt[64];      /* dest addr filter other m'cast table */
478         /* unicast filtering */
479         ulong   dfut[4];                /* dest addr filter unicast table */
480 };
481
482 static Ctlr *ctlrs[MaxEther];
483 static uchar zeroea[Eaddrlen];
484
485 static void getmibstats(Ctlr *);
486
487 static void
488 rxfreeb(Block *b)
489 {
490         b->wp = b->rp =
491                 (uchar*)((uintptr)(b->lim - Rxblklen) & ~(Bufalign - 1));
492         assert(((uintptr)b->rp & (Bufalign - 1)) == 0);
493         b->free = rxfreeb;
494
495         ilock(&freeblocks);
496         b->next = freeblocks.head;
497         freeblocks.head = b;
498         iunlock(&freeblocks);
499 }
500
501 static Block *
502 rxallocb(void)
503 {
504         Block *b;
505
506         ilock(&freeblocks);
507         b = freeblocks.head;
508         if(b != nil) {
509                 freeblocks.head = b->next;
510                 b->next = nil;
511                 b->free = rxfreeb;
512         }
513         iunlock(&freeblocks);
514         return b;
515 }
516
517 static void
518 rxkick(Ctlr *ctlr)
519 {
520         Gbereg *reg = ctlr->reg;
521
522         if (reg->crdp[Qno].r == 0)
523                 reg->crdp[Qno].r = PADDR(&ctlr->rx[ctlr->rxhead]);
524         if ((reg->rqc & 0xff) == 0)             /* all queues are stopped? */
525                 reg->rqc = Rxqon(Qno);          /* restart */
526         coherence();
527 }
528
529 static void
530 txkick(Ctlr *ctlr)
531 {
532         Gbereg *reg = ctlr->reg;
533
534         if (reg->tcqdp[Qno] == 0)
535                 reg->tcqdp[Qno] = PADDR(&ctlr->tx[ctlr->txhead]);
536         if ((reg->tqc & 0xff) == 0)             /* all q's stopped? */
537                 reg->tqc = Txqon(Qno);          /* restart */
538         coherence();
539 }
540
541 static void
542 rxreplenish(Ctlr *ctlr)
543 {
544         Rx *r;
545         Block *b;
546
547         while(ctlr->rxb[ctlr->rxtail] == nil) {
548                 b = rxallocb();
549                 if(b == nil) {
550                         iprint("#l%d: rxreplenish out of buffers\n",
551                                 ctlr->ether->ctlrno);
552                         break;
553                 }
554
555                 ctlr->rxb[ctlr->rxtail] = b;
556
557                 /* set up uncached receive descriptor */
558                 r = &ctlr->rx[ctlr->rxtail];
559                 assert(((uintptr)r & (Descralign - 1)) == 0);
560                 r->countsize = ROUNDUP(Rxblklen, 8);
561                 r->buf = PADDR(b->rp);
562                 coherence();
563
564                 /* and fire */
565                 r->cs = RCSdmaown | RCSenableintr;
566                 coherence();
567
568                 ctlr->rxtail = NEXT(ctlr->rxtail, Nrx);
569         }
570 }
571
572 static void
573 dump(uchar *bp, long max)
574 {
575         if (max > 64)
576                 max = 64;
577         for (; max > 0; max--, bp++)
578                 iprint("%02.2ux ", *bp);
579         print("...\n");
580 }
581
582 static void
583 etheractive(Ether *ether)
584 {
585         Ctlr *ctlr = ether->ctlr;
586         ctlr->starttime = TK2MS(MACHP(0)->ticks)/1000;
587 }
588
589 static void
590 ethercheck(Ether *ether)
591 {
592         Ctlr *ctlr = ether->ctlr;
593         if (ctlr->starttime != 0 &&
594             TK2MS(MACHP(0)->ticks)/1000 - ctlr->starttime > Etherstuck) {
595                 etheractive(ether);
596                 if (ether->ctlrno == 0) /* only complain about main ether */
597                         iprint("#l%d: ethernet stuck\n", ether->ctlrno);
598         }
599 }
600
601 static void
602 receive(Ether *ether)
603 {
604         int i;
605         ulong n;
606         Block *b;
607         Ctlr *ctlr = ether->ctlr;
608         Rx *r;
609
610         ethercheck(ether);
611         for (i = Nrx-2; i > 0; i--) {
612                 r = &ctlr->rx[ctlr->rxhead];    /* *r is uncached */
613                 assert(((uintptr)r & (Descralign - 1)) == 0);
614                 if(r->cs & RCSdmaown)           /* descriptor busy? */
615                         break;
616
617                 b = ctlr->rxb[ctlr->rxhead];    /* got input buffer? */
618                 if (b == nil)
619                         panic("ether1116: nil ctlr->rxb[ctlr->rxhead] "
620                                 "in receive");
621                 ctlr->rxb[ctlr->rxhead] = nil;
622                 ctlr->rxhead = NEXT(ctlr->rxhead, Nrx);
623
624                 if((r->cs & (RCSfirst|RCSlast)) != (RCSfirst|RCSlast)) {
625                         ctlr->nofirstlast++;    /* partial packet */
626                         freeb(b);
627                         continue;
628                 }
629                 if(r->cs & RCSmacerr) {
630                         freeb(b);
631                         continue;
632                 }
633
634                 n = r->countsize >> 16;         /* TODO includes 2 pad bytes? */
635                 assert(n >= 2 && n < 2048);
636
637                 /* clear any cached packet or part thereof */
638                 l2cacheuinvse(b->rp, n+2);
639                 cachedinvse(b->rp, n+2);
640                 b->wp = b->rp + n;
641                 /*
642                  * skip hardware padding intended to align ipv4 address
643                  * in memory (mv-s104860-u0 §8.3.4.1)
644                  */
645                 b->rp += 2;
646                 etheriq(ether, b);
647                 etheractive(ether);
648                 if (i % (Nrx / 2) == 0) {
649                         rxreplenish(ctlr);
650                         rxkick(ctlr);
651                 }
652         }
653         rxreplenish(ctlr);
654         rxkick(ctlr);
655 }
656
657 static void
658 txreplenish(Ether *ether)                       /* free transmitted packets */
659 {
660         Ctlr *ctlr;
661
662         ctlr = ether->ctlr;
663         while(ctlr->txtail != ctlr->txhead) {
664                 /* ctlr->tx is uncached */
665                 if(ctlr->tx[ctlr->txtail].cs & TCSdmaown)
666                         break;
667                 if(ctlr->txb[ctlr->txtail] == nil)
668                         panic("no block for sent packet?!");
669                 freeb(ctlr->txb[ctlr->txtail]);
670                 ctlr->txb[ctlr->txtail] = nil;
671
672                 ctlr->txtail = NEXT(ctlr->txtail, Ntx);
673                 etheractive(ether);
674         }
675 }
676
677 /*
678  * transmit strategy: fill the output ring as far as possible,
679  * perhaps leaving a few spare; kick off the output and take
680  * an interrupt only when the transmit queue is empty.
681  */
682 static void
683 transmit(Ether *ether)
684 {
685         int i, kick, len;
686         Block *b;
687         Ctlr *ctlr = ether->ctlr;
688         Gbereg *reg = ctlr->reg;
689         Tx *t;
690
691         ethercheck(ether);
692         ilock(ctlr);
693         txreplenish(ether);                     /* reap old packets */
694
695         /* queue new packets; use at most half the tx descs to avoid livelock */
696         kick = 0;
697         for (i = Ntx/2 - 2; i > 0; i--) {
698                 t = &ctlr->tx[ctlr->txhead];    /* *t is uncached */
699                 assert(((uintptr)t & (Descralign - 1)) == 0);
700                 if(t->cs & TCSdmaown) {         /* descriptor busy? */
701                         ctlr->txringfull++;
702                         break;
703                 }
704
705                 b = qget(ether->oq);            /* outgoing packet? */
706                 if (b == nil)
707                         break;
708                 len = BLEN(b);
709                 if(len < ether->minmtu || len > ether->maxmtu) {
710                         freeb(b);
711                         continue;
712                 }
713                 ctlr->txb[ctlr->txhead] = b;
714
715                 /* make sure the whole packet is in memory */
716                 cachedwbse(b->rp, len);
717                 l2cacheuwbse(b->rp, len);
718
719                 /* set up the transmit descriptor */
720                 t->buf = PADDR(b->rp);
721                 t->countchk = len << 16;
722                 coherence();
723
724                 /* and fire */
725                 t->cs = TCSpadding | TCSfirst | TCSlast | TCSdmaown |
726                         TCSenableintr;
727                 coherence();
728
729                 kick++;
730                 ctlr->txhead = NEXT(ctlr->txhead, Ntx);
731         }
732         if (kick) {
733                 txkick(ctlr);
734
735                 reg->irqmask  |= Itxendq(Qno);
736                 reg->irqemask |= IEtxerrq(Qno) | IEtxunderrun;
737         }
738         iunlock(ctlr);
739 }
740
741 static void
742 dumprxdescs(Ctlr *ctlr)
743 {
744         int i;
745         Gbereg *reg = ctlr->reg;
746
747         iprint("\nrxhead %d rxtail %d; txcdp %#p rxcdp %#p\n",
748                 ctlr->rxhead, ctlr->rxtail, reg->tcqdp[Qno], reg->crdp[Qno].r);
749         for (i = 0; i < Nrx; i++) {
750                 iprint("rxb %d @ %#p: %#p\n", i, &ctlr->rxb[i], ctlr->rxb[i]);
751                 delay(50);
752         }
753         for (i = 0; i < Nrx; i++) {
754                 iprint("rx %d @ %#p: cs %#lux countsize %lud buf %#lux next %#lux\n",
755                         i, &ctlr->rx[i], ctlr->rx[i].cs,
756                         ctlr->rx[i].countsize >> 3, ctlr->rx[i].buf,
757                         ctlr->rx[i].next);
758                 delay(50);
759         }
760         delay(1000);
761 }
762
763 static int
764 gotinput(void* ctlr)
765 {
766         return ((Ctlr*)ctlr)->haveinput != 0;
767 }
768
769 /*
770  * process any packets in the input ring.
771  * also sum mib stats frequently to avoid the overflow
772  * mentioned in the errata.
773  */
774 static void
775 rcvproc(void* arg)
776 {
777         Ctlr *ctlr;
778         Ether *ether;
779
780         ether = arg;
781         ctlr = ether->ctlr;
782         while(waserror())
783                 ;
784         for(;;){
785                 tsleep(&ctlr->rrendez, gotinput, ctlr, 10*1000);
786                 ilock(ctlr);
787                 getmibstats(ctlr);
788                 if (ctlr->haveinput) {
789                         ctlr->haveinput = 0;
790                         iunlock(ctlr);
791                         receive(ether);
792                 } else
793                         iunlock(ctlr);
794         }
795 }
796
797 static void
798 interrupt(Ureg*, void *arg)
799 {
800         ulong irq, irqe, handled;
801         Ether *ether = arg;
802         Ctlr *ctlr = ether->ctlr;
803         Gbereg *reg = ctlr->reg;
804
805         handled = 0;
806         irq = reg->irq;
807         irqe = reg->irqe;
808         reg->irqe = 0;                          /* extinguish intr causes */
809         reg->irq = 0;                           /* extinguish intr causes */
810         ethercheck(ether);
811
812         if(irq & (Irx | Irxbufferq(Qno))) {
813                 /*
814                  * letting a kproc process the input takes far less real time
815                  * than doing it all at interrupt level.
816                  */
817                 ctlr->haveinput = 1;
818                 wakeup(&ctlr->rrendez);
819                 irq &= ~(Irx | Irxbufferq(Qno));
820                 handled++;
821         } else
822                 rxkick(ctlr);
823
824         if(irq & Itxendq(Qno)) {                /* transmit ring empty? */
825                 reg->irqmask  &= ~Itxendq(Qno); /* prevent more interrupts */
826                 reg->irqemask &= ~(IEtxerrq(Qno) | IEtxunderrun);
827                 transmit(ether);
828                 irq &= ~Itxendq(Qno);
829                 handled++;
830         }
831
832         if(irqe & IEsum) {
833                 /*
834                  * IElinkchg appears to only be set when unplugging.
835                  * autonegotiation is likely not done yet, so linkup not valid,
836                  * thus we note the link change here, and check for
837                  * that and autonegotiation done below.
838                  */
839                 if(irqe & IEphystschg) {
840                         ether->link = (reg->ps0 & PS0linkup) != 0;
841                         ctlr->linkchg = 1;
842                 }
843                 if(irqe & IEtxerrq(Qno))
844                         ether->oerrs++;
845                 if(irqe & IErxoverrun)
846                         ether->overflows++;
847                 if(irqe & IEtxunderrun)
848                         ctlr->txunderrun++;
849                 if(irqe & (IEphystschg | IEtxerrq(Qno) | IErxoverrun |
850                     IEtxunderrun))
851                         handled++;
852         }
853         if (irq & Isum) {
854                 if (irq & Irxerr) {  /* nil desc. ptr. or desc. owned by cpu */
855                         ether->buffs++;         /* approx. error */
856
857                         /* if the input ring is full, drain it */
858                         ctlr->haveinput = 1;
859                         wakeup(&ctlr->rrendez);
860                 }
861                 if(irq & (Irxerr | Irxerrq(Qno)))
862                         handled++;
863                 irq  &= ~(Irxerr | Irxerrq(Qno));
864         }
865
866         if(ctlr->linkchg && (reg->ps1 & PS1an_done)) {
867                 handled++;
868                 ether->link = (reg->ps0 & PS0linkup) != 0;
869                 ctlr->linkchg = 0;
870         }
871         ctlr->newintrs++;
872
873         if (!handled) {
874                 irq  &= ~Isum;
875                 irqe &= ~IEtxbufferq(Qno);
876                 if (irq == 0 && irqe == 0) {
877                         /* seems to be triggered by continuous output */
878                         // iprint("ether1116: spurious interrupt\n");
879                 } else
880                         iprint("ether1116: interrupt cause unknown; "
881                                 "irq %#lux irqe %#lux\n", irq, irqe);
882         }
883         intrclear(Irqlo, ether->irq);
884 }
885
886 void
887 promiscuous(void *arg, int on)
888 {
889         Ether *ether = arg;
890         Ctlr *ctlr = ether->ctlr;
891         Gbereg *reg = ctlr->reg;
892
893         ilock(ctlr);
894         ether->prom = on;
895         if(on)
896                 reg->portcfg |= PCFGupromisc;
897         else
898                 reg->portcfg &= ~PCFGupromisc;
899         iunlock(ctlr);
900 }
901
902 void
903 multicast(void *, uchar *, int)
904 {
905         /* nothing to do; we always accept multicast */
906 }
907
908 static void quiesce(Gbereg *reg);
909
910 static void
911 shutdown(Ether *ether)
912 {
913         int i;
914         Ctlr *ctlr = ether->ctlr;
915         Gbereg *reg = ctlr->reg;
916
917         ilock(ctlr);
918         quiesce(reg);
919         reg->euc |= Portreset;
920         coherence();
921         iunlock(ctlr);
922         delay(100);
923         ilock(ctlr);
924         reg->euc &= ~Portreset;
925         coherence();
926         delay(20);
927
928         reg->psc0 = 0;                  /* no PSC0porton */
929         reg->psc1 |= PSC1portreset;
930         coherence();
931         delay(50);
932         reg->psc1 &= ~PSC1portreset;
933         coherence();
934
935         for (i = 0; i < nelem(reg->tcqdp); i++)
936                 reg->tcqdp[i] = 0;
937         for (i = 0; i < nelem(reg->crdp); i++)
938                 reg->crdp[i].r = 0;
939         coherence();
940
941         iunlock(ctlr);
942 }
943
944 enum {
945         CMjumbo,
946 };
947
948 static Cmdtab ctlmsg[] = {
949         CMjumbo,        "jumbo",        2,
950 };
951
952 long
953 ctl(Ether *e, void *p, long n)
954 {
955         Cmdbuf *cb;
956         Cmdtab *ct;
957         Ctlr *ctlr = e->ctlr;
958         Gbereg *reg = ctlr->reg;
959
960         cb = parsecmd(p, n);
961         if(waserror()) {
962                 free(cb);
963                 nexterror();
964         }
965
966         ct = lookupcmd(cb, ctlmsg, nelem(ctlmsg));
967         switch(ct->index) {
968         case CMjumbo:
969                 if(strcmp(cb->f[1], "on") == 0) {
970                         /* incoming packet queue doesn't expect jumbo frames */
971                         error("jumbo disabled");
972                         reg->psc0 = (reg->psc0 & ~PSC0mrumask) |
973                                 PSC0mru(PSC0mru9022);
974                         e->maxmtu = 9022;
975                 } else if(strcmp(cb->f[1], "off") == 0) {
976                         reg->psc0 = (reg->psc0 & ~PSC0mrumask) |
977                                 PSC0mru(PSC0mru1522);
978                         e->maxmtu = ETHERMAXTU;
979                 } else
980                         error(Ebadctl);
981                 break;
982         default:
983                 error(Ebadctl);
984                 break;
985         }
986         free(cb);
987         poperror();
988         return n;
989 }
990
991 /*
992  * phy/mii goo
993  */
994
995 static int
996 smibusywait(Gbereg *reg, ulong waitbit)
997 {
998         ulong timeout, smi_reg;
999
1000         timeout = PhysmiTimeout;
1001         /* wait till the SMI is not busy */
1002         do {
1003                 /* read smi register */
1004                 smi_reg = reg->smi;
1005                 if (timeout-- == 0) {
1006                         MIIDBG("SMI busy timeout\n");
1007                         return -1;
1008                 }
1009 //              delay(1);
1010         } while (smi_reg & waitbit);
1011         return 0;
1012 }
1013
1014 static int
1015 miird(Mii *mii, int pa, int ra)
1016 {
1017         ulong smi_reg, timeout;
1018         Gbereg *reg;
1019
1020         reg = ((Ctlr*)mii->ctlr)->reg;
1021
1022         /* check params */
1023         if ((pa<<Physmiaddroff) & ~Physmiaddrmask ||
1024             (ra<<SmiRegaddroff) & ~SmiRegaddrmask)
1025                 return -1;
1026
1027         smibusywait(reg, PhysmiBusy);
1028
1029         /* fill the phy address and register offset and read opcode */
1030         reg->smi = pa << Physmiaddroff | ra << SmiRegaddroff | PhysmiopRd;
1031         coherence();
1032
1033         /* wait til read value is ready */
1034         timeout = PhysmiTimeout;
1035         do {
1036                 smi_reg = reg->smi;
1037                 if (timeout-- == 0) {
1038                         MIIDBG("SMI read-valid timeout\n");
1039                         return -1;
1040                 }
1041         } while (!(smi_reg & PhysmiReadok));
1042
1043         /* Wait for the data to update in the SMI register */
1044         for (timeout = 0; timeout < PhysmiTimeout; timeout++)
1045                 ;
1046         return reg->smi & Physmidatamask;
1047 }
1048
1049 static int
1050 miiwr(Mii *mii, int pa, int ra, int v)
1051 {
1052         Gbereg *reg;
1053         ulong smi_reg;
1054
1055         reg = ((Ctlr*)mii->ctlr)->reg;
1056
1057         /* check params */
1058         if (((pa<<Physmiaddroff) & ~Physmiaddrmask) ||
1059             ((ra<<SmiRegaddroff) & ~SmiRegaddrmask))
1060                 return -1;
1061
1062         smibusywait(reg, PhysmiBusy);
1063
1064         /* fill the phy address and register offset and read opcode */
1065         smi_reg = v << Physmidataoff | pa << Physmiaddroff | ra << SmiRegaddroff;
1066         reg->smi = smi_reg & ~PhysmiopRd;
1067         coherence();
1068         return 0;
1069 }
1070
1071 #define MIIMODEL(idr2)  (((idr2) >> 4) & MASK(6))
1072
1073 enum {
1074         Hacknone,
1075         Hackdual,
1076
1077         Ouimarvell      = 0x005043,
1078
1079         /* idr2 mii/phy model numbers */
1080         Phy1000         = 0x00,         /* 88E1000 Gb */
1081         Phy1011         = 0x02,         /* 88E1011 Gb */
1082         Phy1000_3       = 0x03,         /* 88E1000 Gb */
1083         Phy1000s        = 0x04,         /* 88E1000S Gb */
1084         Phy1000_5       = 0x05,         /* 88E1000 Gb */
1085         Phy1000_6       = 0x06,         /* 88E1000 Gb */
1086         Phy3082         = 0x08,         /* 88E3082 10/100 */
1087         Phy1112         = 0x09,         /* 88E1112 Gb */
1088         Phy1121r        = 0x0b,         /* says the 1121r manual */
1089         Phy1149         = 0x0b,         /* 88E1149 Gb */
1090         Phy1111         = 0x0c,         /* 88E1111 Gb */
1091         Phy1116         = 0x21,         /* 88E1116 Gb */
1092         Phy1116r        = 0x24,         /* 88E1116R Gb */
1093         Phy1118         = 0x22,         /* 88E1118 Gb */
1094         Phy3016         = 0x26,         /* 88E3016 10/100 */
1095 };
1096
1097 static int hackflavour;
1098
1099 /*
1100  * on openrd, ether0's phy has address 8, ether1's is ether0's 24.
1101  * on guruplug, ether0's is phy 0 and ether1's is ether0's phy 1.
1102  */
1103 int
1104 mymii(Mii* mii, int mask)
1105 {
1106         Ctlr *ctlr;
1107         MiiPhy *miiphy;
1108         int bit, ctlrno, oui, model, phyno, r, rmask;
1109         static int dualport, phyidx;
1110         static int phynos[NMiiPhy];
1111
1112         ctlr = mii->ctlr;
1113         ctlrno = ctlr->ether->ctlrno;
1114
1115         /* first pass: figure out what kind of phy(s) we have. */
1116         dualport = 0;
1117         if (ctlrno == 0) {
1118                 for(phyno = 0; phyno < NMiiPhy; phyno++){
1119                         bit = 1<<phyno;
1120                         if(!(mask & bit) || mii->mask & bit)
1121                                 continue;
1122                         if(mii->mir(mii, phyno, Bmsr) == -1)
1123                                 continue;
1124                         r = mii->mir(mii, phyno, Phyidr1);
1125                         oui = (r & 0x3FFF)<<6;
1126                         r = mii->mir(mii, phyno, Phyidr2);
1127                         oui |= r>>10;
1128                         model = MIIMODEL(r);
1129                         if (oui == 0xfffff && model == 0x3f)
1130                                 continue;
1131                         MIIDBG("ctlrno %d phy %d oui %#ux model %#ux\n",
1132                                 ctlrno, phyno, oui, model);
1133                         if (oui == Ouimarvell &&
1134                             (model == Phy1121r || model == Phy1116r))
1135                                 ++dualport;
1136                         phynos[phyidx++] = phyno;
1137                 }
1138                 hackflavour = dualport == 2 && phyidx == 2? Hackdual: Hacknone;
1139                 MIIDBG("ether1116: %s-port phy\n",
1140                         hackflavour == Hackdual? "dual": "single");
1141         }
1142
1143         /*
1144          * Probe through mii for PHYs in mask;
1145          * return the mask of those found in the current probe.
1146          * If the PHY has not already been probed, update
1147          * the Mii information.
1148          */
1149         rmask = 0;
1150         if (hackflavour == Hackdual && ctlrno < phyidx) {
1151                 /*
1152                  * openrd, guruplug or the like: use ether0's phys.
1153                  * this is a nasty hack, but so is the hardware.
1154                  */
1155                 MIIDBG("ctlrno %d using ctlrno 0's phyno %d\n",
1156                         ctlrno, phynos[ctlrno]);
1157                 ctlr->mii = mii = ctlrs[0]->mii;
1158                 mask = 1 << phynos[ctlrno];
1159                 mii->mask = ~mask;
1160         }
1161         for(phyno = 0; phyno < NMiiPhy; phyno++){
1162                 bit = 1<<phyno;
1163                 if(!(mask & bit))
1164                         continue;
1165                 if(mii->mask & bit){
1166                         rmask |= bit;
1167                         continue;
1168                 }
1169                 if(mii->mir(mii, phyno, Bmsr) == -1)
1170                         continue;
1171                 r = mii->mir(mii, phyno, Phyidr1);
1172                 oui = (r & 0x3FFF)<<6;
1173                 r = mii->mir(mii, phyno, Phyidr2);
1174                 oui |= r>>10;
1175                 if(oui == 0xFFFFF || oui == 0)
1176                         continue;
1177
1178                 if((miiphy = malloc(sizeof(MiiPhy))) == nil)
1179                         continue;
1180                 miiphy->mii = mii;
1181                 miiphy->oui = oui;
1182                 miiphy->phyno = phyno;
1183
1184                 miiphy->anar = ~0;
1185                 miiphy->fc = ~0;
1186                 miiphy->mscr = ~0;
1187
1188                 mii->phy[phyno] = miiphy;
1189                 if(ctlrno == 0 || hackflavour != Hackdual && mii->curphy == nil)
1190                         mii->curphy = miiphy;
1191                 mii->mask |= bit;
1192                 mii->nphy++;
1193
1194                 rmask |= bit;
1195         }
1196         return rmask;
1197 }
1198
1199 static int
1200 kirkwoodmii(Ether *ether)
1201 {
1202         int i;
1203         Ctlr *ctlr;
1204         MiiPhy *phy;
1205
1206         MIIDBG("mii\n");
1207         ctlr = ether->ctlr;
1208         if((ctlr->mii = malloc(sizeof(Mii))) == nil)
1209                 return -1;
1210         ctlr->mii->ctlr = ctlr;
1211         ctlr->mii->mir = miird;
1212         ctlr->mii->miw = miiwr;
1213
1214         if(mymii(ctlr->mii, ~0) == 0 || (phy = ctlr->mii->curphy) == nil){
1215                 print("#l%d: ether1116: init mii failure\n", ether->ctlrno);
1216                 free(ctlr->mii);
1217                 ctlr->mii = nil;
1218                 return -1;
1219         }
1220
1221         /* oui 005043 is marvell */
1222         MIIDBG("oui %#X phyno %d\n", phy->oui, phy->phyno);
1223         // TODO: does this make sense? shouldn't each phy be initialised?
1224         if((ctlr->ether->ctlrno == 0 || hackflavour != Hackdual) &&
1225             miistatus(ctlr->mii) < 0){
1226                 miireset(ctlr->mii);
1227                 MIIDBG("miireset\n");
1228                 if(miiane(ctlr->mii, ~0, 0, ~0) < 0){
1229                         iprint("miiane failed\n");
1230                         return -1;
1231                 }
1232                 MIIDBG("miistatus\n");
1233                 miistatus(ctlr->mii);
1234                 if(miird(ctlr->mii, phy->phyno, Bmsr) & BmsrLs){
1235                         for(i = 0; ; i++){
1236                                 if(i > 600){
1237                                         iprint("ether1116: autonegotiation failed\n");
1238                                         break;
1239                                 }
1240                                 if(miird(ctlr->mii, phy->phyno, Bmsr) & BmsrAnc)
1241                                         break;
1242                                 delay(10);
1243                         }
1244                         if(miistatus(ctlr->mii) < 0)
1245                                 iprint("miistatus failed\n");
1246                 }else{
1247                         iprint("ether1116: no link\n");
1248                         phy->speed = 10;        /* simple default */
1249                 }
1250         }
1251
1252         ether->mbps = phy->speed;
1253         MIIDBG("#l%d: kirkwoodmii: fd %d speed %d tfc %d rfc %d\n",
1254                 ctlr->port, phy->fd, phy->speed, phy->tfc, phy->rfc);
1255         MIIDBG("mii done\n");
1256         return 0;
1257 }
1258
1259 enum {                                          /* PHY register pages */
1260         Pagcopper,
1261         Pagfiber,
1262         Pagrgmii,
1263         Pagled,
1264         Pagrsvd1,
1265         Pagvct,
1266         Pagtest,
1267         Pagrsvd2,
1268         Pagfactest,
1269 };
1270
1271 static void
1272 miiregpage(Mii *mii, ulong dev, ulong page)
1273 {
1274         miiwr(mii, dev, Eadr, page);
1275 }
1276
1277 static int
1278 miiphyinit(Mii *mii)
1279 {
1280         ulong dev;
1281         Ctlr *ctlr;
1282         Gbereg *reg;
1283
1284         ctlr = (Ctlr*)mii->ctlr;
1285         reg = ctlr->reg;
1286         dev = reg->phy;
1287         MIIDBG("phy dev addr %lux\n", dev);
1288
1289         /* leds link & activity */
1290         miiregpage(mii, dev, Pagled);
1291         /* low 4 bits == 1: on - link, blink - activity, off - no link */
1292         miiwr(mii, dev, Scr, (miird(mii, dev, Scr) & ~0xf) | 1);
1293
1294         miiregpage(mii, dev, Pagrgmii);
1295         miiwr(mii, dev, Scr, miird(mii, dev, Scr) | Rgmiipwrup);
1296         /* must now do a software reset, says the manual */
1297         miireset(ctlr->mii);
1298
1299         /* enable RGMII delay on Tx and Rx for CPU port */
1300         miiwr(mii, dev, Recr, miird(mii, dev, Recr) | Rxtiming | Rxtiming);
1301         /* must now do a software reset, says the manual */
1302         miireset(ctlr->mii);
1303
1304         miiregpage(mii, dev, Pagcopper);
1305         miiwr(mii, dev, Scr,
1306                 (miird(mii, dev, Scr) & ~(Pwrdown|Endetect)) | Mdix);
1307
1308         return 0;
1309 }
1310
1311 /*
1312  * initialisation
1313  */
1314
1315 static void
1316 quiesce(Gbereg *reg)
1317 {
1318         ulong v;
1319
1320         v = reg->tqc;
1321         if (v & 0xFF)
1322                 reg->tqc = v << 8;              /* stop active channels */
1323         v = reg->rqc;
1324         if (v & 0xFF)
1325                 reg->rqc = v << 8;              /* stop active channels */
1326         /* wait for all queues to stop */
1327         while (reg->tqc & 0xFF || reg->rqc & 0xFF)
1328                 ;
1329 }
1330
1331 static void
1332 p16(uchar *p, ulong v)          /* convert big-endian short to bytes */
1333 {
1334         *p++ = v>>8;
1335         *p   = v;
1336 }
1337
1338 static void
1339 p32(uchar *p, ulong v)          /* convert big-endian long to bytes */
1340 {
1341         *p++ = v>>24;
1342         *p++ = v>>16;
1343         *p++ = v>>8;
1344         *p   = v;
1345 }
1346
1347 /*
1348  * set ether->ea from hw mac address,
1349  * configure unicast filtering to accept it.
1350  */
1351 void
1352 archetheraddr(Ether *ether, Gbereg *reg, int rxqno)
1353 {
1354         uchar *ea;
1355         ulong nibble, ucreg, tbloff, regoff;
1356
1357         ea = ether->ea;
1358         p32(ea,   reg->macah);
1359         p16(ea+4, reg->macal);
1360         if (memcmp(ea, zeroea, sizeof zeroea) == 0 && ether->ctlrno > 0) {
1361                 /* hack: use ctlr[0]'s + ctlrno */
1362                 memmove(ea, ctlrs[0]->ether->ea, Eaddrlen);
1363                 ea[Eaddrlen-1] += ether->ctlrno;
1364                 reg->macah = ea[0] << 24 | ea[1] << 16 | ea[2] << 8 | ea[3];
1365                 reg->macal = ea[4] <<  8 | ea[5];
1366                 coherence();
1367         }
1368
1369         /* accept frames on ea */
1370         nibble = ea[5] & 0xf;
1371         tbloff = nibble / 4;
1372         regoff = nibble % 4;
1373
1374         regoff *= 8;
1375         ucreg = reg->dfut[tbloff] & (0xff << regoff);
1376         ucreg |= (rxqno << 1 | Pass) << regoff;
1377         reg->dfut[tbloff] = ucreg;
1378
1379         /* accept all multicast too.  set up special & other tables. */
1380         memset(reg->dfsmt, Qno<<1 | Pass, sizeof reg->dfsmt);
1381         memset(reg->dfomt, Qno<<1 | Pass, sizeof reg->dfomt);
1382         coherence();
1383 }
1384
1385 static void
1386 cfgdramacc(Gbereg *reg)
1387 {
1388         memset(reg->harr, 0, sizeof reg->harr);
1389         memset(reg->base, 0, sizeof reg->base);
1390
1391         reg->bare = MASK(6) - MASK(2);  /* disable wins 2-5 */
1392         /* this doesn't make any sense, but it's required */
1393         reg->epap = 3 << 2 | 3;         /* full access for wins 0 & 1 */
1394 //      reg->epap = 0;          /* no access on access violation for all wins */
1395         coherence();
1396
1397         reg->base[0].base = PHYSDRAM | WINATTR(Attrcs0) | Targdram;
1398         reg->base[0].size = WINSIZE(256*MB);
1399         reg->base[1].base = (PHYSDRAM + 256*MB) | WINATTR(Attrcs1) | Targdram;
1400         reg->base[1].size = WINSIZE(256*MB);
1401         coherence();
1402 }
1403
1404 static void
1405 ctlralloc(Ctlr *ctlr)
1406 {
1407         int i;
1408         Block *b;
1409         Rx *r;
1410         Tx *t;
1411
1412         ilock(&freeblocks);
1413         for(i = 0; i < Nrxblks; i++) {
1414                 b = iallocb(Rxblklen+Bufalign-1);
1415                 if(b == nil) {
1416                         iprint("ether1116: no memory for rx buffers\n");
1417                         break;
1418                 }
1419                 b->wp = b->rp = (uchar*)
1420                         ((uintptr)(b->lim - Rxblklen) & ~(Bufalign - 1));
1421                 assert(((uintptr)b->rp & (Bufalign - 1)) == 0);
1422                 b->free = rxfreeb;
1423                 b->next = freeblocks.head;
1424                 freeblocks.head = b;
1425         }
1426         iunlock(&freeblocks);
1427
1428         /*
1429          * allocate uncached rx ring descriptors because rings are shared
1430          * with the ethernet controller and more than one fits in a cache line.
1431          */
1432         ctlr->rx = ucallocalign(Nrx * sizeof(Rx), Descralign, 0);
1433         if(ctlr->rx == nil)
1434                 panic("ether1116: no memory for rx ring");
1435         for(i = 0; i < Nrx; i++) {
1436                 r = &ctlr->rx[i];
1437                 assert(((uintptr)r & (Descralign - 1)) == 0);
1438                 r->cs = 0;      /* owned by software until r->buf is non-nil */
1439                 r->buf = 0;
1440                 r->next = PADDR(&ctlr->rx[NEXT(i, Nrx)]);
1441                 ctlr->rxb[i] = nil;
1442         }
1443         ctlr->rxtail = ctlr->rxhead = 0;
1444         rxreplenish(ctlr);
1445
1446         /* allocate uncached tx ring descriptors */
1447         ctlr->tx = ucallocalign(Ntx * sizeof(Tx), Descralign, 0);
1448         if(ctlr->tx == nil)
1449                 panic("ether1116: no memory for tx ring");
1450         for(i = 0; i < Ntx; i++) {
1451                 t = &ctlr->tx[i];
1452                 assert(((uintptr)t & (Descralign - 1)) == 0);
1453                 t->cs = 0;
1454                 t->buf = 0;
1455                 t->next = PADDR(&ctlr->tx[NEXT(i, Ntx)]);
1456                 ctlr->txb[i] = nil;
1457         }
1458         ctlr->txtail = ctlr->txhead = 0;
1459 }
1460
1461 static void
1462 ctlrinit(Ether *ether)
1463 {
1464         int i;
1465         Ctlr *ctlr = ether->ctlr;
1466         Gbereg *reg = ctlr->reg;
1467         static char name[KNAMELEN];
1468         static Ctlr fakectlr;           /* bigger than 4K; keep off the stack */
1469
1470         for (i = 0; i < nelem(reg->tcqdp); i++)
1471                 reg->tcqdp[i] = 0;
1472         for (i = 0; i < nelem(reg->crdp); i++)
1473                 reg->crdp[i].r = 0;
1474         coherence();
1475
1476         cfgdramacc(reg);
1477         ctlralloc(ctlr);
1478
1479         reg->tcqdp[Qno]  = PADDR(&ctlr->tx[ctlr->txhead]);
1480         reg->crdp[Qno].r = PADDR(&ctlr->rx[ctlr->rxhead]);
1481         coherence();
1482
1483 //      dumprxdescs(ctlr);
1484
1485         /* clear stats by reading them into fake ctlr */
1486         getmibstats(&fakectlr);
1487
1488         reg->pxmfs = MFS40by;                   /* allow runts in */
1489
1490         /*
1491          * ipg's (inter packet gaps) for interrupt coalescing,
1492          * values in units of 64 clock cycles.  A full-sized
1493          * packet (1514 bytes) takes just over 12µs to transmit.
1494          */
1495         if (CLOCKFREQ/(Maxrxintrsec*64) >= (1<<16))
1496                 panic("rx coalescing value %d too big for short",
1497                         CLOCKFREQ/(Maxrxintrsec*64));
1498         reg->sdc = SDCrifb | SDCrxburst(Burst16) | SDCtxburst(Burst16) |
1499                 SDCrxnobyteswap | SDCtxnobyteswap |
1500                 SDCipgintrx(CLOCKFREQ/(Maxrxintrsec*64));
1501         reg->pxtfut = 0;        /* TFUTipginttx(CLOCKFREQ/(Maxrxintrsec*64)) */
1502
1503         /* allow just these interrupts */
1504         /* guruplug generates Irxerr interrupts continually */
1505         reg->irqmask = Isum | Irx | Irxbufferq(Qno) | Irxerr | Itxendq(Qno);
1506         reg->irqemask = IEsum | IEtxerrq(Qno) | IEphystschg | IErxoverrun |
1507                 IEtxunderrun;
1508
1509         reg->irqe = 0;
1510         reg->euirqmask = 0;
1511         coherence();
1512         reg->irq = 0;
1513         reg->euirq = 0;
1514         /* send errors to end of memory */
1515 //      reg->euda = PHYSDRAM + 512*MB - 8*1024;
1516         reg->euda = 0;
1517         reg->eudid = Attrcs1 << 4 | Targdram;
1518
1519 //      archetheraddr(ether, ctlr->reg, Qno);   /* 2nd location */
1520
1521         reg->portcfg = Rxqdefault(Qno) | Rxqarp(Qno);
1522         reg->portcfgx = 0;
1523         coherence();
1524
1525         /*
1526          * start the controller running.
1527          * turn the port on, kick the receiver.
1528          */
1529
1530         reg->psc1 = PSC1rgmii | PSC1encolonbp | PSC1coldomlim(0x23);
1531         /* do this only when the controller is quiescent */
1532         reg->psc0 = PSC0porton | PSC0an_flctloff |
1533                 PSC0an_pauseadv | PSC0nofrclinkdown | PSC0mru(PSC0mru1522);
1534         coherence();
1535         for (i = 0; i < 4000; i++)              /* magic delay */
1536                 ;
1537
1538         ether->link = (reg->ps0 & PS0linkup) != 0;
1539
1540         /* set ethernet MTU for leaky bucket mechanism to 0 (disabled) */
1541         reg->pmtu = 0;
1542         etheractive(ether);
1543
1544         snprint(name, sizeof name, "#l%drproc", ether->ctlrno);
1545         kproc(name, rcvproc, ether);
1546
1547         reg->rqc = Rxqon(Qno);
1548         coherence();
1549 }
1550
1551 static void
1552 attach(Ether* ether)
1553 {
1554         Ctlr *ctlr = ether->ctlr;
1555
1556         lock(&ctlr->initlock);
1557         if(ctlr->init == 0) {
1558                 ctlrinit(ether);
1559                 ctlr->init = 1;
1560         }
1561         unlock(&ctlr->initlock);
1562 }
1563
1564 /*
1565  * statistics goo.
1566  * mib registers clear on read.
1567  */
1568
1569 static void
1570 getmibstats(Ctlr *ctlr)
1571 {
1572         Gbereg *reg = ctlr->reg;
1573
1574         /*
1575          * Marvell 88f6281 errata FE-ETH-120: high long of rxby and txby
1576          * can't be read correctly, so read the low long frequently
1577          * (every 30 seconds or less), thus avoiding overflow into high long.
1578          */
1579         ctlr->rxby      += reg->rxbylo;
1580         ctlr->txby      += reg->txbylo;
1581
1582         ctlr->badrxby   += reg->badrxby;
1583         ctlr->mactxerr  += reg->mactxerr;
1584         ctlr->rxpkt     += reg->rxpkt;
1585         ctlr->badrxpkt  += reg->badrxpkt;
1586         ctlr->rxbcastpkt+= reg->rxbcastpkt;
1587         ctlr->rxmcastpkt+= reg->rxmcastpkt;
1588         ctlr->rx64      += reg->rx64;
1589         ctlr->rx65_127  += reg->rx65_127;
1590         ctlr->rx128_255 += reg->rx128_255;
1591         ctlr->rx256_511 += reg->rx256_511;
1592         ctlr->rx512_1023+= reg->rx512_1023;
1593         ctlr->rx1024_max+= reg->rx1024_max;
1594         ctlr->txpkt     += reg->txpkt;
1595         ctlr->txcollpktdrop+= reg->txcollpktdrop;
1596         ctlr->txmcastpkt+= reg->txmcastpkt;
1597         ctlr->txbcastpkt+= reg->txbcastpkt;
1598         ctlr->badmacctlpkts+= reg->badmacctlpkts;
1599         ctlr->txflctl   += reg->txflctl;
1600         ctlr->rxflctl   += reg->rxflctl;
1601         ctlr->badrxflctl+= reg->badrxflctl;
1602         ctlr->rxundersized+= reg->rxundersized;
1603         ctlr->rxfrags   += reg->rxfrags;
1604         ctlr->rxtoobig  += reg->rxtoobig;
1605         ctlr->rxjabber  += reg->rxjabber;
1606         ctlr->rxerr     += reg->rxerr;
1607         ctlr->crcerr    += reg->crcerr;
1608         ctlr->collisions+= reg->collisions;
1609         ctlr->latecoll  += reg->latecoll;
1610 }
1611
1612 long
1613 ifstat(Ether *ether, void *a, long n, ulong off)
1614 {
1615         Ctlr *ctlr = ether->ctlr;
1616         Gbereg *reg = ctlr->reg;
1617         char *buf, *p, *e;
1618
1619         buf = p = malloc(READSTR);
1620         e = p + READSTR;
1621
1622         ilock(ctlr);
1623         getmibstats(ctlr);
1624
1625         ctlr->intrs += ctlr->newintrs;
1626         p = seprint(p, e, "interrupts: %lud\n", ctlr->intrs);
1627         p = seprint(p, e, "new interrupts: %lud\n", ctlr->newintrs);
1628         ctlr->newintrs = 0;
1629         p = seprint(p, e, "tx underrun: %lud\n", ctlr->txunderrun);
1630         p = seprint(p, e, "tx ring full: %lud\n", ctlr->txringfull);
1631
1632         ctlr->rxdiscard += reg->pxdfc;
1633         ctlr->rxoverrun += reg->pxofc;
1634         p = seprint(p, e, "rx discarded frames: %lud\n", ctlr->rxdiscard);
1635         p = seprint(p, e, "rx overrun frames: %lud\n", ctlr->rxoverrun);
1636         p = seprint(p, e, "no first+last flag: %lud\n", ctlr->nofirstlast);
1637
1638         p = seprint(p, e, "duplex: %s\n", (reg->ps0 & PS0fd)? "full": "half");
1639         p = seprint(p, e, "flow control: %s\n", (reg->ps0 & PS0flctl)? "on": "off");
1640         /* p = seprint(p, e, "speed: %d mbps\n", ); */
1641
1642         p = seprint(p, e, "received bytes: %llud\n", ctlr->rxby);
1643         p = seprint(p, e, "bad received bytes: %lud\n", ctlr->badrxby);
1644         p = seprint(p, e, "internal mac transmit errors: %lud\n", ctlr->mactxerr);
1645         p = seprint(p, e, "total received frames: %lud\n", ctlr->rxpkt);
1646         p = seprint(p, e, "received broadcast frames: %lud\n", ctlr->rxbcastpkt);
1647         p = seprint(p, e, "received multicast frames: %lud\n", ctlr->rxmcastpkt);
1648         p = seprint(p, e, "bad received frames: %lud\n", ctlr->badrxpkt);
1649         p = seprint(p, e, "received frames 0-64: %lud\n", ctlr->rx64);
1650         p = seprint(p, e, "received frames 65-127: %lud\n", ctlr->rx65_127);
1651         p = seprint(p, e, "received frames 128-255: %lud\n", ctlr->rx128_255);
1652         p = seprint(p, e, "received frames 256-511: %lud\n", ctlr->rx256_511);
1653         p = seprint(p, e, "received frames 512-1023: %lud\n", ctlr->rx512_1023);
1654         p = seprint(p, e, "received frames 1024-max: %lud\n", ctlr->rx1024_max);
1655         p = seprint(p, e, "transmitted bytes: %llud\n", ctlr->txby);
1656         p = seprint(p, e, "total transmitted frames: %lud\n", ctlr->txpkt);
1657         p = seprint(p, e, "transmitted broadcast frames: %lud\n", ctlr->txbcastpkt);
1658         p = seprint(p, e, "transmitted multicast frames: %lud\n", ctlr->txmcastpkt);
1659         p = seprint(p, e, "transmit frames dropped by collision: %lud\n", ctlr->txcollpktdrop);
1660
1661         p = seprint(p, e, "bad mac control frames: %lud\n", ctlr->badmacctlpkts);
1662         p = seprint(p, e, "transmitted flow control messages: %lud\n", ctlr->txflctl);
1663         p = seprint(p, e, "received flow control messages: %lud\n", ctlr->rxflctl);
1664         p = seprint(p, e, "bad received flow control messages: %lud\n", ctlr->badrxflctl);
1665         p = seprint(p, e, "received undersized packets: %lud\n", ctlr->rxundersized);
1666         p = seprint(p, e, "received fragments: %lud\n", ctlr->rxfrags);
1667         p = seprint(p, e, "received oversized packets: %lud\n", ctlr->rxtoobig);
1668         p = seprint(p, e, "received jabber packets: %lud\n", ctlr->rxjabber);
1669         p = seprint(p, e, "mac receive errors: %lud\n", ctlr->rxerr);
1670         p = seprint(p, e, "crc errors: %lud\n", ctlr->crcerr);
1671         p = seprint(p, e, "collisions: %lud\n", ctlr->collisions);
1672         p = seprint(p, e, "late collisions: %lud\n", ctlr->latecoll);
1673         USED(p);
1674         iunlock(ctlr);
1675
1676         n = readstr(off, a, n, buf);
1677         free(buf);
1678         return n;
1679 }
1680
1681
1682 static int
1683 reset(Ether *ether)
1684 {
1685         Ctlr *ctlr;
1686
1687         ether->ctlr = ctlr = malloc(sizeof *ctlr);
1688         switch(ether->ctlrno) {
1689         case 0:
1690                 ether->irq = IRQ0gbe0sum;
1691                 break;
1692         case 1:
1693                 ether->irq = IRQ0gbe1sum;
1694                 break;
1695         default:
1696                 return -1;
1697         }
1698         ctlr->reg = (Gbereg*)soc.ether[ether->ctlrno];
1699
1700         /* need this for guruplug, at least */
1701         *(ulong *)soc.iocfg |= 1 << 7 | 1 << 15;        /* io cfg 0: 1.8v gbe */
1702         coherence();
1703
1704         ctlr->ether = ether;
1705         ctlrs[ether->ctlrno] = ctlr;
1706
1707         shutdown(ether);
1708         /* ensure that both interfaces are set to RGMII before calling mii */
1709         ((Gbereg*)soc.ether[0])->psc1 |= PSC1rgmii;
1710         ((Gbereg*)soc.ether[1])->psc1 |= PSC1rgmii;
1711         coherence();
1712
1713         /* Set phy address of the port */
1714         ctlr->port = ether->ctlrno;
1715         ctlr->reg->phy = ether->ctlrno;
1716         coherence();
1717         ether->port = (uintptr)ctlr->reg;
1718
1719         if(kirkwoodmii(ether) < 0){
1720                 free(ctlr);
1721                 ether->ctlr = nil;
1722                 return -1;
1723         }
1724         miiphyinit(ctlr->mii);
1725         archetheraddr(ether, ctlr->reg, Qno);   /* original location */
1726         if (memcmp(ether->ea, zeroea, sizeof zeroea) == 0){
1727 iprint("ether1116: reset: zero ether->ea\n");
1728                 free(ctlr);
1729                 ether->ctlr = nil;
1730                 return -1;                      /* no rj45 for this ether */
1731         }
1732
1733         ether->attach = attach;
1734         ether->transmit = transmit;
1735         ether->ifstat = ifstat;
1736         ether->shutdown = shutdown;
1737         ether->ctl = ctl;
1738
1739         ether->arg = ether;
1740         ether->promiscuous = promiscuous;
1741         ether->multicast = multicast;
1742
1743         intrenable(Irqlo, ether->irq, interrupt, ether, ether->name);
1744
1745         return 0;
1746 }
1747
1748 void
1749 ether1116link(void)
1750 {
1751         addethercard("88e1116", reset);
1752 }