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