]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/etherigbe.c
kernel: fix inproper use of malloc/smalloc
[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
28 #include "etherif.h"
29 #include "ethermii.h"
30
31 enum {
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,
49 };
50
51 enum {
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 */
104
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 */
110         Nstatistics     = 64,
111
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 */
117 };
118
119 enum {                                  /* Ctrl */
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 */
127         SspeedSHIFT     = 8,
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 */
134         SwdpinsloSHIFT  = 18,
135         SwdpioloMASK    = 0x03C00000,   /* Software Defined Pins - I or O */
136         SwdpioloSHIFT   = 22,
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 */
141 };
142
143 /*
144  * can't find Tckok nor Rbcok in any Intel docs,
145  * but even 82543gc docs define Lanid.
146  */
147 enum {                                  /* Status */
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 */
155         LspeedSHIFT     = 6,
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 */
164         PcixspeedSHIFT  = 14,
165         Pcix66          = 0x00000000,   /* 50-66MHz */
166         Pcix100         = 0x00004000,   /* 66-100MHz */
167         Pcix133         = 0x00008000,   /* 100-133MHz */
168 };
169
170 enum {                                  /* Ctrl and Status */
171         Fd              = 0x00000001,   /* Full-Duplex */
172         AsdvMASK        = 0x00000300,
173         AsdvSHIFT       = 8,
174         Asdv10          = 0x00000000,   /* 10Mb/s */
175         Asdv100         = 0x00000100,   /* 100Mb/s */
176         Asdv1000        = 0x00000200,   /* 1000Mb/s */
177 };
178
179 enum {                                  /* Eecd */
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 */
190 };
191
192 enum {                                  /* Ctrlext */
193         Gpien           = 0x0000000F,   /* General Purpose Interrupt Enables */
194         SwdpinshiMASK   = 0x000000F0,   /* Software Defined Pins - hi nibble */
195         SwdpinshiSHIFT  = 4,
196         SwdpiohiMASK    = 0x00000F00,   /* Software Defined Pins - I or O */
197         SwdpiohiSHIFT   = 8,
198         Asdchk          = 0x00001000,   /* ASD Check */
199         Eerst           = 0x00002000,   /* EEPROM Reset */
200         Ips             = 0x00004000,   /* Invert Power State */
201         Spdbyps         = 0x00008000,   /* Speed Select Bypass */
202 };
203
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 */
214 };
215
216 enum {                                  /* Mdic */
217         MDIdMASK        = 0x0000FFFF,   /* Data */
218         MDIdSHIFT       = 0,
219         MDIrMASK        = 0x001F0000,   /* PHY Register Address */
220         MDIrSHIFT       = 16,
221         MDIpMASK        = 0x03E00000,   /* PHY Address */
222         MDIpSHIFT       = 21,
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 */
228 };
229
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 */
241         Gpi1            = 0x00001000,
242         Gpi2            = 0x00002000,
243         Gpi3            = 0x00004000,
244 };
245
246 /*
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.
251  */
252 enum {
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 */
259 };
260
261 enum {                                  /* Txcw */
262         TxcwFd          = 0x00000020,   /* Full Duplex */
263         TxcwHd          = 0x00000040,   /* Half Duplex */
264         TxcwPauseMASK   = 0x00000180,   /* Pause */
265         TxcwPauseSHIFT  = 7,
266         TxcwPs          = (1<<TxcwPauseSHIFT),  /* Pause Supported */
267         TxcwAs          = (2<<TxcwPauseSHIFT),  /* Asymmetric FC desired */
268         TxcwRfiMASK     = 0x00003000,   /* Remote Fault Indication */
269         TxcwRfiSHIFT    = 12,
270         TxcwNpr         = 0x00008000,   /* Next Page Request */
271         TxcwConfig      = 0x40000000,   /* Transmit COnfig Control */
272         TxcwAne         = 0x80000000,   /* Auto-Negotiation Enable */
273 };
274
275 enum {                                  /* Rxcw */
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 */
283 };
284
285 enum {                                  /* Rctl */
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 */
320 };
321
322 enum {                                  /* Tctl */
323         Trst            = 0x00000001,   /* Transmitter Software Reset */
324         Ten             = 0x00000002,   /* Transmit Enable */
325         Psp             = 0x00000008,   /* Pad Short Packets */
326         CtMASK          = 0x00000FF0,   /* Collision Threshold */
327         CtSHIFT         = 4,
328         ColdMASK        = 0x003FF000,   /* Collision Distance */
329         ColdSHIFT       = 12,
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 */
334 };
335
336 enum {                                  /* [RT]xdctl */
337         PthreshMASK     = 0x0000003F,   /* Prefetch Threshold */
338         PthreshSHIFT    = 0,
339         HthreshMASK     = 0x00003F00,   /* Host Threshold */
340         HthreshSHIFT    = 8,
341         WthreshMASK     = 0x003F0000,   /* Writeback Threshold */
342         WthreshSHIFT    = 16,
343         Gran            = 0x01000000,   /* Granularity */
344         LthreshMASK     = 0xFE000000,   /* Low Threshold */
345         LthreshSHIFT    = 25,
346 };
347
348 enum {                                  /* Rxcsum */
349         PcssMASK        = 0x000000FF,   /* Packet Checksum Start */
350         PcssSHIFT       = 0,
351         Ipofl           = 0x00000100,   /* IP Checksum Off-load Enable */
352         Tuofl           = 0x00000200,   /* TCP/UDP Checksum Off-load Enable */
353 };
354
355 enum {                                  /* Manc */
356         Arpen           = 0x00002000,   /* Enable ARP Request Filtering */
357 };
358
359 enum {                                  /* Receive Delay Timer Ring */
360         DelayMASK       = 0x0000FFFF,   /* delay timer in 1.024nS increments */
361         DelaySHIFT      = 0,
362         Fpd             = 0x80000000,   /* Flush partial Descriptor Block */
363 };
364
365 typedef struct Rd {                     /* Receive Descriptor */
366         uint    addr[2];
367         ushort  length;
368         ushort  checksum;
369         uchar   status;
370         uchar   errors;
371         ushort  special;
372 } Rd;
373
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 */
382 };
383
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 */
392 };
393
394 typedef struct Td Td;
395 struct Td {                             /* Transmit Descriptor */
396         union {
397                 uint    addr[2];        /* Data */
398                 struct {                /* Context */
399                         uchar   ipcss;
400                         uchar   ipcso;
401                         ushort  ipcse;
402                         uchar   tucss;
403                         uchar   tucso;
404                         ushort  tucse;
405                 };
406         };
407         uint    control;
408         uint    status;
409 };
410
411 enum {                                  /* Td control */
412         LenMASK         = 0x000FFFFF,   /* Data/Packet Length Field */
413         LenSHIFT        = 0,
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 */
426 };
427
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) */
436         HdrlenSHIFT     = 8,
437         VlanMASK        = 0x0FFF0000,   /* VLAN Identifier */
438         VlanSHIFT       = 16,
439         Tcfi            = 0x10000000,   /* Canonical Form Indicator */
440         PriMASK         = 0xE0000000,   /* User Priority */
441         PriSHIFT        = 29,
442         MssMASK         = 0xFFFF0000,   /* Maximum Segment Size (Tse) */
443         MssSHIFT        = 16,
444 };
445
446 enum {
447         Nrd             = 256,          /* multiple of 8 */
448         Ntd             = 64,           /* multiple of 8 */
449         Nrb             = 1024,         /* private receive buffers per Ctlr */
450         Rbsz            = 2048,
451 };
452
453 typedef struct Ctlr Ctlr;
454 typedef struct Ctlr {
455         int     port;
456         Pcidev* pcidev;
457         Ctlr*   next;
458         Ether*  edev;
459         int     active;
460         int     started;
461         int     id;
462         int     cls;
463         ushort  eeprom[0x40];
464
465         QLock   alock;                  /* attach */
466         void*   alloc;                  /* receive/transmit descriptors */
467         int     nrd;
468         int     ntd;
469         int     nrb;                    /* how many this Ctlr has in the pool */
470
471         int*    nic;
472         Lock    imlock;
473         int     im;                     /* interrupt mask */
474
475         Mii*    mii;
476         Rendez  lrendez;
477         int     lim;
478
479         int     link;
480
481         QLock   slock;
482         uint    statistics[Nstatistics];
483         uint    lsleep;
484         uint    lintr;
485         uint    rsleep;
486         uint    rintr;
487         uint    txdw;
488         uint    tintr;
489         uint    ixsm;
490         uint    ipcs;
491         uint    tcpcs;
492
493         uchar   ra[Eaddrlen];           /* receive address */
494         ulong   mta[128];               /* multicast table array */
495
496         Rendez  rrendez;
497         int     rim;
498         int     rdfree;
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 */
504
505         Lock    tlock;
506         int     tbusy;
507         int     tdfree;
508         Td*     tdba;                   /* transmit descriptor base address */
509         Block** tb;                     /* transmit buffers */
510         int     tdh;                    /* transmit descriptor head */
511         int     tdt;                    /* transmit descriptor tail */
512
513         int     txcw;
514         int     fcrtl;
515         int     fcrth;
516 } Ctlr;
517
518 #define csr32r(c, r)    (*((c)->nic+((r)/4)))
519 #define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
520
521 static Ctlr* igbectlrhead;
522 static Ctlr* igbectlrtail;
523
524 static Lock igberblock;         /* free receive Blocks */
525 static Block* igberbpool;       /* receive Blocks for all igbe controllers */
526
527 static char* statistics[Nstatistics] = {
528         "CRC Error",
529         "Alignment Error",
530         "Symbol Error",
531         "RX Error",
532         "Missed Packets",
533         "Single Collision",
534         "Excessive Collisions",
535         "Multiple Collision",
536         "Late Collisions",
537         nil,
538         "Collision",
539         "Transmit Underrun",
540         "Defer",
541         "Transmit - No CRS",
542         "Sequence Error",
543         "Carrier Extension Error",
544         "Receive Error Length",
545         nil,
546         "XON Received",
547         "XON Transmitted",
548         "XOFF Received",
549         "XOFF Transmitted",
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",
561         nil,
562         "Good Octets Received",
563         nil,
564         "Good Octets Transmitted",
565         nil,
566         nil,
567         nil,
568         "Receive No Buffers",
569         "Receive Undersize",
570         "Receive Fragment",
571         "Receive Oversize",
572         "Receive Jabber",
573         nil,
574         nil,
575         nil,
576         "Total Octets Received",
577         nil,
578         "Total Octets Transmitted",
579         nil,
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",
592 };
593
594 static long
595 igbeifstat(Ether* edev, void* a, long n, ulong offset)
596 {
597         Ctlr *ctlr;
598         char *p, *s;
599         int i, l, r;
600         uvlong tuvl, ruvl;
601
602         p = smalloc(READSTR);
603         l = 0;
604         ctlr = edev->ctlr;
605         qlock(&ctlr->slock);
606         for(i = 0; i < Nstatistics; i++){
607                 r = csr32r(ctlr, Statistics+i*4);
608                 if((s = statistics[i]) == nil)
609                         continue;
610                 switch(i){
611                 case Gorcl:
612                 case Gotcl:
613                 case Torl:
614                 case Totl:
615                         ruvl = r;
616                         ruvl += ((uvlong)csr32r(ctlr, Statistics+(i+1)*4))<<32;
617                         tuvl = ruvl;
618                         tuvl += ctlr->statistics[i];
619                         tuvl += ((uvlong)ctlr->statistics[i+1])<<32;
620                         if(tuvl == 0)
621                                 continue;
622                         ctlr->statistics[i] = tuvl;
623                         ctlr->statistics[i+1] = tuvl>>32;
624                         l += snprint(p+l, READSTR-l, "%s: %llud %llud\n",
625                                 s, tuvl, ruvl);
626                         i++;
627                         break;
628
629                 default:
630                         ctlr->statistics[i] += r;
631                         if(ctlr->statistics[i] == 0)
632                                 continue;
633                         l += snprint(p+l, READSTR-l, "%s: %ud %ud\n",
634                                 s, ctlr->statistics[i], r);
635                         break;
636                 }
637         }
638
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));
649
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]);
655         }
656         l += snprint(p+l, READSTR-l, "\n");
657
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);
665                 }
666                 snprint(p+l, READSTR-l, "\n");
667         }
668         n = readstr(offset, a, n, p);
669         free(p);
670         qunlock(&ctlr->slock);
671
672         return n;
673 }
674
675 enum {
676         CMrdtr,
677 };
678
679 static Cmdtab igbectlmsg[] = {
680         CMrdtr, "rdtr", 2,
681 };
682
683 static long
684 igbectl(Ether* edev, void* buf, long n)
685 {
686         int v;
687         char *p;
688         Ctlr *ctlr;
689         Cmdbuf *cb;
690         Cmdtab *ct;
691
692         if((ctlr = edev->ctlr) == nil)
693                 error(Enonexist);
694
695         cb = parsecmd(buf, n);
696         if(waserror()){
697                 free(cb);
698                 nexterror();
699         }
700
701         ct = lookupcmd(cb, igbectlmsg, nelem(igbectlmsg));
702         switch(ct->index){
703         case CMrdtr:
704                 v = strtol(cb->f[1], &p, 0);
705                 if(v < 0 || p == cb->f[1] || v > 0xFFFF)
706                         error(Ebadarg);
707                 ctlr->rdtr = v;;
708                 csr32w(ctlr, Rdtr, Fpd|v);
709                 break;
710         }
711         free(cb);
712         poperror();
713
714         return n;
715 }
716
717 static void
718 igbepromiscuous(void* arg, int on)
719 {
720         int rctl;
721         Ctlr *ctlr;
722         Ether *edev;
723
724         edev = arg;
725         ctlr = edev->ctlr;
726
727         rctl = csr32r(ctlr, Rctl);
728         rctl &= ~MoMASK;
729         rctl |= Mo47b36;
730         if(on)
731                 rctl |= Upe|Mpe;
732         else
733                 rctl &= ~(Upe|Mpe);
734         csr32w(ctlr, Rctl, rctl|Mpe);   /* temporarily keep Mpe on */
735 }
736
737 static void
738 igbemulticast(void* arg, uchar* addr, int add)
739 {
740         int bit, x;
741         Ctlr *ctlr;
742         Ether *edev;
743
744         edev = arg;
745         ctlr = edev->ctlr;
746
747         x = addr[5]>>1;
748         bit = ((addr[5] & 1)<<4)|(addr[4]>>4);
749         /*
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.
755          */
756         if(add)
757                 ctlr->mta[x] |= 1<<bit;
758 //      else
759 //              ctlr->mta[x] &= ~(1<<bit);
760
761         csr32w(ctlr, Mta+x*4, ctlr->mta[x]);
762 }
763
764 static Block*
765 igberballoc(void)
766 {
767         Block *bp;
768
769         ilock(&igberblock);
770         if((bp = igberbpool) != nil){
771                 igberbpool = bp->next;
772                 bp->next = nil;
773                 _xinc(&bp->ref);        /* prevent bp from being freed */
774         }
775         iunlock(&igberblock);
776
777         return bp;
778 }
779
780 static void
781 igberbfree(Block* bp)
782 {
783         bp->rp = bp->lim - Rbsz;
784         bp->wp = bp->rp;
785         bp->flag &= ~(Bipck | Budpck | Btcpck | Bpktck);
786
787         ilock(&igberblock);
788         bp->next = igberbpool;
789         igberbpool = bp;
790         iunlock(&igberblock);
791 }
792
793 static void
794 igbeim(Ctlr* ctlr, int im)
795 {
796         ilock(&ctlr->imlock);
797         ctlr->im |= im;
798         csr32w(ctlr, Ims, ctlr->im);
799         iunlock(&ctlr->imlock);
800 }
801
802 static int
803 igbelim(void* ctlr)
804 {
805         return ((Ctlr*)ctlr)->lim != 0;
806 }
807
808 static void
809 igbelproc(void* arg)
810 {
811         Ctlr *ctlr;
812         Ether *edev;
813         MiiPhy *phy;
814         int ctrl, r;
815
816         edev = arg;
817         ctlr = edev->ctlr;
818         for(;;){
819                 if(ctlr->mii == nil || ctlr->mii->curphy == nil)
820                         continue;
821
822                 /*
823                  * To do:
824                  *      logic to manage status change,
825                  *      this is incomplete but should work
826                  *      one time to set up the hardware.
827                  *
828                  *      MiiPhy.speed, etc. should be in Mii.
829                  */
830                 if(miistatus(ctlr->mii) < 0)
831                         //continue;
832                         goto enable;
833
834                 phy = ctlr->mii->curphy;
835                 ctrl = csr32r(ctlr, Ctrl);
836
837                 switch(ctlr->id){
838                 case i82543gc:
839                 case i82544ei:
840                 case i82544eif:
841                 default:
842                         if(!(ctrl & Asde)){
843                                 ctrl &= ~(SspeedMASK|Ilos|Fd);
844                                 ctrl |= Frcdplx|Frcspd;
845                                 if(phy->speed == 1000)
846                                         ctrl |= Sspeed1000;
847                                 else if(phy->speed == 100)
848                                         ctrl |= Sspeed100;
849                                 if(phy->fd)
850                                         ctrl |= Fd;
851                         }
852                         break;
853
854                 case i82540em:
855                 case i82540eplp:
856                 case i82547gi:
857                 case i82541gi:
858                 case i82541gi2:
859                 case i82541pi:
860                         break;
861                 }
862
863                 /*
864                  * Collision Distance.
865                  */
866                 r = csr32r(ctlr, Tctl);
867                 r &= ~ColdMASK;
868                 if(phy->fd)
869                         r |= 64<<ColdSHIFT;
870                 else
871                         r |= 512<<ColdSHIFT;
872                 csr32w(ctlr, Tctl, r);
873
874                 /*
875                  * Flow control.
876                  */
877                 if(phy->rfc)
878                         ctrl |= Rfce;
879                 if(phy->tfc)
880                         ctrl |= Tfce;
881                 csr32w(ctlr, Ctrl, ctrl);
882
883 enable:
884                 ctlr->lim = 0;
885                 igbeim(ctlr, Lsc);
886
887                 ctlr->lsleep++;
888                 sleep(&ctlr->lrendez, igbelim, ctlr);
889         }
890 }
891
892 static void
893 igbetxinit(Ctlr* ctlr)
894 {
895         int i, r;
896         Block *bp;
897
898         csr32w(ctlr, Tctl, (0x0F<<CtSHIFT)|Psp|(66<<ColdSHIFT));
899         switch(ctlr->id){
900         default:
901                 r = 6;
902                 break;
903         case i82543gc:
904         case i82544ei:
905         case i82544eif:
906         case i82544gc:
907         case i82540em:
908         case i82540eplp:
909         case i82541ei:
910         case i82541gi:
911         case i82541gi2:
912         case i82541pi:
913         case i82545em:
914         case i82545gmc:
915         case i82546gb:
916         case i82546eb:
917         case i82547ei:
918         case i82547gi:
919                 r = 8;
920                 break;
921         }
922         csr32w(ctlr, Tipg, (6<<20)|(8<<10)|r);
923         csr32w(ctlr, Ait, 0);
924         csr32w(ctlr, Txdmac, 0);
925
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);
931         ctlr->tdt = 0;
932         csr32w(ctlr, Tdt, 0);
933
934         for(i = 0; i < ctlr->ntd; i++){
935                 if((bp = ctlr->tb[i]) != nil){
936                         ctlr->tb[i] = nil;
937                         freeb(bp);
938                 }
939                 memset(&ctlr->tdba[i], 0, sizeof(Td));
940         }
941         ctlr->tdfree = ctlr->ntd;
942
943         csr32w(ctlr, Tidv, 128);
944         r = (4<<WthreshSHIFT)|(4<<HthreshSHIFT)|(8<<PthreshSHIFT);
945
946         switch(ctlr->id){
947         default:
948                 break;
949         case i82540em:
950         case i82540eplp:
951         case i82547gi:
952         case i82545em:
953         case i82545gmc:
954         case i82546gb:
955         case i82546eb:
956         case i82541gi:
957         case i82541gi2:
958         case i82541pi:
959                 r = csr32r(ctlr, Txdctl);
960                 r &= ~WthreshMASK;
961                 r |= Gran|(4<<WthreshSHIFT);
962
963                 csr32w(ctlr, Tadv, 64);
964                 break;
965         }
966
967         csr32w(ctlr, Txdctl, r);
968
969         r = csr32r(ctlr, Tctl);
970         r |= Ten;
971         csr32w(ctlr, Tctl, r);
972 }
973
974 static void
975 igbetransmit(Ether* edev)
976 {
977         Td *td;
978         Block *bp;
979         Ctlr *ctlr;
980         int tdh, tdt;
981
982         ctlr = edev->ctlr;
983
984         ilock(&ctlr->tlock);
985
986         /*
987          * Free any completed packets
988          */
989         tdh = ctlr->tdh;
990         while(NEXT(tdh, ctlr->ntd) != csr32r(ctlr, Tdh)){
991                 if((bp = ctlr->tb[tdh]) != nil){
992                         ctlr->tb[tdh] = nil;
993                         freeb(bp);
994                 }
995                 memset(&ctlr->tdba[tdh], 0, sizeof(Td));
996                 tdh = NEXT(tdh, ctlr->ntd);
997         }
998         ctlr->tdh = tdh;
999
1000         /*
1001          * Try to fill the ring back up.
1002          */
1003         tdt = ctlr->tdt;
1004         while(NEXT(tdt, ctlr->ntd) != tdh){
1005                 if((bp = qget(edev->oq)) == nil)
1006                         break;
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;
1011                 ctlr->tb[tdt] = bp;
1012                 tdt = NEXT(tdt, ctlr->ntd);
1013                 if(NEXT(tdt, ctlr->ntd) == tdh){
1014                         td->control |= Rs;
1015                         ctlr->txdw++;
1016                         ctlr->tdt = tdt;
1017                         csr32w(ctlr, Tdt, tdt);
1018                         igbeim(ctlr, Txdw);
1019                         break;
1020                 }
1021                 ctlr->tdt = tdt;
1022                 csr32w(ctlr, Tdt, tdt);
1023         }
1024
1025         iunlock(&ctlr->tlock);
1026 }
1027
1028 static void
1029 igbereplenish(Ctlr* ctlr)
1030 {
1031         Rd *rd;
1032         int rdt;
1033         Block *bp;
1034
1035         rdt = ctlr->rdt;
1036         while(NEXT(rdt, ctlr->nrd) != ctlr->rdh){
1037                 rd = &ctlr->rdba[rdt];
1038                 if(ctlr->rb[rdt] == nil){
1039                         bp = igberballoc();
1040                         if(bp == nil){
1041                                 iprint("#l%d: igbereplenish: no available buffers\n",
1042                                         ctlr->edev->ctlrno);
1043                                 break;
1044                         }
1045                         ctlr->rb[rdt] = bp;
1046                         rd->addr[0] = PCIWADDR(bp->rp);
1047                         rd->addr[1] = 0;
1048                 }
1049                 coherence();
1050                 rd->status = 0;
1051                 rdt = NEXT(rdt, ctlr->nrd);
1052                 ctlr->rdfree++;
1053         }
1054         ctlr->rdt = rdt;
1055         csr32w(ctlr, Rdt, rdt);
1056 }
1057
1058 static void
1059 igberxinit(Ctlr* ctlr)
1060 {
1061         int i;
1062         Block *bp;
1063
1064         /* temporarily keep Mpe on */
1065         csr32w(ctlr, Rctl, Dpf|Bsize2048|Bam|RdtmsHALF|Mpe);
1066
1067         csr32w(ctlr, Rdbal, PCIWADDR(ctlr->rdba));
1068         csr32w(ctlr, Rdbah, 0);
1069         csr32w(ctlr, Rdlen, ctlr->nrd*sizeof(Rd));
1070         ctlr->rdh = 0;
1071         csr32w(ctlr, Rdh, 0);
1072         ctlr->rdt = 0;
1073         csr32w(ctlr, Rdt, 0);
1074         ctlr->rdtr = 0;
1075         csr32w(ctlr, Rdtr, Fpd|0);
1076
1077         for(i = 0; i < ctlr->nrd; i++){
1078                 if((bp = ctlr->rb[i]) != nil){
1079                         ctlr->rb[i] = nil;
1080                         freeb(bp);
1081                 }
1082         }
1083         igbereplenish(ctlr);
1084
1085         switch(ctlr->id){
1086         case i82540em:
1087         case i82540eplp:
1088         case i82541gi:
1089         case i82541gi2:
1090         case i82541pi:
1091         case i82545em:
1092         case i82545gmc:
1093         case i82546gb:
1094         case i82546eb:
1095         case i82547gi:
1096                 csr32w(ctlr, Radv, 64);
1097                 break;
1098         }
1099         csr32w(ctlr, Rxdctl, (8<<WthreshSHIFT)|(8<<HthreshSHIFT)|4);
1100
1101         /*
1102          * Enable checksum offload.
1103          */
1104         csr32w(ctlr, Rxcsum, Tuofl|Ipofl|(ETHERHDRSIZE<<PcssSHIFT));
1105 }
1106
1107 static int
1108 igberim(void* ctlr)
1109 {
1110         return ((Ctlr*)ctlr)->rim != 0;
1111 }
1112
1113 static void
1114 igberproc(void* arg)
1115 {
1116         Rd *rd;
1117         Block *bp;
1118         Ctlr *ctlr;
1119         int r, rdh;
1120         Ether *edev;
1121
1122         edev = arg;
1123         ctlr = edev->ctlr;
1124
1125         igberxinit(ctlr);
1126         r = csr32r(ctlr, Rctl);
1127         r |= Ren;
1128         csr32w(ctlr, Rctl, r);
1129
1130         for(;;){
1131                 ctlr->rim = 0;
1132                 igbeim(ctlr, Rxt0|Rxo|Rxdmt0|Rxseq);
1133                 ctlr->rsleep++;
1134                 sleep(&ctlr->rrendez, igberim, ctlr);
1135
1136                 rdh = ctlr->rdh;
1137                 for(;;){
1138                         rd = &ctlr->rdba[rdh];
1139
1140                         if(!(rd->status & Rdd))
1141                                 break;
1142
1143                         /*
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.
1149                          */
1150                         if((rd->status & Reop) && rd->errors == 0){
1151                                 bp = ctlr->rb[rdh];
1152                                 ctlr->rb[rdh] = nil;
1153                                 bp->wp += rd->length;
1154                                 bp->next = nil;
1155                                 if(!(rd->status & Ixsm)){
1156                                         ctlr->ixsm++;
1157                                         if(rd->status & Ipcs){
1158                                                 /*
1159                                                  * IP checksum calculated
1160                                                  * (and valid as errors == 0).
1161                                                  */
1162                                                 ctlr->ipcs++;
1163                                                 bp->flag |= Bipck;
1164                                         }
1165                                         if(rd->status & Tcpcs){
1166                                                 /*
1167                                                  * TCP/UDP checksum calculated
1168                                                  * (and valid as errors == 0).
1169                                                  */
1170                                                 ctlr->tcpcs++;
1171                                                 bp->flag |= Btcpck|Budpck;
1172                                         }
1173                                         bp->checksum = rd->checksum;
1174                                         bp->flag |= Bpktck;
1175                                 }
1176                                 etheriq(edev, bp, 1);
1177                         }
1178                         else if(ctlr->rb[rdh] != nil){
1179                                 freeb(ctlr->rb[rdh]);
1180                                 ctlr->rb[rdh] = nil;
1181                         }
1182
1183                         memset(rd, 0, sizeof(Rd));
1184                         coherence();
1185                         ctlr->rdfree--;
1186                         rdh = NEXT(rdh, ctlr->nrd);
1187                 }
1188                 ctlr->rdh = rdh;
1189
1190                 if(ctlr->rdfree < ctlr->nrd/2 || (ctlr->rim & Rxdmt0))
1191                         igbereplenish(ctlr);
1192         }
1193 }
1194
1195 static void
1196 igbeattach(Ether* edev)
1197 {
1198         Block *bp;
1199         Ctlr *ctlr;
1200         char name[KNAMELEN];
1201
1202         ctlr = edev->ctlr;
1203         ctlr->edev = edev;                      /* point back to Ether* */
1204         qlock(&ctlr->alock);
1205         if(ctlr->alloc != nil){                 /* already allocated? */
1206                 qunlock(&ctlr->alock);
1207                 return;
1208         }
1209
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);
1216                 return;
1217         }
1218         ctlr->rdba = (Rd*)ROUNDUP((uintptr)ctlr->alloc, 128);
1219         ctlr->tdba = (Td*)(ctlr->rdba+ctlr->nrd);
1220
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);
1226                 return;
1227         }
1228
1229         if(waserror()){
1230                 while(ctlr->nrb > 0){
1231                         bp = igberballoc();
1232                         bp->free = nil;
1233                         freeb(bp);
1234                         ctlr->nrb--;
1235                 }
1236                 free(ctlr->tb);
1237                 ctlr->tb = nil;
1238                 free(ctlr->rb);
1239                 ctlr->rb = nil;
1240                 free(ctlr->alloc);
1241                 ctlr->alloc = nil;
1242                 qunlock(&ctlr->alock);
1243                 nexterror();
1244         }
1245
1246         for(ctlr->nrb = 0; ctlr->nrb < Nrb; ctlr->nrb++){
1247                 if((bp = allocb(Rbsz)) == nil)
1248                         break;
1249                 bp->free = igberbfree;
1250                 freeb(bp);
1251         }
1252
1253         snprint(name, KNAMELEN, "#l%dlproc", edev->ctlrno);
1254         kproc(name, igbelproc, edev);
1255
1256         snprint(name, KNAMELEN, "#l%drproc", edev->ctlrno);
1257         kproc(name, igberproc, edev);
1258
1259         igbetxinit(ctlr);
1260
1261         qunlock(&ctlr->alock);
1262         poperror();
1263 }
1264
1265 static void
1266 igbeinterrupt(Ureg*, void* arg)
1267 {
1268         Ctlr *ctlr;
1269         Ether *edev;
1270         int icr, im, txdw;
1271
1272         edev = arg;
1273         ctlr = edev->ctlr;
1274
1275         ilock(&ctlr->imlock);
1276         csr32w(ctlr, Imc, ~0);
1277         im = ctlr->im;
1278         txdw = 0;
1279
1280         while((icr = csr32r(ctlr, Icr) & ctlr->im) != 0){
1281                 if(icr & Lsc){
1282                         im &= ~Lsc;
1283                         ctlr->lim = icr & Lsc;
1284                         wakeup(&ctlr->lrendez);
1285                         ctlr->lintr++;
1286                 }
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);
1291                         ctlr->rintr++;
1292                 }
1293                 if(icr & Txdw){
1294                         im &= ~Txdw;
1295                         txdw++;
1296                         ctlr->tintr++;
1297                 }
1298         }
1299
1300         ctlr->im = im;
1301         csr32w(ctlr, Ims, im);
1302         iunlock(&ctlr->imlock);
1303
1304         if(txdw)
1305                 igbetransmit(edev);
1306 }
1307
1308 static int
1309 i82543mdior(Ctlr* ctlr, int n)
1310 {
1311         int ctrl, data, i, r;
1312
1313         /*
1314          * Read n bits from the Management Data I/O Interface.
1315          */
1316         ctrl = csr32r(ctlr, Ctrl);
1317         r = (ctrl & ~Mddo)|Mdco;
1318         data = 0;
1319         for(i = n-1; i >= 0; i--){
1320                 if(csr32r(ctlr, Ctrl) & Mdd)
1321                         data |= (1<<i);
1322                 csr32w(ctlr, Ctrl, Mdc|r);
1323                 csr32w(ctlr, Ctrl, r);
1324         }
1325         csr32w(ctlr, Ctrl, ctrl);
1326
1327         return data;
1328 }
1329
1330 static int
1331 i82543mdiow(Ctlr* ctlr, int bits, int n)
1332 {
1333         int ctrl, i, r;
1334
1335         /*
1336          * Write n bits to the Management Data I/O Interface.
1337          */
1338         ctrl = csr32r(ctlr, Ctrl);
1339         r = Mdco|Mddo|ctrl;
1340         for(i = n-1; i >= 0; i--){
1341                 if(bits & (1<<i))
1342                         r |= Mdd;
1343                 else
1344                         r &= ~Mdd;
1345                 csr32w(ctlr, Ctrl, Mdc|r);
1346                 csr32w(ctlr, Ctrl, r);
1347         }
1348         csr32w(ctlr, Ctrl, ctrl);
1349
1350         return 0;
1351 }
1352
1353 static int
1354 i82543miimir(Mii* mii, int pa, int ra)
1355 {
1356         int data;
1357         Ctlr *ctlr;
1358
1359         ctlr = mii->ctlr;
1360
1361         /*
1362          * MII Management Interface Read.
1363          *
1364          * Preamble;
1365          * ST+OP+PHYAD+REGAD;
1366          * TA + 16 data bits.
1367          */
1368         i82543mdiow(ctlr, 0xFFFFFFFF, 32);
1369         i82543mdiow(ctlr, 0x1800|(pa<<5)|ra, 14);
1370         data = i82543mdior(ctlr, 18);
1371
1372         if(data & 0x10000)
1373                 return -1;
1374
1375         return data & 0xFFFF;
1376 }
1377
1378 static int
1379 i82543miimiw(Mii* mii, int pa, int ra, int data)
1380 {
1381         Ctlr *ctlr;
1382
1383         ctlr = mii->ctlr;
1384
1385         /*
1386          * MII Management Interface Write.
1387          *
1388          * Preamble;
1389          * ST+OP+PHYAD+REGAD+TA + 16 data bits;
1390          * Z.
1391          */
1392         i82543mdiow(ctlr, 0xFFFFFFFF, 32);
1393         data &= 0xFFFF;
1394         data |= (0x05<<(5+5+2+16))|(pa<<(5+2+16))|(ra<<(2+16))|(0x02<<16);
1395         i82543mdiow(ctlr, data, 32);
1396
1397         return 0;
1398 }
1399
1400 static int
1401 igbemiimir(Mii* mii, int pa, int ra)
1402 {
1403         Ctlr *ctlr;
1404         int mdic, timo;
1405
1406         ctlr = mii->ctlr;
1407
1408         csr32w(ctlr, Mdic, MDIrop|(pa<<MDIpSHIFT)|(ra<<MDIrSHIFT));
1409         mdic = 0;
1410         for(timo = 64; timo; timo--){
1411                 mdic = csr32r(ctlr, Mdic);
1412                 if(mdic & (MDIe|MDIready))
1413                         break;
1414                 microdelay(1);
1415         }
1416
1417         if((mdic & (MDIe|MDIready)) == MDIready)
1418                 return mdic & 0xFFFF;
1419         return -1;
1420 }
1421
1422 static int
1423 igbemiimiw(Mii* mii, int pa, int ra, int data)
1424 {
1425         Ctlr *ctlr;
1426         int mdic, timo;
1427
1428         ctlr = mii->ctlr;
1429
1430         data &= MDIdMASK;
1431         csr32w(ctlr, Mdic, MDIwop|(pa<<MDIpSHIFT)|(ra<<MDIrSHIFT)|data);
1432         mdic = 0;
1433         for(timo = 64; timo; timo--){
1434                 mdic = csr32r(ctlr, Mdic);
1435                 if(mdic & (MDIe|MDIready))
1436                         break;
1437                 microdelay(1);
1438         }
1439         if((mdic & (MDIe|MDIready)) == MDIready)
1440                 return 0;
1441         return -1;
1442 }
1443
1444 static int
1445 igbemii(Ctlr* ctlr)
1446 {
1447         MiiPhy *phy;
1448         int ctrl, p, r;
1449
1450         r = csr32r(ctlr, Status);
1451         if(r & Tbimode)
1452                 return -1;
1453         if((ctlr->mii = malloc(sizeof(Mii))) == nil)
1454                 return -1;
1455         ctlr->mii->ctlr = ctlr;
1456
1457         ctrl = csr32r(ctlr, Ctrl);
1458         ctrl |= Slu;
1459
1460         switch(ctlr->id){
1461         case i82543gc:
1462                 ctrl |= Frcdplx|Frcspd;
1463                 csr32w(ctlr, Ctrl, ctrl);
1464
1465                 /*
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
1469                  * so bail.
1470                  */
1471                 r = csr32r(ctlr, Ctrlext);
1472                 if(!(r & Mdro))
1473                         return -1;
1474                 csr32w(ctlr, Ctrlext, r);
1475                 delay(20);
1476                 r = csr32r(ctlr, Ctrlext);
1477                 r &= ~Mdr;
1478                 csr32w(ctlr, Ctrlext, r);
1479                 delay(20);
1480                 r = csr32r(ctlr, Ctrlext);
1481                 r |= Mdr;
1482                 csr32w(ctlr, Ctrlext, r);
1483                 delay(20);
1484
1485                 ctlr->mii->mir = i82543miimir;
1486                 ctlr->mii->miw = i82543miimiw;
1487                 break;
1488         case i82544ei:
1489         case i82544eif:
1490         case i82544gc:
1491         case i82540em:
1492         case i82540eplp:
1493         case i82547ei:
1494         case i82547gi:
1495         case i82541ei:
1496         case i82541gi:
1497         case i82541gi2:
1498         case i82541pi:
1499         case i82545em:
1500         case i82545gmc:
1501         case i82546gb:
1502         case i82546eb:
1503                 ctrl &= ~(Frcdplx|Frcspd);
1504                 csr32w(ctlr, Ctrl, ctrl);
1505                 ctlr->mii->mir = igbemiimir;
1506                 ctlr->mii->miw = igbemiimiw;
1507                 break;
1508         default:
1509                 free(ctlr->mii);
1510                 ctlr->mii = nil;
1511                 return -1;
1512         }
1513
1514         if(mii(ctlr->mii, ~0) == 0 || (phy = ctlr->mii->curphy) == nil){
1515                 free(ctlr->mii);
1516                 ctlr->mii = nil;
1517                 return -1;
1518         }
1519         USED(phy);
1520         // print("oui %X phyno %d\n", phy->oui, phy->phyno);
1521
1522         /*
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
1527          * changes noted.
1528          */
1529         switch(ctlr->id){
1530         case i82547gi:
1531         case i82541gi:
1532         case i82541gi2:
1533         case i82541pi:
1534         case i82545em:
1535         case i82545gmc:
1536         case i82546gb:
1537         case i82546eb:
1538                 break;
1539         default:
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);
1545
1546                 r = miimir(ctlr->mii, 20);
1547                 r |= 0x0070;                    /* +25MHz clock */
1548                 r &= ~0x0F00;
1549                 r |= 0x0100;                    /* 1x downshift */
1550                 miimiw(ctlr->mii, 20, r);
1551
1552                 miireset(ctlr->mii);
1553                 p = 0;
1554                 if(ctlr->txcw & TxcwPs)
1555                         p |= AnaP;
1556                 if(ctlr->txcw & TxcwAs)
1557                         p |= AnaAP;
1558                 miiane(ctlr->mii, ~0, p, ~0);
1559                 break;
1560         }
1561         return 0;
1562 }
1563
1564 static int
1565 at93c46io(Ctlr* ctlr, char* op, int data)
1566 {
1567         char *lp, *p;
1568         int i, loop, eecd, r;
1569
1570         eecd = csr32r(ctlr, Eecd);
1571
1572         r = 0;
1573         loop = -1;
1574         lp = nil;
1575         for(p = op; *p != '\0'; p++){
1576                 switch(*p){
1577                 default:
1578                         return -1;
1579                 case ' ':
1580                         continue;
1581                 case ':':                       /* start of loop */
1582                         loop = strtol(p+1, &lp, 0)-1;
1583                         lp--;
1584                         if(p == lp)
1585                                 loop = 7;
1586                         p = lp;
1587                         continue;
1588                 case ';':                       /* end of loop */
1589                         if(lp == nil)
1590                                 return -1;
1591                         loop--;
1592                         if(loop >= 0)
1593                                 p = lp;
1594                         else
1595                                 lp = nil;
1596                         continue;
1597                 case 'C':                       /* assert clock */
1598                         eecd |= Sk;
1599                         break;
1600                 case 'c':                       /* deassert clock */
1601                         eecd &= ~Sk;
1602                         break;
1603                 case 'D':                       /* next bit in 'data' byte */
1604                         if(loop < 0)
1605                                 return -1;
1606                         if(data & (1<<loop))
1607                                 eecd |= Di;
1608                         else
1609                                 eecd &= ~Di;
1610                         break;
1611                 case 'O':                       /* collect data output */
1612                         i = (csr32r(ctlr, Eecd) & Do) != 0;
1613                         if(loop >= 0)
1614                                 r |= (i<<loop);
1615                         else
1616                                 r = i;
1617                         continue;
1618                 case 'I':                       /* assert data input */
1619                         eecd |= Di;
1620                         break;
1621                 case 'i':                       /* deassert data input */
1622                         eecd &= ~Di;
1623                         break;
1624                 case 'S':                       /* enable chip select */
1625                         eecd |= Cs;
1626                         break;
1627                 case 's':                       /* disable chip select */
1628                         eecd &= ~Cs;
1629                         break;
1630                 }
1631                 csr32w(ctlr, Eecd, eecd);
1632                 microdelay(50);
1633         }
1634         if(loop >= 0)
1635                 return -1;
1636         return r;
1637 }
1638
1639 static int
1640 at93c46r(Ctlr* ctlr)
1641 {
1642         ushort sum;
1643         char rop[20];
1644         int addr, areq, bits, data, eecd, i;
1645
1646         eecd = csr32r(ctlr, Eecd);
1647         if(eecd & Spi){
1648                 print("igbe: SPI EEPROM access not implemented\n");
1649                 return 0;
1650         }
1651         if(eecd & (Eeszaddr|Eesz256))
1652                 bits = 8;
1653         else
1654                 bits = 6;
1655
1656         sum = 0;
1657
1658         switch(ctlr->id){
1659         default:
1660                 areq = 0;
1661                 break;
1662         case i82540em:
1663         case i82540eplp:
1664         case i82541ei:
1665         case i82541gi:
1666         case i82541gi2:
1667         case i82541pi:
1668         case i82545em:
1669         case i82545gmc:
1670         case i82546gb:
1671         case i82546eb:
1672         case i82547ei:
1673         case i82547gi:
1674                 areq = 1;
1675                 csr32w(ctlr, Eecd, eecd|Areq);
1676                 for(i = 0; i < 1000; i++){
1677                         if((eecd = csr32r(ctlr, Eecd)) & Agnt)
1678                                 break;
1679                         microdelay(5);
1680                 }
1681                 if(!(eecd & Agnt)){
1682                         print("igbe: not granted EEPROM access\n");
1683                         goto release;
1684                 }
1685                 break;
1686         }
1687         snprint(rop, sizeof(rop), "S :%dDCc;", bits+3);
1688
1689         for(addr = 0; addr < 0x40; addr++){
1690                 /*
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.
1695                  */
1696                 if(at93c46io(ctlr, rop, (0x06<<bits)|addr) != 0){
1697                         print("igbe: can't set EEPROM address 0x%2.2X\n", addr);
1698                         goto release;
1699                 }
1700                 data = at93c46io(ctlr, ":16COc;", 0);
1701                 at93c46io(ctlr, "sic", 0);
1702                 ctlr->eeprom[addr] = data;
1703                 sum += data;
1704         }
1705
1706 release:
1707         if(areq)
1708                 csr32w(ctlr, Eecd, eecd & ~Areq);
1709         return sum;
1710 }
1711
1712 static int
1713 igbedetach(Ctlr* ctlr)
1714 {
1715         int r, timeo;
1716
1717         /*
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.
1721          */
1722         csr32w(ctlr, Imc, ~0);
1723         csr32w(ctlr, Rctl, 0);
1724         csr32w(ctlr, Tctl, 0);
1725
1726         delay(10);
1727
1728         csr32w(ctlr, Ctrl, Devrst);
1729         delay(1);
1730         for(timeo = 0; timeo < 1000; timeo++){
1731                 if(!(csr32r(ctlr, Ctrl) & Devrst))
1732                         break;
1733                 delay(1);
1734         }
1735         if(csr32r(ctlr, Ctrl) & Devrst)
1736                 return -1;
1737         r = csr32r(ctlr, Ctrlext);
1738         csr32w(ctlr, Ctrlext, r|Eerst);
1739         delay(1);
1740         for(timeo = 0; timeo < 1000; timeo++){
1741                 if(!(csr32r(ctlr, Ctrlext) & Eerst))
1742                         break;
1743                 delay(1);
1744         }
1745         if(csr32r(ctlr, Ctrlext) & Eerst)
1746                 return -1;
1747
1748         switch(ctlr->id){
1749         default:
1750                 break;
1751         case i82540em:
1752         case i82540eplp:
1753         case i82541gi:
1754         case i82541gi2:
1755         case i82541pi:
1756         case i82545em:
1757         case i82545gmc:
1758         case i82547gi:
1759         case i82546gb:
1760         case i82546eb:
1761                 r = csr32r(ctlr, Manc);
1762                 r &= ~Arpen;
1763                 csr32w(ctlr, Manc, r);
1764                 break;
1765         }
1766
1767         csr32w(ctlr, Imc, ~0);
1768         delay(1);
1769         for(timeo = 0; timeo < 1000; timeo++){
1770                 if(!csr32r(ctlr, Icr))
1771                         break;
1772                 delay(1);
1773         }
1774         if(csr32r(ctlr, Icr))
1775                 return -1;
1776
1777         return 0;
1778 }
1779
1780 static void
1781 igbeshutdown(Ether* ether)
1782 {
1783         igbedetach(ether->ctlr);
1784 }
1785
1786 static int
1787 igbereset(Ctlr* ctlr)
1788 {
1789         int ctrl, i, pause, r, swdpio, txcw;
1790
1791         if(igbedetach(ctlr))
1792                 return -1;
1793
1794         /*
1795          * Read the EEPROM, validate the checksum
1796          * then get the device back to a power-on state.
1797          */
1798         if((r = at93c46r(ctlr)) != 0xBABA){
1799                 print("igbe: bad EEPROM checksum - 0x%4.4uX\n", r);
1800                 return -1;
1801         }
1802
1803         /*
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).
1807          */
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;
1816         }
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 */
1821         }
1822
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);
1830         }
1831
1832         /*
1833          * Clear the Multicast Table Array.
1834          * It's a 4096 bit vector accessed as 128 32-bit registers.
1835          */
1836         memset(ctlr->mta, 0, sizeof(ctlr->mta));
1837         for(i = 0; i < 128; i++)
1838                 csr32w(ctlr, Mta+i*4, 0);
1839
1840         /*
1841          * Just in case the Eerst didn't load the defaults
1842          * (doesn't appear to fully on the 82543GC), do it manually.
1843          */
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);
1849
1850                 if(ctlr->eeprom[Icw1] & 0x0400){
1851                         ctrl |= Fd;
1852                         txcw |= TxcwFd;
1853                 }
1854                 if(ctlr->eeprom[Icw1] & 0x0200)
1855                         ctrl |= Lrst;
1856                 if(ctlr->eeprom[Icw1] & 0x0010)
1857                         ctrl |= Ilos;
1858                 if(ctlr->eeprom[Icw1] & 0x0800)
1859                         ctrl |= Frcspd;
1860                 swdpio = (ctlr->eeprom[Icw1] & 0x01E0)>>5;
1861                 ctrl |= swdpio<<SwdpioloSHIFT;
1862                 csr32w(ctlr, Ctrl, ctrl);
1863
1864                 ctrl = csr32r(ctlr, Ctrlext);
1865                 ctrl &= ~(Ips|SwdpiohiMASK);
1866                 swdpio = (ctlr->eeprom[Icw2] & 0x00F0)>>4;
1867                 if(ctlr->eeprom[Icw1] & 0x1000)
1868                         ctrl |= Ips;
1869                 ctrl |= swdpio<<SwdpiohiSHIFT;
1870                 csr32w(ctlr, Ctrlext, ctrl);
1871
1872                 if(ctlr->eeprom[Icw2] & 0x0800)
1873                         txcw |= TxcwAne;
1874                 pause = (ctlr->eeprom[Icw2] & 0x3000)>>12;
1875                 txcw |= pause<<TxcwPauseSHIFT;
1876                 switch(pause){
1877                 default:
1878                         ctlr->fcrtl = 0x00002000;
1879                         ctlr->fcrth = 0x00004000;
1880                         txcw |= TxcwAs|TxcwPs;
1881                         break;
1882                 case 0:
1883                         ctlr->fcrtl = 0x00002000;
1884                         ctlr->fcrth = 0x00004000;
1885                         break;
1886                 case 2:
1887                         ctlr->fcrtl = 0;
1888                         ctlr->fcrth = 0;
1889                         txcw |= TxcwAs;
1890                         break;
1891                 }
1892                 ctlr->txcw = txcw;
1893                 csr32w(ctlr, Txcw, txcw);
1894         }
1895
1896
1897         /*
1898          * Flow control - values from the datasheet.
1899          */
1900         csr32w(ctlr, Fcal, 0x00C28001);
1901         csr32w(ctlr, Fcah, 0x00000100);
1902         csr32w(ctlr, Fct, 0x00008808);
1903         csr32w(ctlr, Fcttv, 0x00000100);
1904
1905         csr32w(ctlr, Fcrtl, ctlr->fcrtl);
1906         csr32w(ctlr, Fcrth, ctlr->fcrth);
1907
1908         if(!(csr32r(ctlr, Status) & Tbimode) && igbemii(ctlr) < 0)
1909                 return -1;
1910
1911         return 0;
1912 }
1913
1914 static void
1915 igbepci(void)
1916 {
1917         int cls;
1918         Pcidev *p;
1919         Ctlr *ctlr;
1920         void *mem;
1921
1922         p = nil;
1923         while(p = pcimatch(p, 0, 0)){
1924                 if(p->ccrb != 0x02 || p->ccru != 0)
1925                         continue;
1926
1927                 switch((p->did<<16)|p->vid){
1928                 default:
1929                         continue;
1930                 case i82543gc:
1931                 case i82544ei:
1932                 case i82544eif:
1933                 case i82544gc:
1934                 case i82547ei:
1935                 case i82547gi:
1936                 case i82540em:
1937                 case i82540eplp:
1938                 case i82541ei:
1939                 case i82541gi:
1940                 case i82541gi2:
1941                 case i82541pi:
1942                 case i82545em:
1943                 case i82545gmc:
1944                 case i82546gb:
1945                 case i82546eb:
1946                         break;
1947                 }
1948
1949                 mem = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
1950                 if(mem == nil){
1951                         print("igbe: can't map %8.8luX\n", p->mem[0].bar);
1952                         continue;
1953                 }
1954                 cls = pcicfgr8(p, PciCLS);
1955                 switch(cls){
1956                         default:
1957                                 print("igbe: unexpected CLS - %d\n", cls*4);
1958                                 break;
1959                         case 0x00:
1960                         case 0xFF:
1961                                 print("igbe: unusable CLS - %d\n", cls*4);
1962                                 continue;
1963                         case 0x08:
1964                         case 0x10:
1965                                 break;
1966                 }
1967                 ctlr = malloc(sizeof(Ctlr));
1968                 if(ctlr == nil){
1969                         print("igbe: can't allocate memory\n");
1970                         continue;
1971                 }
1972                 ctlr->port = p->mem[0].bar & ~0x0F;
1973                 ctlr->pcidev = p;
1974                 ctlr->id = (p->did<<16)|p->vid;
1975                 ctlr->cls = cls*4;
1976                 ctlr->nic = mem;
1977
1978                 if(igbereset(ctlr)){
1979                         free(ctlr);
1980                         vunmap(mem, p->mem[0].size);
1981                         continue;
1982                 }
1983                 pcisetbme(p);
1984
1985                 if(igbectlrhead != nil)
1986                         igbectlrtail->next = ctlr;
1987                 else
1988                         igbectlrhead = ctlr;
1989                 igbectlrtail = ctlr;
1990         }
1991 }
1992
1993 static int
1994 igbepnp(Ether* edev)
1995 {
1996         Ctlr *ctlr;
1997
1998         if(igbectlrhead == nil)
1999                 igbepci();
2000
2001         /*
2002          * Any adapter matches if no edev->port is supplied,
2003          * otherwise the ports must match.
2004          */
2005         for(ctlr = igbectlrhead; ctlr != nil; ctlr = ctlr->next){
2006                 if(ctlr->active)
2007                         continue;
2008                 if(edev->port == 0 || edev->port == ctlr->port){
2009                         ctlr->active = 1;
2010                         break;
2011                 }
2012         }
2013         if(ctlr == nil)
2014                 return -1;
2015
2016         edev->ctlr = ctlr;
2017         edev->port = ctlr->port;
2018         edev->irq = ctlr->pcidev->intl;
2019         edev->tbdf = ctlr->pcidev->tbdf;
2020         edev->mbps = 1000;
2021         memmove(edev->ea, ctlr->ra, Eaddrlen);
2022
2023         /*
2024          * Linkage to the generic ethernet driver.
2025          */
2026         edev->attach = igbeattach;
2027         edev->transmit = igbetransmit;
2028         edev->interrupt = igbeinterrupt;
2029         edev->ifstat = igbeifstat;
2030         edev->ctl = igbectl;
2031
2032         edev->arg = edev;
2033         edev->promiscuous = igbepromiscuous;
2034         edev->shutdown = igbeshutdown;
2035         edev->multicast = igbemulticast;
2036
2037         return 0;
2038 }
2039
2040 void
2041 etherigbelink(void)
2042 {
2043         addethercard("i82543", igbepnp);
2044         addethercard("igbe", igbepnp);
2045 }
2046