]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/etherigbe.c
kernel: cleanup makefile for $CONF.$O target
[plan9front.git] / sys / src / 9 / pc / etherigbe.c
1 /*
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
7  *      82541[GP]I
8  *      82547GI
9  *      82546GB
10  *      82546EB
11  * To Do:
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.
18  */
19 #include "u.h"
20 #include "../port/lib.h"
21 #include "mem.h"
22 #include "dat.h"
23 #include "fns.h"
24 #include "io.h"
25 #include "../port/error.h"
26 #include "../port/netif.h"
27 #include "../port/etherif.h"
28 #include "../port/ethermii.h"
29
30 enum {
31         i82542          = (0x1000<<16)|0x8086,
32         i82543gc        = (0x1004<<16)|0x8086,
33         i82544ei        = (0x1008<<16)|0x8086,
34         i82544eif       = (0x1009<<16)|0x8086,
35         i82544gc        = (0x100d<<16)|0x8086,
36         i82540em        = (0x100E<<16)|0x8086,
37         i82540eplp      = (0x101E<<16)|0x8086,
38         i82545em        = (0x100F<<16)|0x8086,
39         i82545gmc       = (0x1026<<16)|0x8086,
40         i82547ei        = (0x1019<<16)|0x8086,
41         i82547gi        = (0x1075<<16)|0x8086,
42         i82541ei        = (0x1013<<16)|0x8086,
43         i82541gi        = (0x1076<<16)|0x8086,
44         i82541gi2       = (0x1077<<16)|0x8086,
45         i82541pi        = (0x107c<<16)|0x8086,
46         i82546gb        = (0x1079<<16)|0x8086,
47         i82546eb        = (0x1010<<16)|0x8086,
48 };
49
50 enum {
51         Ctrl            = 0x00000000,   /* Device Control */
52         Ctrldup         = 0x00000004,   /* Device Control Duplicate */
53         Status          = 0x00000008,   /* Device Status */
54         Eecd            = 0x00000010,   /* EEPROM/Flash Control/Data */
55         Ctrlext         = 0x00000018,   /* Extended Device Control */
56         Mdic            = 0x00000020,   /* MDI Control */
57         Fcal            = 0x00000028,   /* Flow Control Address Low */
58         Fcah            = 0x0000002C,   /* Flow Control Address High */
59         Fct             = 0x00000030,   /* Flow Control Type */
60         Icr             = 0x000000C0,   /* Interrupt Cause Read */
61         Ics             = 0x000000C8,   /* Interrupt Cause Set */
62         Ims             = 0x000000D0,   /* Interrupt Mask Set/Read */
63         Imc             = 0x000000D8,   /* Interrupt mask Clear */
64         Rctl            = 0x00000100,   /* Receive Control */
65         Fcttv           = 0x00000170,   /* Flow Control Transmit Timer Value */
66         Txcw            = 0x00000178,   /* Transmit Configuration Word */
67         Rxcw            = 0x00000180,   /* Receive Configuration Word */
68         /* on the oldest cards (8254[23]), the Mta register is at 0x200 */
69         Tctl            = 0x00000400,   /* Transmit Control */
70         Tipg            = 0x00000410,   /* Transmit IPG */
71         Tbt             = 0x00000448,   /* Transmit Burst Timer */
72         Ait             = 0x00000458,   /* Adaptive IFS Throttle */
73         Fcrtl           = 0x00002160,   /* Flow Control RX Threshold Low */
74         Fcrth           = 0x00002168,   /* Flow Control Rx Threshold High */
75         Rdfh            = 0x00002410,   /* Receive data fifo head */
76         Rdft            = 0x00002418,   /* Receive data fifo tail */
77         Rdfhs           = 0x00002420,   /* Receive data fifo head saved */
78         Rdfts           = 0x00002428,   /* Receive data fifo tail saved */
79         Rdfpc           = 0x00002430,   /* Receive data fifo packet count */
80         Rdbal           = 0x00002800,   /* Rd Base Address Low */
81         Rdbah           = 0x00002804,   /* Rd Base Address High */
82         Rdlen           = 0x00002808,   /* Receive Descriptor Length */
83         Rdh             = 0x00002810,   /* Receive Descriptor Head */
84         Rdt             = 0x00002818,   /* Receive Descriptor Tail */
85         Rdtr            = 0x00002820,   /* Receive Descriptor Timer Ring */
86         Rxdctl          = 0x00002828,   /* Receive Descriptor Control */
87         Radv            = 0x0000282C,   /* Receive Interrupt Absolute Delay Timer */
88         Txdmac          = 0x00003000,   /* Transfer DMA Control */
89         Ett             = 0x00003008,   /* Early Transmit Control */
90         Tdfh            = 0x00003410,   /* Transmit data fifo head */
91         Tdft            = 0x00003418,   /* Transmit data fifo tail */
92         Tdfhs           = 0x00003420,   /* Transmit data Fifo Head saved */
93         Tdfts           = 0x00003428,   /* Transmit data fifo tail saved */
94         Tdfpc           = 0x00003430,   /* Trasnmit data Fifo packet count */
95         Tdbal           = 0x00003800,   /* Td Base Address Low */
96         Tdbah           = 0x00003804,   /* Td Base Address High */
97         Tdlen           = 0x00003808,   /* Transmit Descriptor Length */
98         Tdh             = 0x00003810,   /* Transmit Descriptor Head */
99         Tdt             = 0x00003818,   /* Transmit Descriptor Tail */
100         Tidv            = 0x00003820,   /* Transmit Interrupt Delay Value */
101         Txdctl          = 0x00003828,   /* Transmit Descriptor Control */
102         Tadv            = 0x0000382C,   /* Transmit Interrupt Absolute Delay Timer */
103
104         Statistics      = 0x00004000,   /* Start of Statistics Area */
105         Gorcl           = 0x88/4,       /* Good Octets Received Count */
106         Gotcl           = 0x90/4,       /* Good Octets Transmitted Count */
107         Torl            = 0xC0/4,       /* Total Octets Received */
108         Totl            = 0xC8/4,       /* Total Octets Transmitted */
109         Nstatistics     = 64,
110
111         Rxcsum          = 0x00005000,   /* Receive Checksum Control */
112         Mta             = 0x00005200,   /* Multicast Table Array */
113         Ral             = 0x00005400,   /* Receive Address Low */
114         Rah             = 0x00005404,   /* Receive Address High */
115         Manc            = 0x00005820,   /* Management Control */
116 };
117
118 enum {                                  /* Ctrl */
119         Bem             = 0x00000002,   /* Big Endian Mode */
120         Prior           = 0x00000004,   /* Priority on the PCI bus */
121         Lrst            = 0x00000008,   /* Link Reset */
122         Asde            = 0x00000020,   /* Auto-Speed Detection Enable */
123         Slu             = 0x00000040,   /* Set Link Up */
124         Ilos            = 0x00000080,   /* Invert Loss of Signal (LOS) */
125         SspeedMASK      = 0x00000300,   /* Speed Selection */
126         SspeedSHIFT     = 8,
127         Sspeed10        = 0x00000000,   /* 10Mb/s */
128         Sspeed100       = 0x00000100,   /* 100Mb/s */
129         Sspeed1000      = 0x00000200,   /* 1000Mb/s */
130         Frcspd          = 0x00000800,   /* Force Speed */
131         Frcdplx         = 0x00001000,   /* Force Duplex */
132         SwdpinsloMASK   = 0x003C0000,   /* Software Defined Pins - lo nibble */
133         SwdpinsloSHIFT  = 18,
134         SwdpioloMASK    = 0x03C00000,   /* Software Defined Pins - I or O */
135         SwdpioloSHIFT   = 22,
136         Devrst          = 0x04000000,   /* Device Reset */
137         Rfce            = 0x08000000,   /* Receive Flow Control Enable */
138         Tfce            = 0x10000000,   /* Transmit Flow Control Enable */
139         Vme             = 0x40000000,   /* VLAN Mode Enable */
140 };
141
142 /*
143  * can't find Tckok nor Rbcok in any Intel docs,
144  * but even 82543gc docs define Lanid.
145  */
146 enum {                                  /* Status */
147         Lu              = 0x00000002,   /* Link Up */
148         Lanid           = 0x0000000C,   /* mask for Lan ID. (function id) */
149 //      Tckok           = 0x00000004,   /* Transmit clock is running */
150 //      Rbcok           = 0x00000008,   /* Receive clock is running */
151         Txoff           = 0x00000010,   /* Transmission Paused */
152         Tbimode         = 0x00000020,   /* TBI Mode Indication */
153         LspeedMASK      = 0x000000C0,   /* Link Speed Setting */
154         LspeedSHIFT     = 6,
155         Lspeed10        = 0x00000000,   /* 10Mb/s */
156         Lspeed100       = 0x00000040,   /* 100Mb/s */
157         Lspeed1000      = 0x00000080,   /* 1000Mb/s */
158         Mtxckok         = 0x00000400,   /* MTX clock is running */
159         Pci66           = 0x00000800,   /* PCI Bus speed indication */
160         Bus64           = 0x00001000,   /* PCI Bus width indication */
161         Pcixmode        = 0x00002000,   /* PCI-X mode */
162         PcixspeedMASK   = 0x0000C000,   /* PCI-X bus speed */
163         PcixspeedSHIFT  = 14,
164         Pcix66          = 0x00000000,   /* 50-66MHz */
165         Pcix100         = 0x00004000,   /* 66-100MHz */
166         Pcix133         = 0x00008000,   /* 100-133MHz */
167 };
168
169 enum {                                  /* Ctrl and Status */
170         Fd              = 0x00000001,   /* Full-Duplex */
171         AsdvMASK        = 0x00000300,
172         AsdvSHIFT       = 8,
173         Asdv10          = 0x00000000,   /* 10Mb/s */
174         Asdv100         = 0x00000100,   /* 100Mb/s */
175         Asdv1000        = 0x00000200,   /* 1000Mb/s */
176 };
177
178 enum {                                  /* Eecd */
179         Sk              = 0x00000001,   /* Clock input to the EEPROM */
180         Cs              = 0x00000002,   /* Chip Select */
181         Di              = 0x00000004,   /* Data Input to the EEPROM */
182         Do              = 0x00000008,   /* Data Output from the EEPROM */
183         Areq            = 0x00000040,   /* EEPROM Access Request */
184         Agnt            = 0x00000080,   /* EEPROM Access Grant */
185         Eepresent       = 0x00000100,   /* EEPROM Present */
186         Eesz256         = 0x00000200,   /* EEPROM is 256 words not 64 */
187         Eeszaddr        = 0x00000400,   /* EEPROM size for 8254[17] */
188         Spi             = 0x00002000,   /* EEPROM is SPI not Microwire */
189 };
190
191 enum {                                  /* Ctrlext */
192         Gpien           = 0x0000000F,   /* General Purpose Interrupt Enables */
193         SwdpinshiMASK   = 0x000000F0,   /* Software Defined Pins - hi nibble */
194         SwdpinshiSHIFT  = 4,
195         SwdpiohiMASK    = 0x00000F00,   /* Software Defined Pins - I or O */
196         SwdpiohiSHIFT   = 8,
197         Asdchk          = 0x00001000,   /* ASD Check */
198         Eerst           = 0x00002000,   /* EEPROM Reset */
199         Ips             = 0x00004000,   /* Invert Power State */
200         Spdbyps         = 0x00008000,   /* Speed Select Bypass */
201 };
202
203 enum {                                  /* EEPROM content offsets */
204         Ea              = 0x00,         /* Ethernet Address */
205         Cf              = 0x03,         /* Compatibility Field */
206         Pba             = 0x08,         /* Printed Board Assembly number */
207         Icw1            = 0x0A,         /* Initialization Control Word 1 */
208         Sid             = 0x0B,         /* Subsystem ID */
209         Svid            = 0x0C,         /* Subsystem Vendor ID */
210         Did             = 0x0D,         /* Device ID */
211         Vid             = 0x0E,         /* Vendor ID */
212         Icw2            = 0x0F,         /* Initialization Control Word 2 */
213 };
214
215 enum {                                  /* Mdic */
216         MDIdMASK        = 0x0000FFFF,   /* Data */
217         MDIdSHIFT       = 0,
218         MDIrMASK        = 0x001F0000,   /* PHY Register Address */
219         MDIrSHIFT       = 16,
220         MDIpMASK        = 0x03E00000,   /* PHY Address */
221         MDIpSHIFT       = 21,
222         MDIwop          = 0x04000000,   /* Write Operation */
223         MDIrop          = 0x08000000,   /* Read Operation */
224         MDIready        = 0x10000000,   /* End of Transaction */
225         MDIie           = 0x20000000,   /* Interrupt Enable */
226         MDIe            = 0x40000000,   /* Error */
227 };
228
229 enum {                                  /* Icr, Ics, Ims, Imc */
230         Txdw            = 0x00000001,   /* Transmit Descriptor Written Back */
231         Txqe            = 0x00000002,   /* Transmit Queue Empty */
232         Lsc             = 0x00000004,   /* Link Status Change */
233         Rxseq           = 0x00000008,   /* Receive Sequence Error */
234         Rxdmt0          = 0x00000010,   /* Rd Minimum Threshold Reached */
235         Rxo             = 0x00000040,   /* Receiver Overrun */
236         Rxt0            = 0x00000080,   /* Receiver Timer Interrupt */
237         Mdac            = 0x00000200,   /* MDIO Access Completed */
238         Rxcfg           = 0x00000400,   /* Receiving /C/ ordered sets */
239         Gpi0            = 0x00000800,   /* General Purpose Interrupts */
240         Gpi1            = 0x00001000,
241         Gpi2            = 0x00002000,
242         Gpi3            = 0x00004000,
243 };
244
245 /*
246  * The Mdic register isn't implemented on the 82543GC,
247  * the software defined pins are used instead.
248  * These definitions work for the Intel PRO/1000 T Server Adapter.
249  * The direction pin bits are read from the EEPROM.
250  */
251 enum {
252         Mdd             = ((1<<2)<<SwdpinsloSHIFT),     /* data */
253         Mddo            = ((1<<2)<<SwdpioloSHIFT),      /* pin direction */
254         Mdc             = ((1<<3)<<SwdpinsloSHIFT),     /* clock */
255         Mdco            = ((1<<3)<<SwdpioloSHIFT),      /* pin direction */
256         Mdr             = ((1<<0)<<SwdpinshiSHIFT),     /* reset */
257         Mdro            = ((1<<0)<<SwdpiohiSHIFT),      /* pin direction */
258 };
259
260 enum {                                  /* Txcw */
261         TxcwFd          = 0x00000020,   /* Full Duplex */
262         TxcwHd          = 0x00000040,   /* Half Duplex */
263         TxcwPauseMASK   = 0x00000180,   /* Pause */
264         TxcwPauseSHIFT  = 7,
265         TxcwPs          = (1<<TxcwPauseSHIFT),  /* Pause Supported */
266         TxcwAs          = (2<<TxcwPauseSHIFT),  /* Asymmetric FC desired */
267         TxcwRfiMASK     = 0x00003000,   /* Remote Fault Indication */
268         TxcwRfiSHIFT    = 12,
269         TxcwNpr         = 0x00008000,   /* Next Page Request */
270         TxcwConfig      = 0x40000000,   /* Transmit COnfig Control */
271         TxcwAne         = 0x80000000,   /* Auto-Negotiation Enable */
272 };
273
274 enum {                                  /* Rxcw */
275         Rxword          = 0x0000FFFF,   /* Data from auto-negotiation process */
276         Rxnocarrier     = 0x04000000,   /* Carrier Sense indication */
277         Rxinvalid       = 0x08000000,   /* Invalid Symbol during configuration */
278         Rxchange        = 0x10000000,   /* Change to the Rxword indication */
279         Rxconfig        = 0x20000000,   /* /C/ order set reception indication */
280         Rxsync          = 0x40000000,   /* Lost bit synchronization indication */
281         Anc             = 0x80000000,   /* Auto Negotiation Complete */
282 };
283
284 enum {                                  /* Rctl */
285         Rrst            = 0x00000001,   /* Receiver Software Reset */
286         Ren             = 0x00000002,   /* Receiver Enable */
287         Sbp             = 0x00000004,   /* Store Bad Packets */
288         Upe             = 0x00000008,   /* Unicast Promiscuous Enable */
289         Mpe             = 0x00000010,   /* Multicast Promiscuous Enable */
290         Lpe             = 0x00000020,   /* Long Packet Reception Enable */
291         LbmMASK         = 0x000000C0,   /* Loopback Mode */
292         LbmOFF          = 0x00000000,   /* No Loopback */
293         LbmTBI          = 0x00000040,   /* TBI Loopback */
294         LbmMII          = 0x00000080,   /* GMII/MII Loopback */
295         LbmXCVR         = 0x000000C0,   /* Transceiver Loopback */
296         RdtmsMASK       = 0x00000300,   /* Rd Minimum Threshold Size */
297         RdtmsHALF       = 0x00000000,   /* Threshold is 1/2 Rdlen */
298         RdtmsQUARTER    = 0x00000100,   /* Threshold is 1/4 Rdlen */
299         RdtmsEIGHTH     = 0x00000200,   /* Threshold is 1/8 Rdlen */
300         MoMASK          = 0x00003000,   /* Multicast Offset */
301         Mo47b36         = 0x00000000,   /* bits [47:36] of received address */
302         Mo46b35         = 0x00001000,   /* bits [46:35] of received address */
303         Mo45b34         = 0x00002000,   /* bits [45:34] of received address */
304         Mo43b32         = 0x00003000,   /* bits [43:32] of received address */
305         Bam             = 0x00008000,   /* Broadcast Accept Mode */
306         BsizeMASK       = 0x00030000,   /* Receive Buffer Size */
307         Bsize2048       = 0x00000000,   /* Bsex = 0 */
308         Bsize1024       = 0x00010000,   /* Bsex = 0 */
309         Bsize512        = 0x00020000,   /* Bsex = 0 */
310         Bsize256        = 0x00030000,   /* Bsex = 0 */
311         Bsize16384      = 0x00010000,   /* Bsex = 1 */
312         Vfe             = 0x00040000,   /* VLAN Filter Enable */
313         Cfien           = 0x00080000,   /* Canonical Form Indicator Enable */
314         Cfi             = 0x00100000,   /* Canonical Form Indicator value */
315         Dpf             = 0x00400000,   /* Discard Pause Frames */
316         Pmcf            = 0x00800000,   /* Pass MAC Control Frames */
317         Bsex            = 0x02000000,   /* Buffer Size Extension */
318         Secrc           = 0x04000000,   /* Strip CRC from incoming packet */
319 };
320
321 enum {                                  /* Tctl */
322         Trst            = 0x00000001,   /* Transmitter Software Reset */
323         Ten             = 0x00000002,   /* Transmit Enable */
324         Psp             = 0x00000008,   /* Pad Short Packets */
325         CtMASK          = 0x00000FF0,   /* Collision Threshold */
326         CtSHIFT         = 4,
327         ColdMASK        = 0x003FF000,   /* Collision Distance */
328         ColdSHIFT       = 12,
329         Swxoff          = 0x00400000,   /* Sofware XOFF Transmission */
330         Pbe             = 0x00800000,   /* Packet Burst Enable */
331         Rtlc            = 0x01000000,   /* Re-transmit on Late Collision */
332         Nrtu            = 0x02000000,   /* No Re-transmit on Underrrun */
333 };
334
335 enum {                                  /* [RT]xdctl */
336         PthreshMASK     = 0x0000003F,   /* Prefetch Threshold */
337         PthreshSHIFT    = 0,
338         HthreshMASK     = 0x00003F00,   /* Host Threshold */
339         HthreshSHIFT    = 8,
340         WthreshMASK     = 0x003F0000,   /* Writeback Threshold */
341         WthreshSHIFT    = 16,
342         Gran            = 0x01000000,   /* Granularity */
343         LthreshMASK     = 0xFE000000,   /* Low Threshold */
344         LthreshSHIFT    = 25,
345 };
346
347 enum {                                  /* Rxcsum */
348         PcssMASK        = 0x000000FF,   /* Packet Checksum Start */
349         PcssSHIFT       = 0,
350         Ipofl           = 0x00000100,   /* IP Checksum Off-load Enable */
351         Tuofl           = 0x00000200,   /* TCP/UDP Checksum Off-load Enable */
352 };
353
354 enum {                                  /* Manc */
355         Arpen           = 0x00002000,   /* Enable ARP Request Filtering */
356 };
357
358 enum {                                  /* Receive Delay Timer Ring */
359         DelayMASK       = 0x0000FFFF,   /* delay timer in 1.024nS increments */
360         DelaySHIFT      = 0,
361         Fpd             = 0x80000000,   /* Flush partial Descriptor Block */
362 };
363
364 typedef struct Rd {                     /* Receive Descriptor */
365         uint    addr[2];
366         ushort  length;
367         ushort  checksum;
368         uchar   status;
369         uchar   errors;
370         ushort  special;
371 } Rd;
372
373 enum {                                  /* Rd status */
374         Rdd             = 0x01,         /* Descriptor Done */
375         Reop            = 0x02,         /* End of Packet */
376         Ixsm            = 0x04,         /* Ignore Checksum Indication */
377         Vp              = 0x08,         /* Packet is 802.1Q (matched VET) */
378         Tcpcs           = 0x20,         /* TCP Checksum Calculated on Packet */
379         Ipcs            = 0x40,         /* IP Checksum Calculated on Packet */
380         Pif             = 0x80,         /* Passed in-exact filter */
381 };
382
383 enum {                                  /* Rd errors */
384         Ce              = 0x01,         /* CRC Error or Alignment Error */
385         Se              = 0x02,         /* Symbol Error */
386         Seq             = 0x04,         /* Sequence Error */
387         Cxe             = 0x10,         /* Carrier Extension Error */
388         Tcpe            = 0x20,         /* TCP/UDP Checksum Error */
389         Ipe             = 0x40,         /* IP Checksum Error */
390         Rxe             = 0x80,         /* RX Data Error */
391 };
392
393 typedef struct Td Td;
394 struct Td {                             /* Transmit Descriptor */
395         union {
396                 uint    addr[2];        /* Data */
397                 struct {                /* Context */
398                         uchar   ipcss;
399                         uchar   ipcso;
400                         ushort  ipcse;
401                         uchar   tucss;
402                         uchar   tucso;
403                         ushort  tucse;
404                 };
405         };
406         uint    control;
407         uint    status;
408 };
409
410 enum {                                  /* Td control */
411         LenMASK         = 0x000FFFFF,   /* Data/Packet Length Field */
412         LenSHIFT        = 0,
413         DtypeCD         = 0x00000000,   /* Data Type 'Context Descriptor' */
414         DtypeDD         = 0x00100000,   /* Data Type 'Data Descriptor' */
415         PtypeTCP        = 0x01000000,   /* TCP/UDP Packet Type (CD) */
416         Teop            = 0x01000000,   /* End of Packet (DD) */
417         PtypeIP         = 0x02000000,   /* IP Packet Type (CD) */
418         Ifcs            = 0x02000000,   /* Insert FCS (DD) */
419         Tse             = 0x04000000,   /* TCP Segmentation Enable */
420         Rs              = 0x08000000,   /* Report Status */
421         Rps             = 0x10000000,   /* Report Status Sent */
422         Dext            = 0x20000000,   /* Descriptor Extension */
423         Vle             = 0x40000000,   /* VLAN Packet Enable */
424         Ide             = 0x80000000,   /* Interrupt Delay Enable */
425 };
426
427 enum {                                  /* Td status */
428         Tdd             = 0x00000001,   /* Descriptor Done */
429         Ec              = 0x00000002,   /* Excess Collisions */
430         Lc              = 0x00000004,   /* Late Collision */
431         Tu              = 0x00000008,   /* Transmit Underrun */
432         Iixsm           = 0x00000100,   /* Insert IP Checksum */
433         Itxsm           = 0x00000200,   /* Insert TCP/UDP Checksum */
434         HdrlenMASK      = 0x0000FF00,   /* Header Length (Tse) */
435         HdrlenSHIFT     = 8,
436         VlanMASK        = 0x0FFF0000,   /* VLAN Identifier */
437         VlanSHIFT       = 16,
438         Tcfi            = 0x10000000,   /* Canonical Form Indicator */
439         PriMASK         = 0xE0000000,   /* User Priority */
440         PriSHIFT        = 29,
441         MssMASK         = 0xFFFF0000,   /* Maximum Segment Size (Tse) */
442         MssSHIFT        = 16,
443 };
444
445 enum {
446         Nrd             = 256,          /* multiple of 8 */
447         Ntd             = 64,           /* multiple of 8 */
448         Nrb             = 1024,         /* private receive buffers per Ctlr */
449         Rbsz            = 2048,
450 };
451
452 typedef struct Ctlr Ctlr;
453 typedef struct Ctlr {
454         int     port;
455         Pcidev* pcidev;
456         Ctlr*   next;
457         Ether*  edev;
458         int     active;
459         int     started;
460         int     id;
461         int     cls;
462         ushort  eeprom[0x40];
463
464         QLock   alock;                  /* attach */
465         void*   alloc;                  /* receive/transmit descriptors */
466         int     nrd;
467         int     ntd;
468
469         int*    nic;
470         Lock    imlock;
471         int     im;                     /* interrupt mask */
472
473         Mii*    mii;
474         Rendez  lrendez;
475         int     lim;
476
477         int     link;
478
479         QLock   slock;
480         uint    statistics[Nstatistics];
481         uint    lsleep;
482         uint    lintr;
483         uint    rsleep;
484         uint    rintr;
485         uint    txdw;
486         uint    tintr;
487         uint    ixsm;
488         uint    ipcs;
489         uint    tcpcs;
490
491         uchar   ra[Eaddrlen];           /* receive address */
492         ulong   mta[128];               /* multicast table array */
493
494         Rendez  rrendez;
495         int     rim;
496         int     rdfree;
497         Rd*     rdba;                   /* receive descriptor base address */
498         Block** rb;                     /* receive buffers */
499         int     rdh;                    /* receive descriptor head */
500         int     rdt;                    /* receive descriptor tail */
501         int     rdtr;                   /* receive delay timer ring value */
502
503         Lock    tlock;
504         int     tbusy;
505         int     tdfree;
506         Td*     tdba;                   /* transmit descriptor base address */
507         Block** tb;                     /* transmit buffers */
508         int     tdh;                    /* transmit descriptor head */
509         int     tdt;                    /* transmit descriptor tail */
510
511         int     txcw;
512         int     fcrtl;
513         int     fcrth;
514 } Ctlr;
515
516 #define csr32r(c, r)    (*((c)->nic+((r)/4)))
517 #define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
518
519 static Ctlr* igbectlrhead;
520 static Ctlr* igbectlrtail;
521
522 static char* statistics[Nstatistics] = {
523         "CRC Error",
524         "Alignment Error",
525         "Symbol Error",
526         "RX Error",
527         "Missed Packets",
528         "Single Collision",
529         "Excessive Collisions",
530         "Multiple Collision",
531         "Late Collisions",
532         nil,
533         "Collision",
534         "Transmit Underrun",
535         "Defer",
536         "Transmit - No CRS",
537         "Sequence Error",
538         "Carrier Extension Error",
539         "Receive Error Length",
540         nil,
541         "XON Received",
542         "XON Transmitted",
543         "XOFF Received",
544         "XOFF Transmitted",
545         "FC Received Unsupported",
546         "Packets Received (64 Bytes)",
547         "Packets Received (65-127 Bytes)",
548         "Packets Received (128-255 Bytes)",
549         "Packets Received (256-511 Bytes)",
550         "Packets Received (512-1023 Bytes)",
551         "Packets Received (1024-1522 Bytes)",
552         "Good Packets Received",
553         "Broadcast Packets Received",
554         "Multicast Packets Received",
555         "Good Packets Transmitted",
556         nil,
557         "Good Octets Received",
558         nil,
559         "Good Octets Transmitted",
560         nil,
561         nil,
562         nil,
563         "Receive No Buffers",
564         "Receive Undersize",
565         "Receive Fragment",
566         "Receive Oversize",
567         "Receive Jabber",
568         nil,
569         nil,
570         nil,
571         "Total Octets Received",
572         nil,
573         "Total Octets Transmitted",
574         nil,
575         "Total Packets Received",
576         "Total Packets Transmitted",
577         "Packets Transmitted (64 Bytes)",
578         "Packets Transmitted (65-127 Bytes)",
579         "Packets Transmitted (128-255 Bytes)",
580         "Packets Transmitted (256-511 Bytes)",
581         "Packets Transmitted (512-1023 Bytes)",
582         "Packets Transmitted (1024-1522 Bytes)",
583         "Multicast Packets Transmitted",
584         "Broadcast Packets Transmitted",
585         "TCP Segmentation Context Transmitted",
586         "TCP Segmentation Context Fail",
587 };
588
589 static long
590 igbeifstat(Ether* edev, void* a, long n, ulong offset)
591 {
592         Ctlr *ctlr;
593         char *p, *s;
594         int i, l, r;
595         uvlong tuvl, ruvl;
596
597         p = smalloc(READSTR);
598         l = 0;
599         ctlr = edev->ctlr;
600         qlock(&ctlr->slock);
601         for(i = 0; i < Nstatistics; i++){
602                 r = csr32r(ctlr, Statistics+i*4);
603                 if((s = statistics[i]) == nil)
604                         continue;
605                 switch(i){
606                 case Gorcl:
607                 case Gotcl:
608                 case Torl:
609                 case Totl:
610                         ruvl = r;
611                         ruvl += ((uvlong)csr32r(ctlr, Statistics+(i+1)*4))<<32;
612                         tuvl = ruvl;
613                         tuvl += ctlr->statistics[i];
614                         tuvl += ((uvlong)ctlr->statistics[i+1])<<32;
615                         if(tuvl == 0)
616                                 continue;
617                         ctlr->statistics[i] = tuvl;
618                         ctlr->statistics[i+1] = tuvl>>32;
619                         l += snprint(p+l, READSTR-l, "%s: %llud %llud\n",
620                                 s, tuvl, ruvl);
621                         i++;
622                         break;
623
624                 default:
625                         ctlr->statistics[i] += r;
626                         if(ctlr->statistics[i] == 0)
627                                 continue;
628                         l += snprint(p+l, READSTR-l, "%s: %ud %ud\n",
629                                 s, ctlr->statistics[i], r);
630                         break;
631                 }
632         }
633
634         l += snprint(p+l, READSTR-l, "lintr: %ud %ud\n",
635                 ctlr->lintr, ctlr->lsleep);
636         l += snprint(p+l, READSTR-l, "rintr: %ud %ud\n",
637                 ctlr->rintr, ctlr->rsleep);
638         l += snprint(p+l, READSTR-l, "tintr: %ud %ud\n",
639                 ctlr->tintr, ctlr->txdw);
640         l += snprint(p+l, READSTR-l, "ixcs: %ud %ud %ud\n",
641                 ctlr->ixsm, ctlr->ipcs, ctlr->tcpcs);
642         l += snprint(p+l, READSTR-l, "rdtr: %ud\n", ctlr->rdtr);
643         l += snprint(p+l, READSTR-l, "Ctrlext: %08x\n", csr32r(ctlr, Ctrlext));
644
645         l += snprint(p+l, READSTR-l, "eeprom:");
646         for(i = 0; i < 0x40; i++){
647                 if(i && ((i & 0x07) == 0))
648                         l += snprint(p+l, READSTR-l, "\n       ");
649                 l += snprint(p+l, READSTR-l, " %4.4uX", ctlr->eeprom[i]);
650         }
651         l += snprint(p+l, READSTR-l, "\n");
652
653         if(ctlr->mii != nil && ctlr->mii->curphy != nil){
654                 l += snprint(p+l, READSTR-l, "phy:   ");
655                 for(i = 0; i < NMiiPhyr; i++){
656                         if(i && ((i & 0x07) == 0))
657                                 l += snprint(p+l, READSTR-l, "\n       ");
658                         r = miimir(ctlr->mii, i);
659                         l += snprint(p+l, READSTR-l, " %4.4uX", r);
660                 }
661                 snprint(p+l, READSTR-l, "\n");
662         }
663         n = readstr(offset, a, n, p);
664         free(p);
665         qunlock(&ctlr->slock);
666
667         return n;
668 }
669
670 enum {
671         CMrdtr,
672 };
673
674 static Cmdtab igbectlmsg[] = {
675         CMrdtr, "rdtr", 2,
676 };
677
678 static long
679 igbectl(Ether* edev, void* buf, long n)
680 {
681         int v;
682         char *p;
683         Ctlr *ctlr;
684         Cmdbuf *cb;
685         Cmdtab *ct;
686
687         if((ctlr = edev->ctlr) == nil)
688                 error(Enonexist);
689
690         cb = parsecmd(buf, n);
691         if(waserror()){
692                 free(cb);
693                 nexterror();
694         }
695
696         ct = lookupcmd(cb, igbectlmsg, nelem(igbectlmsg));
697         switch(ct->index){
698         case CMrdtr:
699                 v = strtol(cb->f[1], &p, 0);
700                 if(v < 0 || p == cb->f[1] || v > 0xFFFF)
701                         error(Ebadarg);
702                 ctlr->rdtr = v;;
703                 csr32w(ctlr, Rdtr, Fpd|v);
704                 break;
705         }
706         free(cb);
707         poperror();
708
709         return n;
710 }
711
712 static void
713 igbepromiscuous(void* arg, int on)
714 {
715         int rctl;
716         Ctlr *ctlr;
717         Ether *edev;
718
719         edev = arg;
720         ctlr = edev->ctlr;
721
722         rctl = csr32r(ctlr, Rctl);
723         rctl &= ~MoMASK;
724         rctl |= Mo47b36;
725         if(on)
726                 rctl |= Upe|Mpe;
727         else
728                 rctl &= ~(Upe|Mpe);
729         csr32w(ctlr, Rctl, rctl|Mpe);   /* temporarily keep Mpe on */
730 }
731
732 static void
733 igbemulticast(void* arg, uchar* addr, int add)
734 {
735         int bit, x;
736         Ctlr *ctlr;
737         Ether *edev;
738
739         edev = arg;
740         ctlr = edev->ctlr;
741
742         x = addr[5]>>1;
743         bit = ((addr[5] & 1)<<4)|(addr[4]>>4);
744         /*
745          * multiple ether addresses can hash to the same filter bit,
746          * so it's never safe to clear a filter bit.
747          * if we want to clear filter bits, we need to keep track of
748          * all the multicast addresses in use, clear all the filter bits,
749          * then set the ones corresponding to in-use addresses.
750          */
751         if(add)
752                 ctlr->mta[x] |= 1<<bit;
753 //      else
754 //              ctlr->mta[x] &= ~(1<<bit);
755
756         csr32w(ctlr, Mta+x*4, ctlr->mta[x]);
757 }
758
759 static void
760 igbeim(Ctlr* ctlr, int im)
761 {
762         ilock(&ctlr->imlock);
763         ctlr->im |= im;
764         csr32w(ctlr, Ims, ctlr->im);
765         iunlock(&ctlr->imlock);
766 }
767
768 static int
769 igbelim(void* ctlr)
770 {
771         return ((Ctlr*)ctlr)->lim != 0;
772 }
773
774 static void
775 igbelproc(void* arg)
776 {
777         Ctlr *ctlr;
778         Ether *edev;
779         MiiPhy *phy;
780         int ctrl, r;
781
782         edev = arg;
783         ctlr = edev->ctlr;
784         while(waserror())
785                 ;
786         for(;;){
787                 if(ctlr->mii == nil || ctlr->mii->curphy == nil)
788                         continue;
789
790                 /*
791                  * To do:
792                  *      logic to manage status change,
793                  *      this is incomplete but should work
794                  *      one time to set up the hardware.
795                  *
796                  *      MiiPhy.speed, etc. should be in Mii.
797                  */
798                 if(miistatus(ctlr->mii) < 0)
799                         //continue;
800                         goto enable;
801
802                 phy = ctlr->mii->curphy;
803                 ctrl = csr32r(ctlr, Ctrl);
804
805                 switch(ctlr->id){
806                 case i82543gc:
807                 case i82544ei:
808                 case i82544eif:
809                 default:
810                         if(!(ctrl & Asde)){
811                                 ctrl &= ~(SspeedMASK|Ilos|Fd);
812                                 ctrl |= Frcdplx|Frcspd;
813                                 if(phy->speed == 1000)
814                                         ctrl |= Sspeed1000;
815                                 else if(phy->speed == 100)
816                                         ctrl |= Sspeed100;
817                                 if(phy->fd)
818                                         ctrl |= Fd;
819                         }
820                         break;
821
822                 case i82540em:
823                 case i82540eplp:
824                 case i82547gi:
825                 case i82541gi:
826                 case i82541gi2:
827                 case i82541pi:
828                         break;
829                 }
830
831                 /*
832                  * Collision Distance.
833                  */
834                 r = csr32r(ctlr, Tctl);
835                 r &= ~ColdMASK;
836                 if(phy->fd)
837                         r |= 64<<ColdSHIFT;
838                 else
839                         r |= 512<<ColdSHIFT;
840                 csr32w(ctlr, Tctl, r);
841
842                 /*
843                  * Flow control.
844                  */
845                 if(phy->rfc)
846                         ctrl |= Rfce;
847                 if(phy->tfc)
848                         ctrl |= Tfce;
849                 csr32w(ctlr, Ctrl, ctrl);
850
851 enable:
852                 ctlr->lim = 0;
853                 igbeim(ctlr, Lsc);
854
855                 ctlr->lsleep++;
856                 sleep(&ctlr->lrendez, igbelim, ctlr);
857         }
858 }
859
860 static void
861 igbetxinit(Ctlr* ctlr)
862 {
863         int i, r;
864         Block *bp;
865
866         csr32w(ctlr, Tctl, (0x0F<<CtSHIFT)|Psp|(66<<ColdSHIFT));
867         switch(ctlr->id){
868         default:
869                 r = 6;
870                 break;
871         case i82543gc:
872         case i82544ei:
873         case i82544eif:
874         case i82544gc:
875         case i82540em:
876         case i82540eplp:
877         case i82541ei:
878         case i82541gi:
879         case i82541gi2:
880         case i82541pi:
881         case i82545em:
882         case i82545gmc:
883         case i82546gb:
884         case i82546eb:
885         case i82547ei:
886         case i82547gi:
887                 r = 8;
888                 break;
889         }
890         csr32w(ctlr, Tipg, (6<<20)|(8<<10)|r);
891         csr32w(ctlr, Ait, 0);
892         csr32w(ctlr, Txdmac, 0);
893
894         csr32w(ctlr, Tdbal, PCIWADDR(ctlr->tdba));
895         csr32w(ctlr, Tdbah, 0);
896         csr32w(ctlr, Tdlen, ctlr->ntd*sizeof(Td));
897         ctlr->tdh = PREV(0, ctlr->ntd);
898         csr32w(ctlr, Tdh, 0);
899         ctlr->tdt = 0;
900         csr32w(ctlr, Tdt, 0);
901
902         for(i = 0; i < ctlr->ntd; i++){
903                 if((bp = ctlr->tb[i]) != nil){
904                         ctlr->tb[i] = nil;
905                         freeb(bp);
906                 }
907                 memset(&ctlr->tdba[i], 0, sizeof(Td));
908         }
909         ctlr->tdfree = ctlr->ntd;
910
911         csr32w(ctlr, Tidv, 128);
912         r = (4<<WthreshSHIFT)|(4<<HthreshSHIFT)|(8<<PthreshSHIFT);
913
914         switch(ctlr->id){
915         default:
916                 break;
917         case i82540em:
918         case i82540eplp:
919         case i82547gi:
920         case i82545em:
921         case i82545gmc:
922         case i82546gb:
923         case i82546eb:
924         case i82541gi:
925         case i82541gi2:
926         case i82541pi:
927                 r = csr32r(ctlr, Txdctl);
928                 r &= ~WthreshMASK;
929                 r |= Gran|(4<<WthreshSHIFT);
930
931                 csr32w(ctlr, Tadv, 64);
932                 break;
933         }
934
935         csr32w(ctlr, Txdctl, r);
936
937         r = csr32r(ctlr, Tctl);
938         r |= Ten;
939         csr32w(ctlr, Tctl, r);
940 }
941
942 static void
943 igbetransmit(Ether* edev)
944 {
945         Td *td;
946         Block *bp;
947         Ctlr *ctlr;
948         int tdh, tdt;
949
950         ctlr = edev->ctlr;
951
952         ilock(&ctlr->tlock);
953
954         /*
955          * Free any completed packets
956          */
957         tdh = ctlr->tdh;
958         while(NEXT(tdh, ctlr->ntd) != csr32r(ctlr, Tdh)){
959                 if((bp = ctlr->tb[tdh]) != nil){
960                         ctlr->tb[tdh] = nil;
961                         freeb(bp);
962                 }
963                 memset(&ctlr->tdba[tdh], 0, sizeof(Td));
964                 tdh = NEXT(tdh, ctlr->ntd);
965         }
966         ctlr->tdh = tdh;
967
968         /*
969          * Try to fill the ring back up.
970          */
971         tdt = ctlr->tdt;
972         while(NEXT(tdt, ctlr->ntd) != tdh){
973                 if((bp = qget(edev->oq)) == nil)
974                         break;
975                 td = &ctlr->tdba[tdt];
976                 td->addr[0] = PCIWADDR(bp->rp);
977                 td->control = ((BLEN(bp) & LenMASK)<<LenSHIFT);
978                 td->control |= Dext|Ifcs|Teop|DtypeDD;
979                 ctlr->tb[tdt] = bp;
980                 tdt = NEXT(tdt, ctlr->ntd);
981                 if(NEXT(tdt, ctlr->ntd) == tdh){
982                         td->control |= Rs;
983                         ctlr->txdw++;
984                         ctlr->tdt = tdt;
985                         csr32w(ctlr, Tdt, tdt);
986                         igbeim(ctlr, Txdw);
987                         break;
988                 }
989                 ctlr->tdt = tdt;
990                 csr32w(ctlr, Tdt, tdt);
991         }
992
993         iunlock(&ctlr->tlock);
994 }
995
996 static void
997 igbereplenish(Ctlr* ctlr)
998 {
999         Rd *rd;
1000         int rdt;
1001         Block *bp;
1002
1003         rdt = ctlr->rdt;
1004         while(NEXT(rdt, ctlr->nrd) != ctlr->rdh){
1005                 rd = &ctlr->rdba[rdt];
1006                 if(ctlr->rb[rdt] == nil){
1007                         bp = allocb(Rbsz);
1008                         bp->rp = bp->lim - Rbsz;
1009                         bp->wp = bp->rp;
1010                         ctlr->rb[rdt] = bp;
1011                         rd->addr[0] = PCIWADDR(bp->rp);
1012                         rd->addr[1] = 0;
1013                 }
1014                 coherence();
1015                 rd->status = 0;
1016                 rdt = NEXT(rdt, ctlr->nrd);
1017                 ctlr->rdfree++;
1018         }
1019         ctlr->rdt = rdt;
1020         csr32w(ctlr, Rdt, rdt);
1021 }
1022
1023 static void
1024 igberxinit(Ctlr* ctlr)
1025 {
1026         int i;
1027         Block *bp;
1028
1029         /* temporarily keep Mpe on */
1030         csr32w(ctlr, Rctl, Dpf|Bsize2048|Bam|RdtmsHALF|Mpe);
1031
1032         csr32w(ctlr, Rdbal, PCIWADDR(ctlr->rdba));
1033         csr32w(ctlr, Rdbah, 0);
1034         csr32w(ctlr, Rdlen, ctlr->nrd*sizeof(Rd));
1035         ctlr->rdh = 0;
1036         csr32w(ctlr, Rdh, 0);
1037         ctlr->rdt = 0;
1038         csr32w(ctlr, Rdt, 0);
1039         ctlr->rdtr = 0;
1040         csr32w(ctlr, Rdtr, Fpd|0);
1041
1042         for(i = 0; i < ctlr->nrd; i++){
1043                 if((bp = ctlr->rb[i]) != nil){
1044                         ctlr->rb[i] = nil;
1045                         freeb(bp);
1046                 }
1047         }
1048         igbereplenish(ctlr);
1049
1050         switch(ctlr->id){
1051         case i82540em:
1052         case i82540eplp:
1053         case i82541gi:
1054         case i82541gi2:
1055         case i82541pi:
1056         case i82545em:
1057         case i82545gmc:
1058         case i82546gb:
1059         case i82546eb:
1060         case i82547gi:
1061                 csr32w(ctlr, Radv, 64);
1062                 break;
1063         }
1064         csr32w(ctlr, Rxdctl, (8<<WthreshSHIFT)|(8<<HthreshSHIFT)|4);
1065
1066         /*
1067          * Disable checksum offload as it has known bugs.
1068          */
1069         csr32w(ctlr, Rxcsum, ETHERHDRSIZE<<PcssSHIFT);
1070 }
1071
1072 static int
1073 igberim(void* ctlr)
1074 {
1075         return ((Ctlr*)ctlr)->rim != 0;
1076 }
1077
1078 static void
1079 igberproc(void* arg)
1080 {
1081         Rd *rd;
1082         Block *bp;
1083         Ctlr *ctlr;
1084         int r, rdh;
1085         Ether *edev;
1086
1087         edev = arg;
1088         ctlr = edev->ctlr;
1089
1090         igberxinit(ctlr);
1091         r = csr32r(ctlr, Rctl);
1092         r |= Ren;
1093         csr32w(ctlr, Rctl, r);
1094
1095         while(waserror())
1096                 ;
1097
1098         for(;;){
1099                 ctlr->rim = 0;
1100                 igbeim(ctlr, Rxt0|Rxo|Rxdmt0|Rxseq);
1101                 ctlr->rsleep++;
1102                 sleep(&ctlr->rrendez, igberim, ctlr);
1103
1104                 rdh = ctlr->rdh;
1105                 for(;;){
1106                         rd = &ctlr->rdba[rdh];
1107
1108                         if(!(rd->status & Rdd))
1109                                 break;
1110
1111                         /*
1112                          * Accept eop packets with no errors.
1113                          * With no errors and the Ixsm bit set,
1114                          * the descriptor status Tpcs and Ipcs bits give
1115                          * an indication of whether the checksums were
1116                          * calculated and valid.
1117                          */
1118                         if((rd->status & Reop) && rd->errors == 0){
1119                                 bp = ctlr->rb[rdh];
1120                                 ctlr->rb[rdh] = nil;
1121                                 bp->wp += rd->length;
1122                                 bp->next = nil;
1123                                 if(!(rd->status & Ixsm)){
1124                                         ctlr->ixsm++;
1125                                         if(rd->status & Ipcs){
1126                                                 /*
1127                                                  * IP checksum calculated
1128                                                  * (and valid as errors == 0).
1129                                                  */
1130                                                 ctlr->ipcs++;
1131                                                 bp->flag |= Bipck;
1132                                         }
1133                                         if(rd->status & Tcpcs){
1134                                                 /*
1135                                                  * TCP/UDP checksum calculated
1136                                                  * (and valid as errors == 0).
1137                                                  */
1138                                                 ctlr->tcpcs++;
1139                                                 bp->flag |= Btcpck|Budpck;
1140                                         }
1141                                         bp->checksum = rd->checksum;
1142                                         bp->flag |= Bpktck;
1143                                 }
1144                                 etheriq(edev, bp);
1145                         }
1146                         else if(ctlr->rb[rdh] != nil){
1147                                 freeb(ctlr->rb[rdh]);
1148                                 ctlr->rb[rdh] = nil;
1149                         }
1150
1151                         memset(rd, 0, sizeof(Rd));
1152                         coherence();
1153                         ctlr->rdfree--;
1154                         rdh = NEXT(rdh, ctlr->nrd);
1155                 }
1156                 ctlr->rdh = rdh;
1157
1158                 if(ctlr->rdfree < ctlr->nrd/2 || (ctlr->rim & Rxdmt0))
1159                         igbereplenish(ctlr);
1160         }
1161 }
1162
1163 static void
1164 igbeattach(Ether* edev)
1165 {
1166         Ctlr *ctlr;
1167         char name[KNAMELEN];
1168
1169         ctlr = edev->ctlr;
1170         ctlr->edev = edev;                      /* point back to Ether* */
1171         qlock(&ctlr->alock);
1172         if(ctlr->alloc != nil){                 /* already allocated? */
1173                 qunlock(&ctlr->alock);
1174                 return;
1175         }
1176
1177         ctlr->nrd = ROUND(Nrd, 8);
1178         ctlr->ntd = ROUND(Ntd, 8);
1179         ctlr->alloc = malloc(ctlr->nrd*sizeof(Rd)+ctlr->ntd*sizeof(Td) + 127);
1180         if(ctlr->alloc == nil){
1181                 print("igbe: can't allocate ctlr->alloc\n");
1182                 qunlock(&ctlr->alock);
1183                 return;
1184         }
1185         ctlr->rdba = (Rd*)ROUNDUP((uintptr)ctlr->alloc, 128);
1186         ctlr->tdba = (Td*)(ctlr->rdba+ctlr->nrd);
1187
1188         ctlr->rb = malloc(ctlr->nrd*sizeof(Block*));
1189         ctlr->tb = malloc(ctlr->ntd*sizeof(Block*));
1190         if (ctlr->rb == nil || ctlr->tb == nil) {
1191                 print("igbe: can't allocate ctlr->rb or ctlr->tb\n");
1192                 qunlock(&ctlr->alock);
1193                 return;
1194         }
1195
1196         if(waserror()){
1197                 free(ctlr->tb);
1198                 ctlr->tb = nil;
1199                 free(ctlr->rb);
1200                 ctlr->rb = nil;
1201                 free(ctlr->alloc);
1202                 ctlr->alloc = nil;
1203                 qunlock(&ctlr->alock);
1204                 nexterror();
1205         }
1206
1207         snprint(name, KNAMELEN, "#l%dlproc", edev->ctlrno);
1208         kproc(name, igbelproc, edev);
1209
1210         snprint(name, KNAMELEN, "#l%drproc", edev->ctlrno);
1211         kproc(name, igberproc, edev);
1212
1213         igbetxinit(ctlr);
1214
1215         qunlock(&ctlr->alock);
1216         poperror();
1217 }
1218
1219 static void
1220 igbeinterrupt(Ureg*, void* arg)
1221 {
1222         Ctlr *ctlr;
1223         Ether *edev;
1224         int icr, im, txdw;
1225
1226         edev = arg;
1227         ctlr = edev->ctlr;
1228
1229         ilock(&ctlr->imlock);
1230         csr32w(ctlr, Imc, ~0);
1231         im = ctlr->im;
1232         txdw = 0;
1233
1234         while((icr = csr32r(ctlr, Icr) & ctlr->im) != 0){
1235                 if(icr & Lsc){
1236                         im &= ~Lsc;
1237                         ctlr->lim = icr & Lsc;
1238                         wakeup(&ctlr->lrendez);
1239                         ctlr->lintr++;
1240                 }
1241                 if(icr & (Rxt0|Rxo|Rxdmt0|Rxseq)){
1242                         im &= ~(Rxt0|Rxo|Rxdmt0|Rxseq);
1243                         ctlr->rim = icr & (Rxt0|Rxo|Rxdmt0|Rxseq);
1244                         wakeup(&ctlr->rrendez);
1245                         ctlr->rintr++;
1246                 }
1247                 if(icr & Txdw){
1248                         im &= ~Txdw;
1249                         txdw++;
1250                         ctlr->tintr++;
1251                 }
1252         }
1253
1254         ctlr->im = im;
1255         csr32w(ctlr, Ims, im);
1256         iunlock(&ctlr->imlock);
1257
1258         if(txdw)
1259                 igbetransmit(edev);
1260 }
1261
1262 static int
1263 i82543mdior(Ctlr* ctlr, int n)
1264 {
1265         int ctrl, data, i, r;
1266
1267         /*
1268          * Read n bits from the Management Data I/O Interface.
1269          */
1270         ctrl = csr32r(ctlr, Ctrl);
1271         r = (ctrl & ~Mddo)|Mdco;
1272         data = 0;
1273         for(i = n-1; i >= 0; i--){
1274                 if(csr32r(ctlr, Ctrl) & Mdd)
1275                         data |= (1<<i);
1276                 csr32w(ctlr, Ctrl, Mdc|r);
1277                 csr32w(ctlr, Ctrl, r);
1278         }
1279         csr32w(ctlr, Ctrl, ctrl);
1280
1281         return data;
1282 }
1283
1284 static int
1285 i82543mdiow(Ctlr* ctlr, int bits, int n)
1286 {
1287         int ctrl, i, r;
1288
1289         /*
1290          * Write n bits to the Management Data I/O Interface.
1291          */
1292         ctrl = csr32r(ctlr, Ctrl);
1293         r = Mdco|Mddo|ctrl;
1294         for(i = n-1; i >= 0; i--){
1295                 if(bits & (1<<i))
1296                         r |= Mdd;
1297                 else
1298                         r &= ~Mdd;
1299                 csr32w(ctlr, Ctrl, Mdc|r);
1300                 csr32w(ctlr, Ctrl, r);
1301         }
1302         csr32w(ctlr, Ctrl, ctrl);
1303
1304         return 0;
1305 }
1306
1307 static int
1308 i82543miimir(Mii* mii, int pa, int ra)
1309 {
1310         int data;
1311         Ctlr *ctlr;
1312
1313         ctlr = mii->ctlr;
1314
1315         /*
1316          * MII Management Interface Read.
1317          *
1318          * Preamble;
1319          * ST+OP+PHYAD+REGAD;
1320          * TA + 16 data bits.
1321          */
1322         i82543mdiow(ctlr, 0xFFFFFFFF, 32);
1323         i82543mdiow(ctlr, 0x1800|(pa<<5)|ra, 14);
1324         data = i82543mdior(ctlr, 18);
1325
1326         if(data & 0x10000)
1327                 return -1;
1328
1329         return data & 0xFFFF;
1330 }
1331
1332 static int
1333 i82543miimiw(Mii* mii, int pa, int ra, int data)
1334 {
1335         Ctlr *ctlr;
1336
1337         ctlr = mii->ctlr;
1338
1339         /*
1340          * MII Management Interface Write.
1341          *
1342          * Preamble;
1343          * ST+OP+PHYAD+REGAD+TA + 16 data bits;
1344          * Z.
1345          */
1346         i82543mdiow(ctlr, 0xFFFFFFFF, 32);
1347         data &= 0xFFFF;
1348         data |= (0x05<<(5+5+2+16))|(pa<<(5+2+16))|(ra<<(2+16))|(0x02<<16);
1349         i82543mdiow(ctlr, data, 32);
1350
1351         return 0;
1352 }
1353
1354 static int
1355 igbemiimir(Mii* mii, int pa, int ra)
1356 {
1357         Ctlr *ctlr;
1358         int mdic, timo;
1359
1360         ctlr = mii->ctlr;
1361
1362         csr32w(ctlr, Mdic, MDIrop|(pa<<MDIpSHIFT)|(ra<<MDIrSHIFT));
1363         mdic = 0;
1364         for(timo = 64; timo; timo--){
1365                 mdic = csr32r(ctlr, Mdic);
1366                 if(mdic & (MDIe|MDIready))
1367                         break;
1368                 microdelay(1);
1369         }
1370
1371         if((mdic & (MDIe|MDIready)) == MDIready)
1372                 return mdic & 0xFFFF;
1373         return -1;
1374 }
1375
1376 static int
1377 igbemiimiw(Mii* mii, int pa, int ra, int data)
1378 {
1379         Ctlr *ctlr;
1380         int mdic, timo;
1381
1382         ctlr = mii->ctlr;
1383
1384         data &= MDIdMASK;
1385         csr32w(ctlr, Mdic, MDIwop|(pa<<MDIpSHIFT)|(ra<<MDIrSHIFT)|data);
1386         mdic = 0;
1387         for(timo = 64; timo; timo--){
1388                 mdic = csr32r(ctlr, Mdic);
1389                 if(mdic & (MDIe|MDIready))
1390                         break;
1391                 microdelay(1);
1392         }
1393         if((mdic & (MDIe|MDIready)) == MDIready)
1394                 return 0;
1395         return -1;
1396 }
1397
1398 static int
1399 igbemii(Ctlr* ctlr)
1400 {
1401         MiiPhy *phy;
1402         int ctrl, p, r;
1403
1404         r = csr32r(ctlr, Status);
1405         if(r & Tbimode)
1406                 return -1;
1407         if((ctlr->mii = malloc(sizeof(Mii))) == nil)
1408                 return -1;
1409         ctlr->mii->ctlr = ctlr;
1410
1411         ctrl = csr32r(ctlr, Ctrl);
1412         ctrl |= Slu;
1413
1414         switch(ctlr->id){
1415         case i82543gc:
1416                 ctrl |= Frcdplx|Frcspd;
1417                 csr32w(ctlr, Ctrl, ctrl);
1418
1419                 /*
1420                  * The reset pin direction (Mdro) should already
1421                  * be set from the EEPROM load.
1422                  * If it's not set this configuration is unexpected
1423                  * so bail.
1424                  */
1425                 r = csr32r(ctlr, Ctrlext);
1426                 if(!(r & Mdro)) {
1427                         print("igbe: 82543gc Mdro not set\n");
1428                         return -1;
1429                 }
1430                 csr32w(ctlr, Ctrlext, r);
1431                 delay(20);
1432                 r = csr32r(ctlr, Ctrlext);
1433                 r &= ~Mdr;
1434                 csr32w(ctlr, Ctrlext, r);
1435                 delay(20);
1436                 r = csr32r(ctlr, Ctrlext);
1437                 r |= Mdr;
1438                 csr32w(ctlr, Ctrlext, r);
1439                 delay(20);
1440
1441                 ctlr->mii->mir = i82543miimir;
1442                 ctlr->mii->miw = i82543miimiw;
1443                 break;
1444         case i82544ei:
1445         case i82544eif:
1446         case i82544gc:
1447         case i82540em:
1448         case i82540eplp:
1449         case i82547ei:
1450         case i82547gi:
1451         case i82541ei:
1452         case i82541gi:
1453         case i82541gi2:
1454         case i82541pi:
1455         case i82545em:
1456         case i82545gmc:
1457         case i82546gb:
1458         case i82546eb:
1459                 ctrl &= ~(Frcdplx|Frcspd);
1460                 csr32w(ctlr, Ctrl, ctrl);
1461                 ctlr->mii->mir = igbemiimir;
1462                 ctlr->mii->miw = igbemiimiw;
1463                 break;
1464         default:
1465                 free(ctlr->mii);
1466                 ctlr->mii = nil;
1467                 return -1;
1468         }
1469
1470         if(mii(ctlr->mii, ~0) == 0 || (phy = ctlr->mii->curphy) == nil){
1471                 free(ctlr->mii);
1472                 ctlr->mii = nil;
1473                 return -1;
1474         }
1475         USED(phy);
1476         // print("oui %X phyno %d\n", phy->oui, phy->phyno);
1477
1478         /*
1479          * 8254X-specific PHY registers not in 802.3:
1480          *      0x10    PHY specific control
1481          *      0x14    extended PHY specific control
1482          * Set appropriate values then reset the PHY to have
1483          * changes noted.
1484          */
1485         switch(ctlr->id){
1486         case i82547gi:
1487         case i82541gi:
1488         case i82541gi2:
1489         case i82541pi:
1490         case i82545em:
1491         case i82545gmc:
1492         case i82546gb:
1493         case i82546eb:
1494                 break;
1495         default:
1496                 r = miimir(ctlr->mii, 16);
1497                 r |= 0x0800;                    /* assert CRS on Tx */
1498                 r |= 0x0060;                    /* auto-crossover all speeds */
1499                 r |= 0x0002;                    /* polarity reversal enabled */
1500                 miimiw(ctlr->mii, 16, r);
1501
1502                 r = miimir(ctlr->mii, 20);
1503                 r |= 0x0070;                    /* +25MHz clock */
1504                 r &= ~0x0F00;
1505                 r |= 0x0100;                    /* 1x downshift */
1506                 miimiw(ctlr->mii, 20, r);
1507
1508                 miireset(ctlr->mii);
1509                 p = 0;
1510                 if(ctlr->txcw & TxcwPs)
1511                         p |= AnaP;
1512                 if(ctlr->txcw & TxcwAs)
1513                         p |= AnaAP;
1514                 miiane(ctlr->mii, ~0, p, ~0);
1515                 break;
1516         }
1517         return 0;
1518 }
1519
1520 static int
1521 at93c46io(Ctlr* ctlr, char* op, int data)
1522 {
1523         char *lp, *p;
1524         int i, loop, eecd, r;
1525
1526         eecd = csr32r(ctlr, Eecd);
1527
1528         r = 0;
1529         loop = -1;
1530         lp = nil;
1531         for(p = op; *p != '\0'; p++){
1532                 switch(*p){
1533                 default:
1534                         return -1;
1535                 case ' ':
1536                         continue;
1537                 case ':':                       /* start of loop */
1538                         loop = strtol(p+1, &lp, 0)-1;
1539                         lp--;
1540                         if(p == lp)
1541                                 loop = 7;
1542                         p = lp;
1543                         continue;
1544                 case ';':                       /* end of loop */
1545                         if(lp == nil)
1546                                 return -1;
1547                         loop--;
1548                         if(loop >= 0)
1549                                 p = lp;
1550                         else
1551                                 lp = nil;
1552                         continue;
1553                 case 'C':                       /* assert clock */
1554                         eecd |= Sk;
1555                         break;
1556                 case 'c':                       /* deassert clock */
1557                         eecd &= ~Sk;
1558                         break;
1559                 case 'D':                       /* next bit in 'data' byte */
1560                         if(loop < 0)
1561                                 return -1;
1562                         if(data & (1<<loop))
1563                                 eecd |= Di;
1564                         else
1565                                 eecd &= ~Di;
1566                         break;
1567                 case 'O':                       /* collect data output */
1568                         i = (csr32r(ctlr, Eecd) & Do) != 0;
1569                         if(loop >= 0)
1570                                 r |= (i<<loop);
1571                         else
1572                                 r = i;
1573                         continue;
1574                 case 'H':
1575                         eecd |= Do;
1576                         continue;
1577                 case 'h':
1578                         eecd &= ~Do;
1579                         continue;
1580                 case 'I':                       /* assert data input */
1581                         eecd |= Di;
1582                         break;
1583                 case 'i':                       /* deassert data input */
1584                         eecd &= ~Di;
1585                         break;
1586                 case 'S':                       /* enable chip select */
1587                         eecd |= Cs;
1588                         break;
1589                 case 's':                       /* disable chip select */
1590                         eecd &= ~Cs;
1591                         break;
1592                 }
1593                 csr32w(ctlr, Eecd, eecd);
1594                 if (eecd & Spi)
1595                         microdelay(1);
1596                 else
1597                         microdelay(50);
1598         }
1599         if(loop >= 0)
1600                 return -1;
1601         return r;
1602 }
1603
1604 static int
1605 at93c46r(Ctlr* ctlr)
1606 {
1607         ushort sum;
1608         char rop[20];
1609         int addr, areq, bits, data, eecd, i;
1610
1611         sum = 0;
1612         eecd = csr32r(ctlr, Eecd);
1613
1614         switch(ctlr->id){
1615         default:
1616                 areq = 0;
1617                 break;
1618         case i82540em:
1619         case i82540eplp:
1620         case i82541ei:
1621         case i82541gi:
1622         case i82541gi2:
1623         case i82541pi:
1624         case i82545em:
1625         case i82545gmc:
1626         case i82546gb:
1627         case i82546eb:
1628         case i82547ei:
1629         case i82547gi:
1630                 areq = 1;
1631                 csr32w(ctlr, Eecd, eecd|Areq);
1632                 for(i = 0; i < 1000; i++){
1633                         if((eecd = csr32r(ctlr, Eecd)) & Agnt)
1634                                 break;
1635                         microdelay(5);
1636                 }
1637                 if(!(eecd & Agnt)){
1638                         print("igbe: not granted EEPROM access\n");
1639                         goto release;
1640                 }
1641                 break;
1642         }
1643
1644         if(eecd & Spi){
1645                 for(i = 0; i < 1000; i++){
1646                         at93c46io(ctlr, "H :8HDCc;", 0x05);
1647                         data = at93c46io(ctlr, "h :8COc;", 0);
1648
1649                         if (!(data & 0x1))
1650                                 break;
1651
1652                         microdelay(5);
1653                         at93c46io(ctlr, "Ss", 0);
1654                 }
1655                 if(i == 1000){
1656                         print("igbe: SPI EEPROM not ready\n");
1657                         goto release;
1658                 }
1659
1660                 at93c46io(ctlr, "Ss H :8HDCc;", 0x03);
1661
1662                 if(eecd & Eeszaddr)
1663                         bits = 16;
1664                 else
1665                         bits = 8;
1666                 snprint(rop, sizeof(rop), "H :%dHDCc;", bits);
1667                 if(at93c46io(ctlr, rop, 0) != 0){
1668                         print("igbe: can't set EEPROM address 0x00\n");
1669                         goto release;
1670                 }
1671
1672                 for(addr = 0; addr < 0x40; addr++){
1673                         data = at93c46io(ctlr, "h :16COc;", 0);
1674                         ctlr->eeprom[addr] = (data >> 8) | (data << 8);
1675                         sum += ctlr->eeprom[addr];
1676                 }
1677         } else {
1678                 if(eecd & (Eeszaddr|Eesz256))
1679                         bits = 8;
1680                 else
1681                         bits = 6;
1682                 snprint(rop, sizeof(rop), "S :%dDCc;", bits+3);
1683
1684                 for(addr = 0; addr < 0x40; addr++){
1685                         /*
1686                          * Read a word at address 'addr' from the Atmel AT93C46
1687                          * 3-Wire Serial EEPROM or compatible. The EEPROM access is
1688                          * controlled by 4 bits in Eecd. See the AT93C46 datasheet
1689                          * for protocol details.
1690                          */
1691                         if(at93c46io(ctlr, rop, (0x06<<bits)|addr) != 0){
1692                                 print("igbe: can't set EEPROM address 0x%2.2X\n", addr);
1693                                 goto release;
1694                         }
1695                         data = at93c46io(ctlr, ":16COc;", 0);
1696                         at93c46io(ctlr, "sic", 0);
1697                         ctlr->eeprom[addr] = data;
1698                         sum += data;
1699                 }
1700         }
1701
1702 release:
1703         if(areq)
1704                 csr32w(ctlr, Eecd, eecd & ~Areq);
1705         return sum;
1706 }
1707
1708 static int
1709 igbedetach(Ctlr* ctlr)
1710 {
1711         int r, timeo;
1712
1713         /*
1714          * Perform a device reset to get the chip back to the
1715          * power-on state, followed by an EEPROM reset to read
1716          * the defaults for some internal registers.
1717          */
1718         csr32w(ctlr, Imc, ~0);
1719         csr32w(ctlr, Rctl, 0);
1720         csr32w(ctlr, Tctl, 0);
1721
1722         delay(10);
1723
1724         csr32w(ctlr, Ctrl, Devrst);
1725         delay(1);
1726         for(timeo = 0; timeo < 1000; timeo++){
1727                 if(!(csr32r(ctlr, Ctrl) & Devrst))
1728                         break;
1729                 delay(1);
1730         }
1731         if(csr32r(ctlr, Ctrl) & Devrst)
1732                 return -1;
1733         r = csr32r(ctlr, Ctrlext);
1734         csr32w(ctlr, Ctrlext, r|Eerst);
1735         delay(1);
1736         for(timeo = 0; timeo < 1000; timeo++){
1737                 if(!(csr32r(ctlr, Ctrlext) & Eerst))
1738                         break;
1739                 delay(1);
1740         }
1741         if(csr32r(ctlr, Ctrlext) & Eerst)
1742                 return -1;
1743
1744         switch(ctlr->id){
1745         default:
1746                 break;
1747         case i82540em:
1748         case i82540eplp:
1749         case i82541gi:
1750         case i82541gi2:
1751         case i82541pi:
1752         case i82545em:
1753         case i82545gmc:
1754         case i82547gi:
1755         case i82546gb:
1756         case i82546eb:
1757                 r = csr32r(ctlr, Manc);
1758                 r &= ~Arpen;
1759                 csr32w(ctlr, Manc, r);
1760                 break;
1761         }
1762
1763         csr32w(ctlr, Imc, ~0);
1764         delay(1);
1765         for(timeo = 0; timeo < 1000; timeo++){
1766                 if(!csr32r(ctlr, Icr))
1767                         break;
1768                 delay(1);
1769         }
1770         if(csr32r(ctlr, Icr))
1771                 return -1;
1772
1773         return 0;
1774 }
1775
1776 static void
1777 igbeshutdown(Ether* ether)
1778 {
1779         igbedetach(ether->ctlr);
1780 }
1781
1782 static int
1783 igbereset(Ctlr* ctlr)
1784 {
1785         int ctrl, i, pause, r, swdpio, txcw;
1786
1787         if(igbedetach(ctlr))
1788                 return -1;
1789
1790         /*
1791          * Read the EEPROM, validate the checksum
1792          * then get the device back to a power-on state.
1793          */
1794         if((r = at93c46r(ctlr)) != 0xBABA){
1795                 print("igbe: bad EEPROM checksum - 0x%4.4uX\n", r);
1796                 return -1;
1797         }
1798
1799         /*
1800          * Snarf and set up the receive addresses.
1801          * There are 16 addresses. The first should be the MAC address.
1802          * The others are cleared and not marked valid (MS bit of Rah).
1803          */
1804         if ((ctlr->id == i82546gb || ctlr->id == i82546eb) &&
1805             BUSFNO(ctlr->pcidev->tbdf) == 1)
1806                 ctlr->eeprom[Ea+2] += 0x100;            /* second interface */
1807         if(ctlr->id == i82541gi && ctlr->eeprom[Ea] == 0xFFFF)
1808                 ctlr->eeprom[Ea] = 0xD000;
1809         for(i = Ea; i < Eaddrlen/2; i++){
1810                 ctlr->ra[2*i] = ctlr->eeprom[i];
1811                 ctlr->ra[2*i+1] = ctlr->eeprom[i]>>8;
1812         }
1813         /* lan id seems to vary on 82543gc; don't use it */
1814         if (ctlr->id != i82543gc) {
1815                 r = (csr32r(ctlr, Status) & Lanid) >> 2;
1816                 ctlr->ra[5] += r;               /* ea ctlr[1] = ea ctlr[0]+1 */
1817         }
1818
1819         r = (ctlr->ra[3]<<24)|(ctlr->ra[2]<<16)|(ctlr->ra[1]<<8)|ctlr->ra[0];
1820         csr32w(ctlr, Ral, r);
1821         r = 0x80000000|(ctlr->ra[5]<<8)|ctlr->ra[4];
1822         csr32w(ctlr, Rah, r);
1823         for(i = 1; i < 16; i++){
1824                 csr32w(ctlr, Ral+i*8, 0);
1825                 csr32w(ctlr, Rah+i*8, 0);
1826         }
1827
1828         /*
1829          * Clear the Multicast Table Array.
1830          * It's a 4096 bit vector accessed as 128 32-bit registers.
1831          */
1832         memset(ctlr->mta, 0, sizeof(ctlr->mta));
1833         for(i = 0; i < 128; i++)
1834                 csr32w(ctlr, Mta+i*4, 0);
1835
1836         /*
1837          * Just in case the Eerst didn't load the defaults
1838          * (doesn't appear to fully on the 82543GC), do it manually.
1839          */
1840         if (ctlr->id == i82543gc) {
1841                 txcw = csr32r(ctlr, Txcw);
1842                 txcw &= ~(TxcwAne|TxcwPauseMASK|TxcwFd);
1843                 ctrl = csr32r(ctlr, Ctrl);
1844                 ctrl &= ~(SwdpioloMASK|Frcspd|Ilos|Lrst|Fd);
1845
1846                 if(ctlr->eeprom[Icw1] & 0x0400){
1847                         ctrl |= Fd;
1848                         txcw |= TxcwFd;
1849                 }
1850                 if(ctlr->eeprom[Icw1] & 0x0200)
1851                         ctrl |= Lrst;
1852                 if(ctlr->eeprom[Icw1] & 0x0010)
1853                         ctrl |= Ilos;
1854                 if(ctlr->eeprom[Icw1] & 0x0800)
1855                         ctrl |= Frcspd;
1856                 swdpio = (ctlr->eeprom[Icw1] & 0x01E0)>>5;
1857                 ctrl |= swdpio<<SwdpioloSHIFT;
1858                 csr32w(ctlr, Ctrl, ctrl);
1859
1860                 ctrl = csr32r(ctlr, Ctrlext);
1861                 ctrl &= ~(Ips|SwdpiohiMASK);
1862                 swdpio = (ctlr->eeprom[Icw2] & 0x00F0)>>4;
1863                 if(ctlr->eeprom[Icw1] & 0x1000)
1864                         ctrl |= Ips;
1865                 ctrl |= swdpio<<SwdpiohiSHIFT;
1866                 csr32w(ctlr, Ctrlext, ctrl);
1867
1868                 if(ctlr->eeprom[Icw2] & 0x0800)
1869                         txcw |= TxcwAne;
1870                 pause = (ctlr->eeprom[Icw2] & 0x3000)>>12;
1871                 txcw |= pause<<TxcwPauseSHIFT;
1872                 switch(pause){
1873                 default:
1874                         ctlr->fcrtl = 0x00002000;
1875                         ctlr->fcrth = 0x00004000;
1876                         txcw |= TxcwAs|TxcwPs;
1877                         break;
1878                 case 0:
1879                         ctlr->fcrtl = 0x00002000;
1880                         ctlr->fcrth = 0x00004000;
1881                         break;
1882                 case 2:
1883                         ctlr->fcrtl = 0;
1884                         ctlr->fcrth = 0;
1885                         txcw |= TxcwAs;
1886                         break;
1887                 }
1888                 ctlr->txcw = txcw;
1889                 csr32w(ctlr, Txcw, txcw);
1890         }
1891
1892
1893         /*
1894          * Flow control - values from the datasheet.
1895          */
1896         csr32w(ctlr, Fcal, 0x00C28001);
1897         csr32w(ctlr, Fcah, 0x00000100);
1898         csr32w(ctlr, Fct, 0x00008808);
1899         csr32w(ctlr, Fcttv, 0x00000100);
1900
1901         csr32w(ctlr, Fcrtl, ctlr->fcrtl);
1902         csr32w(ctlr, Fcrth, ctlr->fcrth);
1903
1904         if(!(csr32r(ctlr, Status) & Tbimode) && igbemii(ctlr) < 0)
1905                 return -1;
1906
1907         return 0;
1908 }
1909
1910 static void
1911 igbepci(void)
1912 {
1913         int cls;
1914         Pcidev *p;
1915         Ctlr *ctlr;
1916         void *mem;
1917
1918         p = nil;
1919         while(p = pcimatch(p, 0, 0)){
1920                 if(p->ccrb != 0x02 || p->ccru != 0)
1921                         continue;
1922
1923                 switch((p->did<<16)|p->vid){
1924                 default:
1925                         continue;
1926                 case i82543gc:
1927                 case i82544ei:
1928                 case i82544eif:
1929                 case i82544gc:
1930                 case i82547ei:
1931                 case i82547gi:
1932                 case i82540em:
1933                 case i82540eplp:
1934                 case i82541ei:
1935                 case i82541gi:
1936                 case i82541gi2:
1937                 case i82541pi:
1938                 case i82545em:
1939                 case i82545gmc:
1940                 case i82546gb:
1941                 case i82546eb:
1942                         break;
1943                 }
1944
1945                 mem = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
1946                 if(mem == nil){
1947                         print("igbe: can't map %8.8luX\n", p->mem[0].bar);
1948                         continue;
1949                 }
1950                 cls = pcicfgr8(p, PciCLS);
1951                 switch(cls){
1952                 default:
1953                         print("igbe: p->cls %#ux, setting to 0x10\n", p->cls);
1954                         p->cls = 0x10;
1955                         pcicfgw8(p, PciCLS, p->cls);
1956                         break;
1957                 case 0x08:
1958                 case 0x10:
1959                         break;
1960                 }
1961                 ctlr = malloc(sizeof(Ctlr));
1962                 if(ctlr == nil){
1963                         print("igbe: can't allocate memory\n");
1964                         continue;
1965                 }
1966                 ctlr->port = p->mem[0].bar & ~0x0F;
1967                 ctlr->pcidev = p;
1968                 pcienable(p);
1969                 ctlr->id = (p->did<<16)|p->vid;
1970                 ctlr->cls = cls*4;
1971                 ctlr->nic = mem;
1972
1973                 if(igbereset(ctlr)){
1974                         free(ctlr);
1975                         vunmap(mem, p->mem[0].size);
1976                         continue;
1977                 }
1978                 pcisetbme(p);
1979
1980                 if(igbectlrhead != nil)
1981                         igbectlrtail->next = ctlr;
1982                 else
1983                         igbectlrhead = ctlr;
1984                 igbectlrtail = ctlr;
1985         }
1986 }
1987
1988 static int
1989 igbepnp(Ether* edev)
1990 {
1991         Ctlr *ctlr;
1992
1993         if(igbectlrhead == nil)
1994                 igbepci();
1995
1996         /*
1997          * Any adapter matches if no edev->port is supplied,
1998          * otherwise the ports must match.
1999          */
2000         for(ctlr = igbectlrhead; ctlr != nil; ctlr = ctlr->next){
2001                 if(ctlr->active)
2002                         continue;
2003                 if(edev->port == 0 || edev->port == ctlr->port){
2004                         ctlr->active = 1;
2005                         break;
2006                 }
2007         }
2008         if(ctlr == nil)
2009                 return -1;
2010
2011         edev->ctlr = ctlr;
2012         edev->port = ctlr->port;
2013         edev->irq = ctlr->pcidev->intl;
2014         edev->tbdf = ctlr->pcidev->tbdf;
2015         edev->mbps = 1000;
2016         memmove(edev->ea, ctlr->ra, Eaddrlen);
2017
2018         /*
2019          * Linkage to the generic ethernet driver.
2020          */
2021         edev->attach = igbeattach;
2022         edev->transmit = igbetransmit;
2023         edev->ifstat = igbeifstat;
2024         edev->ctl = igbectl;
2025
2026         edev->arg = edev;
2027         edev->promiscuous = igbepromiscuous;
2028         edev->shutdown = igbeshutdown;
2029         edev->multicast = igbemulticast;
2030
2031         intrenable(edev->irq, igbeinterrupt, edev, edev->tbdf, edev->name);
2032
2033         return 0;
2034 }
2035
2036 void
2037 etherigbelink(void)
2038 {
2039         addethercard("i82543", igbepnp);
2040         addethercard("igbe", igbepnp);
2041 }
2042