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 */
469 int nrb; /* how many this Ctlr has in the pool */
473 int im; /* interrupt mask */
482 uint statistics[Nstatistics];
493 uchar ra[Eaddrlen]; /* receive address */
494 ulong mta[128]; /* multicast table array */
499 Rd* rdba; /* receive descriptor base address */
500 Block** rb; /* receive buffers */
501 int rdh; /* receive descriptor head */
502 int rdt; /* receive descriptor tail */
503 int rdtr; /* receive delay timer ring value */
508 Td* tdba; /* transmit descriptor base address */
509 Block** tb; /* transmit buffers */
510 int tdh; /* transmit descriptor head */
511 int tdt; /* transmit descriptor tail */
518 #define csr32r(c, r) (*((c)->nic+((r)/4)))
519 #define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
521 static Ctlr* igbectlrhead;
522 static Ctlr* igbectlrtail;
524 static Lock igberblock; /* free receive Blocks */
525 static Block* igberbpool; /* receive Blocks for all igbe controllers */
527 static char* statistics[Nstatistics] = {
534 "Excessive Collisions",
535 "Multiple Collision",
543 "Carrier Extension Error",
544 "Receive Error Length",
550 "FC Received Unsupported",
551 "Packets Received (64 Bytes)",
552 "Packets Received (65-127 Bytes)",
553 "Packets Received (128-255 Bytes)",
554 "Packets Received (256-511 Bytes)",
555 "Packets Received (512-1023 Bytes)",
556 "Packets Received (1024-1522 Bytes)",
557 "Good Packets Received",
558 "Broadcast Packets Received",
559 "Multicast Packets Received",
560 "Good Packets Transmitted",
562 "Good Octets Received",
564 "Good Octets Transmitted",
568 "Receive No Buffers",
576 "Total Octets Received",
578 "Total Octets Transmitted",
580 "Total Packets Received",
581 "Total Packets Transmitted",
582 "Packets Transmitted (64 Bytes)",
583 "Packets Transmitted (65-127 Bytes)",
584 "Packets Transmitted (128-255 Bytes)",
585 "Packets Transmitted (256-511 Bytes)",
586 "Packets Transmitted (512-1023 Bytes)",
587 "Packets Transmitted (1024-1522 Bytes)",
588 "Multicast Packets Transmitted",
589 "Broadcast Packets Transmitted",
590 "TCP Segmentation Context Transmitted",
591 "TCP Segmentation Context Fail",
595 igbeifstat(Ether* edev, void* a, long n, ulong offset)
606 for(i = 0; i < Nstatistics; i++){
607 r = csr32r(ctlr, Statistics+i*4);
608 if((s = statistics[i]) == nil)
616 ruvl += ((uvlong)csr32r(ctlr, Statistics+(i+1)*4))<<32;
618 tuvl += ctlr->statistics[i];
619 tuvl += ((uvlong)ctlr->statistics[i+1])<<32;
622 ctlr->statistics[i] = tuvl;
623 ctlr->statistics[i+1] = tuvl>>32;
624 l += snprint(p+l, READSTR-l, "%s: %llud %llud\n",
630 ctlr->statistics[i] += r;
631 if(ctlr->statistics[i] == 0)
633 l += snprint(p+l, READSTR-l, "%s: %ud %ud\n",
634 s, ctlr->statistics[i], r);
639 l += snprint(p+l, READSTR-l, "lintr: %ud %ud\n",
640 ctlr->lintr, ctlr->lsleep);
641 l += snprint(p+l, READSTR-l, "rintr: %ud %ud\n",
642 ctlr->rintr, ctlr->rsleep);
643 l += snprint(p+l, READSTR-l, "tintr: %ud %ud\n",
644 ctlr->tintr, ctlr->txdw);
645 l += snprint(p+l, READSTR-l, "ixcs: %ud %ud %ud\n",
646 ctlr->ixsm, ctlr->ipcs, ctlr->tcpcs);
647 l += snprint(p+l, READSTR-l, "rdtr: %ud\n", ctlr->rdtr);
648 l += snprint(p+l, READSTR-l, "Ctrlext: %08x\n", csr32r(ctlr, Ctrlext));
650 l += snprint(p+l, READSTR-l, "eeprom:");
651 for(i = 0; i < 0x40; i++){
652 if(i && ((i & 0x07) == 0))
653 l += snprint(p+l, READSTR-l, "\n ");
654 l += snprint(p+l, READSTR-l, " %4.4uX", ctlr->eeprom[i]);
656 l += snprint(p+l, READSTR-l, "\n");
658 if(ctlr->mii != nil && ctlr->mii->curphy != nil){
659 l += snprint(p+l, READSTR-l, "phy: ");
660 for(i = 0; i < NMiiPhyr; i++){
661 if(i && ((i & 0x07) == 0))
662 l += snprint(p+l, READSTR-l, "\n ");
663 r = miimir(ctlr->mii, i);
664 l += snprint(p+l, READSTR-l, " %4.4uX", r);
666 snprint(p+l, READSTR-l, "\n");
668 n = readstr(offset, a, n, p);
670 qunlock(&ctlr->slock);
679 static Cmdtab igbectlmsg[] = {
684 igbectl(Ether* edev, void* buf, long n)
692 if((ctlr = edev->ctlr) == nil)
695 cb = parsecmd(buf, n);
701 ct = lookupcmd(cb, igbectlmsg, nelem(igbectlmsg));
704 v = strtol(cb->f[1], &p, 0);
705 if(v < 0 || p == cb->f[1] || v > 0xFFFF)
708 csr32w(ctlr, Rdtr, Fpd|v);
718 igbepromiscuous(void* arg, int on)
727 rctl = csr32r(ctlr, Rctl);
734 csr32w(ctlr, Rctl, rctl|Mpe); /* temporarily keep Mpe on */
738 igbemulticast(void* arg, uchar* addr, int add)
748 bit = ((addr[5] & 1)<<4)|(addr[4]>>4);
750 * multiple ether addresses can hash to the same filter bit,
751 * so it's never safe to clear a filter bit.
752 * if we want to clear filter bits, we need to keep track of
753 * all the multicast addresses in use, clear all the filter bits,
754 * then set the ones corresponding to in-use addresses.
757 ctlr->mta[x] |= 1<<bit;
759 // ctlr->mta[x] &= ~(1<<bit);
761 csr32w(ctlr, Mta+x*4, ctlr->mta[x]);
770 if((bp = igberbpool) != nil){
771 igberbpool = bp->next;
773 _xinc(&bp->ref); /* prevent bp from being freed */
775 iunlock(&igberblock);
781 igberbfree(Block* bp)
783 bp->rp = bp->lim - Rbsz;
785 bp->flag &= ~(Bipck | Budpck | Btcpck | Bpktck);
788 bp->next = igberbpool;
790 iunlock(&igberblock);
794 igbeim(Ctlr* ctlr, int im)
796 ilock(&ctlr->imlock);
798 csr32w(ctlr, Ims, ctlr->im);
799 iunlock(&ctlr->imlock);
805 return ((Ctlr*)ctlr)->lim != 0;
819 if(ctlr->mii == nil || ctlr->mii->curphy == nil)
824 * logic to manage status change,
825 * this is incomplete but should work
826 * one time to set up the hardware.
828 * MiiPhy.speed, etc. should be in Mii.
830 if(miistatus(ctlr->mii) < 0)
834 phy = ctlr->mii->curphy;
835 ctrl = csr32r(ctlr, Ctrl);
843 ctrl &= ~(SspeedMASK|Ilos|Fd);
844 ctrl |= Frcdplx|Frcspd;
845 if(phy->speed == 1000)
847 else if(phy->speed == 100)
864 * Collision Distance.
866 r = csr32r(ctlr, Tctl);
872 csr32w(ctlr, Tctl, r);
881 csr32w(ctlr, Ctrl, ctrl);
888 sleep(&ctlr->lrendez, igbelim, ctlr);
893 igbetxinit(Ctlr* ctlr)
898 csr32w(ctlr, Tctl, (0x0F<<CtSHIFT)|Psp|(66<<ColdSHIFT));
922 csr32w(ctlr, Tipg, (6<<20)|(8<<10)|r);
923 csr32w(ctlr, Ait, 0);
924 csr32w(ctlr, Txdmac, 0);
926 csr32w(ctlr, Tdbal, PCIWADDR(ctlr->tdba));
927 csr32w(ctlr, Tdbah, 0);
928 csr32w(ctlr, Tdlen, ctlr->ntd*sizeof(Td));
929 ctlr->tdh = PREV(0, ctlr->ntd);
930 csr32w(ctlr, Tdh, 0);
932 csr32w(ctlr, Tdt, 0);
934 for(i = 0; i < ctlr->ntd; i++){
935 if((bp = ctlr->tb[i]) != nil){
939 memset(&ctlr->tdba[i], 0, sizeof(Td));
941 ctlr->tdfree = ctlr->ntd;
943 csr32w(ctlr, Tidv, 128);
944 r = (4<<WthreshSHIFT)|(4<<HthreshSHIFT)|(8<<PthreshSHIFT);
959 r = csr32r(ctlr, Txdctl);
961 r |= Gran|(4<<WthreshSHIFT);
963 csr32w(ctlr, Tadv, 64);
967 csr32w(ctlr, Txdctl, r);
969 r = csr32r(ctlr, Tctl);
971 csr32w(ctlr, Tctl, r);
975 igbetransmit(Ether* edev)
987 * Free any completed packets
990 while(NEXT(tdh, ctlr->ntd) != csr32r(ctlr, Tdh)){
991 if((bp = ctlr->tb[tdh]) != nil){
995 memset(&ctlr->tdba[tdh], 0, sizeof(Td));
996 tdh = NEXT(tdh, ctlr->ntd);
1001 * Try to fill the ring back up.
1004 while(NEXT(tdt, ctlr->ntd) != tdh){
1005 if((bp = qget(edev->oq)) == nil)
1007 td = &ctlr->tdba[tdt];
1008 td->addr[0] = PCIWADDR(bp->rp);
1009 td->control = ((BLEN(bp) & LenMASK)<<LenSHIFT);
1010 td->control |= Dext|Ifcs|Teop|DtypeDD;
1012 tdt = NEXT(tdt, ctlr->ntd);
1013 if(NEXT(tdt, ctlr->ntd) == tdh){
1017 csr32w(ctlr, Tdt, tdt);
1022 csr32w(ctlr, Tdt, tdt);
1025 iunlock(&ctlr->tlock);
1029 igbereplenish(Ctlr* ctlr)
1036 while(NEXT(rdt, ctlr->nrd) != ctlr->rdh){
1037 rd = &ctlr->rdba[rdt];
1038 if(ctlr->rb[rdt] == nil){
1041 iprint("#l%d: igbereplenish: no available buffers\n",
1042 ctlr->edev->ctlrno);
1046 rd->addr[0] = PCIWADDR(bp->rp);
1051 rdt = NEXT(rdt, ctlr->nrd);
1055 csr32w(ctlr, Rdt, rdt);
1059 igberxinit(Ctlr* ctlr)
1064 /* temporarily keep Mpe on */
1065 csr32w(ctlr, Rctl, Dpf|Bsize2048|Bam|RdtmsHALF|Mpe);
1067 csr32w(ctlr, Rdbal, PCIWADDR(ctlr->rdba));
1068 csr32w(ctlr, Rdbah, 0);
1069 csr32w(ctlr, Rdlen, ctlr->nrd*sizeof(Rd));
1071 csr32w(ctlr, Rdh, 0);
1073 csr32w(ctlr, Rdt, 0);
1075 csr32w(ctlr, Rdtr, Fpd|0);
1077 for(i = 0; i < ctlr->nrd; i++){
1078 if((bp = ctlr->rb[i]) != nil){
1083 igbereplenish(ctlr);
1096 csr32w(ctlr, Radv, 64);
1099 csr32w(ctlr, Rxdctl, (8<<WthreshSHIFT)|(8<<HthreshSHIFT)|4);
1102 * Enable checksum offload.
1104 csr32w(ctlr, Rxcsum, Tuofl|Ipofl|(ETHERHDRSIZE<<PcssSHIFT));
1110 return ((Ctlr*)ctlr)->rim != 0;
1114 igberproc(void* arg)
1126 r = csr32r(ctlr, Rctl);
1128 csr32w(ctlr, Rctl, r);
1132 igbeim(ctlr, Rxt0|Rxo|Rxdmt0|Rxseq);
1134 sleep(&ctlr->rrendez, igberim, ctlr);
1138 rd = &ctlr->rdba[rdh];
1140 if(!(rd->status & Rdd))
1144 * Accept eop packets with no errors.
1145 * With no errors and the Ixsm bit set,
1146 * the descriptor status Tpcs and Ipcs bits give
1147 * an indication of whether the checksums were
1148 * calculated and valid.
1150 if((rd->status & Reop) && rd->errors == 0){
1152 ctlr->rb[rdh] = nil;
1153 bp->wp += rd->length;
1155 if(!(rd->status & Ixsm)){
1157 if(rd->status & Ipcs){
1159 * IP checksum calculated
1160 * (and valid as errors == 0).
1165 if(rd->status & Tcpcs){
1167 * TCP/UDP checksum calculated
1168 * (and valid as errors == 0).
1171 bp->flag |= Btcpck|Budpck;
1173 bp->checksum = rd->checksum;
1176 etheriq(edev, bp, 1);
1178 else if(ctlr->rb[rdh] != nil){
1179 freeb(ctlr->rb[rdh]);
1180 ctlr->rb[rdh] = nil;
1183 memset(rd, 0, sizeof(Rd));
1186 rdh = NEXT(rdh, ctlr->nrd);
1190 if(ctlr->rdfree < ctlr->nrd/2 || (ctlr->rim & Rxdmt0))
1191 igbereplenish(ctlr);
1196 igbeattach(Ether* edev)
1200 char name[KNAMELEN];
1203 ctlr->edev = edev; /* point back to Ether* */
1204 qlock(&ctlr->alock);
1205 if(ctlr->alloc != nil){ /* already allocated? */
1206 qunlock(&ctlr->alock);
1210 ctlr->nrd = ROUND(Nrd, 8);
1211 ctlr->ntd = ROUND(Ntd, 8);
1212 ctlr->alloc = malloc(ctlr->nrd*sizeof(Rd)+ctlr->ntd*sizeof(Td) + 127);
1213 if(ctlr->alloc == nil){
1214 print("igbe: can't allocate ctlr->alloc\n");
1215 qunlock(&ctlr->alock);
1218 ctlr->rdba = (Rd*)ROUNDUP((uintptr)ctlr->alloc, 128);
1219 ctlr->tdba = (Td*)(ctlr->rdba+ctlr->nrd);
1221 ctlr->rb = malloc(ctlr->nrd*sizeof(Block*));
1222 ctlr->tb = malloc(ctlr->ntd*sizeof(Block*));
1223 if (ctlr->rb == nil || ctlr->tb == nil) {
1224 print("igbe: can't allocate ctlr->rb or ctlr->tb\n");
1225 qunlock(&ctlr->alock);
1230 while(ctlr->nrb > 0){
1242 qunlock(&ctlr->alock);
1246 for(ctlr->nrb = 0; ctlr->nrb < Nrb; ctlr->nrb++){
1247 if((bp = allocb(Rbsz)) == nil)
1249 bp->free = igberbfree;
1253 snprint(name, KNAMELEN, "#l%dlproc", edev->ctlrno);
1254 kproc(name, igbelproc, edev);
1256 snprint(name, KNAMELEN, "#l%drproc", edev->ctlrno);
1257 kproc(name, igberproc, edev);
1261 qunlock(&ctlr->alock);
1266 igbeinterrupt(Ureg*, void* arg)
1275 ilock(&ctlr->imlock);
1276 csr32w(ctlr, Imc, ~0);
1280 while((icr = csr32r(ctlr, Icr) & ctlr->im) != 0){
1283 ctlr->lim = icr & Lsc;
1284 wakeup(&ctlr->lrendez);
1287 if(icr & (Rxt0|Rxo|Rxdmt0|Rxseq)){
1288 im &= ~(Rxt0|Rxo|Rxdmt0|Rxseq);
1289 ctlr->rim = icr & (Rxt0|Rxo|Rxdmt0|Rxseq);
1290 wakeup(&ctlr->rrendez);
1301 csr32w(ctlr, Ims, im);
1302 iunlock(&ctlr->imlock);
1309 i82543mdior(Ctlr* ctlr, int n)
1311 int ctrl, data, i, r;
1314 * Read n bits from the Management Data I/O Interface.
1316 ctrl = csr32r(ctlr, Ctrl);
1317 r = (ctrl & ~Mddo)|Mdco;
1319 for(i = n-1; i >= 0; i--){
1320 if(csr32r(ctlr, Ctrl) & Mdd)
1322 csr32w(ctlr, Ctrl, Mdc|r);
1323 csr32w(ctlr, Ctrl, r);
1325 csr32w(ctlr, Ctrl, ctrl);
1331 i82543mdiow(Ctlr* ctlr, int bits, int n)
1336 * Write n bits to the Management Data I/O Interface.
1338 ctrl = csr32r(ctlr, Ctrl);
1340 for(i = n-1; i >= 0; i--){
1345 csr32w(ctlr, Ctrl, Mdc|r);
1346 csr32w(ctlr, Ctrl, r);
1348 csr32w(ctlr, Ctrl, ctrl);
1354 i82543miimir(Mii* mii, int pa, int ra)
1362 * MII Management Interface Read.
1365 * ST+OP+PHYAD+REGAD;
1366 * TA + 16 data bits.
1368 i82543mdiow(ctlr, 0xFFFFFFFF, 32);
1369 i82543mdiow(ctlr, 0x1800|(pa<<5)|ra, 14);
1370 data = i82543mdior(ctlr, 18);
1375 return data & 0xFFFF;
1379 i82543miimiw(Mii* mii, int pa, int ra, int data)
1386 * MII Management Interface Write.
1389 * ST+OP+PHYAD+REGAD+TA + 16 data bits;
1392 i82543mdiow(ctlr, 0xFFFFFFFF, 32);
1394 data |= (0x05<<(5+5+2+16))|(pa<<(5+2+16))|(ra<<(2+16))|(0x02<<16);
1395 i82543mdiow(ctlr, data, 32);
1401 igbemiimir(Mii* mii, int pa, int ra)
1408 csr32w(ctlr, Mdic, MDIrop|(pa<<MDIpSHIFT)|(ra<<MDIrSHIFT));
1410 for(timo = 64; timo; timo--){
1411 mdic = csr32r(ctlr, Mdic);
1412 if(mdic & (MDIe|MDIready))
1417 if((mdic & (MDIe|MDIready)) == MDIready)
1418 return mdic & 0xFFFF;
1423 igbemiimiw(Mii* mii, int pa, int ra, int data)
1431 csr32w(ctlr, Mdic, MDIwop|(pa<<MDIpSHIFT)|(ra<<MDIrSHIFT)|data);
1433 for(timo = 64; timo; timo--){
1434 mdic = csr32r(ctlr, Mdic);
1435 if(mdic & (MDIe|MDIready))
1439 if((mdic & (MDIe|MDIready)) == MDIready)
1450 r = csr32r(ctlr, Status);
1453 if((ctlr->mii = malloc(sizeof(Mii))) == nil)
1455 ctlr->mii->ctlr = ctlr;
1457 ctrl = csr32r(ctlr, Ctrl);
1462 ctrl |= Frcdplx|Frcspd;
1463 csr32w(ctlr, Ctrl, ctrl);
1466 * The reset pin direction (Mdro) should already
1467 * be set from the EEPROM load.
1468 * If it's not set this configuration is unexpected
1471 r = csr32r(ctlr, Ctrlext);
1474 csr32w(ctlr, Ctrlext, r);
1476 r = csr32r(ctlr, Ctrlext);
1478 csr32w(ctlr, Ctrlext, r);
1480 r = csr32r(ctlr, Ctrlext);
1482 csr32w(ctlr, Ctrlext, r);
1485 ctlr->mii->mir = i82543miimir;
1486 ctlr->mii->miw = i82543miimiw;
1503 ctrl &= ~(Frcdplx|Frcspd);
1504 csr32w(ctlr, Ctrl, ctrl);
1505 ctlr->mii->mir = igbemiimir;
1506 ctlr->mii->miw = igbemiimiw;
1514 if(mii(ctlr->mii, ~0) == 0 || (phy = ctlr->mii->curphy) == nil){
1520 // print("oui %X phyno %d\n", phy->oui, phy->phyno);
1523 * 8254X-specific PHY registers not in 802.3:
1524 * 0x10 PHY specific control
1525 * 0x14 extended PHY specific control
1526 * Set appropriate values then reset the PHY to have
1540 r = miimir(ctlr->mii, 16);
1541 r |= 0x0800; /* assert CRS on Tx */
1542 r |= 0x0060; /* auto-crossover all speeds */
1543 r |= 0x0002; /* polarity reversal enabled */
1544 miimiw(ctlr->mii, 16, r);
1546 r = miimir(ctlr->mii, 20);
1547 r |= 0x0070; /* +25MHz clock */
1549 r |= 0x0100; /* 1x downshift */
1550 miimiw(ctlr->mii, 20, r);
1552 miireset(ctlr->mii);
1554 if(ctlr->txcw & TxcwPs)
1556 if(ctlr->txcw & TxcwAs)
1558 miiane(ctlr->mii, ~0, p, ~0);
1565 at93c46io(Ctlr* ctlr, char* op, int data)
1568 int i, loop, eecd, r;
1570 eecd = csr32r(ctlr, Eecd);
1575 for(p = op; *p != '\0'; p++){
1581 case ':': /* start of loop */
1582 loop = strtol(p+1, &lp, 0)-1;
1588 case ';': /* end of loop */
1597 case 'C': /* assert clock */
1600 case 'c': /* deassert clock */
1603 case 'D': /* next bit in 'data' byte */
1606 if(data & (1<<loop))
1611 case 'O': /* collect data output */
1612 i = (csr32r(ctlr, Eecd) & Do) != 0;
1618 case 'I': /* assert data input */
1621 case 'i': /* deassert data input */
1624 case 'S': /* enable chip select */
1627 case 's': /* disable chip select */
1631 csr32w(ctlr, Eecd, eecd);
1640 at93c46r(Ctlr* ctlr)
1644 int addr, areq, bits, data, eecd, i;
1646 eecd = csr32r(ctlr, Eecd);
1648 print("igbe: SPI EEPROM access not implemented\n");
1651 if(eecd & (Eeszaddr|Eesz256))
1675 csr32w(ctlr, Eecd, eecd|Areq);
1676 for(i = 0; i < 1000; i++){
1677 if((eecd = csr32r(ctlr, Eecd)) & Agnt)
1682 print("igbe: not granted EEPROM access\n");
1687 snprint(rop, sizeof(rop), "S :%dDCc;", bits+3);
1689 for(addr = 0; addr < 0x40; addr++){
1691 * Read a word at address 'addr' from the Atmel AT93C46
1692 * 3-Wire Serial EEPROM or compatible. The EEPROM access is
1693 * controlled by 4 bits in Eecd. See the AT93C46 datasheet
1694 * for protocol details.
1696 if(at93c46io(ctlr, rop, (0x06<<bits)|addr) != 0){
1697 print("igbe: can't set EEPROM address 0x%2.2X\n", addr);
1700 data = at93c46io(ctlr, ":16COc;", 0);
1701 at93c46io(ctlr, "sic", 0);
1702 ctlr->eeprom[addr] = data;
1708 csr32w(ctlr, Eecd, eecd & ~Areq);
1713 igbedetach(Ctlr* ctlr)
1718 * Perform a device reset to get the chip back to the
1719 * power-on state, followed by an EEPROM reset to read
1720 * the defaults for some internal registers.
1722 csr32w(ctlr, Imc, ~0);
1723 csr32w(ctlr, Rctl, 0);
1724 csr32w(ctlr, Tctl, 0);
1728 csr32w(ctlr, Ctrl, Devrst);
1730 for(timeo = 0; timeo < 1000; timeo++){
1731 if(!(csr32r(ctlr, Ctrl) & Devrst))
1735 if(csr32r(ctlr, Ctrl) & Devrst)
1737 r = csr32r(ctlr, Ctrlext);
1738 csr32w(ctlr, Ctrlext, r|Eerst);
1740 for(timeo = 0; timeo < 1000; timeo++){
1741 if(!(csr32r(ctlr, Ctrlext) & Eerst))
1745 if(csr32r(ctlr, Ctrlext) & Eerst)
1761 r = csr32r(ctlr, Manc);
1763 csr32w(ctlr, Manc, r);
1767 csr32w(ctlr, Imc, ~0);
1769 for(timeo = 0; timeo < 1000; timeo++){
1770 if(!csr32r(ctlr, Icr))
1774 if(csr32r(ctlr, Icr))
1781 igbeshutdown(Ether* ether)
1783 igbedetach(ether->ctlr);
1787 igbereset(Ctlr* ctlr)
1789 int ctrl, i, pause, r, swdpio, txcw;
1791 if(igbedetach(ctlr))
1795 * Read the EEPROM, validate the checksum
1796 * then get the device back to a power-on state.
1798 if((r = at93c46r(ctlr)) != 0xBABA){
1799 print("igbe: bad EEPROM checksum - 0x%4.4uX\n", r);
1804 * Snarf and set up the receive addresses.
1805 * There are 16 addresses. The first should be the MAC address.
1806 * The others are cleared and not marked valid (MS bit of Rah).
1808 if ((ctlr->id == i82546gb || ctlr->id == i82546eb) &&
1809 BUSFNO(ctlr->pcidev->tbdf) == 1)
1810 ctlr->eeprom[Ea+2] += 0x100; /* second interface */
1811 if(ctlr->id == i82541gi && ctlr->eeprom[Ea] == 0xFFFF)
1812 ctlr->eeprom[Ea] = 0xD000;
1813 for(i = Ea; i < Eaddrlen/2; i++){
1814 ctlr->ra[2*i] = ctlr->eeprom[i];
1815 ctlr->ra[2*i+1] = ctlr->eeprom[i]>>8;
1817 /* lan id seems to vary on 82543gc; don't use it */
1818 if (ctlr->id != i82543gc) {
1819 r = (csr32r(ctlr, Status) & Lanid) >> 2;
1820 ctlr->ra[5] += r; /* ea ctlr[1] = ea ctlr[0]+1 */
1823 r = (ctlr->ra[3]<<24)|(ctlr->ra[2]<<16)|(ctlr->ra[1]<<8)|ctlr->ra[0];
1824 csr32w(ctlr, Ral, r);
1825 r = 0x80000000|(ctlr->ra[5]<<8)|ctlr->ra[4];
1826 csr32w(ctlr, Rah, r);
1827 for(i = 1; i < 16; i++){
1828 csr32w(ctlr, Ral+i*8, 0);
1829 csr32w(ctlr, Rah+i*8, 0);
1833 * Clear the Multicast Table Array.
1834 * It's a 4096 bit vector accessed as 128 32-bit registers.
1836 memset(ctlr->mta, 0, sizeof(ctlr->mta));
1837 for(i = 0; i < 128; i++)
1838 csr32w(ctlr, Mta+i*4, 0);
1841 * Just in case the Eerst didn't load the defaults
1842 * (doesn't appear to fully on the 82543GC), do it manually.
1844 if (ctlr->id == i82543gc) {
1845 txcw = csr32r(ctlr, Txcw);
1846 txcw &= ~(TxcwAne|TxcwPauseMASK|TxcwFd);
1847 ctrl = csr32r(ctlr, Ctrl);
1848 ctrl &= ~(SwdpioloMASK|Frcspd|Ilos|Lrst|Fd);
1850 if(ctlr->eeprom[Icw1] & 0x0400){
1854 if(ctlr->eeprom[Icw1] & 0x0200)
1856 if(ctlr->eeprom[Icw1] & 0x0010)
1858 if(ctlr->eeprom[Icw1] & 0x0800)
1860 swdpio = (ctlr->eeprom[Icw1] & 0x01E0)>>5;
1861 ctrl |= swdpio<<SwdpioloSHIFT;
1862 csr32w(ctlr, Ctrl, ctrl);
1864 ctrl = csr32r(ctlr, Ctrlext);
1865 ctrl &= ~(Ips|SwdpiohiMASK);
1866 swdpio = (ctlr->eeprom[Icw2] & 0x00F0)>>4;
1867 if(ctlr->eeprom[Icw1] & 0x1000)
1869 ctrl |= swdpio<<SwdpiohiSHIFT;
1870 csr32w(ctlr, Ctrlext, ctrl);
1872 if(ctlr->eeprom[Icw2] & 0x0800)
1874 pause = (ctlr->eeprom[Icw2] & 0x3000)>>12;
1875 txcw |= pause<<TxcwPauseSHIFT;
1878 ctlr->fcrtl = 0x00002000;
1879 ctlr->fcrth = 0x00004000;
1880 txcw |= TxcwAs|TxcwPs;
1883 ctlr->fcrtl = 0x00002000;
1884 ctlr->fcrth = 0x00004000;
1893 csr32w(ctlr, Txcw, txcw);
1898 * Flow control - values from the datasheet.
1900 csr32w(ctlr, Fcal, 0x00C28001);
1901 csr32w(ctlr, Fcah, 0x00000100);
1902 csr32w(ctlr, Fct, 0x00008808);
1903 csr32w(ctlr, Fcttv, 0x00000100);
1905 csr32w(ctlr, Fcrtl, ctlr->fcrtl);
1906 csr32w(ctlr, Fcrth, ctlr->fcrth);
1908 if(!(csr32r(ctlr, Status) & Tbimode) && igbemii(ctlr) < 0)
1923 while(p = pcimatch(p, 0, 0)){
1924 if(p->ccrb != 0x02 || p->ccru != 0)
1927 switch((p->did<<16)|p->vid){
1949 mem = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
1951 print("igbe: can't map %8.8luX\n", p->mem[0].bar);
1954 cls = pcicfgr8(p, PciCLS);
1957 print("igbe: unexpected CLS - %d\n", cls*4);
1961 print("igbe: unusable CLS - %d\n", cls*4);
1967 ctlr = malloc(sizeof(Ctlr));
1968 ctlr->port = p->mem[0].bar & ~0x0F;
1970 ctlr->id = (p->did<<16)|p->vid;
1974 if(igbereset(ctlr)){
1976 vunmap(mem, p->mem[0].size);
1981 if(igbectlrhead != nil)
1982 igbectlrtail->next = ctlr;
1984 igbectlrhead = ctlr;
1985 igbectlrtail = ctlr;
1990 igbepnp(Ether* edev)
1994 if(igbectlrhead == nil)
1998 * Any adapter matches if no edev->port is supplied,
1999 * otherwise the ports must match.
2001 for(ctlr = igbectlrhead; ctlr != nil; ctlr = ctlr->next){
2004 if(edev->port == 0 || edev->port == ctlr->port){
2013 edev->port = ctlr->port;
2014 edev->irq = ctlr->pcidev->intl;
2015 edev->tbdf = ctlr->pcidev->tbdf;
2017 memmove(edev->ea, ctlr->ra, Eaddrlen);
2020 * Linkage to the generic ethernet driver.
2022 edev->attach = igbeattach;
2023 edev->transmit = igbetransmit;
2024 edev->interrupt = igbeinterrupt;
2025 edev->ifstat = igbeifstat;
2026 edev->ctl = igbectl;
2029 edev->promiscuous = igbepromiscuous;
2030 edev->shutdown = igbeshutdown;
2031 edev->multicast = igbemulticast;
2039 addethercard("i82543", igbepnp);
2040 addethercard("igbe", igbepnp);