2 * Intel 8254[340]NN Gigabit Ethernet PCI Controllers
3 * as found on the Intel PRO/1000 series of adapters:
4 * 82543GC Intel PRO/1000 T
5 * 82544EI Intel PRO/1000 XT
6 * 82540EM Intel PRO/1000 MT
12 * finish autonegotiation code;
13 * integrate fiber stuff back in (this ONLY handles
14 * the CAT5 cards at the moment);
15 * add checksum-offload;
16 * add tuning control via ctl file;
17 * this driver is little-endian specific.
20 #include "../port/lib.h"
25 #include "../port/error.h"
26 #include "../port/netif.h"
32 i82542 = (0x1000<<16)|0x8086,
33 i82543gc = (0x1004<<16)|0x8086,
34 i82544ei = (0x1008<<16)|0x8086,
35 i82544eif = (0x1009<<16)|0x8086,
36 i82544gc = (0x100d<<16)|0x8086,
37 i82540em = (0x100E<<16)|0x8086,
38 i82540eplp = (0x101E<<16)|0x8086,
39 i82545em = (0x100F<<16)|0x8086,
40 i82545gmc = (0x1026<<16)|0x8086,
41 i82547ei = (0x1019<<16)|0x8086,
42 i82547gi = (0x1075<<16)|0x8086,
43 i82541ei = (0x1013<<16)|0x8086,
44 i82541gi = (0x1076<<16)|0x8086,
45 i82541gi2 = (0x1077<<16)|0x8086,
46 i82541pi = (0x107c<<16)|0x8086,
47 i82546gb = (0x1079<<16)|0x8086,
48 i82546eb = (0x1010<<16)|0x8086,
52 Ctrl = 0x00000000, /* Device Control */
53 Ctrldup = 0x00000004, /* Device Control Duplicate */
54 Status = 0x00000008, /* Device Status */
55 Eecd = 0x00000010, /* EEPROM/Flash Control/Data */
56 Ctrlext = 0x00000018, /* Extended Device Control */
57 Mdic = 0x00000020, /* MDI Control */
58 Fcal = 0x00000028, /* Flow Control Address Low */
59 Fcah = 0x0000002C, /* Flow Control Address High */
60 Fct = 0x00000030, /* Flow Control Type */
61 Icr = 0x000000C0, /* Interrupt Cause Read */
62 Ics = 0x000000C8, /* Interrupt Cause Set */
63 Ims = 0x000000D0, /* Interrupt Mask Set/Read */
64 Imc = 0x000000D8, /* Interrupt mask Clear */
65 Rctl = 0x00000100, /* Receive Control */
66 Fcttv = 0x00000170, /* Flow Control Transmit Timer Value */
67 Txcw = 0x00000178, /* Transmit Configuration Word */
68 Rxcw = 0x00000180, /* Receive Configuration Word */
69 /* on the oldest cards (8254[23]), the Mta register is at 0x200 */
70 Tctl = 0x00000400, /* Transmit Control */
71 Tipg = 0x00000410, /* Transmit IPG */
72 Tbt = 0x00000448, /* Transmit Burst Timer */
73 Ait = 0x00000458, /* Adaptive IFS Throttle */
74 Fcrtl = 0x00002160, /* Flow Control RX Threshold Low */
75 Fcrth = 0x00002168, /* Flow Control Rx Threshold High */
76 Rdfh = 0x00002410, /* Receive data fifo head */
77 Rdft = 0x00002418, /* Receive data fifo tail */
78 Rdfhs = 0x00002420, /* Receive data fifo head saved */
79 Rdfts = 0x00002428, /* Receive data fifo tail saved */
80 Rdfpc = 0x00002430, /* Receive data fifo packet count */
81 Rdbal = 0x00002800, /* Rd Base Address Low */
82 Rdbah = 0x00002804, /* Rd Base Address High */
83 Rdlen = 0x00002808, /* Receive Descriptor Length */
84 Rdh = 0x00002810, /* Receive Descriptor Head */
85 Rdt = 0x00002818, /* Receive Descriptor Tail */
86 Rdtr = 0x00002820, /* Receive Descriptor Timer Ring */
87 Rxdctl = 0x00002828, /* Receive Descriptor Control */
88 Radv = 0x0000282C, /* Receive Interrupt Absolute Delay Timer */
89 Txdmac = 0x00003000, /* Transfer DMA Control */
90 Ett = 0x00003008, /* Early Transmit Control */
91 Tdfh = 0x00003410, /* Transmit data fifo head */
92 Tdft = 0x00003418, /* Transmit data fifo tail */
93 Tdfhs = 0x00003420, /* Transmit data Fifo Head saved */
94 Tdfts = 0x00003428, /* Transmit data fifo tail saved */
95 Tdfpc = 0x00003430, /* Trasnmit data Fifo packet count */
96 Tdbal = 0x00003800, /* Td Base Address Low */
97 Tdbah = 0x00003804, /* Td Base Address High */
98 Tdlen = 0x00003808, /* Transmit Descriptor Length */
99 Tdh = 0x00003810, /* Transmit Descriptor Head */
100 Tdt = 0x00003818, /* Transmit Descriptor Tail */
101 Tidv = 0x00003820, /* Transmit Interrupt Delay Value */
102 Txdctl = 0x00003828, /* Transmit Descriptor Control */
103 Tadv = 0x0000382C, /* Transmit Interrupt Absolute Delay Timer */
105 Statistics = 0x00004000, /* Start of Statistics Area */
106 Gorcl = 0x88/4, /* Good Octets Received Count */
107 Gotcl = 0x90/4, /* Good Octets Transmitted Count */
108 Torl = 0xC0/4, /* Total Octets Received */
109 Totl = 0xC8/4, /* Total Octets Transmitted */
112 Rxcsum = 0x00005000, /* Receive Checksum Control */
113 Mta = 0x00005200, /* Multicast Table Array */
114 Ral = 0x00005400, /* Receive Address Low */
115 Rah = 0x00005404, /* Receive Address High */
116 Manc = 0x00005820, /* Management Control */
120 Bem = 0x00000002, /* Big Endian Mode */
121 Prior = 0x00000004, /* Priority on the PCI bus */
122 Lrst = 0x00000008, /* Link Reset */
123 Asde = 0x00000020, /* Auto-Speed Detection Enable */
124 Slu = 0x00000040, /* Set Link Up */
125 Ilos = 0x00000080, /* Invert Loss of Signal (LOS) */
126 SspeedMASK = 0x00000300, /* Speed Selection */
128 Sspeed10 = 0x00000000, /* 10Mb/s */
129 Sspeed100 = 0x00000100, /* 100Mb/s */
130 Sspeed1000 = 0x00000200, /* 1000Mb/s */
131 Frcspd = 0x00000800, /* Force Speed */
132 Frcdplx = 0x00001000, /* Force Duplex */
133 SwdpinsloMASK = 0x003C0000, /* Software Defined Pins - lo nibble */
135 SwdpioloMASK = 0x03C00000, /* Software Defined Pins - I or O */
137 Devrst = 0x04000000, /* Device Reset */
138 Rfce = 0x08000000, /* Receive Flow Control Enable */
139 Tfce = 0x10000000, /* Transmit Flow Control Enable */
140 Vme = 0x40000000, /* VLAN Mode Enable */
144 * can't find Tckok nor Rbcok in any Intel docs,
145 * but even 82543gc docs define Lanid.
148 Lu = 0x00000002, /* Link Up */
149 Lanid = 0x0000000C, /* mask for Lan ID. (function id) */
150 // Tckok = 0x00000004, /* Transmit clock is running */
151 // Rbcok = 0x00000008, /* Receive clock is running */
152 Txoff = 0x00000010, /* Transmission Paused */
153 Tbimode = 0x00000020, /* TBI Mode Indication */
154 LspeedMASK = 0x000000C0, /* Link Speed Setting */
156 Lspeed10 = 0x00000000, /* 10Mb/s */
157 Lspeed100 = 0x00000040, /* 100Mb/s */
158 Lspeed1000 = 0x00000080, /* 1000Mb/s */
159 Mtxckok = 0x00000400, /* MTX clock is running */
160 Pci66 = 0x00000800, /* PCI Bus speed indication */
161 Bus64 = 0x00001000, /* PCI Bus width indication */
162 Pcixmode = 0x00002000, /* PCI-X mode */
163 PcixspeedMASK = 0x0000C000, /* PCI-X bus speed */
165 Pcix66 = 0x00000000, /* 50-66MHz */
166 Pcix100 = 0x00004000, /* 66-100MHz */
167 Pcix133 = 0x00008000, /* 100-133MHz */
170 enum { /* Ctrl and Status */
171 Fd = 0x00000001, /* Full-Duplex */
172 AsdvMASK = 0x00000300,
174 Asdv10 = 0x00000000, /* 10Mb/s */
175 Asdv100 = 0x00000100, /* 100Mb/s */
176 Asdv1000 = 0x00000200, /* 1000Mb/s */
180 Sk = 0x00000001, /* Clock input to the EEPROM */
181 Cs = 0x00000002, /* Chip Select */
182 Di = 0x00000004, /* Data Input to the EEPROM */
183 Do = 0x00000008, /* Data Output from the EEPROM */
184 Areq = 0x00000040, /* EEPROM Access Request */
185 Agnt = 0x00000080, /* EEPROM Access Grant */
186 Eepresent = 0x00000100, /* EEPROM Present */
187 Eesz256 = 0x00000200, /* EEPROM is 256 words not 64 */
188 Eeszaddr = 0x00000400, /* EEPROM size for 8254[17] */
189 Spi = 0x00002000, /* EEPROM is SPI not Microwire */
193 Gpien = 0x0000000F, /* General Purpose Interrupt Enables */
194 SwdpinshiMASK = 0x000000F0, /* Software Defined Pins - hi nibble */
196 SwdpiohiMASK = 0x00000F00, /* Software Defined Pins - I or O */
198 Asdchk = 0x00001000, /* ASD Check */
199 Eerst = 0x00002000, /* EEPROM Reset */
200 Ips = 0x00004000, /* Invert Power State */
201 Spdbyps = 0x00008000, /* Speed Select Bypass */
204 enum { /* EEPROM content offsets */
205 Ea = 0x00, /* Ethernet Address */
206 Cf = 0x03, /* Compatibility Field */
207 Pba = 0x08, /* Printed Board Assembly number */
208 Icw1 = 0x0A, /* Initialization Control Word 1 */
209 Sid = 0x0B, /* Subsystem ID */
210 Svid = 0x0C, /* Subsystem Vendor ID */
211 Did = 0x0D, /* Device ID */
212 Vid = 0x0E, /* Vendor ID */
213 Icw2 = 0x0F, /* Initialization Control Word 2 */
217 MDIdMASK = 0x0000FFFF, /* Data */
219 MDIrMASK = 0x001F0000, /* PHY Register Address */
221 MDIpMASK = 0x03E00000, /* PHY Address */
223 MDIwop = 0x04000000, /* Write Operation */
224 MDIrop = 0x08000000, /* Read Operation */
225 MDIready = 0x10000000, /* End of Transaction */
226 MDIie = 0x20000000, /* Interrupt Enable */
227 MDIe = 0x40000000, /* Error */
230 enum { /* Icr, Ics, Ims, Imc */
231 Txdw = 0x00000001, /* Transmit Descriptor Written Back */
232 Txqe = 0x00000002, /* Transmit Queue Empty */
233 Lsc = 0x00000004, /* Link Status Change */
234 Rxseq = 0x00000008, /* Receive Sequence Error */
235 Rxdmt0 = 0x00000010, /* Rd Minimum Threshold Reached */
236 Rxo = 0x00000040, /* Receiver Overrun */
237 Rxt0 = 0x00000080, /* Receiver Timer Interrupt */
238 Mdac = 0x00000200, /* MDIO Access Completed */
239 Rxcfg = 0x00000400, /* Receiving /C/ ordered sets */
240 Gpi0 = 0x00000800, /* General Purpose Interrupts */
247 * The Mdic register isn't implemented on the 82543GC,
248 * the software defined pins are used instead.
249 * These definitions work for the Intel PRO/1000 T Server Adapter.
250 * The direction pin bits are read from the EEPROM.
253 Mdd = ((1<<2)<<SwdpinsloSHIFT), /* data */
254 Mddo = ((1<<2)<<SwdpioloSHIFT), /* pin direction */
255 Mdc = ((1<<3)<<SwdpinsloSHIFT), /* clock */
256 Mdco = ((1<<3)<<SwdpioloSHIFT), /* pin direction */
257 Mdr = ((1<<0)<<SwdpinshiSHIFT), /* reset */
258 Mdro = ((1<<0)<<SwdpiohiSHIFT), /* pin direction */
262 TxcwFd = 0x00000020, /* Full Duplex */
263 TxcwHd = 0x00000040, /* Half Duplex */
264 TxcwPauseMASK = 0x00000180, /* Pause */
266 TxcwPs = (1<<TxcwPauseSHIFT), /* Pause Supported */
267 TxcwAs = (2<<TxcwPauseSHIFT), /* Asymmetric FC desired */
268 TxcwRfiMASK = 0x00003000, /* Remote Fault Indication */
270 TxcwNpr = 0x00008000, /* Next Page Request */
271 TxcwConfig = 0x40000000, /* Transmit COnfig Control */
272 TxcwAne = 0x80000000, /* Auto-Negotiation Enable */
276 Rxword = 0x0000FFFF, /* Data from auto-negotiation process */
277 Rxnocarrier = 0x04000000, /* Carrier Sense indication */
278 Rxinvalid = 0x08000000, /* Invalid Symbol during configuration */
279 Rxchange = 0x10000000, /* Change to the Rxword indication */
280 Rxconfig = 0x20000000, /* /C/ order set reception indication */
281 Rxsync = 0x40000000, /* Lost bit synchronization indication */
282 Anc = 0x80000000, /* Auto Negotiation Complete */
286 Rrst = 0x00000001, /* Receiver Software Reset */
287 Ren = 0x00000002, /* Receiver Enable */
288 Sbp = 0x00000004, /* Store Bad Packets */
289 Upe = 0x00000008, /* Unicast Promiscuous Enable */
290 Mpe = 0x00000010, /* Multicast Promiscuous Enable */
291 Lpe = 0x00000020, /* Long Packet Reception Enable */
292 LbmMASK = 0x000000C0, /* Loopback Mode */
293 LbmOFF = 0x00000000, /* No Loopback */
294 LbmTBI = 0x00000040, /* TBI Loopback */
295 LbmMII = 0x00000080, /* GMII/MII Loopback */
296 LbmXCVR = 0x000000C0, /* Transceiver Loopback */
297 RdtmsMASK = 0x00000300, /* Rd Minimum Threshold Size */
298 RdtmsHALF = 0x00000000, /* Threshold is 1/2 Rdlen */
299 RdtmsQUARTER = 0x00000100, /* Threshold is 1/4 Rdlen */
300 RdtmsEIGHTH = 0x00000200, /* Threshold is 1/8 Rdlen */
301 MoMASK = 0x00003000, /* Multicast Offset */
302 Mo47b36 = 0x00000000, /* bits [47:36] of received address */
303 Mo46b35 = 0x00001000, /* bits [46:35] of received address */
304 Mo45b34 = 0x00002000, /* bits [45:34] of received address */
305 Mo43b32 = 0x00003000, /* bits [43:32] of received address */
306 Bam = 0x00008000, /* Broadcast Accept Mode */
307 BsizeMASK = 0x00030000, /* Receive Buffer Size */
308 Bsize2048 = 0x00000000, /* Bsex = 0 */
309 Bsize1024 = 0x00010000, /* Bsex = 0 */
310 Bsize512 = 0x00020000, /* Bsex = 0 */
311 Bsize256 = 0x00030000, /* Bsex = 0 */
312 Bsize16384 = 0x00010000, /* Bsex = 1 */
313 Vfe = 0x00040000, /* VLAN Filter Enable */
314 Cfien = 0x00080000, /* Canonical Form Indicator Enable */
315 Cfi = 0x00100000, /* Canonical Form Indicator value */
316 Dpf = 0x00400000, /* Discard Pause Frames */
317 Pmcf = 0x00800000, /* Pass MAC Control Frames */
318 Bsex = 0x02000000, /* Buffer Size Extension */
319 Secrc = 0x04000000, /* Strip CRC from incoming packet */
323 Trst = 0x00000001, /* Transmitter Software Reset */
324 Ten = 0x00000002, /* Transmit Enable */
325 Psp = 0x00000008, /* Pad Short Packets */
326 CtMASK = 0x00000FF0, /* Collision Threshold */
328 ColdMASK = 0x003FF000, /* Collision Distance */
330 Swxoff = 0x00400000, /* Sofware XOFF Transmission */
331 Pbe = 0x00800000, /* Packet Burst Enable */
332 Rtlc = 0x01000000, /* Re-transmit on Late Collision */
333 Nrtu = 0x02000000, /* No Re-transmit on Underrrun */
336 enum { /* [RT]xdctl */
337 PthreshMASK = 0x0000003F, /* Prefetch Threshold */
339 HthreshMASK = 0x00003F00, /* Host Threshold */
341 WthreshMASK = 0x003F0000, /* Writeback Threshold */
343 Gran = 0x01000000, /* Granularity */
344 LthreshMASK = 0xFE000000, /* Low Threshold */
349 PcssMASK = 0x000000FF, /* Packet Checksum Start */
351 Ipofl = 0x00000100, /* IP Checksum Off-load Enable */
352 Tuofl = 0x00000200, /* TCP/UDP Checksum Off-load Enable */
356 Arpen = 0x00002000, /* Enable ARP Request Filtering */
359 enum { /* Receive Delay Timer Ring */
360 DelayMASK = 0x0000FFFF, /* delay timer in 1.024nS increments */
362 Fpd = 0x80000000, /* Flush partial Descriptor Block */
365 typedef struct Rd { /* Receive Descriptor */
374 enum { /* Rd status */
375 Rdd = 0x01, /* Descriptor Done */
376 Reop = 0x02, /* End of Packet */
377 Ixsm = 0x04, /* Ignore Checksum Indication */
378 Vp = 0x08, /* Packet is 802.1Q (matched VET) */
379 Tcpcs = 0x20, /* TCP Checksum Calculated on Packet */
380 Ipcs = 0x40, /* IP Checksum Calculated on Packet */
381 Pif = 0x80, /* Passed in-exact filter */
384 enum { /* Rd errors */
385 Ce = 0x01, /* CRC Error or Alignment Error */
386 Se = 0x02, /* Symbol Error */
387 Seq = 0x04, /* Sequence Error */
388 Cxe = 0x10, /* Carrier Extension Error */
389 Tcpe = 0x20, /* TCP/UDP Checksum Error */
390 Ipe = 0x40, /* IP Checksum Error */
391 Rxe = 0x80, /* RX Data Error */
394 typedef struct Td Td;
395 struct Td { /* Transmit Descriptor */
397 uint addr[2]; /* Data */
398 struct { /* Context */
411 enum { /* Td control */
412 LenMASK = 0x000FFFFF, /* Data/Packet Length Field */
414 DtypeCD = 0x00000000, /* Data Type 'Context Descriptor' */
415 DtypeDD = 0x00100000, /* Data Type 'Data Descriptor' */
416 PtypeTCP = 0x01000000, /* TCP/UDP Packet Type (CD) */
417 Teop = 0x01000000, /* End of Packet (DD) */
418 PtypeIP = 0x02000000, /* IP Packet Type (CD) */
419 Ifcs = 0x02000000, /* Insert FCS (DD) */
420 Tse = 0x04000000, /* TCP Segmentation Enable */
421 Rs = 0x08000000, /* Report Status */
422 Rps = 0x10000000, /* Report Status Sent */
423 Dext = 0x20000000, /* Descriptor Extension */
424 Vle = 0x40000000, /* VLAN Packet Enable */
425 Ide = 0x80000000, /* Interrupt Delay Enable */
428 enum { /* Td status */
429 Tdd = 0x00000001, /* Descriptor Done */
430 Ec = 0x00000002, /* Excess Collisions */
431 Lc = 0x00000004, /* Late Collision */
432 Tu = 0x00000008, /* Transmit Underrun */
433 Iixsm = 0x00000100, /* Insert IP Checksum */
434 Itxsm = 0x00000200, /* Insert TCP/UDP Checksum */
435 HdrlenMASK = 0x0000FF00, /* Header Length (Tse) */
437 VlanMASK = 0x0FFF0000, /* VLAN Identifier */
439 Tcfi = 0x10000000, /* Canonical Form Indicator */
440 PriMASK = 0xE0000000, /* User Priority */
442 MssMASK = 0xFFFF0000, /* Maximum Segment Size (Tse) */
447 Nrd = 256, /* multiple of 8 */
448 Ntd = 64, /* multiple of 8 */
449 Nrb = 1024, /* private receive buffers per Ctlr */
453 typedef struct Ctlr Ctlr;
454 typedef struct Ctlr {
465 QLock alock; /* attach */
466 void* alloc; /* receive/transmit descriptors */
472 int im; /* interrupt mask */
481 uint statistics[Nstatistics];
492 uchar ra[Eaddrlen]; /* receive address */
493 ulong mta[128]; /* multicast table array */
498 Rd* rdba; /* receive descriptor base address */
499 Block** rb; /* receive buffers */
500 int rdh; /* receive descriptor head */
501 int rdt; /* receive descriptor tail */
502 int rdtr; /* receive delay timer ring value */
507 Td* tdba; /* transmit descriptor base address */
508 Block** tb; /* transmit buffers */
509 int tdh; /* transmit descriptor head */
510 int tdt; /* transmit descriptor tail */
517 #define csr32r(c, r) (*((c)->nic+((r)/4)))
518 #define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
520 static Ctlr* igbectlrhead;
521 static Ctlr* igbectlrtail;
523 static char* statistics[Nstatistics] = {
530 "Excessive Collisions",
531 "Multiple Collision",
539 "Carrier Extension Error",
540 "Receive Error Length",
546 "FC Received Unsupported",
547 "Packets Received (64 Bytes)",
548 "Packets Received (65-127 Bytes)",
549 "Packets Received (128-255 Bytes)",
550 "Packets Received (256-511 Bytes)",
551 "Packets Received (512-1023 Bytes)",
552 "Packets Received (1024-1522 Bytes)",
553 "Good Packets Received",
554 "Broadcast Packets Received",
555 "Multicast Packets Received",
556 "Good Packets Transmitted",
558 "Good Octets Received",
560 "Good Octets Transmitted",
564 "Receive No Buffers",
572 "Total Octets Received",
574 "Total Octets Transmitted",
576 "Total Packets Received",
577 "Total Packets Transmitted",
578 "Packets Transmitted (64 Bytes)",
579 "Packets Transmitted (65-127 Bytes)",
580 "Packets Transmitted (128-255 Bytes)",
581 "Packets Transmitted (256-511 Bytes)",
582 "Packets Transmitted (512-1023 Bytes)",
583 "Packets Transmitted (1024-1522 Bytes)",
584 "Multicast Packets Transmitted",
585 "Broadcast Packets Transmitted",
586 "TCP Segmentation Context Transmitted",
587 "TCP Segmentation Context Fail",
591 igbeifstat(Ether* edev, void* a, long n, ulong offset)
598 p = smalloc(READSTR);
602 for(i = 0; i < Nstatistics; i++){
603 r = csr32r(ctlr, Statistics+i*4);
604 if((s = statistics[i]) == nil)
612 ruvl += ((uvlong)csr32r(ctlr, Statistics+(i+1)*4))<<32;
614 tuvl += ctlr->statistics[i];
615 tuvl += ((uvlong)ctlr->statistics[i+1])<<32;
618 ctlr->statistics[i] = tuvl;
619 ctlr->statistics[i+1] = tuvl>>32;
620 l += snprint(p+l, READSTR-l, "%s: %llud %llud\n",
626 ctlr->statistics[i] += r;
627 if(ctlr->statistics[i] == 0)
629 l += snprint(p+l, READSTR-l, "%s: %ud %ud\n",
630 s, ctlr->statistics[i], r);
635 l += snprint(p+l, READSTR-l, "lintr: %ud %ud\n",
636 ctlr->lintr, ctlr->lsleep);
637 l += snprint(p+l, READSTR-l, "rintr: %ud %ud\n",
638 ctlr->rintr, ctlr->rsleep);
639 l += snprint(p+l, READSTR-l, "tintr: %ud %ud\n",
640 ctlr->tintr, ctlr->txdw);
641 l += snprint(p+l, READSTR-l, "ixcs: %ud %ud %ud\n",
642 ctlr->ixsm, ctlr->ipcs, ctlr->tcpcs);
643 l += snprint(p+l, READSTR-l, "rdtr: %ud\n", ctlr->rdtr);
644 l += snprint(p+l, READSTR-l, "Ctrlext: %08x\n", csr32r(ctlr, Ctrlext));
646 l += snprint(p+l, READSTR-l, "eeprom:");
647 for(i = 0; i < 0x40; i++){
648 if(i && ((i & 0x07) == 0))
649 l += snprint(p+l, READSTR-l, "\n ");
650 l += snprint(p+l, READSTR-l, " %4.4uX", ctlr->eeprom[i]);
652 l += snprint(p+l, READSTR-l, "\n");
654 if(ctlr->mii != nil && ctlr->mii->curphy != nil){
655 l += snprint(p+l, READSTR-l, "phy: ");
656 for(i = 0; i < NMiiPhyr; i++){
657 if(i && ((i & 0x07) == 0))
658 l += snprint(p+l, READSTR-l, "\n ");
659 r = miimir(ctlr->mii, i);
660 l += snprint(p+l, READSTR-l, " %4.4uX", r);
662 snprint(p+l, READSTR-l, "\n");
664 n = readstr(offset, a, n, p);
666 qunlock(&ctlr->slock);
675 static Cmdtab igbectlmsg[] = {
680 igbectl(Ether* edev, void* buf, long n)
688 if((ctlr = edev->ctlr) == nil)
691 cb = parsecmd(buf, n);
697 ct = lookupcmd(cb, igbectlmsg, nelem(igbectlmsg));
700 v = strtol(cb->f[1], &p, 0);
701 if(v < 0 || p == cb->f[1] || v > 0xFFFF)
704 csr32w(ctlr, Rdtr, Fpd|v);
714 igbepromiscuous(void* arg, int on)
723 rctl = csr32r(ctlr, Rctl);
730 csr32w(ctlr, Rctl, rctl|Mpe); /* temporarily keep Mpe on */
734 igbemulticast(void* arg, uchar* addr, int add)
744 bit = ((addr[5] & 1)<<4)|(addr[4]>>4);
746 * multiple ether addresses can hash to the same filter bit,
747 * so it's never safe to clear a filter bit.
748 * if we want to clear filter bits, we need to keep track of
749 * all the multicast addresses in use, clear all the filter bits,
750 * then set the ones corresponding to in-use addresses.
753 ctlr->mta[x] |= 1<<bit;
755 // ctlr->mta[x] &= ~(1<<bit);
757 csr32w(ctlr, Mta+x*4, ctlr->mta[x]);
761 igbeim(Ctlr* ctlr, int im)
763 ilock(&ctlr->imlock);
765 csr32w(ctlr, Ims, ctlr->im);
766 iunlock(&ctlr->imlock);
772 return ((Ctlr*)ctlr)->lim != 0;
788 if(ctlr->mii == nil || ctlr->mii->curphy == nil)
793 * logic to manage status change,
794 * this is incomplete but should work
795 * one time to set up the hardware.
797 * MiiPhy.speed, etc. should be in Mii.
799 if(miistatus(ctlr->mii) < 0)
803 phy = ctlr->mii->curphy;
804 ctrl = csr32r(ctlr, Ctrl);
812 ctrl &= ~(SspeedMASK|Ilos|Fd);
813 ctrl |= Frcdplx|Frcspd;
814 if(phy->speed == 1000)
816 else if(phy->speed == 100)
833 * Collision Distance.
835 r = csr32r(ctlr, Tctl);
841 csr32w(ctlr, Tctl, r);
850 csr32w(ctlr, Ctrl, ctrl);
857 sleep(&ctlr->lrendez, igbelim, ctlr);
862 igbetxinit(Ctlr* ctlr)
867 csr32w(ctlr, Tctl, (0x0F<<CtSHIFT)|Psp|(66<<ColdSHIFT));
891 csr32w(ctlr, Tipg, (6<<20)|(8<<10)|r);
892 csr32w(ctlr, Ait, 0);
893 csr32w(ctlr, Txdmac, 0);
895 csr32w(ctlr, Tdbal, PCIWADDR(ctlr->tdba));
896 csr32w(ctlr, Tdbah, 0);
897 csr32w(ctlr, Tdlen, ctlr->ntd*sizeof(Td));
898 ctlr->tdh = PREV(0, ctlr->ntd);
899 csr32w(ctlr, Tdh, 0);
901 csr32w(ctlr, Tdt, 0);
903 for(i = 0; i < ctlr->ntd; i++){
904 if((bp = ctlr->tb[i]) != nil){
908 memset(&ctlr->tdba[i], 0, sizeof(Td));
910 ctlr->tdfree = ctlr->ntd;
912 csr32w(ctlr, Tidv, 128);
913 r = (4<<WthreshSHIFT)|(4<<HthreshSHIFT)|(8<<PthreshSHIFT);
928 r = csr32r(ctlr, Txdctl);
930 r |= Gran|(4<<WthreshSHIFT);
932 csr32w(ctlr, Tadv, 64);
936 csr32w(ctlr, Txdctl, r);
938 r = csr32r(ctlr, Tctl);
940 csr32w(ctlr, Tctl, r);
944 igbetransmit(Ether* edev)
956 * Free any completed packets
959 while(NEXT(tdh, ctlr->ntd) != csr32r(ctlr, Tdh)){
960 if((bp = ctlr->tb[tdh]) != nil){
964 memset(&ctlr->tdba[tdh], 0, sizeof(Td));
965 tdh = NEXT(tdh, ctlr->ntd);
970 * Try to fill the ring back up.
973 while(NEXT(tdt, ctlr->ntd) != tdh){
974 if((bp = qget(edev->oq)) == nil)
976 td = &ctlr->tdba[tdt];
977 td->addr[0] = PCIWADDR(bp->rp);
978 td->control = ((BLEN(bp) & LenMASK)<<LenSHIFT);
979 td->control |= Dext|Ifcs|Teop|DtypeDD;
981 tdt = NEXT(tdt, ctlr->ntd);
982 if(NEXT(tdt, ctlr->ntd) == tdh){
986 csr32w(ctlr, Tdt, tdt);
991 csr32w(ctlr, Tdt, tdt);
994 iunlock(&ctlr->tlock);
998 igbereplenish(Ctlr* ctlr)
1005 while(NEXT(rdt, ctlr->nrd) != ctlr->rdh){
1006 rd = &ctlr->rdba[rdt];
1007 if(ctlr->rb[rdt] == nil){
1009 bp->rp = bp->lim - Rbsz;
1012 rd->addr[0] = PCIWADDR(bp->rp);
1017 rdt = NEXT(rdt, ctlr->nrd);
1021 csr32w(ctlr, Rdt, rdt);
1025 igberxinit(Ctlr* ctlr)
1030 /* temporarily keep Mpe on */
1031 csr32w(ctlr, Rctl, Dpf|Bsize2048|Bam|RdtmsHALF|Mpe);
1033 csr32w(ctlr, Rdbal, PCIWADDR(ctlr->rdba));
1034 csr32w(ctlr, Rdbah, 0);
1035 csr32w(ctlr, Rdlen, ctlr->nrd*sizeof(Rd));
1037 csr32w(ctlr, Rdh, 0);
1039 csr32w(ctlr, Rdt, 0);
1041 csr32w(ctlr, Rdtr, Fpd|0);
1043 for(i = 0; i < ctlr->nrd; i++){
1044 if((bp = ctlr->rb[i]) != nil){
1049 igbereplenish(ctlr);
1062 csr32w(ctlr, Radv, 64);
1065 csr32w(ctlr, Rxdctl, (8<<WthreshSHIFT)|(8<<HthreshSHIFT)|4);
1068 * Disable checksum offload as it has known bugs.
1070 csr32w(ctlr, Rxcsum, ETHERHDRSIZE<<PcssSHIFT);
1076 return ((Ctlr*)ctlr)->rim != 0;
1080 igberproc(void* arg)
1092 r = csr32r(ctlr, Rctl);
1094 csr32w(ctlr, Rctl, r);
1101 igbeim(ctlr, Rxt0|Rxo|Rxdmt0|Rxseq);
1103 sleep(&ctlr->rrendez, igberim, ctlr);
1107 rd = &ctlr->rdba[rdh];
1109 if(!(rd->status & Rdd))
1113 * Accept eop packets with no errors.
1114 * With no errors and the Ixsm bit set,
1115 * the descriptor status Tpcs and Ipcs bits give
1116 * an indication of whether the checksums were
1117 * calculated and valid.
1119 if((rd->status & Reop) && rd->errors == 0){
1121 ctlr->rb[rdh] = nil;
1122 bp->wp += rd->length;
1124 if(!(rd->status & Ixsm)){
1126 if(rd->status & Ipcs){
1128 * IP checksum calculated
1129 * (and valid as errors == 0).
1134 if(rd->status & Tcpcs){
1136 * TCP/UDP checksum calculated
1137 * (and valid as errors == 0).
1140 bp->flag |= Btcpck|Budpck;
1142 bp->checksum = rd->checksum;
1145 etheriq(edev, bp, 1);
1147 else if(ctlr->rb[rdh] != nil){
1148 freeb(ctlr->rb[rdh]);
1149 ctlr->rb[rdh] = nil;
1152 memset(rd, 0, sizeof(Rd));
1155 rdh = NEXT(rdh, ctlr->nrd);
1159 if(ctlr->rdfree < ctlr->nrd/2 || (ctlr->rim & Rxdmt0))
1160 igbereplenish(ctlr);
1165 igbeattach(Ether* edev)
1168 char name[KNAMELEN];
1171 ctlr->edev = edev; /* point back to Ether* */
1172 qlock(&ctlr->alock);
1173 if(ctlr->alloc != nil){ /* already allocated? */
1174 qunlock(&ctlr->alock);
1178 ctlr->nrd = ROUND(Nrd, 8);
1179 ctlr->ntd = ROUND(Ntd, 8);
1180 ctlr->alloc = malloc(ctlr->nrd*sizeof(Rd)+ctlr->ntd*sizeof(Td) + 127);
1181 if(ctlr->alloc == nil){
1182 print("igbe: can't allocate ctlr->alloc\n");
1183 qunlock(&ctlr->alock);
1186 ctlr->rdba = (Rd*)ROUNDUP((uintptr)ctlr->alloc, 128);
1187 ctlr->tdba = (Td*)(ctlr->rdba+ctlr->nrd);
1189 ctlr->rb = malloc(ctlr->nrd*sizeof(Block*));
1190 ctlr->tb = malloc(ctlr->ntd*sizeof(Block*));
1191 if (ctlr->rb == nil || ctlr->tb == nil) {
1192 print("igbe: can't allocate ctlr->rb or ctlr->tb\n");
1193 qunlock(&ctlr->alock);
1204 qunlock(&ctlr->alock);
1208 snprint(name, KNAMELEN, "#l%dlproc", edev->ctlrno);
1209 kproc(name, igbelproc, edev);
1211 snprint(name, KNAMELEN, "#l%drproc", edev->ctlrno);
1212 kproc(name, igberproc, edev);
1216 qunlock(&ctlr->alock);
1221 igbeinterrupt(Ureg*, void* arg)
1230 ilock(&ctlr->imlock);
1231 csr32w(ctlr, Imc, ~0);
1235 while((icr = csr32r(ctlr, Icr) & ctlr->im) != 0){
1238 ctlr->lim = icr & Lsc;
1239 wakeup(&ctlr->lrendez);
1242 if(icr & (Rxt0|Rxo|Rxdmt0|Rxseq)){
1243 im &= ~(Rxt0|Rxo|Rxdmt0|Rxseq);
1244 ctlr->rim = icr & (Rxt0|Rxo|Rxdmt0|Rxseq);
1245 wakeup(&ctlr->rrendez);
1256 csr32w(ctlr, Ims, im);
1257 iunlock(&ctlr->imlock);
1264 i82543mdior(Ctlr* ctlr, int n)
1266 int ctrl, data, i, r;
1269 * Read n bits from the Management Data I/O Interface.
1271 ctrl = csr32r(ctlr, Ctrl);
1272 r = (ctrl & ~Mddo)|Mdco;
1274 for(i = n-1; i >= 0; i--){
1275 if(csr32r(ctlr, Ctrl) & Mdd)
1277 csr32w(ctlr, Ctrl, Mdc|r);
1278 csr32w(ctlr, Ctrl, r);
1280 csr32w(ctlr, Ctrl, ctrl);
1286 i82543mdiow(Ctlr* ctlr, int bits, int n)
1291 * Write n bits to the Management Data I/O Interface.
1293 ctrl = csr32r(ctlr, Ctrl);
1295 for(i = n-1; i >= 0; i--){
1300 csr32w(ctlr, Ctrl, Mdc|r);
1301 csr32w(ctlr, Ctrl, r);
1303 csr32w(ctlr, Ctrl, ctrl);
1309 i82543miimir(Mii* mii, int pa, int ra)
1317 * MII Management Interface Read.
1320 * ST+OP+PHYAD+REGAD;
1321 * TA + 16 data bits.
1323 i82543mdiow(ctlr, 0xFFFFFFFF, 32);
1324 i82543mdiow(ctlr, 0x1800|(pa<<5)|ra, 14);
1325 data = i82543mdior(ctlr, 18);
1330 return data & 0xFFFF;
1334 i82543miimiw(Mii* mii, int pa, int ra, int data)
1341 * MII Management Interface Write.
1344 * ST+OP+PHYAD+REGAD+TA + 16 data bits;
1347 i82543mdiow(ctlr, 0xFFFFFFFF, 32);
1349 data |= (0x05<<(5+5+2+16))|(pa<<(5+2+16))|(ra<<(2+16))|(0x02<<16);
1350 i82543mdiow(ctlr, data, 32);
1356 igbemiimir(Mii* mii, int pa, int ra)
1363 csr32w(ctlr, Mdic, MDIrop|(pa<<MDIpSHIFT)|(ra<<MDIrSHIFT));
1365 for(timo = 64; timo; timo--){
1366 mdic = csr32r(ctlr, Mdic);
1367 if(mdic & (MDIe|MDIready))
1372 if((mdic & (MDIe|MDIready)) == MDIready)
1373 return mdic & 0xFFFF;
1378 igbemiimiw(Mii* mii, int pa, int ra, int data)
1386 csr32w(ctlr, Mdic, MDIwop|(pa<<MDIpSHIFT)|(ra<<MDIrSHIFT)|data);
1388 for(timo = 64; timo; timo--){
1389 mdic = csr32r(ctlr, Mdic);
1390 if(mdic & (MDIe|MDIready))
1394 if((mdic & (MDIe|MDIready)) == MDIready)
1405 r = csr32r(ctlr, Status);
1408 if((ctlr->mii = malloc(sizeof(Mii))) == nil)
1410 ctlr->mii->ctlr = ctlr;
1412 ctrl = csr32r(ctlr, Ctrl);
1417 ctrl |= Frcdplx|Frcspd;
1418 csr32w(ctlr, Ctrl, ctrl);
1421 * The reset pin direction (Mdro) should already
1422 * be set from the EEPROM load.
1423 * If it's not set this configuration is unexpected
1426 r = csr32r(ctlr, Ctrlext);
1428 print("igbe: 82543gc Mdro not set\n");
1431 csr32w(ctlr, Ctrlext, r);
1433 r = csr32r(ctlr, Ctrlext);
1435 csr32w(ctlr, Ctrlext, r);
1437 r = csr32r(ctlr, Ctrlext);
1439 csr32w(ctlr, Ctrlext, r);
1442 ctlr->mii->mir = i82543miimir;
1443 ctlr->mii->miw = i82543miimiw;
1460 ctrl &= ~(Frcdplx|Frcspd);
1461 csr32w(ctlr, Ctrl, ctrl);
1462 ctlr->mii->mir = igbemiimir;
1463 ctlr->mii->miw = igbemiimiw;
1471 if(mii(ctlr->mii, ~0) == 0 || (phy = ctlr->mii->curphy) == nil){
1477 // print("oui %X phyno %d\n", phy->oui, phy->phyno);
1480 * 8254X-specific PHY registers not in 802.3:
1481 * 0x10 PHY specific control
1482 * 0x14 extended PHY specific control
1483 * Set appropriate values then reset the PHY to have
1497 r = miimir(ctlr->mii, 16);
1498 r |= 0x0800; /* assert CRS on Tx */
1499 r |= 0x0060; /* auto-crossover all speeds */
1500 r |= 0x0002; /* polarity reversal enabled */
1501 miimiw(ctlr->mii, 16, r);
1503 r = miimir(ctlr->mii, 20);
1504 r |= 0x0070; /* +25MHz clock */
1506 r |= 0x0100; /* 1x downshift */
1507 miimiw(ctlr->mii, 20, r);
1509 miireset(ctlr->mii);
1511 if(ctlr->txcw & TxcwPs)
1513 if(ctlr->txcw & TxcwAs)
1515 miiane(ctlr->mii, ~0, p, ~0);
1522 at93c46io(Ctlr* ctlr, char* op, int data)
1525 int i, loop, eecd, r;
1527 eecd = csr32r(ctlr, Eecd);
1532 for(p = op; *p != '\0'; p++){
1538 case ':': /* start of loop */
1539 loop = strtol(p+1, &lp, 0)-1;
1545 case ';': /* end of loop */
1554 case 'C': /* assert clock */
1557 case 'c': /* deassert clock */
1560 case 'D': /* next bit in 'data' byte */
1563 if(data & (1<<loop))
1568 case 'O': /* collect data output */
1569 i = (csr32r(ctlr, Eecd) & Do) != 0;
1581 case 'I': /* assert data input */
1584 case 'i': /* deassert data input */
1587 case 'S': /* enable chip select */
1590 case 's': /* disable chip select */
1594 csr32w(ctlr, Eecd, eecd);
1606 at93c46r(Ctlr* ctlr)
1610 int addr, areq, bits, data, eecd, i;
1613 eecd = csr32r(ctlr, Eecd);
1632 csr32w(ctlr, Eecd, eecd|Areq);
1633 for(i = 0; i < 1000; i++){
1634 if((eecd = csr32r(ctlr, Eecd)) & Agnt)
1639 print("igbe: not granted EEPROM access\n");
1646 for(i = 0; i < 1000; i++){
1647 at93c46io(ctlr, "H :8HDCc;", 0x05);
1648 data = at93c46io(ctlr, "h :8COc;", 0);
1654 at93c46io(ctlr, "Ss", 0);
1657 print("igbe: SPI EEPROM not ready\n");
1661 at93c46io(ctlr, "Ss H :8HDCc;", 0x03);
1667 snprint(rop, sizeof(rop), "H :%dHDCc;", bits);
1668 if(at93c46io(ctlr, rop, 0) != 0){
1669 print("igbe: can't set EEPROM address 0x00\n");
1673 for(addr = 0; addr < 0x40; addr++){
1674 data = at93c46io(ctlr, "h :16COc;", 0);
1675 ctlr->eeprom[addr] = (data >> 8) | (data << 8);
1676 sum += ctlr->eeprom[addr];
1679 if(eecd & (Eeszaddr|Eesz256))
1683 snprint(rop, sizeof(rop), "S :%dDCc;", bits+3);
1685 for(addr = 0; addr < 0x40; addr++){
1687 * Read a word at address 'addr' from the Atmel AT93C46
1688 * 3-Wire Serial EEPROM or compatible. The EEPROM access is
1689 * controlled by 4 bits in Eecd. See the AT93C46 datasheet
1690 * for protocol details.
1692 if(at93c46io(ctlr, rop, (0x06<<bits)|addr) != 0){
1693 print("igbe: can't set EEPROM address 0x%2.2X\n", addr);
1696 data = at93c46io(ctlr, ":16COc;", 0);
1697 at93c46io(ctlr, "sic", 0);
1698 ctlr->eeprom[addr] = data;
1705 csr32w(ctlr, Eecd, eecd & ~Areq);
1710 igbedetach(Ctlr* ctlr)
1715 * Perform a device reset to get the chip back to the
1716 * power-on state, followed by an EEPROM reset to read
1717 * the defaults for some internal registers.
1719 csr32w(ctlr, Imc, ~0);
1720 csr32w(ctlr, Rctl, 0);
1721 csr32w(ctlr, Tctl, 0);
1725 csr32w(ctlr, Ctrl, Devrst);
1727 for(timeo = 0; timeo < 1000; timeo++){
1728 if(!(csr32r(ctlr, Ctrl) & Devrst))
1732 if(csr32r(ctlr, Ctrl) & Devrst)
1734 r = csr32r(ctlr, Ctrlext);
1735 csr32w(ctlr, Ctrlext, r|Eerst);
1737 for(timeo = 0; timeo < 1000; timeo++){
1738 if(!(csr32r(ctlr, Ctrlext) & Eerst))
1742 if(csr32r(ctlr, Ctrlext) & Eerst)
1758 r = csr32r(ctlr, Manc);
1760 csr32w(ctlr, Manc, r);
1764 csr32w(ctlr, Imc, ~0);
1766 for(timeo = 0; timeo < 1000; timeo++){
1767 if(!csr32r(ctlr, Icr))
1771 if(csr32r(ctlr, Icr))
1778 igbeshutdown(Ether* ether)
1780 igbedetach(ether->ctlr);
1784 igbereset(Ctlr* ctlr)
1786 int ctrl, i, pause, r, swdpio, txcw;
1788 if(igbedetach(ctlr))
1792 * Read the EEPROM, validate the checksum
1793 * then get the device back to a power-on state.
1795 if((r = at93c46r(ctlr)) != 0xBABA){
1796 print("igbe: bad EEPROM checksum - 0x%4.4uX\n", r);
1801 * Snarf and set up the receive addresses.
1802 * There are 16 addresses. The first should be the MAC address.
1803 * The others are cleared and not marked valid (MS bit of Rah).
1805 if ((ctlr->id == i82546gb || ctlr->id == i82546eb) &&
1806 BUSFNO(ctlr->pcidev->tbdf) == 1)
1807 ctlr->eeprom[Ea+2] += 0x100; /* second interface */
1808 if(ctlr->id == i82541gi && ctlr->eeprom[Ea] == 0xFFFF)
1809 ctlr->eeprom[Ea] = 0xD000;
1810 for(i = Ea; i < Eaddrlen/2; i++){
1811 ctlr->ra[2*i] = ctlr->eeprom[i];
1812 ctlr->ra[2*i+1] = ctlr->eeprom[i]>>8;
1814 /* lan id seems to vary on 82543gc; don't use it */
1815 if (ctlr->id != i82543gc) {
1816 r = (csr32r(ctlr, Status) & Lanid) >> 2;
1817 ctlr->ra[5] += r; /* ea ctlr[1] = ea ctlr[0]+1 */
1820 r = (ctlr->ra[3]<<24)|(ctlr->ra[2]<<16)|(ctlr->ra[1]<<8)|ctlr->ra[0];
1821 csr32w(ctlr, Ral, r);
1822 r = 0x80000000|(ctlr->ra[5]<<8)|ctlr->ra[4];
1823 csr32w(ctlr, Rah, r);
1824 for(i = 1; i < 16; i++){
1825 csr32w(ctlr, Ral+i*8, 0);
1826 csr32w(ctlr, Rah+i*8, 0);
1830 * Clear the Multicast Table Array.
1831 * It's a 4096 bit vector accessed as 128 32-bit registers.
1833 memset(ctlr->mta, 0, sizeof(ctlr->mta));
1834 for(i = 0; i < 128; i++)
1835 csr32w(ctlr, Mta+i*4, 0);
1838 * Just in case the Eerst didn't load the defaults
1839 * (doesn't appear to fully on the 82543GC), do it manually.
1841 if (ctlr->id == i82543gc) {
1842 txcw = csr32r(ctlr, Txcw);
1843 txcw &= ~(TxcwAne|TxcwPauseMASK|TxcwFd);
1844 ctrl = csr32r(ctlr, Ctrl);
1845 ctrl &= ~(SwdpioloMASK|Frcspd|Ilos|Lrst|Fd);
1847 if(ctlr->eeprom[Icw1] & 0x0400){
1851 if(ctlr->eeprom[Icw1] & 0x0200)
1853 if(ctlr->eeprom[Icw1] & 0x0010)
1855 if(ctlr->eeprom[Icw1] & 0x0800)
1857 swdpio = (ctlr->eeprom[Icw1] & 0x01E0)>>5;
1858 ctrl |= swdpio<<SwdpioloSHIFT;
1859 csr32w(ctlr, Ctrl, ctrl);
1861 ctrl = csr32r(ctlr, Ctrlext);
1862 ctrl &= ~(Ips|SwdpiohiMASK);
1863 swdpio = (ctlr->eeprom[Icw2] & 0x00F0)>>4;
1864 if(ctlr->eeprom[Icw1] & 0x1000)
1866 ctrl |= swdpio<<SwdpiohiSHIFT;
1867 csr32w(ctlr, Ctrlext, ctrl);
1869 if(ctlr->eeprom[Icw2] & 0x0800)
1871 pause = (ctlr->eeprom[Icw2] & 0x3000)>>12;
1872 txcw |= pause<<TxcwPauseSHIFT;
1875 ctlr->fcrtl = 0x00002000;
1876 ctlr->fcrth = 0x00004000;
1877 txcw |= TxcwAs|TxcwPs;
1880 ctlr->fcrtl = 0x00002000;
1881 ctlr->fcrth = 0x00004000;
1890 csr32w(ctlr, Txcw, txcw);
1895 * Flow control - values from the datasheet.
1897 csr32w(ctlr, Fcal, 0x00C28001);
1898 csr32w(ctlr, Fcah, 0x00000100);
1899 csr32w(ctlr, Fct, 0x00008808);
1900 csr32w(ctlr, Fcttv, 0x00000100);
1902 csr32w(ctlr, Fcrtl, ctlr->fcrtl);
1903 csr32w(ctlr, Fcrth, ctlr->fcrth);
1905 if(!(csr32r(ctlr, Status) & Tbimode) && igbemii(ctlr) < 0)
1920 while(p = pcimatch(p, 0, 0)){
1921 if(p->ccrb != 0x02 || p->ccru != 0)
1924 switch((p->did<<16)|p->vid){
1946 mem = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
1948 print("igbe: can't map %8.8luX\n", p->mem[0].bar);
1951 cls = pcicfgr8(p, PciCLS);
1954 print("igbe: p->cls %#ux, setting to 0x10\n", p->cls);
1956 pcicfgw8(p, PciCLS, p->cls);
1962 ctlr = malloc(sizeof(Ctlr));
1964 print("igbe: can't allocate memory\n");
1967 ctlr->port = p->mem[0].bar & ~0x0F;
1969 ctlr->id = (p->did<<16)|p->vid;
1973 if(igbereset(ctlr)){
1975 vunmap(mem, p->mem[0].size);
1980 if(igbectlrhead != nil)
1981 igbectlrtail->next = ctlr;
1983 igbectlrhead = ctlr;
1984 igbectlrtail = ctlr;
1989 igbepnp(Ether* edev)
1993 if(igbectlrhead == nil)
1997 * Any adapter matches if no edev->port is supplied,
1998 * otherwise the ports must match.
2000 for(ctlr = igbectlrhead; ctlr != nil; ctlr = ctlr->next){
2003 if(edev->port == 0 || edev->port == ctlr->port){
2012 edev->port = ctlr->port;
2013 edev->irq = ctlr->pcidev->intl;
2014 edev->tbdf = ctlr->pcidev->tbdf;
2016 memmove(edev->ea, ctlr->ra, Eaddrlen);
2019 * Linkage to the generic ethernet driver.
2021 edev->attach = igbeattach;
2022 edev->transmit = igbetransmit;
2023 edev->interrupt = igbeinterrupt;
2024 edev->ifstat = igbeifstat;
2025 edev->ctl = igbectl;
2028 edev->promiscuous = igbepromiscuous;
2029 edev->shutdown = igbeshutdown;
2030 edev->multicast = igbemulticast;
2038 addethercard("i82543", igbepnp);
2039 addethercard("igbe", igbepnp);