2 * this driver is too bloated with firmware to include in 9pxeload,
3 * which must fit in 512K. it's also for a very old card.
6 * Netgear GA620 Gigabit Ethernet Card.
7 * Specific for the Alteon Tigon 2 and Intel Pentium or later.
9 * cache alignment for PCI Write-and-Invalidate
10 * mini ring (what size)?
11 * tune coalescing values
12 * statistics formatting
13 * don't update Spi if nothing to send
14 * receive ring alignment
15 * watchdog for link management?
24 #define malign(n) xspanalloc((n), 32, 0)
27 #include "etherga620fw.h"
30 Mhc = 0x0040, /* Miscellaneous Host Control */
31 Mlc = 0x0044, /* Miscellaneous Local Control */
32 Mc = 0x0050, /* Miscellaneous Configuration */
33 Ps = 0x005C, /* PCI State */
34 Wba = 0x0068, /* Window Base Address */
35 Wd = 0x006C, /* Window Data */
37 DMAas = 0x011C, /* DMA Assist State */
39 CPUAstate = 0x0140, /* CPU A State */
40 CPUApc = 0x0144, /* CPU A Programme Counter */
42 CPUBstate = 0x0240, /* CPU B State */
44 Hi = 0x0504, /* Host In Interrupt Handler */
45 Cpi = 0x050C, /* Command Producer Index */
46 Spi = 0x0514, /* Send Producer Index */
47 Rspi = 0x051C, /* Receive Standard Producer Index */
48 Rjpi = 0x0524, /* Receive Jumbo Producer Index */
49 Rmpi = 0x052C, /* Receive Mini Producer Index */
51 Mac = 0x0600, /* MAC Address */
52 Gip = 0x0608, /* General Information Pointer */
53 Om = 0x0618, /* Operating Mode */
54 DMArc = 0x061C, /* DMA Read Configuration */
55 DMAwc = 0x0620, /* DMA Write Configuration */
56 Tbr = 0x0624, /* Transmit Buffer Ratio */
57 Eci = 0x0628, /* Event Consumer Index */
58 Cci = 0x062C, /* Command Consumer Index */
60 Rct = 0x0630, /* Receive Coalesced Ticks */
61 Sct = 0x0634, /* Send Coalesced Ticks */
62 St = 0x0638, /* Stat Ticks */
63 SmcBD = 0x063C, /* Send Max. Coalesced BDs */
64 RmcBD = 0x0640, /* Receive Max. Coalesced BDs */
65 Nt = 0x0644, /* NIC Tracing */
66 Gln = 0x0648, /* Gigabit Link Negotiation */
67 Fln = 0x064C, /* 10/100 Link Negotiation */
68 Ifx = 0x065C, /* Interface Index */
69 IfMTU = 0x0660, /* Interface MTU */
70 Mi = 0x0664, /* Mask Interrupts */
71 Gls = 0x0668, /* Gigabit Link State */
72 Fls = 0x066C, /* 10/100 Link State */
74 Cr = 0x0700, /* Command Ring */
76 Lmw = 0x0800, /* Local Memory Window */
80 Is = 0x00000001, /* Interrupt State */
81 Ci = 0x00000002, /* Clear Interrupt */
82 Hr = 0x00000008, /* Hard Reset */
83 Eebs = 0x00000010, /* Enable Endian Byte Swap */
84 Eews = 0x00000020, /* Enable Endian Word (64-bit) swap */
85 Mpio = 0x00000040, /* Mask PCI Interrupt Output */
89 SRAM512 = 0x00000200, /* SRAM Bank Size of 512KB */
90 SRAMmask = 0x00000300,
91 EEclk = 0x00100000, /* Serial EEPROM Clock Output */
92 EEdoe = 0x00200000, /* Serial EEPROM Data Out Enable */
93 EEdo = 0x00400000, /* Serial EEPROM Data Out Value */
94 EEdi = 0x00800000, /* Serial EEPROM Data Input */
98 SyncSRAM = 0x00100000, /* Set Synchronous SRAM Timing */
102 PCIwm32 = 0x000000C0, /* Write Max DMA 32 */
103 PCImrm = 0x00020000, /* Use Memory Read Multiple Command */
106 PCIrcmd = 0x06000000, /* PCI Read Command */
107 PCIwcmd = 0x70000000, /* PCI Write Command */
110 enum { /* CPUAstate */
111 CPUrf = 0x00000010, /* ROM Fail */
112 CPUhalt = 0x00010000, /* Halt the internal CPU */
113 CPUhie = 0x00040000, /* HALT instruction executed */
117 BswapBD = 0x00000002, /* Byte Swap Buffer Descriptors */
118 WswapBD = 0x00000004, /* Word Swap Buffer Descriptors */
120 BswapDMA = 0x00000010, /* Byte Swap DMA Data */
121 Only1DMA = 0x00000040, /* Only One DMA Active at a time */
122 NoJFrag = 0x00000200, /* Don't Fragment Jumbo Frames */
127 Lmwsz = 2*1024, /* Local Memory Window Size */
130 * legal values are 0x3800 iff Nsr is 128, 0x3000 iff Nsr is 256,
131 * or 0x2000 iff Nsr is 512.
133 Sr = 0x3800, /* Send Ring (accessed via Lmw) */
137 Lpref = 0x00008000, /* Preferred Link */
140 L1000MB = 0x00040000,
141 Lfd = 0x00080000, /* Full Duplex */
142 Lhd = 0x00100000, /* Half Duplex */
143 Lefc = 0x00200000, /* Emit Flow Control Packets */
144 Lofc = 0x00800000, /* Obey Flow Control Packets */
145 Lean = 0x20000000, /* Enable Autonegotiation/Sensing */
146 Le = 0x40000000, /* Link Enable */
149 typedef struct Host64 {
154 typedef struct Ere { /* Event Ring Element */
155 int event; /* event<<24 | code<<12 | index */
159 typedef int Cmd; /* cmd<<24 | flags<<12 | index */
161 typedef struct Rbd { /* Receive Buffer Descriptor */
163 int indexlen; /* ring-index<<16 | buffer-length */
164 int flags; /* only lower 16-bits */
165 int checksum; /* ip<<16 |tcp/udp */
166 int error; /* only upper 16-bits */
168 void* opaque; /* passed to receive return ring */
171 typedef struct Sbd { /* Send Buffer Descriptor */
173 int lenflags; /* len<<16 |flags */
177 enum { /* Buffer Descriptor Flags */
178 Fend = 0x00000004, /* Frame Ends in this Buffer */
179 Frjr = 0x00000010, /* Receive Jumbo Ring Buffer */
180 Funicast = 0x00000020, /* Unicast packet (2-bit field) */
181 Fmulticast = 0x00000040, /* Multicast packet */
182 Fbroadcast = 0x00000060, /* Broadcast packet */
183 Ferror = 0x00000400, /* Frame Has Error */
184 Frmr = 0x00001000, /* Receive Mini Ring Buffer */
187 enum { /* Buffer Error Flags */
188 Ecrc = 0x00010000, /* bad CRC */
189 Ecollision = 0x00020000, /* collision */
190 Elink = 0x00040000, /* link lost */
191 Ephy = 0x00080000, /* unspecified PHY frame decode error */
192 Eodd = 0x00100000, /* odd number of nibbles */
193 Emac = 0x00200000, /* unspecified MAC abort */
194 Elen64 = 0x00400000, /* short packet */
195 Eresources = 0x00800000, /* MAC out of internal resources */
196 Egiant = 0x01000000, /* packet too big */
199 typedef struct Rcb { /* Ring Control Block */
200 Host64 addr; /* points to the Rbd ring */
201 int control; /* max_len<<16 |flags */
206 TcpUdpCksum = 0x0001, /* Perform TCP or UDP checksum */
207 IpCksum = 0x0002, /* Perform IP checksum */
208 NoPseudoHdrCksum= 0x0008, /* Don't include the pseudo header */
209 VlanAssist = 0x0010, /* Enable VLAN tagging */
210 CoalUpdateOnly = 0x0020, /* Coalesce transmit interrupts */
211 HostRing = 0x0040, /* Sr in host memory */
212 SnapCksum = 0x0080, /* Parse + offload 802.3 SNAP frames */
213 UseExtRxBd = 0x0100, /* Extended Rbd for Jumbo frames */
214 RingDisabled = 0x0200, /* Jumbo or Mini RCB only */
217 typedef struct Gib { /* General Information Block */
218 int statistics[256]; /* Statistics */
219 Rcb ercb; /* Event Ring */
220 Rcb crcb; /* Command Ring */
221 Rcb srcb; /* Send Ring */
222 Rcb rsrcb; /* Receive Standard Ring */
223 Rcb rjrcb; /* Receive Jumbo Ring */
224 Rcb rmrcb; /* Receive Mini Ring */
225 Rcb rrrcb; /* Receive Return Ring */
226 Host64 epp; /* Event Producer */
227 Host64 rrrpp; /* Receive Return Ring Producer */
228 Host64 scp; /* Send Consumer */
229 Host64 rsp; /* Refresh Stats */
233 * these sizes are all fixed in the card,
234 * except for Nsr, which has only 3 valid sizes.
236 enum { /* Host/NIC Interface ring sizes */
237 Ner = 256, /* event ring */
238 Ncr = 64, /* command ring */
239 Nsr = 128, /* send ring: 128, 256 or 512 */
240 Nrsr = 512, /* receive standard ring */
241 Nrjr = 256, /* receive jumbo ring */
242 Nrmr = 1024, /* receive mini ring, optional */
243 Nrrr = 2048, /* receive return ring */
247 NrsrHI = 72, /* Fill-level of Rsr (m.b. < Nrsr) */
248 NrsrLO = 54, /* Level at which to top-up ring */
249 NrjrHI = 0, /* Fill-level of Rjr (m.b. < Nrjr) */
250 NrjrLO = 0, /* Level at which to top-up ring */
251 NrmrHI = 0, /* Fill-level of Rmr (m.b. < Nrmr) */
252 NrmrLO = 0, /* Level at which to top-up ring */
255 typedef struct Ctlr Ctlr;
273 int nsr; /* currently in send ring */
276 int nrsr; /* currently in Receive Standard Ring */
278 int nrjr; /* currently in Receive Jumbo Ring */
280 int nrmr; /* currently in Receive Mini Ring */
282 int rrrci; /* Receive Return Ring Consumer Index */
284 int epi[2]; /* Event Producer Index */
285 int rrrpi[2]; /* Receive Return Ring Producer Index */
286 int sci[3]; /* Send Consumer Index ([2] is host) */
288 int interrupts; /* statistics */
292 int coalupdateonly; /* tuning */
294 int rct; /* Receive Coalesce Ticks */
295 int sct; /* Send Coalesce Ticks */
296 int st; /* Stat Ticks */
297 int smcbd; /* Send Max. Coalesced BDs */
298 int rmcbd; /* Receive Max. Coalesced BDs */
301 static Ctlr* ctlrhead;
302 static Ctlr* ctlrtail;
304 #define csr32r(c, r) (*((c)->nic+((r)/4)))
305 #define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
308 sethost64(Host64* host64, void* addr)
312 uvl = PCIWADDR(addr);
313 host64->hi = uvl>>32;
314 host64->lo = uvl & 0xFFFFFFFFL;
318 ga620command(Ctlr* ctlr, int cmd, int flags, int index)
322 cpi = csr32r(ctlr, Cpi);
323 csr32w(ctlr, Cr+(cpi*4), cmd<<24 | flags<<12 | index);
324 cpi = NEXT(cpi, Ncr);
325 csr32w(ctlr, Cpi, cpi);
334 waitforlink(Ether *edev)
338 if (edev->mbps == 0) {
339 print("#l%d: ga620: waiting for link", edev->ctlrno);
340 /* usually takes about 10 seconds */
341 for (i = 0; i < 20 && edev->mbps == 0; i++) {
346 if (i == 20 && edev->mbps == 0)
347 edev->mbps = 1; /* buggered */
352 toringbuf(Ether *ether, Block *bp)
354 RingBuf *rb = ðer->rb[ether->ri];
356 if (rb->owner == Interface) {
358 memmove(rb->pkt, bp->rp, rb->len);
360 ether->ri = NEXT(ether->ri, ether->nrb);
362 /* else no one is expecting packets from the network */
366 fromringbuf(Ether *ether)
368 RingBuf *tb = ðer->tb[ether->ti];
369 Block *bp = allocb(tb->len);
372 panic("fromringbuf: nil allocb return");
374 panic("fromringbuf: nil bp->wb");
375 memmove(bp->wp, tb->pkt, tb->len);
376 memmove(bp->wp+Eaddrlen, ether->ea, Eaddrlen);
382 _ga620transmit(Ether* edev)
391 * For now there are no smarts here, just empty the
392 * ring and try to fill it back up. Tuning comes later.
396 ilock(&ctlr->srlock);
399 * Free any completed packets.
400 * Ctlr->sci[0] is where the NIC has got to consuming the ring.
401 * Ctlr->sci[2] is where the host has got to tidying up after the
402 * NIC has done with the packets.
405 for(sci = ctlr->sci[2]; sci != ctlr->sci[0]; sci = NEXT(sci, Nsr)){
406 if(ctlr->srb[sci] == nil)
408 freeb(ctlr->srb[sci]);
409 ctlr->srb[sci] = nil;
414 sci = PREV(sci, Nsr);
416 tb = &edev->tb[edev->ti];
417 for(spi = csr32r(ctlr, Spi); spi != sci && tb->owner == Interface;
418 spi = NEXT(spi, Nsr)){
419 bp = fromringbuf(edev);
421 sbd = &ctlr->sr[spi];
422 sethost64(&sbd->addr, bp->rp);
423 sbd->lenflags = BLEN(bp)<<16 |Fend;
429 edev->ti = NEXT(edev->ti, edev->ntb);
430 tb = &edev->tb[edev->ti];
432 csr32w(ctlr, Spi, spi);
434 iunlock(&ctlr->srlock);
440 ga620transmit(Ether* edev)
442 _ga620transmit(edev);
446 ga620replenish(Ctlr* ctlr)
452 rspi = csr32r(ctlr, Rspi);
453 while(ctlr->nrsr < NrsrHI){
454 if((bp = allocb(ETHERMAXTU+4)) == nil)
456 rbd = &ctlr->rsr[rspi];
457 sethost64(&rbd->addr, bp->rp);
458 rbd->indexlen = rspi<<16 | (ETHERMAXTU+4);
462 rspi = NEXT(rspi, Nrsr);
465 csr32w(ctlr, Rspi, rspi);
469 ga620event(Ether *edev, int eci, int epi)
471 unsigned event, code;
476 event = ctlr->er[eci].event;
477 code = (event >> 12) & ((1<<12)-1);
479 case 0x01: /* firmware operational */
480 /* host stack (us) is up. 3rd arg of 2 means down. */
481 ga620command(ctlr, 0x01, 0x01, 0x00);
483 * link negotiation: any speed is okay.
484 * 3rd arg of 1 selects gigabit only; 2 10/100 only.
486 ga620command(ctlr, 0x0B, 0x00, 0x00);
487 print("#l%d: ga620: port %8.8uX: firmware is up\n",
488 edev->ctlrno, ctlr->port);
490 case 0x04: /* statistics updated */
492 case 0x06: /* link state changed */
498 print("#l%d: link down\n", edev->ctlrno);
501 edev->mbps = 100; /* it's 10 or 100 */
505 print("#l%d: %dMbps link up\n",
506 edev->ctlrno, edev->mbps);
508 case 0x07: /* event error */
510 print("#l%d: ga620: er[%d] = %8.8uX\n", edev->ctlrno,
514 eci = NEXT(eci, Ner);
516 csr32w(ctlr, Eci, eci);
520 ga620receive(Ether* edev)
528 while(ctlr->rrrci != ctlr->rrrpi[0]){
529 rbd = &ctlr->rrr[ctlr->rrrci];
531 * Errors are collected in the statistics block so
532 * no need to tally them here, let ifstat do the work.
534 len = rbd->indexlen & 0xFFFF;
535 if(!(rbd->flags & Ferror) && len != 0){
544 if(rbd->flags & Frjr)
546 else if(rbd->flags & Frmr)
551 ctlr->rrrci = NEXT(ctlr->rrrci, Nrrr);
556 ga620interrupt(Ureg*, void* arg)
565 if(!(csr32r(ctlr, Mhc) & Is))
574 if(ctlr->rrrci != ctlr->rrrpi[0]){
579 if(_ga620transmit(edev) != 0)
582 csr = csr32r(ctlr, Eci);
583 if(csr != ctlr->epi[0]){
584 ga620event(edev, csr, ctlr->epi[0]);
588 if(ctlr->nrsr <= NrsrLO)
589 ga620replenish(ctlr);
600 ga620lmw(Ctlr* ctlr, int addr, int* data, int len)
605 * Write to or clear ('data' == nil) 'len' bytes of the NIC
606 * local memory at address 'addr'.
607 * The destination address and count should be 32-bit aligned.
612 * 1) Set the window. The (Lmwsz-1) bits are ignored
613 * in Wba when accessing through the local memory window;
614 * 2) Find the minimum of how many bytes still to
615 * transfer and how many left in this window;
616 * 3) Create the offset into the local memory window in the
617 * shared memory space then copy (or zero) the data;
618 * 4) Bump the counts.
620 csr32w(ctlr, Wba, addr);
622 l = ROUNDUP(addr+1, Lmwsz) - addr;
626 lmw = Lmw + (addr & (Lmwsz-1));
627 for(i = 0; i < l; i += 4){
630 csr32w(ctlr, lmw+i, v);
639 ga620init(Ether* edev)
643 int csr, ea, i, flags;
648 * Load the MAC address.
650 ea = edev->ea[0]<<8 | edev->ea[1];
651 csr32w(ctlr, Mac, ea);
652 ea = edev->ea[2]<<24 | edev->ea[3]<<16 | edev->ea[4]<<8 | edev->ea[5];
653 csr32w(ctlr, Mac+4, ea);
656 * General Information Block.
658 ctlr->gib = malloc(sizeof(Gib));
659 sethost64(&host64, ctlr->gib);
660 csr32w(ctlr, Gip, host64.hi);
661 csr32w(ctlr, Gip+4, host64.lo);
665 * This is located in host memory. Allocate the ring,
666 * tell the NIC where it is and initialise the indices.
668 ctlr->er = malign(sizeof(Ere)*Ner);
669 sethost64(&ctlr->gib->ercb.addr, ctlr->er);
670 sethost64(&ctlr->gib->epp, ctlr->epi);
671 csr32w(ctlr, Eci, 0);
675 * This is located in the General Communications Region
676 * and so the value placed in the Rcb is unused, the NIC
677 * knows where it is. Stick in the value according to
678 * the datasheet anyway.
679 * Initialise the ring and indices.
681 ctlr->gib->crcb.addr.lo = Cr - 0x400;
682 for(i = 0; i < Ncr*4; i += 4)
683 csr32w(ctlr, Cr+i, 0);
684 csr32w(ctlr, Cpi, 0);
685 csr32w(ctlr, Cci, 0);
689 * This ring is either in NIC memory at a fixed location depending
690 * on how big the ring is or it is in host memory. If in NIC
691 * memory it is accessed via the Local Memory Window; with a send
692 * ring size of 128 the window covers the whole ring and then need
694 * ctlr->sr = (uchar*)ctlr->nic+Lmw;
695 * ga620lmw(ctlr, Sr, nil, sizeof(Sbd)*Nsr);
696 * ctlr->gib->srcb.addr.lo = Sr;
697 * There is nowhere in the Sbd to hold the Block* associated
698 * with this entry so an external array must be kept.
700 ctlr->sr = malign(sizeof(Sbd)*Nsr);
701 sethost64(&ctlr->gib->srcb.addr, ctlr->sr);
702 if(ctlr->hardwarecksum)
703 flags = TcpUdpCksum|NoPseudoHdrCksum|HostRing;
706 if(ctlr->coalupdateonly)
707 flags |= CoalUpdateOnly;
708 ctlr->gib->srcb.control = Nsr<<16 | flags;
709 sethost64(&ctlr->gib->scp, ctlr->sci);
710 csr32w(ctlr, Spi, 0);
711 ctlr->srb = malloc(sizeof(Block*)*Nsr);
714 * Receive Standard Ring.
716 ctlr->rsr = malign(sizeof(Rbd)*Nrsr);
717 sethost64(&ctlr->gib->rsrcb.addr, ctlr->rsr);
718 if(ctlr->hardwarecksum)
719 flags = TcpUdpCksum|NoPseudoHdrCksum;
722 ctlr->gib->rsrcb.control = (ETHERMAXTU+4)<<16 | flags;
723 csr32w(ctlr, Rspi, 0);
726 * Jumbo and Mini Rings. Unused for now.
728 ctlr->gib->rjrcb.control = RingDisabled;
729 ctlr->gib->rmrcb.control = RingDisabled;
732 * Receive Return Ring.
733 * This is located in host memory. Allocate the ring,
734 * tell the NIC where it is and initialise the indices.
736 ctlr->rrr = malign(sizeof(Rbd)*Nrrr);
737 sethost64(&ctlr->gib->rrrcb.addr, ctlr->rrr);
738 ctlr->gib->rrrcb.control = Nrrr<<16 | 0;
739 sethost64(&ctlr->gib->rrrpp, ctlr->rrrpi);
743 * Refresh Stats Pointer.
744 * For now just point it at the existing statistics block.
746 sethost64(&ctlr->gib->rsp, ctlr->gib->statistics);
750 * Use the recommended values.
752 csr32w(ctlr, DMArc, 0x80);
753 csr32w(ctlr, DMAwc, 0x80);
756 * Transmit Buffer Ratio.
757 * Set to 1/3 of available buffer space (units are 1/64ths)
758 * if using Jumbo packets, ~64KB otherwise (assume 1MB on NIC).
760 if(NrjrHI > 0 || Nsr > 128)
761 csr32w(ctlr, Tbr, 64/3);
763 csr32w(ctlr, Tbr, 4);
766 * Tuneable parameters.
767 * These defaults are based on the tuning hints in the Alteon
768 * Host/NIC Software Interface Definition and example software.
770 ctlr->rct = 1 /*100*/;
771 csr32w(ctlr, Rct, ctlr->rct);
773 csr32w(ctlr, Sct, ctlr->sct);
775 csr32w(ctlr, St, ctlr->st);
777 csr32w(ctlr, SmcBD, ctlr->smcbd);
778 ctlr->rmcbd = 4 /*6*/;
779 csr32w(ctlr, RmcBD, ctlr->rmcbd);
782 * Enable DMA Assist Logic.
784 csr = csr32r(ctlr, DMAas) & ~0x03;
785 csr32w(ctlr, DMAas, csr|0x01);
789 * The bits are set here but the NIC must be given a command
790 * once it is running to set negotiation in motion.
792 csr32w(ctlr, Gln, Le|Lean|Lofc|Lfd|L1000MB|Lpref);
793 csr32w(ctlr, Fln, Le|Lean|Lhd|Lfd|L100MB|L10MB);
796 * A unique index for this controller and the maximum packet
798 * For now only standard packets are expected.
800 csr32w(ctlr, Ifx, 1);
801 csr32w(ctlr, IfMTU, ETHERMAXTU+4);
805 * There are 3 ways to mask interrupts - a bit in the Mhc (which
806 * is already cleared), the Mi register and the Hi mailbox.
807 * Writing to the Hi mailbox has the side-effect of clearing the
814 * Start the firmware.
816 csr32w(ctlr, CPUApc, tigon2FwStartAddr);
817 csr = csr32r(ctlr, CPUAstate) & ~CPUhalt;
818 csr32w(ctlr, CPUAstate, csr);
824 at24c32io(Ctlr* ctlr, char* op, int data)
829 mlc = csr32r(ctlr, Mlc);
834 for(p = op; *p != '\0'; p++){
840 case ':': /* start of 8-bit loop */
846 case ';': /* end of 8-bit loop */
855 case 'C': /* assert clock */
858 case 'c': /* deassert clock */
861 case 'D': /* next bit in 'data' byte */
869 case 'E': /* enable data output */
872 case 'e': /* disable data output */
875 case 'I': /* input bit */
876 i = (csr32r(ctlr, Mlc) & EEdi) != 0;
882 case 'O': /* assert data output */
885 case 'o': /* deassert data output */
889 csr32w(ctlr, Mlc, mlc);
898 at24c32r(Ctlr* ctlr, int addr)
903 * Read a byte at address 'addr' from the Atmel AT24C32
904 * Serial EEPROM. The 2-wire EEPROM access is controlled
905 * by 4 bits in Mlc. See the AT24C32 datasheet for
909 * Start condition - a high to low transition of data
910 * with the clock high must precede any other command.
912 at24c32io(ctlr, "OECoc", 0);
915 * Perform a random read at 'addr'. A dummy byte
916 * write sequence is performed to clock in the device
917 * and data word addresses (0 and 'addr' respectively).
920 if(at24c32io(ctlr, "oE :DCc; oeCIc", 0xA0) != 0)
922 if(at24c32io(ctlr, "oE :DCc; oeCIc", addr>>8) != 0)
924 if(at24c32io(ctlr, "oE :DCc; oeCIc", addr) != 0)
928 * Now send another start condition followed by a
929 * request to read the device. The EEPROM responds
930 * by clocking out the data.
932 at24c32io(ctlr, "OECoc", 0);
933 if(at24c32io(ctlr, "oE :DCc; oeCIc", 0xA1) != 0)
935 data = at24c32io(ctlr, ":CIc;", 0xA1);
939 * Stop condition - a low to high transition of data
940 * with the clock high is a stop condition. After a read
941 * sequence, the stop command will place the EEPROM in
942 * a standby power mode.
944 at24c32io(ctlr, "oECOc", 0);
950 ga620detach(Ctlr* ctlr)
955 * Hard reset (don't know which endian so catch both);
956 * enable for little-endian mode;
957 * wait for code to be loaded from serial EEPROM or flash;
958 * make sure CPU A is halted.
960 csr32w(ctlr, Mhc, Hr<<24 | Hr);
961 csr32w(ctlr, Mhc, (Eews|Ci)<<24 | Eews|Ci);
964 for(timeo = 0; timeo < 500000; timeo++){
965 if((csr32r(ctlr, CPUAstate) & (CPUhie|CPUrf)) == CPUhie)
969 if((csr32r(ctlr, CPUAstate) & (CPUhie|CPUrf)) != CPUhie)
971 csr32w(ctlr, CPUAstate, CPUhalt);
974 * After reset, CPU B seems to be stuck in 'CPUrf'.
975 * Worry about it later.
977 csr32w(ctlr, CPUBstate, CPUhalt);
983 ga620shutdown(Ether* ether)
985 print("ga620shutdown\n");
986 ga620detach(ether->ctlr);
990 ga620reset(Ctlr* ctlr)
994 if(ga620detach(ctlr) < 0)
998 * Tigon 2 PCI NICs have 512KB SRAM per bank.
999 * Clear out any lingering serial EEPROM state
1002 csr = csr32r(ctlr, Mlc) & ~(EEdi|EEdo|EEdoe|EEclk|SRAMmask);
1003 csr32w(ctlr, Mlc, SRAM512|csr);
1004 csr = csr32r(ctlr, Mc);
1005 csr32w(ctlr, Mc, SyncSRAM|csr);
1008 * Initialise PCI State register.
1009 * If PCI Write-and-Invalidate is enabled set the max write DMA
1010 * value to the host cache-line size (32 on Pentium or later).
1012 csr = csr32r(ctlr, Ps) & (PCI32|PCI66);
1013 csr |= PCIwcmd|PCIrcmd|PCImrm;
1014 if(ctlr->pcidev->pcr & 0x0010){
1015 cls = pcicfgr8(ctlr->pcidev, PciCLS) * 4;
1017 pcicfgw8(ctlr->pcidev, PciCLS, 32/4);
1020 csr32w(ctlr, Ps, csr);
1025 csr32w(ctlr, Om, Fatal|NoJFrag|BswapDMA|WswapBD);
1028 * Snarf the MAC address from the serial EEPROM.
1030 for(i = 0; i < Eaddrlen; i++){
1031 if((r = at24c32r(ctlr, 0x8E+i)) == -1)
1037 * Load the firmware.
1039 ga620lmw(ctlr, tigon2FwTextAddr, tigon2FwText, tigon2FwTextLen);
1040 ga620lmw(ctlr, tigon2FwRodataAddr, tigon2FwRodata, tigon2FwRodataLen);
1041 ga620lmw(ctlr, tigon2FwDataAddr, tigon2FwData, tigon2FwDataLen);
1042 ga620lmw(ctlr, tigon2FwSbssAddr, nil, tigon2FwSbssLen);
1043 ga620lmw(ctlr, tigon2FwBssAddr, nil, tigon2FwBssLen);
1046 * we will eventually get events telling us that the firmware is
1047 * up and that the link is up.
1060 while(p = pcimatch(p, 0, 0)){
1061 if(p->ccrb != 0x02 || p->ccru != 0)
1064 switch(p->did<<16 | p->vid){
1067 case 0x620A<<16 | 0x1385: /* Netgear GA620 fiber */
1068 case 0x630A<<16 | 0x1385: /* Netgear GA620T copper */
1069 case 0x0001<<16 | 0x12AE: /* Alteon Acenic fiber
1070 * and DEC DEGPA-SA */
1071 case 0x0002<<16 | 0x12AE: /* Alteon Acenic copper */
1072 case 0x0009<<16 | 0x10A9: /* SGI Acenic */
1076 port = upamalloc(p->mem[0].bar & ~0x0F, p->mem[0].size, 0);
1078 print("ga620: can't map %d @ 0x%8.8luX\n",
1079 p->mem[0].size, p->mem[0].bar);
1083 ctlr = malloc(sizeof(Ctlr));
1086 ctlr->id = p->did<<16 | p->vid;
1088 ctlr->nic = KADDR(ctlr->port);
1089 if(ga620reset(ctlr)){
1095 ctlrtail->next = ctlr;
1103 ga620pnp(Ether* edev)
1112 * Any adapter matches if no edev->port is supplied,
1113 * otherwise the ports must match.
1115 for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
1118 if(edev->port == 0 || edev->port == ctlr->port){
1127 edev->port = ctlr->port;
1128 edev->irq = ctlr->pcidev->intl;
1129 edev->tbdf = ctlr->pcidev->tbdf;
1132 * Check if the adapter's station address is to be overridden.
1133 * If not, read it from the EEPROM and set in ether->ea prior to
1134 * loading the station address in the hardware.
1136 memset(ea, 0, Eaddrlen);
1137 if(memcmp(ea, edev->ea, Eaddrlen) == 0)
1138 memmove(edev->ea, ctlr->ea, Eaddrlen);
1140 ga620init(edev); /* enables interrupts */
1143 * Linkage to the generic ethernet driver.
1145 edev->attach = ga620attach;
1146 edev->transmit = ga620transmit;
1147 edev->interrupt = ga620interrupt;
1148 edev->detach = ga620shutdown;