]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/etherigbe.c
pc, pc64: more conservative pcirouting
[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
470         int*    nic;
471         Lock    imlock;
472         int     im;                     /* interrupt mask */
473
474         Mii*    mii;
475         Rendez  lrendez;
476         int     lim;
477
478         int     link;
479
480         QLock   slock;
481         uint    statistics[Nstatistics];
482         uint    lsleep;
483         uint    lintr;
484         uint    rsleep;
485         uint    rintr;
486         uint    txdw;
487         uint    tintr;
488         uint    ixsm;
489         uint    ipcs;
490         uint    tcpcs;
491
492         uchar   ra[Eaddrlen];           /* receive address */
493         ulong   mta[128];               /* multicast table array */
494
495         Rendez  rrendez;
496         int     rim;
497         int     rdfree;
498         Rd*     rdba;                   /* receive descriptor base address */
499         Block** rb;                     /* receive buffers */
500         int     rdh;                    /* receive descriptor head */
501         int     rdt;                    /* receive descriptor tail */
502         int     rdtr;                   /* receive delay timer ring value */
503
504         Lock    tlock;
505         int     tbusy;
506         int     tdfree;
507         Td*     tdba;                   /* transmit descriptor base address */
508         Block** tb;                     /* transmit buffers */
509         int     tdh;                    /* transmit descriptor head */
510         int     tdt;                    /* transmit descriptor tail */
511
512         int     txcw;
513         int     fcrtl;
514         int     fcrth;
515 } Ctlr;
516
517 #define csr32r(c, r)    (*((c)->nic+((r)/4)))
518 #define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
519
520 static Ctlr* igbectlrhead;
521 static Ctlr* igbectlrtail;
522
523 static char* statistics[Nstatistics] = {
524         "CRC Error",
525         "Alignment Error",
526         "Symbol Error",
527         "RX Error",
528         "Missed Packets",
529         "Single Collision",
530         "Excessive Collisions",
531         "Multiple Collision",
532         "Late Collisions",
533         nil,
534         "Collision",
535         "Transmit Underrun",
536         "Defer",
537         "Transmit - No CRS",
538         "Sequence Error",
539         "Carrier Extension Error",
540         "Receive Error Length",
541         nil,
542         "XON Received",
543         "XON Transmitted",
544         "XOFF Received",
545         "XOFF Transmitted",
546         "FC Received Unsupported",
547         "Packets Received (64 Bytes)",
548         "Packets Received (65-127 Bytes)",
549         "Packets Received (128-255 Bytes)",
550         "Packets Received (256-511 Bytes)",
551         "Packets Received (512-1023 Bytes)",
552         "Packets Received (1024-1522 Bytes)",
553         "Good Packets Received",
554         "Broadcast Packets Received",
555         "Multicast Packets Received",
556         "Good Packets Transmitted",
557         nil,
558         "Good Octets Received",
559         nil,
560         "Good Octets Transmitted",
561         nil,
562         nil,
563         nil,
564         "Receive No Buffers",
565         "Receive Undersize",
566         "Receive Fragment",
567         "Receive Oversize",
568         "Receive Jabber",
569         nil,
570         nil,
571         nil,
572         "Total Octets Received",
573         nil,
574         "Total Octets Transmitted",
575         nil,
576         "Total Packets Received",
577         "Total Packets Transmitted",
578         "Packets Transmitted (64 Bytes)",
579         "Packets Transmitted (65-127 Bytes)",
580         "Packets Transmitted (128-255 Bytes)",
581         "Packets Transmitted (256-511 Bytes)",
582         "Packets Transmitted (512-1023 Bytes)",
583         "Packets Transmitted (1024-1522 Bytes)",
584         "Multicast Packets Transmitted",
585         "Broadcast Packets Transmitted",
586         "TCP Segmentation Context Transmitted",
587         "TCP Segmentation Context Fail",
588 };
589
590 static long
591 igbeifstat(Ether* edev, void* a, long n, ulong offset)
592 {
593         Ctlr *ctlr;
594         char *p, *s;
595         int i, l, r;
596         uvlong tuvl, ruvl;
597
598         p = smalloc(READSTR);
599         l = 0;
600         ctlr = edev->ctlr;
601         qlock(&ctlr->slock);
602         for(i = 0; i < Nstatistics; i++){
603                 r = csr32r(ctlr, Statistics+i*4);
604                 if((s = statistics[i]) == nil)
605                         continue;
606                 switch(i){
607                 case Gorcl:
608                 case Gotcl:
609                 case Torl:
610                 case Totl:
611                         ruvl = r;
612                         ruvl += ((uvlong)csr32r(ctlr, Statistics+(i+1)*4))<<32;
613                         tuvl = ruvl;
614                         tuvl += ctlr->statistics[i];
615                         tuvl += ((uvlong)ctlr->statistics[i+1])<<32;
616                         if(tuvl == 0)
617                                 continue;
618                         ctlr->statistics[i] = tuvl;
619                         ctlr->statistics[i+1] = tuvl>>32;
620                         l += snprint(p+l, READSTR-l, "%s: %llud %llud\n",
621                                 s, tuvl, ruvl);
622                         i++;
623                         break;
624
625                 default:
626                         ctlr->statistics[i] += r;
627                         if(ctlr->statistics[i] == 0)
628                                 continue;
629                         l += snprint(p+l, READSTR-l, "%s: %ud %ud\n",
630                                 s, ctlr->statistics[i], r);
631                         break;
632                 }
633         }
634
635         l += snprint(p+l, READSTR-l, "lintr: %ud %ud\n",
636                 ctlr->lintr, ctlr->lsleep);
637         l += snprint(p+l, READSTR-l, "rintr: %ud %ud\n",
638                 ctlr->rintr, ctlr->rsleep);
639         l += snprint(p+l, READSTR-l, "tintr: %ud %ud\n",
640                 ctlr->tintr, ctlr->txdw);
641         l += snprint(p+l, READSTR-l, "ixcs: %ud %ud %ud\n",
642                 ctlr->ixsm, ctlr->ipcs, ctlr->tcpcs);
643         l += snprint(p+l, READSTR-l, "rdtr: %ud\n", ctlr->rdtr);
644         l += snprint(p+l, READSTR-l, "Ctrlext: %08x\n", csr32r(ctlr, Ctrlext));
645
646         l += snprint(p+l, READSTR-l, "eeprom:");
647         for(i = 0; i < 0x40; i++){
648                 if(i && ((i & 0x07) == 0))
649                         l += snprint(p+l, READSTR-l, "\n       ");
650                 l += snprint(p+l, READSTR-l, " %4.4uX", ctlr->eeprom[i]);
651         }
652         l += snprint(p+l, READSTR-l, "\n");
653
654         if(ctlr->mii != nil && ctlr->mii->curphy != nil){
655                 l += snprint(p+l, READSTR-l, "phy:   ");
656                 for(i = 0; i < NMiiPhyr; i++){
657                         if(i && ((i & 0x07) == 0))
658                                 l += snprint(p+l, READSTR-l, "\n       ");
659                         r = miimir(ctlr->mii, i);
660                         l += snprint(p+l, READSTR-l, " %4.4uX", r);
661                 }
662                 snprint(p+l, READSTR-l, "\n");
663         }
664         n = readstr(offset, a, n, p);
665         free(p);
666         qunlock(&ctlr->slock);
667
668         return n;
669 }
670
671 enum {
672         CMrdtr,
673 };
674
675 static Cmdtab igbectlmsg[] = {
676         CMrdtr, "rdtr", 2,
677 };
678
679 static long
680 igbectl(Ether* edev, void* buf, long n)
681 {
682         int v;
683         char *p;
684         Ctlr *ctlr;
685         Cmdbuf *cb;
686         Cmdtab *ct;
687
688         if((ctlr = edev->ctlr) == nil)
689                 error(Enonexist);
690
691         cb = parsecmd(buf, n);
692         if(waserror()){
693                 free(cb);
694                 nexterror();
695         }
696
697         ct = lookupcmd(cb, igbectlmsg, nelem(igbectlmsg));
698         switch(ct->index){
699         case CMrdtr:
700                 v = strtol(cb->f[1], &p, 0);
701                 if(v < 0 || p == cb->f[1] || v > 0xFFFF)
702                         error(Ebadarg);
703                 ctlr->rdtr = v;;
704                 csr32w(ctlr, Rdtr, Fpd|v);
705                 break;
706         }
707         free(cb);
708         poperror();
709
710         return n;
711 }
712
713 static void
714 igbepromiscuous(void* arg, int on)
715 {
716         int rctl;
717         Ctlr *ctlr;
718         Ether *edev;
719
720         edev = arg;
721         ctlr = edev->ctlr;
722
723         rctl = csr32r(ctlr, Rctl);
724         rctl &= ~MoMASK;
725         rctl |= Mo47b36;
726         if(on)
727                 rctl |= Upe|Mpe;
728         else
729                 rctl &= ~(Upe|Mpe);
730         csr32w(ctlr, Rctl, rctl|Mpe);   /* temporarily keep Mpe on */
731 }
732
733 static void
734 igbemulticast(void* arg, uchar* addr, int add)
735 {
736         int bit, x;
737         Ctlr *ctlr;
738         Ether *edev;
739
740         edev = arg;
741         ctlr = edev->ctlr;
742
743         x = addr[5]>>1;
744         bit = ((addr[5] & 1)<<4)|(addr[4]>>4);
745         /*
746          * multiple ether addresses can hash to the same filter bit,
747          * so it's never safe to clear a filter bit.
748          * if we want to clear filter bits, we need to keep track of
749          * all the multicast addresses in use, clear all the filter bits,
750          * then set the ones corresponding to in-use addresses.
751          */
752         if(add)
753                 ctlr->mta[x] |= 1<<bit;
754 //      else
755 //              ctlr->mta[x] &= ~(1<<bit);
756
757         csr32w(ctlr, Mta+x*4, ctlr->mta[x]);
758 }
759
760 static void
761 igbeim(Ctlr* ctlr, int im)
762 {
763         ilock(&ctlr->imlock);
764         ctlr->im |= im;
765         csr32w(ctlr, Ims, ctlr->im);
766         iunlock(&ctlr->imlock);
767 }
768
769 static int
770 igbelim(void* ctlr)
771 {
772         return ((Ctlr*)ctlr)->lim != 0;
773 }
774
775 static void
776 igbelproc(void* arg)
777 {
778         Ctlr *ctlr;
779         Ether *edev;
780         MiiPhy *phy;
781         int ctrl, r;
782
783         edev = arg;
784         ctlr = edev->ctlr;
785         while(waserror())
786                 ;
787         for(;;){
788                 if(ctlr->mii == nil || ctlr->mii->curphy == nil)
789                         continue;
790
791                 /*
792                  * To do:
793                  *      logic to manage status change,
794                  *      this is incomplete but should work
795                  *      one time to set up the hardware.
796                  *
797                  *      MiiPhy.speed, etc. should be in Mii.
798                  */
799                 if(miistatus(ctlr->mii) < 0)
800                         //continue;
801                         goto enable;
802
803                 phy = ctlr->mii->curphy;
804                 ctrl = csr32r(ctlr, Ctrl);
805
806                 switch(ctlr->id){
807                 case i82543gc:
808                 case i82544ei:
809                 case i82544eif:
810                 default:
811                         if(!(ctrl & Asde)){
812                                 ctrl &= ~(SspeedMASK|Ilos|Fd);
813                                 ctrl |= Frcdplx|Frcspd;
814                                 if(phy->speed == 1000)
815                                         ctrl |= Sspeed1000;
816                                 else if(phy->speed == 100)
817                                         ctrl |= Sspeed100;
818                                 if(phy->fd)
819                                         ctrl |= Fd;
820                         }
821                         break;
822
823                 case i82540em:
824                 case i82540eplp:
825                 case i82547gi:
826                 case i82541gi:
827                 case i82541gi2:
828                 case i82541pi:
829                         break;
830                 }
831
832                 /*
833                  * Collision Distance.
834                  */
835                 r = csr32r(ctlr, Tctl);
836                 r &= ~ColdMASK;
837                 if(phy->fd)
838                         r |= 64<<ColdSHIFT;
839                 else
840                         r |= 512<<ColdSHIFT;
841                 csr32w(ctlr, Tctl, r);
842
843                 /*
844                  * Flow control.
845                  */
846                 if(phy->rfc)
847                         ctrl |= Rfce;
848                 if(phy->tfc)
849                         ctrl |= Tfce;
850                 csr32w(ctlr, Ctrl, ctrl);
851
852 enable:
853                 ctlr->lim = 0;
854                 igbeim(ctlr, Lsc);
855
856                 ctlr->lsleep++;
857                 sleep(&ctlr->lrendez, igbelim, ctlr);
858         }
859 }
860
861 static void
862 igbetxinit(Ctlr* ctlr)
863 {
864         int i, r;
865         Block *bp;
866
867         csr32w(ctlr, Tctl, (0x0F<<CtSHIFT)|Psp|(66<<ColdSHIFT));
868         switch(ctlr->id){
869         default:
870                 r = 6;
871                 break;
872         case i82543gc:
873         case i82544ei:
874         case i82544eif:
875         case i82544gc:
876         case i82540em:
877         case i82540eplp:
878         case i82541ei:
879         case i82541gi:
880         case i82541gi2:
881         case i82541pi:
882         case i82545em:
883         case i82545gmc:
884         case i82546gb:
885         case i82546eb:
886         case i82547ei:
887         case i82547gi:
888                 r = 8;
889                 break;
890         }
891         csr32w(ctlr, Tipg, (6<<20)|(8<<10)|r);
892         csr32w(ctlr, Ait, 0);
893         csr32w(ctlr, Txdmac, 0);
894
895         csr32w(ctlr, Tdbal, PCIWADDR(ctlr->tdba));
896         csr32w(ctlr, Tdbah, 0);
897         csr32w(ctlr, Tdlen, ctlr->ntd*sizeof(Td));
898         ctlr->tdh = PREV(0, ctlr->ntd);
899         csr32w(ctlr, Tdh, 0);
900         ctlr->tdt = 0;
901         csr32w(ctlr, Tdt, 0);
902
903         for(i = 0; i < ctlr->ntd; i++){
904                 if((bp = ctlr->tb[i]) != nil){
905                         ctlr->tb[i] = nil;
906                         freeb(bp);
907                 }
908                 memset(&ctlr->tdba[i], 0, sizeof(Td));
909         }
910         ctlr->tdfree = ctlr->ntd;
911
912         csr32w(ctlr, Tidv, 128);
913         r = (4<<WthreshSHIFT)|(4<<HthreshSHIFT)|(8<<PthreshSHIFT);
914
915         switch(ctlr->id){
916         default:
917                 break;
918         case i82540em:
919         case i82540eplp:
920         case i82547gi:
921         case i82545em:
922         case i82545gmc:
923         case i82546gb:
924         case i82546eb:
925         case i82541gi:
926         case i82541gi2:
927         case i82541pi:
928                 r = csr32r(ctlr, Txdctl);
929                 r &= ~WthreshMASK;
930                 r |= Gran|(4<<WthreshSHIFT);
931
932                 csr32w(ctlr, Tadv, 64);
933                 break;
934         }
935
936         csr32w(ctlr, Txdctl, r);
937
938         r = csr32r(ctlr, Tctl);
939         r |= Ten;
940         csr32w(ctlr, Tctl, r);
941 }
942
943 static void
944 igbetransmit(Ether* edev)
945 {
946         Td *td;
947         Block *bp;
948         Ctlr *ctlr;
949         int tdh, tdt;
950
951         ctlr = edev->ctlr;
952
953         ilock(&ctlr->tlock);
954
955         /*
956          * Free any completed packets
957          */
958         tdh = ctlr->tdh;
959         while(NEXT(tdh, ctlr->ntd) != csr32r(ctlr, Tdh)){
960                 if((bp = ctlr->tb[tdh]) != nil){
961                         ctlr->tb[tdh] = nil;
962                         freeb(bp);
963                 }
964                 memset(&ctlr->tdba[tdh], 0, sizeof(Td));
965                 tdh = NEXT(tdh, ctlr->ntd);
966         }
967         ctlr->tdh = tdh;
968
969         /*
970          * Try to fill the ring back up.
971          */
972         tdt = ctlr->tdt;
973         while(NEXT(tdt, ctlr->ntd) != tdh){
974                 if((bp = qget(edev->oq)) == nil)
975                         break;
976                 td = &ctlr->tdba[tdt];
977                 td->addr[0] = PCIWADDR(bp->rp);
978                 td->control = ((BLEN(bp) & LenMASK)<<LenSHIFT);
979                 td->control |= Dext|Ifcs|Teop|DtypeDD;
980                 ctlr->tb[tdt] = bp;
981                 tdt = NEXT(tdt, ctlr->ntd);
982                 if(NEXT(tdt, ctlr->ntd) == tdh){
983                         td->control |= Rs;
984                         ctlr->txdw++;
985                         ctlr->tdt = tdt;
986                         csr32w(ctlr, Tdt, tdt);
987                         igbeim(ctlr, Txdw);
988                         break;
989                 }
990                 ctlr->tdt = tdt;
991                 csr32w(ctlr, Tdt, tdt);
992         }
993
994         iunlock(&ctlr->tlock);
995 }
996
997 static void
998 igbereplenish(Ctlr* ctlr)
999 {
1000         Rd *rd;
1001         int rdt;
1002         Block *bp;
1003
1004         rdt = ctlr->rdt;
1005         while(NEXT(rdt, ctlr->nrd) != ctlr->rdh){
1006                 rd = &ctlr->rdba[rdt];
1007                 if(ctlr->rb[rdt] == nil){
1008                         bp = allocb(Rbsz);
1009                         bp->rp = bp->lim - Rbsz;
1010                         bp->wp = bp->rp;
1011                         ctlr->rb[rdt] = bp;
1012                         rd->addr[0] = PCIWADDR(bp->rp);
1013                         rd->addr[1] = 0;
1014                 }
1015                 coherence();
1016                 rd->status = 0;
1017                 rdt = NEXT(rdt, ctlr->nrd);
1018                 ctlr->rdfree++;
1019         }
1020         ctlr->rdt = rdt;
1021         csr32w(ctlr, Rdt, rdt);
1022 }
1023
1024 static void
1025 igberxinit(Ctlr* ctlr)
1026 {
1027         int i;
1028         Block *bp;
1029
1030         /* temporarily keep Mpe on */
1031         csr32w(ctlr, Rctl, Dpf|Bsize2048|Bam|RdtmsHALF|Mpe);
1032
1033         csr32w(ctlr, Rdbal, PCIWADDR(ctlr->rdba));
1034         csr32w(ctlr, Rdbah, 0);
1035         csr32w(ctlr, Rdlen, ctlr->nrd*sizeof(Rd));
1036         ctlr->rdh = 0;
1037         csr32w(ctlr, Rdh, 0);
1038         ctlr->rdt = 0;
1039         csr32w(ctlr, Rdt, 0);
1040         ctlr->rdtr = 0;
1041         csr32w(ctlr, Rdtr, Fpd|0);
1042
1043         for(i = 0; i < ctlr->nrd; i++){
1044                 if((bp = ctlr->rb[i]) != nil){
1045                         ctlr->rb[i] = nil;
1046                         freeb(bp);
1047                 }
1048         }
1049         igbereplenish(ctlr);
1050
1051         switch(ctlr->id){
1052         case i82540em:
1053         case i82540eplp:
1054         case i82541gi:
1055         case i82541gi2:
1056         case i82541pi:
1057         case i82545em:
1058         case i82545gmc:
1059         case i82546gb:
1060         case i82546eb:
1061         case i82547gi:
1062                 csr32w(ctlr, Radv, 64);
1063                 break;
1064         }
1065         csr32w(ctlr, Rxdctl, (8<<WthreshSHIFT)|(8<<HthreshSHIFT)|4);
1066
1067         /*
1068          * Disable checksum offload as it has known bugs.
1069          */
1070         csr32w(ctlr, Rxcsum, ETHERHDRSIZE<<PcssSHIFT);
1071 }
1072
1073 static int
1074 igberim(void* ctlr)
1075 {
1076         return ((Ctlr*)ctlr)->rim != 0;
1077 }
1078
1079 static void
1080 igberproc(void* arg)
1081 {
1082         Rd *rd;
1083         Block *bp;
1084         Ctlr *ctlr;
1085         int r, rdh;
1086         Ether *edev;
1087
1088         edev = arg;
1089         ctlr = edev->ctlr;
1090
1091         igberxinit(ctlr);
1092         r = csr32r(ctlr, Rctl);
1093         r |= Ren;
1094         csr32w(ctlr, Rctl, r);
1095
1096         while(waserror())
1097                 ;
1098
1099         for(;;){
1100                 ctlr->rim = 0;
1101                 igbeim(ctlr, Rxt0|Rxo|Rxdmt0|Rxseq);
1102                 ctlr->rsleep++;
1103                 sleep(&ctlr->rrendez, igberim, ctlr);
1104
1105                 rdh = ctlr->rdh;
1106                 for(;;){
1107                         rd = &ctlr->rdba[rdh];
1108
1109                         if(!(rd->status & Rdd))
1110                                 break;
1111
1112                         /*
1113                          * Accept eop packets with no errors.
1114                          * With no errors and the Ixsm bit set,
1115                          * the descriptor status Tpcs and Ipcs bits give
1116                          * an indication of whether the checksums were
1117                          * calculated and valid.
1118                          */
1119                         if((rd->status & Reop) && rd->errors == 0){
1120                                 bp = ctlr->rb[rdh];
1121                                 ctlr->rb[rdh] = nil;
1122                                 bp->wp += rd->length;
1123                                 bp->next = nil;
1124                                 if(!(rd->status & Ixsm)){
1125                                         ctlr->ixsm++;
1126                                         if(rd->status & Ipcs){
1127                                                 /*
1128                                                  * IP checksum calculated
1129                                                  * (and valid as errors == 0).
1130                                                  */
1131                                                 ctlr->ipcs++;
1132                                                 bp->flag |= Bipck;
1133                                         }
1134                                         if(rd->status & Tcpcs){
1135                                                 /*
1136                                                  * TCP/UDP checksum calculated
1137                                                  * (and valid as errors == 0).
1138                                                  */
1139                                                 ctlr->tcpcs++;
1140                                                 bp->flag |= Btcpck|Budpck;
1141                                         }
1142                                         bp->checksum = rd->checksum;
1143                                         bp->flag |= Bpktck;
1144                                 }
1145                                 etheriq(edev, bp, 1);
1146                         }
1147                         else if(ctlr->rb[rdh] != nil){
1148                                 freeb(ctlr->rb[rdh]);
1149                                 ctlr->rb[rdh] = nil;
1150                         }
1151
1152                         memset(rd, 0, sizeof(Rd));
1153                         coherence();
1154                         ctlr->rdfree--;
1155                         rdh = NEXT(rdh, ctlr->nrd);
1156                 }
1157                 ctlr->rdh = rdh;
1158
1159                 if(ctlr->rdfree < ctlr->nrd/2 || (ctlr->rim & Rxdmt0))
1160                         igbereplenish(ctlr);
1161         }
1162 }
1163
1164 static void
1165 igbeattach(Ether* edev)
1166 {
1167         Ctlr *ctlr;
1168         char name[KNAMELEN];
1169
1170         ctlr = edev->ctlr;
1171         ctlr->edev = edev;                      /* point back to Ether* */
1172         qlock(&ctlr->alock);
1173         if(ctlr->alloc != nil){                 /* already allocated? */
1174                 qunlock(&ctlr->alock);
1175                 return;
1176         }
1177
1178         ctlr->nrd = ROUND(Nrd, 8);
1179         ctlr->ntd = ROUND(Ntd, 8);
1180         ctlr->alloc = malloc(ctlr->nrd*sizeof(Rd)+ctlr->ntd*sizeof(Td) + 127);
1181         if(ctlr->alloc == nil){
1182                 print("igbe: can't allocate ctlr->alloc\n");
1183                 qunlock(&ctlr->alock);
1184                 return;
1185         }
1186         ctlr->rdba = (Rd*)ROUNDUP((uintptr)ctlr->alloc, 128);
1187         ctlr->tdba = (Td*)(ctlr->rdba+ctlr->nrd);
1188
1189         ctlr->rb = malloc(ctlr->nrd*sizeof(Block*));
1190         ctlr->tb = malloc(ctlr->ntd*sizeof(Block*));
1191         if (ctlr->rb == nil || ctlr->tb == nil) {
1192                 print("igbe: can't allocate ctlr->rb or ctlr->tb\n");
1193                 qunlock(&ctlr->alock);
1194                 return;
1195         }
1196
1197         if(waserror()){
1198                 free(ctlr->tb);
1199                 ctlr->tb = nil;
1200                 free(ctlr->rb);
1201                 ctlr->rb = nil;
1202                 free(ctlr->alloc);
1203                 ctlr->alloc = nil;
1204                 qunlock(&ctlr->alock);
1205                 nexterror();
1206         }
1207
1208         snprint(name, KNAMELEN, "#l%dlproc", edev->ctlrno);
1209         kproc(name, igbelproc, edev);
1210
1211         snprint(name, KNAMELEN, "#l%drproc", edev->ctlrno);
1212         kproc(name, igberproc, edev);
1213
1214         igbetxinit(ctlr);
1215
1216         qunlock(&ctlr->alock);
1217         poperror();
1218 }
1219
1220 static void
1221 igbeinterrupt(Ureg*, void* arg)
1222 {
1223         Ctlr *ctlr;
1224         Ether *edev;
1225         int icr, im, txdw;
1226
1227         edev = arg;
1228         ctlr = edev->ctlr;
1229
1230         ilock(&ctlr->imlock);
1231         csr32w(ctlr, Imc, ~0);
1232         im = ctlr->im;
1233         txdw = 0;
1234
1235         while((icr = csr32r(ctlr, Icr) & ctlr->im) != 0){
1236                 if(icr & Lsc){
1237                         im &= ~Lsc;
1238                         ctlr->lim = icr & Lsc;
1239                         wakeup(&ctlr->lrendez);
1240                         ctlr->lintr++;
1241                 }
1242                 if(icr & (Rxt0|Rxo|Rxdmt0|Rxseq)){
1243                         im &= ~(Rxt0|Rxo|Rxdmt0|Rxseq);
1244                         ctlr->rim = icr & (Rxt0|Rxo|Rxdmt0|Rxseq);
1245                         wakeup(&ctlr->rrendez);
1246                         ctlr->rintr++;
1247                 }
1248                 if(icr & Txdw){
1249                         im &= ~Txdw;
1250                         txdw++;
1251                         ctlr->tintr++;
1252                 }
1253         }
1254
1255         ctlr->im = im;
1256         csr32w(ctlr, Ims, im);
1257         iunlock(&ctlr->imlock);
1258
1259         if(txdw)
1260                 igbetransmit(edev);
1261 }
1262
1263 static int
1264 i82543mdior(Ctlr* ctlr, int n)
1265 {
1266         int ctrl, data, i, r;
1267
1268         /*
1269          * Read n bits from the Management Data I/O Interface.
1270          */
1271         ctrl = csr32r(ctlr, Ctrl);
1272         r = (ctrl & ~Mddo)|Mdco;
1273         data = 0;
1274         for(i = n-1; i >= 0; i--){
1275                 if(csr32r(ctlr, Ctrl) & Mdd)
1276                         data |= (1<<i);
1277                 csr32w(ctlr, Ctrl, Mdc|r);
1278                 csr32w(ctlr, Ctrl, r);
1279         }
1280         csr32w(ctlr, Ctrl, ctrl);
1281
1282         return data;
1283 }
1284
1285 static int
1286 i82543mdiow(Ctlr* ctlr, int bits, int n)
1287 {
1288         int ctrl, i, r;
1289
1290         /*
1291          * Write n bits to the Management Data I/O Interface.
1292          */
1293         ctrl = csr32r(ctlr, Ctrl);
1294         r = Mdco|Mddo|ctrl;
1295         for(i = n-1; i >= 0; i--){
1296                 if(bits & (1<<i))
1297                         r |= Mdd;
1298                 else
1299                         r &= ~Mdd;
1300                 csr32w(ctlr, Ctrl, Mdc|r);
1301                 csr32w(ctlr, Ctrl, r);
1302         }
1303         csr32w(ctlr, Ctrl, ctrl);
1304
1305         return 0;
1306 }
1307
1308 static int
1309 i82543miimir(Mii* mii, int pa, int ra)
1310 {
1311         int data;
1312         Ctlr *ctlr;
1313
1314         ctlr = mii->ctlr;
1315
1316         /*
1317          * MII Management Interface Read.
1318          *
1319          * Preamble;
1320          * ST+OP+PHYAD+REGAD;
1321          * TA + 16 data bits.
1322          */
1323         i82543mdiow(ctlr, 0xFFFFFFFF, 32);
1324         i82543mdiow(ctlr, 0x1800|(pa<<5)|ra, 14);
1325         data = i82543mdior(ctlr, 18);
1326
1327         if(data & 0x10000)
1328                 return -1;
1329
1330         return data & 0xFFFF;
1331 }
1332
1333 static int
1334 i82543miimiw(Mii* mii, int pa, int ra, int data)
1335 {
1336         Ctlr *ctlr;
1337
1338         ctlr = mii->ctlr;
1339
1340         /*
1341          * MII Management Interface Write.
1342          *
1343          * Preamble;
1344          * ST+OP+PHYAD+REGAD+TA + 16 data bits;
1345          * Z.
1346          */
1347         i82543mdiow(ctlr, 0xFFFFFFFF, 32);
1348         data &= 0xFFFF;
1349         data |= (0x05<<(5+5+2+16))|(pa<<(5+2+16))|(ra<<(2+16))|(0x02<<16);
1350         i82543mdiow(ctlr, data, 32);
1351
1352         return 0;
1353 }
1354
1355 static int
1356 igbemiimir(Mii* mii, int pa, int ra)
1357 {
1358         Ctlr *ctlr;
1359         int mdic, timo;
1360
1361         ctlr = mii->ctlr;
1362
1363         csr32w(ctlr, Mdic, MDIrop|(pa<<MDIpSHIFT)|(ra<<MDIrSHIFT));
1364         mdic = 0;
1365         for(timo = 64; timo; timo--){
1366                 mdic = csr32r(ctlr, Mdic);
1367                 if(mdic & (MDIe|MDIready))
1368                         break;
1369                 microdelay(1);
1370         }
1371
1372         if((mdic & (MDIe|MDIready)) == MDIready)
1373                 return mdic & 0xFFFF;
1374         return -1;
1375 }
1376
1377 static int
1378 igbemiimiw(Mii* mii, int pa, int ra, int data)
1379 {
1380         Ctlr *ctlr;
1381         int mdic, timo;
1382
1383         ctlr = mii->ctlr;
1384
1385         data &= MDIdMASK;
1386         csr32w(ctlr, Mdic, MDIwop|(pa<<MDIpSHIFT)|(ra<<MDIrSHIFT)|data);
1387         mdic = 0;
1388         for(timo = 64; timo; timo--){
1389                 mdic = csr32r(ctlr, Mdic);
1390                 if(mdic & (MDIe|MDIready))
1391                         break;
1392                 microdelay(1);
1393         }
1394         if((mdic & (MDIe|MDIready)) == MDIready)
1395                 return 0;
1396         return -1;
1397 }
1398
1399 static int
1400 igbemii(Ctlr* ctlr)
1401 {
1402         MiiPhy *phy;
1403         int ctrl, p, r;
1404
1405         r = csr32r(ctlr, Status);
1406         if(r & Tbimode)
1407                 return -1;
1408         if((ctlr->mii = malloc(sizeof(Mii))) == nil)
1409                 return -1;
1410         ctlr->mii->ctlr = ctlr;
1411
1412         ctrl = csr32r(ctlr, Ctrl);
1413         ctrl |= Slu;
1414
1415         switch(ctlr->id){
1416         case i82543gc:
1417                 ctrl |= Frcdplx|Frcspd;
1418                 csr32w(ctlr, Ctrl, ctrl);
1419
1420                 /*
1421                  * The reset pin direction (Mdro) should already
1422                  * be set from the EEPROM load.
1423                  * If it's not set this configuration is unexpected
1424                  * so bail.
1425                  */
1426                 r = csr32r(ctlr, Ctrlext);
1427                 if(!(r & Mdro)) {
1428                         print("igbe: 82543gc Mdro not set\n");
1429                         return -1;
1430                 }
1431                 csr32w(ctlr, Ctrlext, r);
1432                 delay(20);
1433                 r = csr32r(ctlr, Ctrlext);
1434                 r &= ~Mdr;
1435                 csr32w(ctlr, Ctrlext, r);
1436                 delay(20);
1437                 r = csr32r(ctlr, Ctrlext);
1438                 r |= Mdr;
1439                 csr32w(ctlr, Ctrlext, r);
1440                 delay(20);
1441
1442                 ctlr->mii->mir = i82543miimir;
1443                 ctlr->mii->miw = i82543miimiw;
1444                 break;
1445         case i82544ei:
1446         case i82544eif:
1447         case i82544gc:
1448         case i82540em:
1449         case i82540eplp:
1450         case i82547ei:
1451         case i82547gi:
1452         case i82541ei:
1453         case i82541gi:
1454         case i82541gi2:
1455         case i82541pi:
1456         case i82545em:
1457         case i82545gmc:
1458         case i82546gb:
1459         case i82546eb:
1460                 ctrl &= ~(Frcdplx|Frcspd);
1461                 csr32w(ctlr, Ctrl, ctrl);
1462                 ctlr->mii->mir = igbemiimir;
1463                 ctlr->mii->miw = igbemiimiw;
1464                 break;
1465         default:
1466                 free(ctlr->mii);
1467                 ctlr->mii = nil;
1468                 return -1;
1469         }
1470
1471         if(mii(ctlr->mii, ~0) == 0 || (phy = ctlr->mii->curphy) == nil){
1472                 free(ctlr->mii);
1473                 ctlr->mii = nil;
1474                 return -1;
1475         }
1476         USED(phy);
1477         // print("oui %X phyno %d\n", phy->oui, phy->phyno);
1478
1479         /*
1480          * 8254X-specific PHY registers not in 802.3:
1481          *      0x10    PHY specific control
1482          *      0x14    extended PHY specific control
1483          * Set appropriate values then reset the PHY to have
1484          * changes noted.
1485          */
1486         switch(ctlr->id){
1487         case i82547gi:
1488         case i82541gi:
1489         case i82541gi2:
1490         case i82541pi:
1491         case i82545em:
1492         case i82545gmc:
1493         case i82546gb:
1494         case i82546eb:
1495                 break;
1496         default:
1497                 r = miimir(ctlr->mii, 16);
1498                 r |= 0x0800;                    /* assert CRS on Tx */
1499                 r |= 0x0060;                    /* auto-crossover all speeds */
1500                 r |= 0x0002;                    /* polarity reversal enabled */
1501                 miimiw(ctlr->mii, 16, r);
1502
1503                 r = miimir(ctlr->mii, 20);
1504                 r |= 0x0070;                    /* +25MHz clock */
1505                 r &= ~0x0F00;
1506                 r |= 0x0100;                    /* 1x downshift */
1507                 miimiw(ctlr->mii, 20, r);
1508
1509                 miireset(ctlr->mii);
1510                 p = 0;
1511                 if(ctlr->txcw & TxcwPs)
1512                         p |= AnaP;
1513                 if(ctlr->txcw & TxcwAs)
1514                         p |= AnaAP;
1515                 miiane(ctlr->mii, ~0, p, ~0);
1516                 break;
1517         }
1518         return 0;
1519 }
1520
1521 static int
1522 at93c46io(Ctlr* ctlr, char* op, int data)
1523 {
1524         char *lp, *p;
1525         int i, loop, eecd, r;
1526
1527         eecd = csr32r(ctlr, Eecd);
1528
1529         r = 0;
1530         loop = -1;
1531         lp = nil;
1532         for(p = op; *p != '\0'; p++){
1533                 switch(*p){
1534                 default:
1535                         return -1;
1536                 case ' ':
1537                         continue;
1538                 case ':':                       /* start of loop */
1539                         loop = strtol(p+1, &lp, 0)-1;
1540                         lp--;
1541                         if(p == lp)
1542                                 loop = 7;
1543                         p = lp;
1544                         continue;
1545                 case ';':                       /* end of loop */
1546                         if(lp == nil)
1547                                 return -1;
1548                         loop--;
1549                         if(loop >= 0)
1550                                 p = lp;
1551                         else
1552                                 lp = nil;
1553                         continue;
1554                 case 'C':                       /* assert clock */
1555                         eecd |= Sk;
1556                         break;
1557                 case 'c':                       /* deassert clock */
1558                         eecd &= ~Sk;
1559                         break;
1560                 case 'D':                       /* next bit in 'data' byte */
1561                         if(loop < 0)
1562                                 return -1;
1563                         if(data & (1<<loop))
1564                                 eecd |= Di;
1565                         else
1566                                 eecd &= ~Di;
1567                         break;
1568                 case 'O':                       /* collect data output */
1569                         i = (csr32r(ctlr, Eecd) & Do) != 0;
1570                         if(loop >= 0)
1571                                 r |= (i<<loop);
1572                         else
1573                                 r = i;
1574                         continue;
1575                 case 'I':                       /* assert data input */
1576                         eecd |= Di;
1577                         break;
1578                 case 'i':                       /* deassert data input */
1579                         eecd &= ~Di;
1580                         break;
1581                 case 'S':                       /* enable chip select */
1582                         eecd |= Cs;
1583                         break;
1584                 case 's':                       /* disable chip select */
1585                         eecd &= ~Cs;
1586                         break;
1587                 }
1588                 csr32w(ctlr, Eecd, eecd);
1589                 microdelay(50);
1590         }
1591         if(loop >= 0)
1592                 return -1;
1593         return r;
1594 }
1595
1596 static int
1597 at93c46r(Ctlr* ctlr)
1598 {
1599         ushort sum;
1600         char rop[20];
1601         int addr, areq, bits, data, eecd, i;
1602
1603         eecd = csr32r(ctlr, Eecd);
1604         if(eecd & Spi){
1605                 print("igbe: SPI EEPROM access not implemented\n");
1606                 return 0;
1607         }
1608         if(eecd & (Eeszaddr|Eesz256))
1609                 bits = 8;
1610         else
1611                 bits = 6;
1612
1613         sum = 0;
1614
1615         switch(ctlr->id){
1616         default:
1617                 areq = 0;
1618                 break;
1619         case i82540em:
1620         case i82540eplp:
1621         case i82541ei:
1622         case i82541gi:
1623         case i82541gi2:
1624         case i82541pi:
1625         case i82545em:
1626         case i82545gmc:
1627         case i82546gb:
1628         case i82546eb:
1629         case i82547ei:
1630         case i82547gi:
1631                 areq = 1;
1632                 csr32w(ctlr, Eecd, eecd|Areq);
1633                 for(i = 0; i < 1000; i++){
1634                         if((eecd = csr32r(ctlr, Eecd)) & Agnt)
1635                                 break;
1636                         microdelay(5);
1637                 }
1638                 if(!(eecd & Agnt)){
1639                         print("igbe: not granted EEPROM access\n");
1640                         goto release;
1641                 }
1642                 break;
1643         }
1644         snprint(rop, sizeof(rop), "S :%dDCc;", bits+3);
1645
1646         for(addr = 0; addr < 0x40; addr++){
1647                 /*
1648                  * Read a word at address 'addr' from the Atmel AT93C46
1649                  * 3-Wire Serial EEPROM or compatible. The EEPROM access is
1650                  * controlled by 4 bits in Eecd. See the AT93C46 datasheet
1651                  * for protocol details.
1652                  */
1653                 if(at93c46io(ctlr, rop, (0x06<<bits)|addr) != 0){
1654                         print("igbe: can't set EEPROM address 0x%2.2X\n", addr);
1655                         goto release;
1656                 }
1657                 data = at93c46io(ctlr, ":16COc;", 0);
1658                 at93c46io(ctlr, "sic", 0);
1659                 ctlr->eeprom[addr] = data;
1660                 sum += data;
1661         }
1662
1663 release:
1664         if(areq)
1665                 csr32w(ctlr, Eecd, eecd & ~Areq);
1666         return sum;
1667 }
1668
1669 static int
1670 igbedetach(Ctlr* ctlr)
1671 {
1672         int r, timeo;
1673
1674         /*
1675          * Perform a device reset to get the chip back to the
1676          * power-on state, followed by an EEPROM reset to read
1677          * the defaults for some internal registers.
1678          */
1679         csr32w(ctlr, Imc, ~0);
1680         csr32w(ctlr, Rctl, 0);
1681         csr32w(ctlr, Tctl, 0);
1682
1683         delay(10);
1684
1685         csr32w(ctlr, Ctrl, Devrst);
1686         delay(1);
1687         for(timeo = 0; timeo < 1000; timeo++){
1688                 if(!(csr32r(ctlr, Ctrl) & Devrst))
1689                         break;
1690                 delay(1);
1691         }
1692         if(csr32r(ctlr, Ctrl) & Devrst)
1693                 return -1;
1694         r = csr32r(ctlr, Ctrlext);
1695         csr32w(ctlr, Ctrlext, r|Eerst);
1696         delay(1);
1697         for(timeo = 0; timeo < 1000; timeo++){
1698                 if(!(csr32r(ctlr, Ctrlext) & Eerst))
1699                         break;
1700                 delay(1);
1701         }
1702         if(csr32r(ctlr, Ctrlext) & Eerst)
1703                 return -1;
1704
1705         switch(ctlr->id){
1706         default:
1707                 break;
1708         case i82540em:
1709         case i82540eplp:
1710         case i82541gi:
1711         case i82541gi2:
1712         case i82541pi:
1713         case i82545em:
1714         case i82545gmc:
1715         case i82547gi:
1716         case i82546gb:
1717         case i82546eb:
1718                 r = csr32r(ctlr, Manc);
1719                 r &= ~Arpen;
1720                 csr32w(ctlr, Manc, r);
1721                 break;
1722         }
1723
1724         csr32w(ctlr, Imc, ~0);
1725         delay(1);
1726         for(timeo = 0; timeo < 1000; timeo++){
1727                 if(!csr32r(ctlr, Icr))
1728                         break;
1729                 delay(1);
1730         }
1731         if(csr32r(ctlr, Icr))
1732                 return -1;
1733
1734         return 0;
1735 }
1736
1737 static void
1738 igbeshutdown(Ether* ether)
1739 {
1740         igbedetach(ether->ctlr);
1741 }
1742
1743 static int
1744 igbereset(Ctlr* ctlr)
1745 {
1746         int ctrl, i, pause, r, swdpio, txcw;
1747
1748         if(igbedetach(ctlr))
1749                 return -1;
1750
1751         /*
1752          * Read the EEPROM, validate the checksum
1753          * then get the device back to a power-on state.
1754          */
1755         if((r = at93c46r(ctlr)) != 0xBABA){
1756                 print("igbe: bad EEPROM checksum - 0x%4.4uX\n", r);
1757                 return -1;
1758         }
1759
1760         /*
1761          * Snarf and set up the receive addresses.
1762          * There are 16 addresses. The first should be the MAC address.
1763          * The others are cleared and not marked valid (MS bit of Rah).
1764          */
1765         if ((ctlr->id == i82546gb || ctlr->id == i82546eb) &&
1766             BUSFNO(ctlr->pcidev->tbdf) == 1)
1767                 ctlr->eeprom[Ea+2] += 0x100;            /* second interface */
1768         if(ctlr->id == i82541gi && ctlr->eeprom[Ea] == 0xFFFF)
1769                 ctlr->eeprom[Ea] = 0xD000;
1770         for(i = Ea; i < Eaddrlen/2; i++){
1771                 ctlr->ra[2*i] = ctlr->eeprom[i];
1772                 ctlr->ra[2*i+1] = ctlr->eeprom[i]>>8;
1773         }
1774         /* lan id seems to vary on 82543gc; don't use it */
1775         if (ctlr->id != i82543gc) {
1776                 r = (csr32r(ctlr, Status) & Lanid) >> 2;
1777                 ctlr->ra[5] += r;               /* ea ctlr[1] = ea ctlr[0]+1 */
1778         }
1779
1780         r = (ctlr->ra[3]<<24)|(ctlr->ra[2]<<16)|(ctlr->ra[1]<<8)|ctlr->ra[0];
1781         csr32w(ctlr, Ral, r);
1782         r = 0x80000000|(ctlr->ra[5]<<8)|ctlr->ra[4];
1783         csr32w(ctlr, Rah, r);
1784         for(i = 1; i < 16; i++){
1785                 csr32w(ctlr, Ral+i*8, 0);
1786                 csr32w(ctlr, Rah+i*8, 0);
1787         }
1788
1789         /*
1790          * Clear the Multicast Table Array.
1791          * It's a 4096 bit vector accessed as 128 32-bit registers.
1792          */
1793         memset(ctlr->mta, 0, sizeof(ctlr->mta));
1794         for(i = 0; i < 128; i++)
1795                 csr32w(ctlr, Mta+i*4, 0);
1796
1797         /*
1798          * Just in case the Eerst didn't load the defaults
1799          * (doesn't appear to fully on the 82543GC), do it manually.
1800          */
1801         if (ctlr->id == i82543gc) {
1802                 txcw = csr32r(ctlr, Txcw);
1803                 txcw &= ~(TxcwAne|TxcwPauseMASK|TxcwFd);
1804                 ctrl = csr32r(ctlr, Ctrl);
1805                 ctrl &= ~(SwdpioloMASK|Frcspd|Ilos|Lrst|Fd);
1806
1807                 if(ctlr->eeprom[Icw1] & 0x0400){
1808                         ctrl |= Fd;
1809                         txcw |= TxcwFd;
1810                 }
1811                 if(ctlr->eeprom[Icw1] & 0x0200)
1812                         ctrl |= Lrst;
1813                 if(ctlr->eeprom[Icw1] & 0x0010)
1814                         ctrl |= Ilos;
1815                 if(ctlr->eeprom[Icw1] & 0x0800)
1816                         ctrl |= Frcspd;
1817                 swdpio = (ctlr->eeprom[Icw1] & 0x01E0)>>5;
1818                 ctrl |= swdpio<<SwdpioloSHIFT;
1819                 csr32w(ctlr, Ctrl, ctrl);
1820
1821                 ctrl = csr32r(ctlr, Ctrlext);
1822                 ctrl &= ~(Ips|SwdpiohiMASK);
1823                 swdpio = (ctlr->eeprom[Icw2] & 0x00F0)>>4;
1824                 if(ctlr->eeprom[Icw1] & 0x1000)
1825                         ctrl |= Ips;
1826                 ctrl |= swdpio<<SwdpiohiSHIFT;
1827                 csr32w(ctlr, Ctrlext, ctrl);
1828
1829                 if(ctlr->eeprom[Icw2] & 0x0800)
1830                         txcw |= TxcwAne;
1831                 pause = (ctlr->eeprom[Icw2] & 0x3000)>>12;
1832                 txcw |= pause<<TxcwPauseSHIFT;
1833                 switch(pause){
1834                 default:
1835                         ctlr->fcrtl = 0x00002000;
1836                         ctlr->fcrth = 0x00004000;
1837                         txcw |= TxcwAs|TxcwPs;
1838                         break;
1839                 case 0:
1840                         ctlr->fcrtl = 0x00002000;
1841                         ctlr->fcrth = 0x00004000;
1842                         break;
1843                 case 2:
1844                         ctlr->fcrtl = 0;
1845                         ctlr->fcrth = 0;
1846                         txcw |= TxcwAs;
1847                         break;
1848                 }
1849                 ctlr->txcw = txcw;
1850                 csr32w(ctlr, Txcw, txcw);
1851         }
1852
1853
1854         /*
1855          * Flow control - values from the datasheet.
1856          */
1857         csr32w(ctlr, Fcal, 0x00C28001);
1858         csr32w(ctlr, Fcah, 0x00000100);
1859         csr32w(ctlr, Fct, 0x00008808);
1860         csr32w(ctlr, Fcttv, 0x00000100);
1861
1862         csr32w(ctlr, Fcrtl, ctlr->fcrtl);
1863         csr32w(ctlr, Fcrth, ctlr->fcrth);
1864
1865         if(!(csr32r(ctlr, Status) & Tbimode) && igbemii(ctlr) < 0)
1866                 return -1;
1867
1868         return 0;
1869 }
1870
1871 static void
1872 igbepci(void)
1873 {
1874         int cls;
1875         Pcidev *p;
1876         Ctlr *ctlr;
1877         void *mem;
1878
1879         p = nil;
1880         while(p = pcimatch(p, 0, 0)){
1881                 if(p->ccrb != 0x02 || p->ccru != 0)
1882                         continue;
1883
1884                 switch((p->did<<16)|p->vid){
1885                 default:
1886                         continue;
1887                 case i82543gc:
1888                 case i82544ei:
1889                 case i82544eif:
1890                 case i82544gc:
1891                 case i82547ei:
1892                 case i82547gi:
1893                 case i82540em:
1894                 case i82540eplp:
1895                 case i82541ei:
1896                 case i82541gi:
1897                 case i82541gi2:
1898                 case i82541pi:
1899                 case i82545em:
1900                 case i82545gmc:
1901                 case i82546gb:
1902                 case i82546eb:
1903                         break;
1904                 }
1905
1906                 mem = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
1907                 if(mem == nil){
1908                         print("igbe: can't map %8.8luX\n", p->mem[0].bar);
1909                         continue;
1910                 }
1911                 cls = pcicfgr8(p, PciCLS);
1912                 switch(cls){
1913                 default:
1914                         print("igbe: p->cls %#ux, setting to 0x10\n", p->cls);
1915                         p->cls = 0x10;
1916                         pcicfgw8(p, PciCLS, p->cls);
1917                         break;
1918                 case 0x08:
1919                 case 0x10:
1920                         break;
1921                 }
1922                 ctlr = malloc(sizeof(Ctlr));
1923                 if(ctlr == nil){
1924                         print("igbe: can't allocate memory\n");
1925                         continue;
1926                 }
1927                 ctlr->port = p->mem[0].bar & ~0x0F;
1928                 ctlr->pcidev = p;
1929                 ctlr->id = (p->did<<16)|p->vid;
1930                 ctlr->cls = cls*4;
1931                 ctlr->nic = mem;
1932
1933                 if(igbereset(ctlr)){
1934                         free(ctlr);
1935                         vunmap(mem, p->mem[0].size);
1936                         continue;
1937                 }
1938                 pcisetbme(p);
1939
1940                 if(igbectlrhead != nil)
1941                         igbectlrtail->next = ctlr;
1942                 else
1943                         igbectlrhead = ctlr;
1944                 igbectlrtail = ctlr;
1945         }
1946 }
1947
1948 static int
1949 igbepnp(Ether* edev)
1950 {
1951         Ctlr *ctlr;
1952
1953         if(igbectlrhead == nil)
1954                 igbepci();
1955
1956         /*
1957          * Any adapter matches if no edev->port is supplied,
1958          * otherwise the ports must match.
1959          */
1960         for(ctlr = igbectlrhead; ctlr != nil; ctlr = ctlr->next){
1961                 if(ctlr->active)
1962                         continue;
1963                 if(edev->port == 0 || edev->port == ctlr->port){
1964                         ctlr->active = 1;
1965                         break;
1966                 }
1967         }
1968         if(ctlr == nil)
1969                 return -1;
1970
1971         edev->ctlr = ctlr;
1972         edev->port = ctlr->port;
1973         edev->irq = ctlr->pcidev->intl;
1974         edev->tbdf = ctlr->pcidev->tbdf;
1975         edev->mbps = 1000;
1976         memmove(edev->ea, ctlr->ra, Eaddrlen);
1977
1978         /*
1979          * Linkage to the generic ethernet driver.
1980          */
1981         edev->attach = igbeattach;
1982         edev->transmit = igbetransmit;
1983         edev->interrupt = igbeinterrupt;
1984         edev->ifstat = igbeifstat;
1985         edev->ctl = igbectl;
1986
1987         edev->arg = edev;
1988         edev->promiscuous = igbepromiscuous;
1989         edev->shutdown = igbeshutdown;
1990         edev->multicast = igbemulticast;
1991
1992         return 0;
1993 }
1994
1995 void
1996 etherigbelink(void)
1997 {
1998         addethercard("i82543", igbepnp);
1999         addethercard("igbe", igbepnp);
2000 }
2001