]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/etherga620.c
kernel: fix inproper use of malloc/smalloc
[plan9front.git] / sys / src / 9 / pc / etherga620.c
1 /*
2  * Netgear GA620 Gigabit Ethernet Card.
3  * Specific for the Alteon Tigon 2 and Intel Pentium or later.
4  * To Do:
5  *      cache alignment for PCI Write-and-Invalidate
6  *      mini ring (what size)?
7  *      tune coalescing values
8  *      statistics formatting
9  *      don't update Spi if nothing to send
10  *      receive ring alignment
11  *      watchdog for link management?
12  */
13 #include "u.h"
14 #include "../port/lib.h"
15 #include "mem.h"
16 #include "dat.h"
17 #include "fns.h"
18 #include "io.h"
19 #include "../port/error.h"
20 #include "../port/netif.h"
21
22 #define malign(n)       xspanalloc((n), 32, 0)
23
24 #include "etherif.h"
25 #include "etherga620fw.h"
26
27 enum {
28         Mhc             = 0x0040,       /* Miscellaneous Host Control */
29         Mlc             = 0x0044,       /* Miscellaneous Local Control */
30         Mc              = 0x0050,       /* Miscellaneous Configuration */
31         Ps              = 0x005C,       /* PCI State */
32         Wba             = 0x0068,       /* Window Base Address */
33         Wd              = 0x006C,       /* Window Data */
34
35         DMAas           = 0x011C,       /* DMA Assist State */
36
37         CPUAstate       = 0x0140,       /* CPU A State */
38         CPUApc          = 0x0144,       /* CPU A Programme Counter */
39
40         CPUBstate       = 0x0240,       /* CPU B State */
41
42         Hi              = 0x0504,       /* Host In Interrupt Handler */
43         Cpi             = 0x050C,       /* Command Producer Index */
44         Spi             = 0x0514,       /* Send Producer Index */
45         Rspi            = 0x051C,       /* Receive Standard Producer Index */
46         Rjpi            = 0x0524,       /* Receive Jumbo Producer Index */
47         Rmpi            = 0x052C,       /* Receive Mini Producer Index */
48
49         Mac             = 0x0600,       /* MAC Address */
50         Gip             = 0x0608,       /* General Information Pointer */
51         Om              = 0x0618,       /* Operating Mode */
52         DMArc           = 0x061C,       /* DMA Read Configuration */
53         DMAwc           = 0x0620,       /* DMA Write Configuration */
54         Tbr             = 0x0624,       /* Transmit Buffer Ratio */
55         Eci             = 0x0628,       /* Event Consumer Index */
56         Cci             = 0x062C,       /* Command Consumer Index */
57
58         Rct             = 0x0630,       /* Receive Coalesced Ticks */
59         Sct             = 0x0634,       /* Send Coalesced Ticks */
60         St              = 0x0638,       /* Stat Ticks */
61         SmcBD           = 0x063C,       /* Send Max. Coalesced BDs */
62         RmcBD           = 0x0640,       /* Receive Max. Coalesced BDs */
63         Nt              = 0x0644,       /* NIC Tracing */
64         Gln             = 0x0648,       /* Gigabit Link Negotiation */
65         Fln             = 0x064C,       /* 10/100 Link Negotiation */
66         Ifx             = 0x065C,       /* Interface Index */
67         IfMTU           = 0x0660,       /* Interface MTU */
68         Mi              = 0x0664,       /* Mask Interrupts */
69         Gls             = 0x0668,       /* Gigabit Link State */
70         Fls             = 0x066C,       /* 10/100 Link State */
71
72         Cr              = 0x0700,       /* Command Ring */
73
74         Lmw             = 0x0800,       /* Local Memory Window */
75 };
76
77 enum {                                  /* Mhc */
78         Is              = 0x00000001,   /* Interrupt State */
79         Ci              = 0x00000002,   /* Clear Interrupt */
80         Hr              = 0x00000008,   /* Hard Reset */
81         Eebs            = 0x00000010,   /* Enable Endian Byte Swap */
82         Eews            = 0x00000020,   /* Enable Endian Word (64-bit) swap */
83         Mpio            = 0x00000040,   /* Mask PCI Interrupt Output */
84 };
85
86 enum {                                  /* Mlc */
87         SRAM512         = 0x00000200,   /* SRAM Bank Size of 512KB */
88         SRAMmask        = 0x00000300,
89         EEclk           = 0x00100000,   /* Serial EEPROM Clock Output */
90         EEdoe           = 0x00200000,   /* Serial EEPROM Data Out Enable */
91         EEdo            = 0x00400000,   /* Serial EEPROM Data Out Value */
92         EEdi            = 0x00800000,   /* Serial EEPROM Data Input */
93 };
94
95 enum {                                  /* Mc */
96         SyncSRAM        = 0x00100000,   /* Set Synchronous SRAM Timing */
97 };
98
99 enum {                                  /* Ps */
100         PCIwm32         = 0x000000C0,   /* Write Max DMA 32 */
101         PCImrm          = 0x00020000,   /* Use Memory Read Multiple Command */
102         PCI66           = 0x00080000,
103         PCI32           = 0x00100000,
104         PCIrcmd         = 0x06000000,   /* PCI Read Command */
105         PCIwcmd         = 0x70000000,   /* PCI Write Command */
106 };
107
108 enum {                                  /* CPUAstate */
109         CPUrf           = 0x00000010,   /* ROM Fail */
110         CPUhalt         = 0x00010000,   /* Halt the internal CPU */
111         CPUhie          = 0x00040000,   /* HALT instruction executed */
112 };
113
114 enum {                                  /* Om */
115         BswapBD         = 0x00000002,   /* Byte Swap Buffer Descriptors */
116         WswapBD         = 0x00000004,   /* Word Swap Buffer Descriptors */
117         Warn            = 0x00000008,
118         BswapDMA        = 0x00000010,   /* Byte Swap DMA Data */
119         Only1DMA        = 0x00000040,   /* Only One DMA Active at a time */
120         NoJFrag         = 0x00000200,   /* Don't Fragment Jumbo Frames */
121         Fatal           = 0x40000000,
122 };
123
124 enum {                                  /* Lmw */
125         Lmwsz           = 2*1024,       /* Local Memory Window Size */
126
127         /*
128          * legal values are 0x3800 iff Nsr is 128, 0x3000 iff Nsr is 256,
129          * or 0x2000 iff Nsr is 512.
130          */
131         Sr              = 0x2000,       /* Send Ring (accessed via Lmw) */
132 };
133
134 enum {                                  /* Link */
135         Lpref           = 0x00008000,   /* Preferred Link */
136         L10MB           = 0x00010000,
137         L100MB          = 0x00020000,
138         L1000MB         = 0x00040000,
139         Lfd             = 0x00080000,   /* Full Duplex */
140         Lhd             = 0x00100000,   /* Half Duplex */
141         Lefc            = 0x00200000,   /* Emit Flow Control Packets */
142         Lofc            = 0x00800000,   /* Obey Flow Control Packets */
143         Lean            = 0x20000000,   /* Enable Autonegotiation/Sensing */
144         Le              = 0x40000000,   /* Link Enable */
145 };
146
147 typedef struct Host64 {
148         uint    hi;
149         uint    lo;
150 } Host64;
151
152 typedef struct Ere {                    /* Event Ring Element */
153         int     event;                  /* event<<24 | code<<12 | index */
154         int     unused;
155 } Ere;
156
157 typedef int Cmd;                        /* cmd<<24 | flags<<12 | index */
158
159 typedef struct Rbd {                    /* Receive Buffer Descriptor */
160         Host64  addr;
161         int     indexlen;               /* ring-index<<16 | buffer-length */
162         int     flags;                  /* only lower 16-bits */
163         int     checksum;               /* ip<<16 | tcp/udp */
164         int     error;                  /* only upper 16-bits */
165         int     reserved;
166         void*   opaque;                 /* passed to receive return ring */
167 } Rbd;
168
169 typedef struct Sbd {                    /* Send Buffer Descriptor */
170         Host64  addr;
171         int     lenflags;               /* len<<16 | flags */
172         int     reserved;
173 } Sbd;
174
175 enum {                                  /* Buffer Descriptor Flags */
176         Fend            = 0x00000004,   /* Frame Ends in this Buffer */
177         Frjr            = 0x00000010,   /* Receive Jumbo Ring Buffer */
178         Funicast        = 0x00000020,   /* Unicast packet (2-bit field) */
179         Fmulticast      = 0x00000040,   /* Multicast packet */
180         Fbroadcast      = 0x00000060,   /* Broadcast packet */
181         Ferror          = 0x00000400,   /* Frame Has Error */
182         Frmr            = 0x00001000,   /* Receive Mini Ring Buffer */
183 };
184
185 enum {                                  /* Buffer Error Flags */
186         Ecrc            = 0x00010000,   /* bad CRC */
187         Ecollision      = 0x00020000,   /* collision */
188         Elink           = 0x00040000,   /* link lost */
189         Ephy            = 0x00080000,   /* unspecified PHY frame decode error */
190         Eodd            = 0x00100000,   /* odd number of nibbles */
191         Emac            = 0x00200000,   /* unspecified MAC abort */
192         Elen64          = 0x00400000,   /* short packet */
193         Eresources      = 0x00800000,   /* MAC out of internal resources */
194         Egiant          = 0x01000000,   /* packet too big */
195 };
196
197 typedef struct Rcb {                    /* Ring Control Block */
198         Host64  addr;                   /* points to the Rbd ring */
199         int     control;                /* max_len<<16 | flags */
200         int     unused;
201 } Rcb;
202
203 enum {
204         TcpUdpCksum     = 0x0001,       /* Perform TCP or UDP checksum */
205         IpCksum         = 0x0002,       /* Perform IP checksum */
206         NoPseudoHdrCksum= 0x0008,       /* Don't include the pseudo header */
207         VlanAssist      = 0x0010,       /* Enable VLAN tagging */
208         CoalUpdateOnly  = 0x0020,       /* Coalesce transmit interrupts */
209         HostRing        = 0x0040,       /* Sr in host memory */
210         SnapCksum       = 0x0080,       /* Parse + offload 802.3 SNAP frames */
211         UseExtRxBd      = 0x0100,       /* Extended Rbd for Jumbo frames */
212         RingDisabled    = 0x0200,       /* Jumbo or Mini RCB only */
213 };
214
215 typedef struct Gib {                    /* General Information Block */
216         int     statistics[256];        /* Statistics */
217         Rcb     ercb;                   /* Event Ring */
218         Rcb     crcb;                   /* Command Ring */
219         Rcb     srcb;                   /* Send Ring */
220         Rcb     rsrcb;                  /* Receive Standard Ring */
221         Rcb     rjrcb;                  /* Receive Jumbo Ring */
222         Rcb     rmrcb;                  /* Receive Mini Ring */
223         Rcb     rrrcb;                  /* Receive Return Ring */
224         Host64  epp;                    /* Event Producer */
225         Host64  rrrpp;                  /* Receive Return Ring Producer */
226         Host64  scp;                    /* Send Consumer */
227         Host64  rsp;                    /* Refresh Stats */
228 } Gib;
229
230 /*
231  * these sizes are all fixed in the card,
232  * except for Nsr, which has only 3 valid sizes.
233  */
234 enum {                                  /* Host/NIC Interface ring sizes */
235         Ner             = 256,          /* event ring */
236         Ncr             = 64,           /* command ring */
237         Nsr             = 512,          /* send ring: 128, 256 or 512 */
238         Nrsr            = 512,          /* receive standard ring */
239         Nrjr            = 256,          /* receive jumbo ring */
240         Nrmr            = 1024,         /* receive mini ring, optional */
241         Nrrr            = 2048,         /* receive return ring */
242 };
243
244 enum {
245         NrsrHI          = 72,           /* Fill-level of Rsr (m.b. < Nrsr) */
246         NrsrLO          = 54,           /* Level at which to top-up ring */
247         NrjrHI          = 0,            /* Fill-level of Rjr (m.b. < Nrjr) */
248         NrjrLO          = 0,            /* Level at which to top-up ring */
249         NrmrHI          = 0,            /* Fill-level of Rmr (m.b. < Nrmr) */
250         NrmrLO          = 0,            /* Level at which to top-up ring */
251 };
252
253 typedef struct Ctlr Ctlr;
254 struct Ctlr {
255         int     port;
256         Pcidev* pcidev;
257         Ctlr*   next;
258         int     active;
259         int     id;
260
261         uchar   ea[Eaddrlen];
262
263         int*    nic;
264         Gib*    gib;
265
266         Ere*    er;
267
268         Lock    srlock;
269         Sbd*    sr;
270         Block** srb;
271         int     nsr;                    /* currently in send ring */
272
273         Rbd*    rsr;
274         int     nrsr;                   /* currently in Receive Standard Ring */
275         Rbd*    rjr;
276         int     nrjr;                   /* currently in Receive Jumbo Ring */
277         Rbd*    rmr;
278         int     nrmr;                   /* currently in Receive Mini Ring */
279         Rbd*    rrr;
280         int     rrrci;                  /* Receive Return Ring Consumer Index */
281
282         int     epi[2];                 /* Event Producer Index */
283         int     rrrpi[2];               /* Receive Return Ring Producer Index */
284         int     sci[3];                 /* Send Consumer Index ([2] is host) */
285
286         int     interrupts;             /* statistics */
287         int     mi;
288         uvlong  ticks;
289
290         int     coalupdateonly;         /* tuning */
291         int     hardwarecksum;
292         int     rct;                    /* Receive Coalesce Ticks */
293         int     sct;                    /* Send Coalesce Ticks */
294         int     st;                     /* Stat Ticks */
295         int     smcbd;                  /* Send Max. Coalesced BDs */
296         int     rmcbd;                  /* Receive Max. Coalesced BDs */
297 };
298
299 static Ctlr* ctlrhead;
300 static Ctlr* ctlrtail;
301
302 #define csr32r(c, r)    (*((c)->nic+((r)/4)))
303 #define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
304
305 static void
306 sethost64(Host64* host64, void* addr)
307 {
308         uvlong uvl;
309
310         uvl = PCIWADDR(addr);
311         host64->hi = uvl>>32;
312         host64->lo = uvl & 0xFFFFFFFFL;
313 }
314
315 static void
316 ga620command(Ctlr* ctlr, int cmd, int flags, int index)
317 {
318         int cpi;
319
320         cpi = csr32r(ctlr, Cpi);
321         csr32w(ctlr, Cr+(cpi*4), cmd<<24 | flags<<12 | index);
322         cpi = NEXT(cpi, Ncr);
323         csr32w(ctlr, Cpi, cpi);
324 }
325
326 static void
327 ga620attach(Ether* edev)
328 {
329         Ctlr *ctlr;
330
331         ctlr = edev->ctlr;
332         USED(ctlr);
333 }
334
335 static long
336 ga620ifstat(Ether* edev, void* a, long n, ulong offset)
337 {
338         char *p;
339         Ctlr *ctlr;
340         int i, l, r;
341
342         ctlr = edev->ctlr;
343
344         if(n == 0)
345                 return 0;
346         p = smalloc(READSTR);
347         l = 0;
348         for(i = 0; i < 256; i++){
349                 if((r = ctlr->gib->statistics[i]) == 0)
350                         continue;
351                 l += snprint(p+l, READSTR-l, "%d: %ud\n", i, r);
352         }
353
354         l += snprint(p+l, READSTR-l, "interrupts: %ud\n", ctlr->interrupts);
355         l += snprint(p+l, READSTR-l, "mi: %ud\n", ctlr->mi);
356         l += snprint(p+l, READSTR-l, "ticks: %llud\n", ctlr->ticks);
357         l += snprint(p+l, READSTR-l, "coalupdateonly: %d\n", ctlr->coalupdateonly);
358         l += snprint(p+l, READSTR-l, "hardwarecksum: %d\n", ctlr->hardwarecksum);
359         l += snprint(p+l, READSTR-l, "rct: %d\n", ctlr->rct);
360         l += snprint(p+l, READSTR-l, "sct: %d\n", ctlr->sct);
361         l += snprint(p+l, READSTR-l, "smcbd: %d\n", ctlr->smcbd);
362         snprint(p+l, READSTR-l, "rmcbd: %d\n", ctlr->rmcbd);
363
364         n = readstr(offset, a, n, p);
365         free(p);
366
367         return n;
368 }
369
370 static long
371 ga620ctl(Ether* edev, void* buf, long n)
372 {
373         char *p;
374         Cmdbuf *cb;
375         Ctlr *ctlr;
376         int control, i, r;
377
378         ctlr = edev->ctlr;
379         if(ctlr == nil)
380                 error(Enonexist);
381         r = 0;
382         cb = parsecmd(buf, n);
383         if(cb->nf < 2)
384                 r = -1;
385         else if(cistrcmp(cb->f[0], "coalupdateonly") == 0){
386                 if(cistrcmp(cb->f[1], "off") == 0){
387                         control = ctlr->gib->srcb.control;
388                         control &= ~CoalUpdateOnly;
389                         ctlr->gib->srcb.control = control;
390                         ctlr->coalupdateonly = 0;
391                 }
392                 else if(cistrcmp(cb->f[1], "on") == 0){
393                         control = ctlr->gib->srcb.control;
394                         control |= CoalUpdateOnly;
395                         ctlr->gib->srcb.control = control;
396                         ctlr->coalupdateonly = 1;
397                 }
398                 else
399                         r = -1;
400         }
401         else if(cistrcmp(cb->f[0], "hardwarecksum") == 0){
402                 if(cistrcmp(cb->f[1], "off") == 0){
403                         control = ctlr->gib->srcb.control;
404                         control &= ~(TcpUdpCksum|NoPseudoHdrCksum);
405                         ctlr->gib->srcb.control = control;
406
407                         control = ctlr->gib->rsrcb.control;
408                         control &= ~(TcpUdpCksum|NoPseudoHdrCksum);
409                         ctlr->gib->rsrcb.control = control;
410
411                         ctlr->hardwarecksum = 0;
412                 }
413                 else if(cistrcmp(cb->f[1], "on") == 0){
414                         control = ctlr->gib->srcb.control;
415                         control |= (TcpUdpCksum|NoPseudoHdrCksum);
416                         ctlr->gib->srcb.control = control;
417
418                         control = ctlr->gib->rsrcb.control;
419                         control |= (TcpUdpCksum|NoPseudoHdrCksum);
420                         ctlr->gib->rsrcb.control = control;
421
422                         ctlr->hardwarecksum = 1;
423                 }
424                 else
425                         r = -1;
426         }
427         else if(cistrcmp(cb->f[0], "rct") == 0){
428                 i = strtol(cb->f[1], &p, 0);
429                 if(i < 0 || p == cb->f[1])
430                         r = -1;
431                 else{
432                         ctlr->rct = i;
433                         csr32w(ctlr, Rct, ctlr->rct);
434                 }
435         }
436         else if(cistrcmp(cb->f[0], "sct") == 0){
437                 i = strtol(cb->f[1], &p, 0);
438                 if(i < 0 || p == cb->f[1])
439                         r = -1;
440                 else{
441                         ctlr->sct = i;
442                         csr32w(ctlr, Sct, ctlr->sct);
443                 }
444         }
445         else if(cistrcmp(cb->f[0], "st") == 0){
446                 i = strtol(cb->f[1], &p, 0);
447                 if(i < 0 || p == cb->f[1])
448                         r = -1;
449                 else{
450                         ctlr->st = i;
451                         csr32w(ctlr, St, ctlr->st);
452                 }
453         }
454         else if(cistrcmp(cb->f[0], "smcbd") == 0){
455                 i = strtol(cb->f[1], &p, 0);
456                 if(i < 0 || p == cb->f[1])
457                         r = -1;
458                 else{
459                         ctlr->smcbd = i;
460                         csr32w(ctlr, SmcBD, ctlr->smcbd);
461                 }
462         }
463         else if(cistrcmp(cb->f[0], "rmcbd") == 0){
464                 i = strtol(cb->f[1], &p, 0);
465                 if(i < 0 || p == cb->f[1])
466                         r = -1;
467                 else{
468                         ctlr->rmcbd = i;
469                         csr32w(ctlr, RmcBD, ctlr->rmcbd);
470                 }
471         }
472         else
473                 r = -1;
474
475         free(cb);
476         if(r == 0)
477                 return n;
478         return r;
479 }
480
481 static int
482 _ga620transmit(Ether* edev)
483 {
484         Sbd *sbd;
485         Block *bp;
486         Ctlr *ctlr;
487         int sci, spi, work;
488
489         /*
490          * For now there are no smarts here, just empty the
491          * ring and try to fill it back up. Tuning comes later.
492          */
493         ctlr = edev->ctlr;
494         ilock(&ctlr->srlock);
495
496         /*
497          * Free any completed packets.
498          * Ctlr->sci[0] is where the NIC has got to consuming the ring.
499          * Ctlr->sci[2] is where the host has got to tidying up after the
500          * NIC has done with the packets.
501          */
502         work = 0;
503         for(sci = ctlr->sci[2]; sci != ctlr->sci[0]; sci = NEXT(sci, Nsr)){
504                 if(ctlr->srb[sci] == nil)
505                         continue;
506                 freeb(ctlr->srb[sci]);
507                 ctlr->srb[sci] = nil;
508                 work++;
509         }
510         ctlr->sci[2] = sci;
511
512         sci = PREV(sci, Nsr);
513         for(spi = csr32r(ctlr, Spi); spi != sci; spi = NEXT(spi, Nsr)){
514                 if((bp = qget(edev->oq)) == nil)
515                         break;
516
517                 sbd = &ctlr->sr[spi];
518                 sethost64(&sbd->addr, bp->rp);
519                 sbd->lenflags = BLEN(bp)<<16 | Fend;
520
521                 ctlr->srb[spi] = bp;
522                 work++;
523         }
524         csr32w(ctlr, Spi, spi);
525
526         iunlock(&ctlr->srlock);
527
528         return work;
529 }
530
531 static void
532 ga620transmit(Ether* edev)
533 {
534         _ga620transmit(edev);
535 }
536
537 static void
538 ga620replenish(Ctlr* ctlr)
539 {
540         Rbd *rbd;
541         int rspi;
542         Block *bp;
543
544         rspi = csr32r(ctlr, Rspi);
545         while(ctlr->nrsr < NrsrHI){
546                 if((bp = iallocb(ETHERMAXTU+4)) == nil)
547                         break;
548                 rbd = &ctlr->rsr[rspi];
549                 sethost64(&rbd->addr, bp->rp);
550                 rbd->indexlen = rspi<<16 | (ETHERMAXTU+4);
551                 rbd->flags = 0;
552                 rbd->opaque = bp;
553
554                 rspi = NEXT(rspi, Nrsr);
555                 ctlr->nrsr++;
556         }
557         csr32w(ctlr, Rspi, rspi);
558 }
559
560 static void
561 ga620event(Ether *edev, int eci, int epi)
562 {
563         unsigned event, code;
564         Ctlr *ctlr;
565
566         ctlr = edev->ctlr;
567         while(eci != epi){
568                 event = ctlr->er[eci].event;
569                 code = (event >> 12) & ((1<<12)-1);
570                 switch(event>>24){
571                 case 0x01:              /* firmware operational */
572                         /* host stack (us) is up.  3rd arg of 2 means down. */
573                         ga620command(ctlr, 0x01, 0x01, 0x00);
574                         /*
575                          * link negotiation: any speed is okay.
576                          * 3rd arg of 1 selects gigabit only; 2 10/100 only.
577                          */
578                         ga620command(ctlr, 0x0B, 0x00, 0x00);
579                         print("#l%d: ga620: port %8.8uX: firmware is up\n",
580                                 edev->ctlrno, ctlr->port);
581                         break;
582                 case 0x04:              /* statistics updated */
583                         break;
584                 case 0x06:              /* link state changed */
585                         switch (code) {
586                         case 1:
587                                 edev->mbps = 1000;
588                                 break;
589                         case 2:
590                                 print("#l%d: link down\n", edev->ctlrno);
591                                 break;
592                         case 3:
593                                 edev->mbps = 100;       /* it's 10 or 100 */
594                                 break;
595                         }
596                         if (code != 2)
597                                 print("#l%d: %dMbps link up\n",
598                                         edev->ctlrno, edev->mbps);
599                         break;
600                 case 0x07:              /* event error */
601                 default:
602                         print("#l%d: ga620: er[%d] = %8.8uX\n", edev->ctlrno,
603                                 eci, event);
604                         break;
605                 }
606                 eci = NEXT(eci, Ner);
607         }
608         csr32w(ctlr, Eci, eci);
609 }
610
611 static void
612 ga620receive(Ether* edev)
613 {
614         int len;
615         Rbd *rbd;
616         Block *bp;
617         Ctlr* ctlr;
618
619         ctlr = edev->ctlr;
620         while(ctlr->rrrci != ctlr->rrrpi[0]){
621                 rbd = &ctlr->rrr[ctlr->rrrci];
622                 /*
623                  * Errors are collected in the statistics block so
624                  * no need to tally them here, let ifstat do the work.
625                  */
626                 len = rbd->indexlen & 0xFFFF;
627                 if(!(rbd->flags & Ferror) && len != 0){
628                         bp = rbd->opaque;
629                         bp->wp = bp->rp+len;
630                         etheriq(edev, bp, 1);
631                 }
632                 else
633                         freeb(rbd->opaque);
634                 rbd->opaque = nil;
635
636                 if(rbd->flags & Frjr)
637                         ctlr->nrjr--;
638                 else if(rbd->flags & Frmr)
639                         ctlr->nrmr--;
640                 else
641                         ctlr->nrsr--;
642
643                 ctlr->rrrci = NEXT(ctlr->rrrci, Nrrr);
644         }
645 }
646
647 static void
648 ga620interrupt(Ureg*, void* arg)
649 {
650         int csr, ie, work;
651         Ctlr *ctlr;
652         Ether *edev;
653         uvlong tsc0, tsc1;
654
655         edev = arg;
656         ctlr = edev->ctlr;
657
658         if(!(csr32r(ctlr, Mhc) & Is))
659                 return;
660         cycles(&tsc0);
661
662         ctlr->interrupts++;
663         csr32w(ctlr, Hi, 1);
664
665         ie = 0;
666         work = 0;
667         while(ie < 2){
668                 if(ctlr->rrrci != ctlr->rrrpi[0]){
669                         ga620receive(edev);
670                         work = 1;
671                 }
672
673                 if(_ga620transmit(edev) != 0)
674                         work = 1;
675
676                 csr = csr32r(ctlr, Eci);
677                 if(csr != ctlr->epi[0]){
678                         ga620event(edev, csr, ctlr->epi[0]);
679                         work = 1;
680                 }
681
682                 if(ctlr->nrsr <= NrsrLO)
683                         ga620replenish(ctlr);
684                 if(work == 0){
685                         if(ie == 0)
686                                 csr32w(ctlr, Hi, 0);
687                         ie++;
688                 }
689                 work = 0;
690         }
691
692         cycles(&tsc1);
693         ctlr->ticks += tsc1-tsc0;
694 }
695
696 static void
697 ga620lmw(Ctlr* ctlr, int addr, int* data, int len)
698 {
699         int i, l, lmw, v;
700
701         /*
702          * Write to or clear ('data' == nil) 'len' bytes of the NIC
703          * local memory at address 'addr'.
704          * The destination address and count should be 32-bit aligned.
705          */
706         v = 0;
707         while(len > 0){
708                 /*
709                  * 1) Set the window. The (Lmwsz-1) bits are ignored
710                  *    in Wba when accessing through the local memory window;
711                  * 2) Find the minimum of how many bytes still to
712                  *    transfer and how many left in this window;
713                  * 3) Create the offset into the local memory window in the
714                  *    shared memory space then copy (or zero) the data;
715                  * 4) Bump the counts.
716                  */
717                 csr32w(ctlr, Wba, addr);
718
719                 l = ROUNDUP(addr+1, Lmwsz) - addr;
720                 if(l > len)
721                         l = len;
722
723                 lmw = Lmw + (addr & (Lmwsz-1));
724                 for(i = 0; i < l; i += 4){
725                         if(data != nil)
726                                 v = *data++;
727                         csr32w(ctlr, lmw+i, v);
728                 }
729
730                 len -= l;
731                 addr += l;
732         }
733 }
734
735 static int
736 ga620init(Ether* edev)
737 {
738         Ctlr *ctlr;
739         Host64 host64;
740         int csr, ea, i, flags;
741
742         ctlr = edev->ctlr;
743
744         /*
745          * Load the MAC address.
746          */
747         ea = edev->ea[0]<<8 | edev->ea[1];
748         csr32w(ctlr, Mac, ea);
749         ea = edev->ea[2]<<24 | edev->ea[3]<<16 | edev->ea[4]<<8 | edev->ea[5];
750         csr32w(ctlr, Mac+4, ea);
751
752         /*
753          * General Information Block.
754          */
755         ctlr->gib = malloc(sizeof(Gib));
756         sethost64(&host64, ctlr->gib);
757         csr32w(ctlr, Gip, host64.hi);
758         csr32w(ctlr, Gip+4, host64.lo);
759
760         /*
761          * Event Ring.
762          * This is located in host memory. Allocate the ring,
763          * tell the NIC where it is and initialise the indices.
764          */
765         ctlr->er = malign(sizeof(Ere)*Ner);
766         sethost64(&ctlr->gib->ercb.addr, ctlr->er);
767         sethost64(&ctlr->gib->epp, ctlr->epi);
768         csr32w(ctlr, Eci, 0);
769
770         /*
771          * Command Ring.
772          * This is located in the General Communications Region
773          * and so the value placed in the Rcb is unused, the NIC
774          * knows where it is. Stick in the value according to
775          * the datasheet anyway.
776          * Initialise the ring and indices.
777          */
778         ctlr->gib->crcb.addr.lo = Cr-0x400;
779         for(i = 0; i < Ncr*4; i += 4)
780                 csr32w(ctlr, Cr+i, 0);
781         csr32w(ctlr, Cpi, 0);
782         csr32w(ctlr, Cci, 0);
783
784         /*
785          * Send Ring.
786          * This ring is either in NIC memory at a fixed location depending
787          * on how big the ring is or it is in host memory. If in NIC
788          * memory it is accessed via the Local Memory Window; with a send
789          * ring size of 128 the window covers the whole ring and then need
790          * only be set once:
791          *      ctlr->sr = (uchar*)ctlr->nic+Lmw;
792          *      ga620lmw(ctlr, Sr, nil, sizeof(Sbd)*Nsr);
793          *      ctlr->gib->srcb.addr.lo = Sr;
794          * There is nowhere in the Sbd to hold the Block* associated
795          * with this entry so an external array must be kept.
796          */
797         ctlr->sr = malign(sizeof(Sbd)*Nsr);
798         sethost64(&ctlr->gib->srcb.addr, ctlr->sr);
799         if(ctlr->hardwarecksum)
800                 flags = TcpUdpCksum|NoPseudoHdrCksum|HostRing;
801         else 
802                 flags = HostRing;
803         if(ctlr->coalupdateonly) 
804                 flags |= CoalUpdateOnly;
805         ctlr->gib->srcb.control = Nsr<<16 | flags;
806         sethost64(&ctlr->gib->scp, ctlr->sci);
807         csr32w(ctlr, Spi, 0);
808         ctlr->srb = malloc(sizeof(Block*)*Nsr);
809
810         /*
811          * Receive Standard Ring.
812          */
813         ctlr->rsr = malign(sizeof(Rbd)*Nrsr);
814         sethost64(&ctlr->gib->rsrcb.addr, ctlr->rsr);
815         if(ctlr->hardwarecksum)
816                 flags = TcpUdpCksum|NoPseudoHdrCksum;
817         else
818                 flags = 0;
819         ctlr->gib->rsrcb.control = (ETHERMAXTU+4)<<16 | flags;
820         csr32w(ctlr, Rspi, 0);
821
822         /*
823          * Jumbo and Mini Rings. Unused for now.
824          */
825         ctlr->gib->rjrcb.control = RingDisabled;
826         ctlr->gib->rmrcb.control = RingDisabled;
827
828         /*
829          * Receive Return Ring.
830          * This is located in host memory. Allocate the ring,
831          * tell the NIC where it is and initialise the indices.
832          */
833         ctlr->rrr = malign(sizeof(Rbd)*Nrrr);
834         sethost64(&ctlr->gib->rrrcb.addr, ctlr->rrr);
835         ctlr->gib->rrrcb.control = Nrrr<<16 | 0;
836         sethost64(&ctlr->gib->rrrpp, ctlr->rrrpi);
837         ctlr->rrrci = 0;
838
839         /*
840          * Refresh Stats Pointer.
841          * For now just point it at the existing statistics block.
842          */
843         sethost64(&ctlr->gib->rsp, ctlr->gib->statistics);
844
845         /*
846          * DMA configuration.
847          * Use the recommended values.
848          */
849         csr32w(ctlr, DMArc, 0x80);
850         csr32w(ctlr, DMAwc, 0x80);
851
852         /*
853          * Transmit Buffer Ratio.
854          * Set to 1/3 of available buffer space (units are 1/64ths)
855          * if using Jumbo packets, ~64KB otherwise (assume 1MB on NIC).
856          */
857         if(NrjrHI > 0 || Nsr > 128)
858                 csr32w(ctlr, Tbr, 64/3);
859         else
860                 csr32w(ctlr, Tbr, 4);
861
862         /*
863          * Tuneable parameters.
864          * These defaults are based on the tuning hints in the Alteon
865          * Host/NIC Software Interface Definition and example software.
866          */
867         ctlr->rct = 1/*100*/;
868         csr32w(ctlr, Rct, ctlr->rct);
869         ctlr->sct = 0;
870         csr32w(ctlr, Sct, ctlr->sct);
871         ctlr->st = 1000000;
872         csr32w(ctlr, St, ctlr->st);
873         ctlr->smcbd = Nsr/4;
874         csr32w(ctlr, SmcBD, ctlr->smcbd);
875         ctlr->rmcbd = 4/*6*/;
876         csr32w(ctlr, RmcBD, ctlr->rmcbd);
877
878         /*
879          * Enable DMA Assist Logic.
880          */
881         csr = csr32r(ctlr, DMAas) & ~0x03;
882         csr32w(ctlr, DMAas, csr|0x01);
883
884         /*
885          * Link negotiation.
886          * The bits are set here but the NIC must be given a command
887          * once it is running to set negotiation in motion.
888          */
889         csr32w(ctlr, Gln, Le|Lean|Lofc|Lfd|L1000MB|Lpref);
890         csr32w(ctlr, Fln, Le|Lean|Lhd|Lfd|L100MB|L10MB);
891
892         /*
893          * A unique index for this controller and the maximum packet
894          * length expected.
895          * For now only standard packets are expected.
896          */
897         csr32w(ctlr, Ifx, 1);
898         csr32w(ctlr, IfMTU, ETHERMAXTU+4);
899
900         /*
901          * Enable Interrupts.
902          * There are 3 ways to mask interrupts - a bit in the Mhc (which
903          * is already cleared), the Mi register and the Hi mailbox.
904          * Writing to the Hi mailbox has the side-effect of clearing the
905          * PCI interrupt.
906          */
907         csr32w(ctlr, Mi, 0);
908         csr32w(ctlr, Hi, 0);
909
910         /*
911          * Start the firmware.
912          */
913         csr32w(ctlr, CPUApc, tigon2FwStartAddr);
914         csr = csr32r(ctlr, CPUAstate) & ~CPUhalt;
915         csr32w(ctlr, CPUAstate, csr);
916
917         return 0;
918 }
919
920 static int
921 at24c32io(Ctlr* ctlr, char* op, int data)
922 {
923         char *lp, *p;
924         int i, loop, mlc, r;
925
926         mlc = csr32r(ctlr, Mlc);
927
928         r = 0;
929         loop = -1;
930         lp = nil;
931         for(p = op; *p != '\0'; p++){
932                 switch(*p){
933                 default:
934                         return -1;
935                 case ' ':
936                         continue;
937                 case ':':                       /* start of 8-bit loop */
938                         if(lp != nil)
939                                 return -1;
940                         lp = p;
941                         loop = 7;
942                         continue;
943                 case ';':                       /* end of 8-bit loop */
944                         if(lp == nil)
945                                 return -1;
946                         loop--;
947                         if(loop >= 0)
948                                 p = lp;
949                         else
950                                 lp = nil;
951                         continue;
952                 case 'C':                       /* assert clock */
953                         mlc |= EEclk;
954                         break;
955                 case 'c':                       /* deassert clock */
956                         mlc &= ~EEclk;
957                         break;
958                 case 'D':                       /* next bit in 'data' byte */
959                         if(loop < 0)
960                                 return -1;
961                         if(data & (1<<loop))
962                                 mlc |= EEdo;
963                         else
964                                 mlc &= ~EEdo;
965                         break;
966                 case 'E':                       /* enable data output */
967                         mlc |= EEdoe;
968                         break;
969                 case 'e':                       /* disable data output */
970                         mlc &= ~EEdoe;
971                         break;
972                 case 'I':                       /* input bit */
973                         i = (csr32r(ctlr, Mlc) & EEdi) != 0;
974                         if(loop >= 0)
975                                 r |= (i<<loop);
976                         else
977                                 r = i;
978                         continue;
979                 case 'O':                       /* assert data output */
980                         mlc |= EEdo;
981                         break;
982                 case 'o':                       /* deassert data output */
983                         mlc &= ~EEdo;
984                         break;
985                 }
986                 csr32w(ctlr, Mlc, mlc);
987                 microdelay(1);
988         }
989         if(loop >= 0)
990                 return -1;
991         return r;
992 }
993
994 static int
995 at24c32r(Ctlr* ctlr, int addr)
996 {
997         int data;
998
999         /*
1000          * Read a byte at address 'addr' from the Atmel AT24C32
1001          * Serial EEPROM. The 2-wire EEPROM access is controlled
1002          * by 4 bits in Mlc. See the AT24C32 datasheet for
1003          * protocol details.
1004          */
1005         /*
1006          * Start condition - a high to low transition of data
1007          * with the clock high must precede any other command.
1008          */
1009         at24c32io(ctlr, "OECoc", 0);
1010
1011         /*
1012          * Perform a random read at 'addr'. A dummy byte
1013          * write sequence is performed to clock in the device
1014          * and data word addresses (0 and 'addr' respectively).
1015          */
1016         data = -1;
1017         if(at24c32io(ctlr, "oE :DCc; oeCIc", 0xA0) != 0)
1018                 goto stop;
1019         if(at24c32io(ctlr, "oE :DCc; oeCIc", addr>>8) != 0)
1020                 goto stop;
1021         if(at24c32io(ctlr, "oE :DCc; oeCIc", addr) != 0)
1022                 goto stop;
1023
1024         /*
1025          * Now send another start condition followed by a
1026          * request to read the device. The EEPROM responds
1027          * by clocking out the data.
1028          */
1029         at24c32io(ctlr, "OECoc", 0);
1030         if(at24c32io(ctlr, "oE :DCc; oeCIc", 0xA1) != 0)
1031                 goto stop;
1032         data = at24c32io(ctlr, ":CIc;", 0xA1);
1033
1034 stop:
1035         /*
1036          * Stop condition - a low to high transition of data
1037          * with the clock high is a stop condition. After a read
1038          * sequence, the stop command will place the EEPROM in
1039          * a standby power mode.
1040          */
1041         at24c32io(ctlr, "oECOc", 0);
1042
1043         return data;
1044 }
1045
1046 static int
1047 ga620detach(Ctlr* ctlr)
1048 {
1049         int timeo;
1050
1051         /*
1052          * Hard reset (don't know which endian so catch both);
1053          * enable for little-endian mode;
1054          * wait for code to be loaded from serial EEPROM or flash;
1055          * make sure CPU A is halted.
1056          */
1057         csr32w(ctlr, Mhc, Hr<<24 | Hr);
1058         csr32w(ctlr, Mhc, (Eews|Ci)<<24 | Eews|Ci);
1059
1060         microdelay(1);
1061         for(timeo = 0; timeo < 500000; timeo++){
1062                 if((csr32r(ctlr, CPUAstate) & (CPUhie|CPUrf)) == CPUhie)
1063                         break;
1064                 microdelay(1);
1065         }
1066         if((csr32r(ctlr, CPUAstate) & (CPUhie|CPUrf)) != CPUhie)
1067                 return -1;
1068         csr32w(ctlr, CPUAstate, CPUhalt);
1069
1070         /*
1071          * After reset, CPU B seems to be stuck in 'CPUrf'.
1072          * Worry about it later.
1073          */
1074         csr32w(ctlr, CPUBstate, CPUhalt);
1075
1076         return 0;
1077 }
1078
1079 static void
1080 ga620shutdown(Ether* ether)
1081 {
1082 print("ga620shutdown\n");
1083         ga620detach(ether->ctlr);
1084 }
1085
1086 static int
1087 ga620reset(Ctlr* ctlr)
1088 {
1089         int cls, csr, i, r;
1090
1091         if(ga620detach(ctlr) < 0)
1092                 return -1;
1093
1094         /*
1095          * Tigon 2 PCI NICs have 512KB SRAM per bank.
1096          * Clear out any lingering serial EEPROM state
1097          * bits.
1098          */
1099         csr = csr32r(ctlr, Mlc) & ~(EEdi|EEdo|EEdoe|EEclk|SRAMmask);
1100         csr32w(ctlr, Mlc, SRAM512|csr);
1101         csr = csr32r(ctlr, Mc);
1102         csr32w(ctlr, Mc, SyncSRAM|csr);
1103
1104         /*
1105          * Initialise PCI State register.
1106          * If PCI Write-and-Invalidate is enabled set the max write DMA
1107          * value to the host cache-line size (32 on Pentium or later).
1108          */
1109         csr = csr32r(ctlr, Ps) & (PCI32|PCI66);
1110         csr |= PCIwcmd|PCIrcmd|PCImrm;
1111         if(ctlr->pcidev->pcr & 0x0010){
1112                 cls = pcicfgr8(ctlr->pcidev, PciCLS) * 4;
1113                 if(cls != 32)
1114                         pcicfgw8(ctlr->pcidev, PciCLS, 32/4);
1115                 csr |= PCIwm32;
1116         }
1117         csr32w(ctlr, Ps, csr);
1118
1119         /*
1120          * Operating Mode.
1121          */
1122         csr32w(ctlr, Om, Fatal|NoJFrag|BswapDMA|WswapBD);
1123
1124         /*
1125          * Snarf the MAC address from the serial EEPROM.
1126          */
1127         for(i = 0; i < Eaddrlen; i++){
1128                 if((r = at24c32r(ctlr, 0x8E+i)) == -1)
1129                         return -1;
1130                 ctlr->ea[i] = r;
1131         }
1132
1133         /*
1134          * Load the firmware.
1135          */
1136         ga620lmw(ctlr, tigon2FwTextAddr, tigon2FwText, tigon2FwTextLen);
1137         ga620lmw(ctlr, tigon2FwRodataAddr, tigon2FwRodata, tigon2FwRodataLen);
1138         ga620lmw(ctlr, tigon2FwDataAddr, tigon2FwData, tigon2FwDataLen);
1139         ga620lmw(ctlr, tigon2FwSbssAddr, nil, tigon2FwSbssLen);
1140         ga620lmw(ctlr, tigon2FwBssAddr, nil, tigon2FwBssLen);
1141
1142         return 0;
1143 }
1144
1145 static void
1146 ga620pci(void)
1147 {
1148         void *mem;
1149         Pcidev *p;
1150         Ctlr *ctlr;
1151
1152         p = nil;
1153         while(p = pcimatch(p, 0, 0)){
1154                 if(p->ccrb != 0x02 || p->ccru != 0)
1155                         continue;
1156
1157                 switch(p->did<<16 | p->vid){
1158                 default:
1159                         continue;
1160                 case 0x620A<<16 | 0x1385:       /* Netgear GA620 fiber */
1161                 case 0x630A<<16 | 0x1385:       /* Netgear GA620T copper */
1162                 case 0x0001<<16 | 0x12AE:       /* Alteon Acenic fiber
1163                                                  * and DEC DEGPA-SA */
1164                 case 0x0002<<16 | 0x12AE:       /* Alteon Acenic copper */
1165                 case 0x0009<<16 | 0x10A9:       /* SGI Acenic */
1166                         break;
1167                 }
1168
1169                 mem = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
1170                 if(mem == 0){
1171                         print("ga620: can't map %8.8luX\n", p->mem[0].bar);
1172                         continue;
1173                 }
1174
1175                 ctlr = malloc(sizeof(Ctlr));
1176                 if(ctlr == nil){
1177                         print("ga620: can't allocate memory\n");
1178                         continue;
1179                 }
1180                 ctlr->port = p->mem[0].bar & ~0x0F;
1181                 ctlr->pcidev = p;
1182                 ctlr->id = p->did<<16 | p->vid;
1183
1184                 ctlr->nic = mem;
1185                 if(ga620reset(ctlr)){
1186                         free(ctlr);
1187                         continue;
1188                 }
1189
1190                 if(ctlrhead != nil)
1191                         ctlrtail->next = ctlr;
1192                 else
1193                         ctlrhead = ctlr;
1194                 ctlrtail = ctlr;
1195         }
1196 }
1197
1198 static void
1199 ga620promiscuous(void *arg, int on)
1200 {
1201         Ether *ether = arg;
1202
1203         /* 3rd arg: 1 enables, 2 disables */
1204         ga620command(ether->ctlr, 0xa, (on? 1: 2), 0);
1205 }
1206
1207 static void
1208 ga620multicast(void *arg, uchar *addr, int add)
1209 {
1210         Ether *ether = arg;
1211
1212         USED(addr);
1213         if (add)
1214                 ga620command(ether->ctlr, 0xe, 1, 0);   /* 1 == enable */
1215 }
1216
1217 static int
1218 ga620pnp(Ether* edev)
1219 {
1220         Ctlr *ctlr;
1221         uchar ea[Eaddrlen];
1222
1223         if(ctlrhead == nil)
1224                 ga620pci();
1225
1226         /*
1227          * Any adapter matches if no edev->port is supplied,
1228          * otherwise the ports must match.
1229          */
1230         for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
1231                 if(ctlr->active)
1232                         continue;
1233                 if(edev->port == 0 || edev->port == ctlr->port){
1234                         ctlr->active = 1;
1235                         break;
1236                 }
1237         }
1238         if(ctlr == nil)
1239                 return -1;
1240
1241         edev->ctlr = ctlr;
1242         edev->port = ctlr->port;
1243         edev->irq = ctlr->pcidev->intl;
1244         edev->tbdf = ctlr->pcidev->tbdf;
1245         edev->mbps = 1000;              /* placeholder */
1246
1247         /*
1248          * Check if the adapter's station address is to be overridden.
1249          * If not, read it from the EEPROM and set in ether->ea prior to
1250          * loading the station address in the hardware.
1251          */
1252         memset(ea, 0, Eaddrlen);
1253         if(memcmp(ea, edev->ea, Eaddrlen) == 0)
1254                 memmove(edev->ea, ctlr->ea, Eaddrlen);
1255
1256         ga620init(edev);
1257
1258         /*
1259          * Linkage to the generic ethernet driver.
1260          */
1261         edev->attach = ga620attach;
1262         edev->transmit = ga620transmit;
1263         edev->interrupt = ga620interrupt;
1264         edev->ifstat = ga620ifstat;
1265         edev->ctl = ga620ctl;
1266
1267         edev->arg = edev;
1268         edev->promiscuous = ga620promiscuous;
1269         edev->multicast = ga620multicast;
1270         edev->shutdown = ga620shutdown;
1271
1272         return 0;
1273 }
1274
1275 void
1276 etherga620link(void)
1277 {
1278         addethercard("GA620", ga620pnp);
1279 }