FreeBSD/Linux Kernel Cross Reference
sys/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 = malloc(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 ctlr->port = p->mem[0].bar & ~0x0F;
1177 ctlr->pcidev = p;
1178 ctlr->id = p->did<<16 | p->vid;
1179
1180 ctlr->nic = mem;
1181 if(ga620reset(ctlr)){
1182 free(ctlr);
1183 continue;
1184 }
1185
1186 if(ctlrhead != nil)
1187 ctlrtail->next = ctlr;
1188 else
1189 ctlrhead = ctlr;
1190 ctlrtail = ctlr;
1191 }
1192 }
1193
1194 static void
1195 ga620promiscuous(void *arg, int on)
1196 {
1197 Ether *ether = arg;
1198
1199 /* 3rd arg: 1 enables, 2 disables */
1200 ga620command(ether->ctlr, 0xa, (on? 1: 2), 0);
1201 }
1202
1203 static void
1204 ga620multicast(void *arg, uchar *addr, int add)
1205 {
1206 Ether *ether = arg;
1207
1208 USED(addr);
1209 if (add)
1210 ga620command(ether->ctlr, 0xe, 1, 0); /* 1 == enable */
1211 }
1212
1213 static int
1214 ga620pnp(Ether* edev)
1215 {
1216 Ctlr *ctlr;
1217 uchar ea[Eaddrlen];
1218
1219 if(ctlrhead == nil)
1220 ga620pci();
1221
1222 /*
1223 * Any adapter matches if no edev->port is supplied,
1224 * otherwise the ports must match.
1225 */
1226 for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
1227 if(ctlr->active)
1228 continue;
1229 if(edev->port == 0 || edev->port == ctlr->port){
1230 ctlr->active = 1;
1231 break;
1232 }
1233 }
1234 if(ctlr == nil)
1235 return -1;
1236
1237 edev->ctlr = ctlr;
1238 edev->port = ctlr->port;
1239 edev->irq = ctlr->pcidev->intl;
1240 edev->tbdf = ctlr->pcidev->tbdf;
1241 edev->mbps = 1000; /* placeholder */
1242
1243 /*
1244 * Check if the adapter's station address is to be overridden.
1245 * If not, read it from the EEPROM and set in ether->ea prior to
1246 * loading the station address in the hardware.
1247 */
1248 memset(ea, 0, Eaddrlen);
1249 if(memcmp(ea, edev->ea, Eaddrlen) == 0)
1250 memmove(edev->ea, ctlr->ea, Eaddrlen);
1251
1252 ga620init(edev);
1253
1254 /*
1255 * Linkage to the generic ethernet driver.
1256 */
1257 edev->attach = ga620attach;
1258 edev->transmit = ga620transmit;
1259 edev->interrupt = ga620interrupt;
1260 edev->ifstat = ga620ifstat;
1261 edev->ctl = ga620ctl;
1262
1263 edev->arg = edev;
1264 edev->promiscuous = ga620promiscuous;
1265 edev->multicast = ga620multicast;
1266 edev->shutdown = ga620shutdown;
1267
1268 return 0;
1269 }
1270
1271 void
1272 etherga620link(void)
1273 {
1274 addethercard("GA620", ga620pnp);
1275 }
Cache object: 2bd929b45256f32bed527a991cc19a90
|