]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/ether82563.c
1fa71c6f600f06cb0f10cafd23d1d7d8b8951895
[plan9front.git] / sys / src / 9 / pc / ether82563.c
1 /*
2  * Intel 8256[367], 8257[1-9], 8258[03], i350
3  *      Gigabit Ethernet PCI-Express Controllers
4  * Coraid EtherDrive® hba
5  */
6 #include "u.h"
7 #include "../port/lib.h"
8 #include "mem.h"
9 #include "dat.h"
10 #include "fns.h"
11 #include "io.h"
12 #include "../port/error.h"
13 #include "../port/netif.h"
14 #include "../port/etherif.h"
15
16 /*
17  * note: the 82575, 82576 and 82580 are operated using registers aliased
18  * to the 82563-style architecture.  many features seen in the 82598
19  * are also seen in the 82575 part.
20  */
21
22 enum {
23         /* General */
24
25         Ctrl            = 0x0000,       /* Device Control */
26         Status          = 0x0008,       /* Device Status */
27         Eec             = 0x0010,       /* EEPROM/Flash Control/Data */
28         Eerd            = 0x0014,       /* EEPROM Read */
29         Ctrlext         = 0x0018,       /* Extended Device Control */
30         Fla             = 0x001c,       /* Flash Access */
31         Mdic            = 0x0020,       /* MDI Control */
32         Fcal            = 0x0028,       /* Flow Control Address Low */
33         Fcah            = 0x002C,       /* Flow Control Address High */
34         Fct             = 0x0030,       /* Flow Control Type */
35         Kumctrlsta      = 0x0034,       /* Kumeran Control and Status Register */
36         Connsw          = 0x0034,       /* copper / fiber switch control; 82575/82576 */
37         Vet             = 0x0038,       /* VLAN EtherType */
38         Fcttv           = 0x0170,       /* Flow Control Transmit Timer Value */
39         Txcw            = 0x0178,       /* Transmit Configuration Word */
40         Rxcw            = 0x0180,       /* Receive Configuration Word */
41         Ledctl          = 0x0E00,       /* LED control */
42         Pba             = 0x1000,       /* Packet Buffer Allocation */
43         Pbs             = 0x1008,       /* Packet Buffer Size */
44
45         /* Interrupt */
46
47         Icr             = 0x00C0,       /* Interrupt Cause Read */
48         Itr             = 0x00c4,       /* Interrupt Throttling Rate */
49         Ics             = 0x00C8,       /* Interrupt Cause Set */
50         Ims             = 0x00D0,       /* Interrupt Mask Set/Read */
51         Imc             = 0x00D8,       /* Interrupt mask Clear */
52         Iam             = 0x00E0,       /* Interrupt acknowledge Auto Mask */
53         Eitr            = 0x1680,       /* Extended itr; 82575/6 80 only */
54
55         /* Receive */
56
57         Rctl            = 0x0100,       /* Control */
58         Ert             = 0x2008,       /* Early Receive Threshold (573[EVL], 82578 only) */
59         Fcrtl           = 0x2160,       /* Flow Control RX Threshold Low */
60         Fcrth           = 0x2168,       /* Flow Control Rx Threshold High */
61         Psrctl          = 0x2170,       /* Packet Split Receive Control */
62         Drxmxod         = 0x2540,       /* dma max outstanding bytes (82575) */
63         Rdbal           = 0x2800,       /* Rdesc Base Address Low Queue 0 */
64         Rdbah           = 0x2804,       /* Rdesc Base Address High Queue 0 */
65         Rdlen           = 0x2808,       /* Descriptor Length Queue 0 */
66         Srrctl          = 0x280c,       /* split and replication rx control (82575) */
67         Rdh             = 0x2810,       /* Descriptor Head Queue 0 */
68         Rdt             = 0x2818,       /* Descriptor Tail Queue 0 */
69         Rdtr            = 0x2820,       /* Descriptor Timer Ring */
70         Rxdctl          = 0x2828,       /* Descriptor Control */
71         Radv            = 0x282C,       /* Interrupt Absolute Delay Timer */
72         Rsrpd           = 0x2c00,       /* Small Packet Detect */
73         Raid            = 0x2c08,       /* ACK interrupt delay */
74         Cpuvec          = 0x2c10,       /* CPU Vector */
75         Rxcsum          = 0x5000,       /* Checksum Control */
76         Rmpl            = 0x5004,       /* rx maximum packet length (82575) */
77         Rfctl           = 0x5008,       /* Filter Control */
78         Mta             = 0x5200,       /* Multicast Table Array */
79         Ral             = 0x5400,       /* Receive Address Low */
80         Rah             = 0x5404,       /* Receive Address High */
81         Vfta            = 0x5600,       /* VLAN Filter Table Array */
82         Mrqc            = 0x5818,       /* Multiple Receive Queues Command */
83
84         /* Transmit */
85
86         Tctl            = 0x0400,       /* Transmit Control */
87         Tipg            = 0x0410,       /* Transmit IPG */
88         Tkabgtxd        = 0x3004,       /* glci afe band gap transmit ref data, or something */
89         Tdbal           = 0x3800,       /* Tdesc Base Address Low */
90         Tdbah           = 0x3804,       /* Tdesc Base Address High */
91         Tdlen           = 0x3808,       /* Descriptor Length */
92         Tdh             = 0x3810,       /* Descriptor Head */
93         Tdt             = 0x3818,       /* Descriptor Tail */
94         Tidv            = 0x3820,       /* Interrupt Delay Value */
95         Txdctl          = 0x3828,       /* Descriptor Control */
96         Tadv            = 0x382C,       /* Interrupt Absolute Delay Timer */
97         Tarc0           = 0x3840,       /* Arbitration Counter Queue 0 */
98
99         /* Statistics */
100
101         Statistics      = 0x4000,       /* Start of Statistics Area */
102         Gorcl           = 0x88/4,       /* Good Octets Received Count */
103         Gotcl           = 0x90/4,       /* Good Octets Transmitted Count */
104         Torl            = 0xC0/4,       /* Total Octets Received */
105         Totl            = 0xC8/4,       /* Total Octets Transmitted */
106         Nstatistics     = 0x124/4,
107
108         /* iNVM (i211) */
109         Invmdata0       = 0x12120,
110 };
111
112 enum {                                  /* Ctrl */
113         Lrst            = 1<<3,         /* link reset */
114         Slu             = 1<<6,         /* Set Link Up */
115         Devrst          = 1<<26,        /* Device Reset */
116         Rfce            = 1<<27,        /* Receive Flow Control Enable */
117         Tfce            = 1<<28,        /* Transmit Flow Control Enable */
118         Phyrst          = 1<<31,        /* Phy Reset */
119 };
120
121 enum {                                  /* Status */
122         Lu              = 1<<1,         /* Link Up */
123         Lanid           = 3<<2,         /* mask for Lan ID. */
124         Txoff           = 1<<4,         /* Transmission Paused */
125         Tbimode         = 1<<5,         /* TBI Mode Indication */
126         Phyra           = 1<<10,        /* PHY Reset Asserted */
127         GIOme           = 1<<19,        /* GIO Master Enable Status */
128 };
129
130 enum {                                  /* Eec */
131         Nvpres          = 1<<8,
132         Autord          = 1<<9,
133         Flupd           = 1<<19,
134         Sec1val         = 1<<22,
135 };
136
137 enum {                                  /* Eerd */
138         EEstart         = 1<<0,         /* Start Read */
139         EEdone          = 1<<1,         /* Read done */
140 };
141
142 enum {                                  /* Ctrlext */
143         Eerst           = 1<<13,        /* EEPROM Reset */
144         Linkmode        = 3<<22,        /* linkmode */
145         Internalphy     = 0<<22,        /* " internal phy (copper) */
146         Sgmii           = 2<<22,        /* " sgmii */
147         Serdes          = 3<<22,        /* " serdes */
148 };
149
150 enum {
151         /* Connsw */
152         Enrgirq         = 1<<2, /* interrupt on power detect (enrgsrc) */
153 };
154
155 enum {                                  /* EEPROM content offsets */
156         Ea              = 0x00,         /* Ethernet Address */
157 };
158
159 enum {                                  /* Mdic */
160         MDIdMASK        = 0x0000FFFF,   /* Data */
161         MDIdSHIFT       = 0,
162         MDIrMASK        = 0x001F0000,   /* PHY Register Address */
163         MDIrSHIFT       = 16,
164         MDIpMASK        = 0x03E00000,   /* PHY Address */
165         MDIpSHIFT       = 21,
166         MDIwop          = 0x04000000,   /* Write Operation */
167         MDIrop          = 0x08000000,   /* Read Operation */
168         MDIready        = 0x10000000,   /* End of Transaction */
169         MDIie           = 0x20000000,   /* Interrupt Enable */
170         MDIe            = 0x40000000,   /* Error */
171 };
172
173 enum {                                  /* phy interface */
174         Phyctl          = 0,            /* phy ctl register */
175         Physr           = 1,            /* phy status register */
176         Phyid1          = 2,            /* phy id1 */
177         Phyid2          = 3,            /* phy id2 */
178         Phyisr          = 19,           /* 82563 phy interrupt status register */
179         Phylhr          = 19,           /* 8257[12] link health register */
180         Physsr          = 17,           /* phy secondary status register */
181         Phyprst         = 193<<8 | 17,  /* 8256[34] phy port reset */
182         Phyier          = 18,           /* 82573 phy interrupt enable register */
183         Phypage         = 22,           /* 8256[34] page register */
184         Phystat         = 26,           /* 82580 phy status */
185         Phyapage        = 29,
186         Rtlink          = 1<<10,        /* realtime link status */
187         Phyan           = 1<<11,        /* phy has autonegotiated */
188
189         /* Phyctl bits */
190         Ran             = 1<<9, /* restart auto negotiation */
191         Ean             = 1<<12,        /* enable auto negotiation */
192
193         /* Phyprst bits */
194         Prst            = 1<<0, /* reset the port */
195
196         /* 82573 Phyier bits */
197         Lscie           = 1<<10,        /* link status changed ie */
198         Ancie           = 1<<11,        /* auto negotiation complete ie */
199         Spdie           = 1<<14,        /* speed changed ie */
200         Panie           = 1<<15,        /* phy auto negotiation error ie */
201
202         /* Phylhr/Phyisr bits */
203         Anf             = 1<<6, /* lhr: auto negotiation fault */
204         Ane             = 1<<15,        /* isr: auto negotiation error */
205
206         /* 82580 Phystat bits */
207         Ans     = 1<<14 | 1<<15,        /* 82580 autoneg. status */
208         Link    = 1<<6,         /* 82580 Link */
209
210         /* Rxcw builtin serdes */
211         Anc             = 1<<31,
212         Rxsynch         = 1<<30,
213         Rxcfg           = 1<<29,
214         Rxcfgch         = 1<<28,
215         Rxcfgbad        = 1<<27,
216         Rxnc            = 1<<26,
217
218         /* Txcw */
219         Txane           = 1<<31,
220         Txcfg           = 1<<30,
221 };
222
223 enum {                                  /* fiber (pcs) interface */
224         Pcsctl  = 0x4208,               /* pcs control */
225         Pcsstat = 0x420c,               /* pcs status */
226
227         /* Pcsctl bits */
228         Pan     = 1<<16,                /* autoegotiate */
229         Prestart        = 1<<17,                /* restart an (self clearing) */
230
231         /* Pcsstat bits */
232         Linkok  = 1<<0,         /* link is okay */
233         Andone  = 1<<16,                /* an phase is done see below for success */
234         Anbad   = 1<<19 | 1<<20,        /* Anerror | Anremfault */
235 };
236
237 enum {                                  /* Icr, Ics, Ims, Imc */
238         Txdw            = 0x00000001,   /* Transmit Descriptor Written Back */
239         Txqe            = 0x00000002,   /* Transmit Queue Empty */
240         Lsc             = 0x00000004,   /* Link Status Change */
241         Rxseq           = 0x00000008,   /* Receive Sequence Error */
242         Rxdmt0          = 0x00000010,   /* Rdesc Minimum Threshold Reached */
243         Rxo             = 0x00000040,   /* Receiver Overrun */
244         Rxt0            = 0x00000080,   /* Receiver Timer Interrupt; !82575/6/80 only */
245         Rxdw            = 0x00000080,   /* Rdesc write back; 82575/6/80 only */
246         Mdac            = 0x00000200,   /* MDIO Access Completed */
247         Rxcfgset                = 0x00000400,   /* Receiving /C/ ordered sets */
248         Ack             = 0x00020000,   /* Receive ACK frame */
249         Omed            = 1<<20,        /* media change; pcs interface */
250 };
251
252 enum {                                  /* Txcw */
253         TxcwFd          = 0x00000020,   /* Full Duplex */
254         TxcwHd          = 0x00000040,   /* Half Duplex */
255         TxcwPauseMASK   = 0x00000180,   /* Pause */
256         TxcwPauseSHIFT  = 7,
257         TxcwPs          = 1<<TxcwPauseSHIFT,    /* Pause Supported */
258         TxcwAs          = 2<<TxcwPauseSHIFT,    /* Asymmetric FC desired */
259         TxcwRfiMASK     = 0x00003000,   /* Remote Fault Indication */
260         TxcwRfiSHIFT    = 12,
261         TxcwNpr         = 0x00008000,   /* Next Page Request */
262         TxcwConfig      = 0x40000000,   /* Transmit COnfig Control */
263         TxcwAne         = 0x80000000,   /* Auto-Negotiation Enable */
264 };
265
266 enum {                                  /* Rctl */
267         Rrst            = 0x00000001,   /* Receiver Software Reset */
268         Ren             = 0x00000002,   /* Receiver Enable */
269         Sbp             = 0x00000004,   /* Store Bad Packets */
270         Upe             = 0x00000008,   /* Unicast Promiscuous Enable */
271         Mpe             = 0x00000010,   /* Multicast Promiscuous Enable */
272         Lpe             = 0x00000020,   /* Long Packet Reception Enable */
273         RdtmsMASK       = 0x00000300,   /* Rdesc Minimum Threshold Size */
274         RdtmsHALF       = 0x00000000,   /* Threshold is 1/2 Rdlen */
275         RdtmsQUARTER    = 0x00000100,   /* Threshold is 1/4 Rdlen */
276         RdtmsEIGHTH     = 0x00000200,   /* Threshold is 1/8 Rdlen */
277         MoMASK          = 0x00003000,   /* Multicast Offset */
278         Bam             = 0x00008000,   /* Broadcast Accept Mode */
279         BsizeMASK       = 0x00030000,   /* Receive Buffer Size */
280         Bsize16384      = 0x00010000,   /* Bsex = 1 */
281         Bsize8192       = 0x00020000,   /* Bsex = 1 */
282         Bsize2048       = 0x00000000,
283         Bsize1024       = 0x00010000,
284         Bsize512        = 0x00020000,
285         Bsize256        = 0x00030000,
286         BsizeFlex       = 0x08000000,   /* Flexable Bsize in 1kb increments */
287         Vfe             = 0x00040000,   /* VLAN Filter Enable */
288         Cfien           = 0x00080000,   /* Canonical Form Indicator Enable */
289         Cfi             = 0x00100000,   /* Canonical Form Indicator value */
290         Dpf             = 0x00400000,   /* Discard Pause Frames */
291         Pmcf            = 0x00800000,   /* Pass MAC Control Frames */
292         Bsex            = 0x02000000,   /* Buffer Size Extension */
293         Secrc           = 0x04000000,   /* Strip CRC from incoming packet */
294 };
295
296 enum {                                  /* Srrctl */
297         Dropen          = 1<<31,
298 };
299
300 enum {                                  /* Tctl */
301         Trst            = 0x00000001,   /* Transmitter Software Reset */
302         Ten             = 0x00000002,   /* Transmit Enable */
303         Psp             = 0x00000008,   /* Pad Short Packets */
304         Mulr            = 0x10000000,   /* Allow multiple concurrent requests */
305         CtMASK          = 0x00000FF0,   /* Collision Threshold */
306         CtSHIFT         = 4,
307         ColdMASK        = 0x003FF000,   /* Collision Distance */
308         ColdSHIFT       = 12,
309         Swxoff          = 0x00400000,   /* Sofware XOFF Transmission */
310         Pbe             = 0x00800000,   /* Packet Burst Enable */
311         Rtlc            = 0x01000000,   /* Re-transmit on Late Collision */
312         Nrtu            = 0x02000000,   /* No Re-transmit on Underrrun */
313 };
314
315 enum {                                  /* [RT]xdctl */
316         PthreshMASK     = 0x0000003F,   /* Prefetch Threshold */
317         PthreshSHIFT    = 0,
318         HthreshMASK     = 0x00003F00,   /* Host Threshold */
319         HthreshSHIFT    = 8,
320         WthreshMASK     = 0x003F0000,   /* Writeback Threshold */
321         WthreshSHIFT    = 16,
322         Gran            = 0x01000000,   /* Granularity; not 82575 */
323         Enable          = 0x02000000,
324 };
325
326 enum {                                  /* Rxcsum */
327         Ipofl           = 0x0100,       /* IP Checksum Off-load Enable */
328         Tuofl           = 0x0200,       /* TCP/UDP Checksum Off-load Enable */
329 };
330
331 typedef struct Rd {                     /* Receive Descriptor */
332         u32int  addr[2];
333         u16int  length;
334         u16int  checksum;
335         uchar   status;
336         uchar   errors;
337         u16int  special;
338 } Rd;
339
340 enum {                                  /* Rd status */
341         Rdd             = 0x01,         /* Descriptor Done */
342         Reop            = 0x02,         /* End of Packet */
343         Ixsm            = 0x04,         /* Ignore Checksum Indication */
344         Vp              = 0x08,         /* Packet is 802.1Q (matched VET) */
345         Tcpcs           = 0x20,         /* TCP Checksum Calculated on Packet */
346         Ipcs            = 0x40,         /* IP Checksum Calculated on Packet */
347         Pif             = 0x80,         /* Passed in-exact filter */
348 };
349
350 enum {                                  /* Rd errors */
351         Ce              = 0x01,         /* CRC Error or Alignment Error */
352         Se              = 0x02,         /* Symbol Error */
353         Seq             = 0x04,         /* Sequence Error */
354         Cxe             = 0x10,         /* Carrier Extension Error */
355         Tcpe            = 0x20,         /* TCP/UDP Checksum Error */
356         Ipe             = 0x40,         /* IP Checksum Error */
357         Rxe             = 0x80,         /* RX Data Error */
358 };
359
360 typedef struct {                        /* Transmit Descriptor */
361         u32int  addr[2];                /* Data */
362         u32int  control;
363         u32int  status;
364 } Td;
365
366 enum {                                  /* Tdesc control */
367         LenMASK         = 0x000FFFFF,   /* Data/Packet Length Field */
368         LenSHIFT        = 0,
369         DtypeCD         = 0x00000000,   /* Data Type 'Context Descriptor' */
370         DtypeDD         = 0x00100000,   /* Data Type 'Data Descriptor' */
371         PtypeTCP        = 0x01000000,   /* TCP/UDP Packet Type (CD) */
372         Teop            = 0x01000000,   /* End of Packet (DD) */
373         PtypeIP         = 0x02000000,   /* IP Packet Type (CD) */
374         Ifcs            = 0x02000000,   /* Insert FCS (DD) */
375         Tse             = 0x04000000,   /* TCP Segmentation Enable */
376         Rs              = 0x08000000,   /* Report Status */
377         Rps             = 0x10000000,   /* Report Status Sent */
378         Dext            = 0x20000000,   /* Descriptor Extension */
379         Vle             = 0x40000000,   /* VLAN Packet Enable */
380         Ide             = 0x80000000,   /* Interrupt Delay Enable */
381 };
382
383 enum {                                  /* Tdesc status */
384         Tdd             = 0x0001,       /* Descriptor Done */
385         Ec              = 0x0002,       /* Excess Collisions */
386         Lc              = 0x0004,       /* Late Collision */
387         Tu              = 0x0008,       /* Transmit Underrun */
388         CssMASK         = 0xFF00,       /* Checksum Start Field */
389         CssSHIFT        = 8,
390 };
391
392 typedef struct {
393         u16int  *reg;
394         u32int  *reg32;
395         uint    base;
396         uint    lim;
397 } Flash;
398
399 enum {
400         /* 16 and 32-bit flash registers for ich flash parts */
401         Bfpr    = 0x00/4,               /* flash base 0:12; lim 16:28 */
402         Fsts    = 0x04/2,               /* flash status; Hsfsts */
403         Fctl    = 0x06/2,               /* flash control; Hsfctl */
404         Faddr   = 0x08/4,               /* flash address to r/w */
405         Fdata   = 0x10/4,               /* data @ address */
406
407         /* status register */
408         Fdone   = 1<<0,                 /* flash cycle done */
409         Fcerr   = 1<<1,                 /* cycle error; write 1 to clear */
410         Ael     = 1<<2,                 /* direct access error log; 1 to clear */
411         Scip    = 1<<5,                 /* spi cycle in progress */
412         Fvalid  = 1<<14,                /* flash descriptor valid */
413
414         /* control register */
415         Fgo     = 1<<0,                 /* start cycle */
416         Flcycle = 1<<1,                 /* two bits: r=0; w=2 */
417         Fdbc    = 1<<8,                 /* bytes to read; 5 bits */
418 };
419
420 enum {
421         Nrd             = 256,          /* power of two */
422         Ntd             = 128,          /* power of two */
423         Nrb             = 512+512,      /* private receive buffers per Ctlr */
424         Rbalign         = BY2PG,        /* rx buffer alignment */
425 };
426
427 /*
428  * cavet emptor: 82577/78 have been entered speculatitively.
429  * awating datasheet from intel.
430  */
431 enum {
432         i82563,
433         i82566,
434         i82567,
435         i82567m,
436         i82571,
437         i82572,
438         i82573,
439         i82574,
440         i82575,
441         i82576,
442         i82577,
443         i82577m,        
444         i82578,
445         i82578m,
446         i82579,
447         i82580,
448         i82583,
449         i210,
450         i217,
451         i218,
452         i219,
453         i350,
454         Nctlrtype,
455 };
456
457 enum {
458         Fload   = 1<<0,
459         Fert    = 1<<1,
460         F75     = 1<<2,
461         Fpba    = 1<<3,
462         Fflashea= 1<<4,
463         F79phy  = 1<<5,
464         Fnofct  = 1<<6,
465         Fbadcsum= 1<<7,
466 };
467
468 typedef struct Ctlrtype Ctlrtype;
469 struct Ctlrtype {
470         char    *name;
471         int     mtu;
472         int     flag;
473 };
474
475 static Ctlrtype cttab[Nctlrtype] = {
476 [i82563]        "i82563",       9014,   Fpba,
477 [i82566]        "i82566",       1514,   Fload,
478 [i82567]        "i82567",       9234,   Fload,
479 [i82567m]       "i82567m",      1514,   Fload,
480 [i82571]        "i82571",       9234,   Fpba,
481 [i82572]        "i82572",       9234,   Fpba,
482 [i82573]        "i82573",       8192,   Fert,           /* terrible perf above 8k */
483 [i82574]        "i82574",       9018,   0,
484 [i82575]        "i82575",       9728,   F75|Fflashea,
485 [i82576]        "i82576",       9728,   F75,
486 [i82577]        "i82577",       4096,   Fload|Fert,
487 [i82577m]       "i82577",       1514,   Fload|Fert,
488 [i82578]        "i82578",       4096,   Fload|Fert,
489 [i82578m]       "i82578",       1514,   Fload|Fert,
490 [i82579]        "i82579",       9018,   Fload|Fert|F79phy|Fnofct,
491 [i82580]        "i82580",       9728,   F75|F79phy,
492 [i82583]        "i82583",       1514,   0,
493 [i210]          "i210",         9728,   F75|Fnofct|Fert,
494 [i217]          "i217",         9728,   Fload|Fnofct|Fert|Fbadcsum,
495 [i218]          "i218",         9728,   Fload|Fert|F79phy|Fnofct|Fbadcsum,
496 [i219]          "i219",         9728,   Fload|Fert|F79phy|Fnofct|Fbadcsum,
497 [i350]          "i350",         9728,   F75|F79phy|Fnofct,
498 };
499
500 typedef void (*Freefn)(Block*);
501
502 typedef struct Ctlr Ctlr;
503 struct Ctlr {
504         ulong   port;
505         Pcidev  *pcidev;
506         Ctlr    *next;
507         int     active;
508         int     type;
509         u16int  eeprom[0x40];
510
511         QLock   alock;                  /* attach */
512         void    *alloc;                 /* receive/transmit descriptors */
513         int     nrd;
514         int     ntd;
515         uint    rbsz;
516
517         u32int  *nic;
518         Lock    imlock;
519         int     im;                     /* interrupt mask */
520
521         Rendez  lrendez;
522         int     lim;
523
524         QLock   slock;
525         u32int  statistics[Nstatistics];
526         uint    lsleep;
527         uint    lintr;
528         uint    rsleep;
529         uint    rintr;
530         uint    txdw;
531         uint    tintr;
532         uint    ixsm;
533         uint    ipcs;
534         uint    tcpcs;
535         uint    speeds[4];
536         uint    phyerrata;
537
538         uchar   ra[Eaddrlen];           /* receive address */
539         u32int  mta[128];               /* multicast table array */
540
541         Rendez  rrendez;
542         int     rim;
543         int     rdfree;
544         Rd      *rdba;                  /* receive descriptor base address */
545         Block   **rb;                   /* receive buffers */
546         uint    rdh;                    /* receive descriptor head */
547         uint    rdt;                    /* receive descriptor tail */
548         int     rdtr;                   /* receive delay timer ring value */
549         int     radv;                   /* receive interrupt absolute delay timer */
550
551         Rendez  trendez;
552         QLock   tlock;
553         int     tbusy;
554         Td      *tdba;                  /* transmit descriptor base address */
555         Block   **tb;                   /* transmit buffers */
556         int     tdh;                    /* transmit descriptor head */
557         int     tdt;                    /* transmit descriptor tail */
558
559         int     fcrtl;
560         int     fcrth;
561
562         u32int  pba;                    /* packet buffer allocation */
563 };
564
565 #define csr32r(c, r)    (*((c)->nic+((r)/4)))
566 #define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
567
568 static  Ctlr    *i82563ctlrhead;
569 static  Ctlr    *i82563ctlrtail;
570
571 static char *statistics[Nstatistics] = {
572         "CRC Error",
573         "Alignment Error",
574         "Symbol Error",
575         "RX Error",
576         "Missed Packets",
577         "Single Collision",
578         "Excessive Collisions",
579         "Multiple Collision",
580         "Late Collisions",
581         nil,
582         "Collision",
583         "Transmit Underrun",
584         "Defer",
585         "Transmit - No CRS",
586         "Sequence Error",
587         "Carrier Extension Error",
588         "Receive Error Length",
589         nil,
590         "XON Received",
591         "XON Transmitted",
592         "XOFF Received",
593         "XOFF Transmitted",
594         "FC Received Unsupported",
595         "Packets Received (64 Bytes)",
596         "Packets Received (65-127 Bytes)",
597         "Packets Received (128-255 Bytes)",
598         "Packets Received (256-511 Bytes)",
599         "Packets Received (512-1023 Bytes)",
600         "Packets Received (1024-mtu Bytes)",
601         "Good Packets Received",
602         "Broadcast Packets Received",
603         "Multicast Packets Received",
604         "Good Packets Transmitted",
605         nil,
606         "Good Octets Received",
607         nil,
608         "Good Octets Transmitted",
609         nil,
610         nil,
611         nil,
612         "Receive No Buffers",
613         "Receive Undersize",
614         "Receive Fragment",
615         "Receive Oversize",
616         "Receive Jabber",
617         "Management Packets Rx",
618         "Management Packets Drop",
619         "Management Packets Tx",
620         "Total Octets Received",
621         nil,
622         "Total Octets Transmitted",
623         nil,
624         "Total Packets Received",
625         "Total Packets Transmitted",
626         "Packets Transmitted (64 Bytes)",
627         "Packets Transmitted (65-127 Bytes)",
628         "Packets Transmitted (128-255 Bytes)",
629         "Packets Transmitted (256-511 Bytes)",
630         "Packets Transmitted (512-1023 Bytes)",
631         "Packets Transmitted (1024-mtu Bytes)",
632         "Multicast Packets Transmitted",
633         "Broadcast Packets Transmitted",
634         "TCP Segmentation Context Transmitted",
635         "TCP Segmentation Context Fail",
636         "Interrupt Assertion",
637         "Interrupt Rx Pkt Timer",
638         "Interrupt Rx Abs Timer",
639         "Interrupt Tx Pkt Timer",
640         "Interrupt Tx Abs Timer",
641         "Interrupt Tx Queue Empty",
642         "Interrupt Tx Desc Low",
643         "Interrupt Rx Min",
644         "Interrupt Rx Overrun",
645 };
646
647 static char*
648 cname(Ctlr *c)
649 {
650         return cttab[c->type].name;
651 }
652
653 static long
654 i82563ifstat(Ether *edev, void *a, long n, ulong offset)
655 {
656         char *s, *p, *e, *stat;
657         int i, r;
658         uvlong tuvl, ruvl;
659         Ctlr *ctlr;
660
661         p = s = smalloc(READSTR);
662         e = p + READSTR;
663
664         ctlr = edev->ctlr;
665         qlock(&ctlr->slock);
666
667         for(i = 0; i < Nstatistics; i++){
668                 r = csr32r(ctlr, Statistics + i*4);
669                 if((stat = statistics[i]) == nil)
670                         continue;
671                 switch(i){
672                 case Gorcl:
673                 case Gotcl:
674                 case Torl:
675                 case Totl:
676                         ruvl = r;
677                         ruvl += (uvlong)csr32r(ctlr, Statistics+(i+1)*4) << 32;
678                         tuvl = ruvl;
679                         tuvl += ctlr->statistics[i];
680                         tuvl += (uvlong)ctlr->statistics[i+1] << 32;
681                         if(tuvl == 0)
682                                 continue;
683                         ctlr->statistics[i] = tuvl;
684                         ctlr->statistics[i+1] = tuvl >> 32;
685                         p = seprint(p, e, "%s: %llud %llud\n", stat, tuvl, ruvl);
686                         i++;
687                         break;
688
689                 default:
690                         ctlr->statistics[i] += r;
691                         if(ctlr->statistics[i] == 0)
692                                 continue;
693                         p = seprint(p, e, "%s: %ud %ud\n", stat,
694                                 ctlr->statistics[i], r);
695                         break;
696                 }
697         }
698
699         p = seprint(p, e, "lintr: %ud %ud\n", ctlr->lintr, ctlr->lsleep);
700         p = seprint(p, e, "rintr: %ud %ud\n", ctlr->rintr, ctlr->rsleep);
701         p = seprint(p, e, "tintr: %ud %ud\n", ctlr->tintr, ctlr->txdw);
702         p = seprint(p, e, "ixcs: %ud %ud %ud\n", ctlr->ixsm, ctlr->ipcs, ctlr->tcpcs);
703         p = seprint(p, e, "rdtr: %ud\n", ctlr->rdtr);
704         p = seprint(p, e, "radv: %ud\n", ctlr->radv);
705         p = seprint(p, e, "ctrl: %.8ux\n", csr32r(ctlr, Ctrl));
706         p = seprint(p, e, "ctrlext: %.8ux\n", csr32r(ctlr, Ctrlext));
707         p = seprint(p, e, "status: %.8ux\n", csr32r(ctlr, Status));
708         p = seprint(p, e, "txcw: %.8ux\n", csr32r(ctlr, Txcw));
709         p = seprint(p, e, "txdctl: %.8ux\n", csr32r(ctlr, Txdctl));
710         p = seprint(p, e, "pba: %.8ux\n", ctlr->pba);
711
712         p = seprint(p, e, "speeds: 10:%ud 100:%ud 1000:%ud ?:%ud\n",
713                 ctlr->speeds[0], ctlr->speeds[1], ctlr->speeds[2], ctlr->speeds[3]);
714         p = seprint(p, e, "type: %s\n", cname(ctlr));
715
716         p = seprint(p, e, "eeprom:");
717         for(i = 0; i < 0x40; i++){
718                 if(i && ((i & 7) == 0))
719                         p = seprint(p, e, "\n       ");
720                 p = seprint(p, e, " %4.4ux", ctlr->eeprom[i]);
721         }
722         p = seprint(p, e, "\n");
723
724         USED(p);
725         n = readstr(offset, a, n, s);
726         free(s);
727         qunlock(&ctlr->slock);
728
729         return n;
730 }
731
732 static void
733 i82563promiscuous(void *arg, int on)
734 {
735         int rctl;
736         Ctlr *ctlr;
737         Ether *edev;
738
739         edev = arg;
740         ctlr = edev->ctlr;
741
742         rctl = csr32r(ctlr, Rctl);
743         rctl &= ~MoMASK;
744         if(on)
745                 rctl |= Upe|Mpe;
746         else
747                 rctl &= ~(Upe|Mpe);
748         csr32w(ctlr, Rctl, rctl);
749 }
750
751 static void
752 i82563multicast(void *arg, uchar *addr, int on)
753 {
754         int bit, x;
755         Ctlr *ctlr;
756         Ether *edev;
757
758         edev = arg;
759         ctlr = edev->ctlr;
760
761         switch(ctlr->type){
762         case i82566:
763         case i82567:
764         case i82567m:
765         case i82577:
766         case i82577m:
767         case i82579:
768         case i210:
769         case i217:
770         case i218:
771         case i219:
772                 bit = (addr[5]<<2)|(addr[4]>>6);
773                 x = (bit>>5) & 31;
774                 break;
775         default:
776                 bit = (addr[5]<<4)|(addr[4]>>4);
777                 x = (bit>>5) & 127;
778                 break;
779         }
780         bit &= 31;
781
782         /*
783          * multiple ether addresses can hash to the same filter bit,
784          * so it's never safe to clear a filter bit.
785          * if we want to clear filter bits, we need to keep track of
786          * all the multicast addresses in use, clear all the filter bits,
787          * then set the ones corresponding to in-use addresses.
788          */
789         if(on)
790                 ctlr->mta[x] |= 1<<bit;
791
792         csr32w(ctlr, Mta+x*4, ctlr->mta[x]);
793 }
794
795 static void
796 i82563im(Ctlr *ctlr, int im)
797 {
798         ilock(&ctlr->imlock);
799         ctlr->im |= im;
800         csr32w(ctlr, Ims, ctlr->im);
801         iunlock(&ctlr->imlock);
802 }
803
804 static void
805 i82563txinit(Ctlr *ctlr)
806 {
807         u32int r;
808         Block *b;
809         int i;
810
811         if(cttab[ctlr->type].flag & F75)
812                 csr32w(ctlr, Tctl, 0x0F<<CtSHIFT | Psp);
813         else
814                 csr32w(ctlr, Tctl, 0x0F<<CtSHIFT | Psp | 66<<ColdSHIFT | Mulr);
815         csr32w(ctlr, Tipg, 6<<20 | 8<<10 | 8);          /* yb sez: 0x702008 */
816         for(i = 0; i < ctlr->ntd; i++){
817                 if((b = ctlr->tb[i]) != nil){
818                         ctlr->tb[i] = nil;
819                         freeb(b);
820                 }
821                 memset(&ctlr->tdba[i], 0, sizeof(Td));
822         }
823         csr32w(ctlr, Tdbal, PCIWADDR(ctlr->tdba));
824         csr32w(ctlr, Tdbah, 0);
825         csr32w(ctlr, Tdlen, ctlr->ntd * sizeof(Td));
826         ctlr->tdh = PREV(0, ctlr->ntd);
827         csr32w(ctlr, Tdh, 0);
828         ctlr->tdt = 0;
829         csr32w(ctlr, Tdt, 0);
830         csr32w(ctlr, Tidv, 128);
831         csr32w(ctlr, Tadv, 64);
832         csr32w(ctlr, Tctl, csr32r(ctlr, Tctl) | Ten);
833         r = csr32r(ctlr, Txdctl) & ~WthreshMASK;
834         r |= 4<<WthreshSHIFT | 4<<PthreshSHIFT;
835         if(cttab[ctlr->type].flag & F75)
836                 r |= Enable;
837         csr32w(ctlr, Txdctl, r);
838 }
839
840 static uint
841 i82563cleanup(Ctlr *c)
842 {
843         Block *b;
844         uint tdh, n;
845
846         tdh = c->tdh;
847         while(c->tdba[n = NEXT(tdh, c->ntd)].status & Tdd){
848                 tdh = n;
849                 if((b = c->tb[tdh]) != nil){
850                         c->tb[tdh] = nil;
851                         freeb(b);
852                 }else
853                         iprint("82563 tx underrun!\n");
854                 c->tdba[tdh].status = 0;
855         }
856
857         return c->tdh = tdh;
858 }
859
860 static int
861 notrim(void *v)
862 {
863         Ctlr *c;
864
865         c = v;
866         return (c->im & Txdw) == 0;
867 }
868
869 static void
870 i82563tproc(void *v)
871 {
872         Td *td;
873         Block *bp;
874         Ether *edev;
875         Ctlr *ctlr;
876         uint tdt, n;
877
878         edev = v;
879         ctlr = edev->ctlr;
880         i82563txinit(ctlr);
881
882         tdt = ctlr->tdt;
883         while(waserror())
884                 ;
885         for(;;){
886                 n = NEXT(tdt, ctlr->ntd);
887                 if(n == i82563cleanup(ctlr)){
888                         ctlr->txdw++;
889                         i82563im(ctlr, Txdw);
890                         sleep(&ctlr->trendez, notrim, ctlr);
891                         continue;
892                 }
893                 bp = qbread(edev->oq, 100000);
894                 td = &ctlr->tdba[tdt];
895                 td->addr[0] = PCIWADDR(bp->rp);
896                 td->addr[1] = 0;
897                 td->control = Ide|Rs|Ifcs|Teop|BLEN(bp);
898                 coherence();
899                 ctlr->tb[tdt] = bp;
900                 ctlr->tdt = tdt = n;
901                 csr32w(ctlr, Tdt, tdt);
902         }
903 }
904
905 static void
906 i82563replenish(Ctlr *ctlr)
907 {
908         uint rdt, i;
909         Block *bp;
910         Rd *rd;
911
912         i = 0;
913         for(rdt = ctlr->rdt; NEXT(rdt, ctlr->nrd) != ctlr->rdh; rdt = NEXT(rdt, ctlr->nrd)){
914                 rd = &ctlr->rdba[rdt];
915                 if(ctlr->rb[rdt] != nil){
916                         iprint("82563: tx overrun\n");
917                         break;
918                 }
919                 i++;
920                 bp = allocb(ctlr->rbsz + Rbalign);
921                 bp->rp = bp->wp = (uchar*)ROUND((uintptr)bp->base, Rbalign);
922                 ctlr->rb[rdt] = bp;
923                 rd->addr[0] = PCIWADDR(bp->rp);
924                 rd->addr[1] = 0;
925                 rd->status = 0;
926                 ctlr->rdfree++;
927         }
928         if(i != 0){
929                 coherence();
930                 ctlr->rdt = rdt;
931                 csr32w(ctlr, Rdt, rdt);
932         }
933 }
934
935 static void
936 i82563rxinit(Ctlr *ctlr)
937 {
938         int i;
939         Block *bp;
940
941         if(ctlr->rbsz <= 2048)
942                 csr32w(ctlr, Rctl, Dpf|Bsize2048|Bam|RdtmsHALF);
943         else{
944                 i = ctlr->rbsz / 1024;
945                 if(ctlr->rbsz % 1024)
946                         i++;
947                 if(cttab[ctlr->type].flag & F75){
948                         csr32w(ctlr, Rctl, Lpe|Dpf|Bsize2048|Bam|RdtmsHALF|Secrc);
949                         if(ctlr->type != i82575)
950                                 i |= (ctlr->nrd/2>>4)<<20;              /* RdmsHalf */
951                         csr32w(ctlr, Srrctl, i | Dropen);
952                         csr32w(ctlr, Rmpl, ctlr->rbsz);
953 //                      csr32w(ctlr, Drxmxod, 0x7ff);
954                 }else
955                         csr32w(ctlr, Rctl, Lpe|Dpf|BsizeFlex*i|Bam|RdtmsHALF|Secrc);
956         }
957
958         if(cttab[ctlr->type].flag & Fert)
959                 csr32w(ctlr, Ert, 1024/8);
960
961         if(ctlr->type == i82566)
962                 csr32w(ctlr, Pbs, 16);
963
964         csr32w(ctlr, Rdbal, PCIWADDR(ctlr->rdba));
965         csr32w(ctlr, Rdbah, 0);
966         csr32w(ctlr, Rdlen, ctlr->nrd * sizeof(Rd));
967         ctlr->rdh = 0;
968         csr32w(ctlr, Rdh, 0);
969         ctlr->rdt = 0;
970         csr32w(ctlr, Rdt, 0);
971         ctlr->rdtr = 25;
972         ctlr->radv = 500;
973         csr32w(ctlr, Rdtr, ctlr->rdtr);
974         csr32w(ctlr, Radv, ctlr->radv);
975
976         for(i = 0; i < ctlr->nrd; i++)
977                 if((bp = ctlr->rb[i]) != nil){
978                         ctlr->rb[i] = nil;
979                         freeb(bp);
980                 }
981         if(cttab[ctlr->type].flag & F75)
982                 csr32w(ctlr, Rxdctl, 1<<WthreshSHIFT | 8<<PthreshSHIFT | 1<<HthreshSHIFT | Enable);
983         else
984                 csr32w(ctlr, Rxdctl, 2<<WthreshSHIFT | 2<<PthreshSHIFT);
985
986         /*
987          * Enable checksum offload.
988          */
989         csr32w(ctlr, Rxcsum, Tuofl | Ipofl | ETHERHDRSIZE);
990 }
991
992 static int
993 i82563rim(void *v)
994 {
995         return ((Ctlr*)v)->rim != 0;
996 }
997
998 static void
999 i82563rproc(void *arg)
1000 {
1001         uint rdh, rim, im;
1002         Block *bp;
1003         Ctlr *ctlr;
1004         Ether *edev;
1005         Rd *rd;
1006
1007         edev = arg;
1008         ctlr = edev->ctlr;
1009
1010         i82563rxinit(ctlr);
1011         csr32w(ctlr, Rctl, csr32r(ctlr, Rctl) | Ren);
1012         if(cttab[ctlr->type].flag & F75){
1013                 csr32w(ctlr, Rxdctl, csr32r(ctlr, Rxdctl) | Enable);
1014                 im = Rxt0|Rxo|Rxdmt0|Rxseq|Ack;
1015         }else
1016                 im = Rxt0|Rxo|Rxdmt0|Rxseq|Ack;
1017
1018         while(waserror())
1019                 ;
1020         for(;;){
1021                 i82563im(ctlr, im);
1022                 ctlr->rsleep++;
1023                 i82563replenish(ctlr);
1024                 sleep(&ctlr->rrendez, i82563rim, ctlr);
1025
1026                 rdh = ctlr->rdh;
1027                 for(;;){
1028                         rim = ctlr->rim;
1029                         ctlr->rim = 0;
1030                         rd = &ctlr->rdba[rdh];
1031                         if(!(rd->status & Rdd))
1032                                 break;
1033
1034                         /*
1035                          * Accept eop packets with no errors.
1036                          * With no errors and the Ixsm bit set,
1037                          * the descriptor status Tpcs and Ipcs bits give
1038                          * an indication of whether the checksums were
1039                          * calculated and valid.
1040                          */
1041                         bp = ctlr->rb[rdh];
1042                         if((rd->status & Reop) && rd->errors == 0){
1043                                 bp->wp += rd->length;
1044                                 if(!(rd->status & Ixsm)){
1045                                         ctlr->ixsm++;
1046                                         if(rd->status & Ipcs){
1047                                                 /*
1048                                                  * IP checksum calculated
1049                                                  * (and valid as errors == 0).
1050                                                  */
1051                                                 ctlr->ipcs++;
1052                                                 bp->flag |= Bipck;
1053                                         }
1054                                         if(rd->status & Tcpcs){
1055                                                 /*
1056                                                  * TCP/UDP checksum calculated
1057                                                  * (and valid as errors == 0).
1058                                                  */
1059                                                 ctlr->tcpcs++;
1060                                                 bp->flag |= Btcpck|Budpck;
1061                                         }
1062                                         bp->checksum = rd->checksum;
1063                                         bp->flag |= Bpktck;
1064                                 }
1065                                 etheriq(edev, bp);
1066                         } else
1067                                 freeb(bp);
1068                         ctlr->rb[rdh] = nil;
1069                         ctlr->rdfree--;
1070                         ctlr->rdh = rdh = NEXT(rdh, ctlr->nrd);
1071                         if(ctlr->nrd-ctlr->rdfree >= 32 || (rim & Rxdmt0))
1072                                 i82563replenish(ctlr);
1073                 }
1074         }
1075 }
1076
1077 static int
1078 i82563lim(void *v)
1079 {
1080         return ((Ctlr*)v)->lim != 0;
1081 }
1082
1083 static int speedtab[] = {
1084         10, 100, 1000, 0
1085 };
1086
1087 static uint
1088 phyread(Ctlr *c, int phyno, int reg)
1089 {
1090         uint phy, i;
1091
1092         csr32w(c, Mdic, MDIrop | phyno<<MDIpSHIFT | reg<<MDIrSHIFT);
1093         phy = 0;
1094         for(i = 0; i < 64; i++){
1095                 phy = csr32r(c, Mdic);
1096                 if(phy & (MDIe|MDIready))
1097                         break;
1098                 microdelay(1);
1099         }
1100         if((phy & (MDIe|MDIready)) != MDIready){
1101                 print("%s: phy %d wedged %.8ux\n", cttab[c->type].name, phyno, phy);
1102                 return ~0;
1103         }
1104         return phy & 0xffff;
1105 }
1106
1107 static uint
1108 phywrite0(Ctlr *c, int phyno, int reg, ushort val)
1109 {
1110         uint phy, i;
1111
1112         csr32w(c, Mdic, MDIwop | phyno<<MDIpSHIFT | reg<<MDIrSHIFT | val);
1113         phy = 0;
1114         for(i = 0; i < 64; i++){
1115                 phy = csr32r(c, Mdic);
1116                 if(phy & (MDIe|MDIready))
1117                         break;
1118                 microdelay(1);
1119         }
1120         if((phy & (MDIe|MDIready)) != MDIready)
1121                 return ~0;
1122         return 0;
1123 }
1124
1125 static uint
1126 setpage(Ctlr *c, uint phyno, uint p, uint r)
1127 {
1128         uint pr;
1129
1130         if(c->type == i82563){
1131                 if(r >= 16 && r <= 28 && r != 22)
1132                         pr = Phypage;
1133                 else if(r == 30 || r == 31)
1134                         pr = Phyapage;
1135                 else
1136                         return 0;
1137                 return phywrite0(c, phyno, pr, p);
1138         }else if(p == 0)
1139                 return 0;
1140         return ~0;
1141 }
1142
1143 static uint
1144 phywrite(Ctlr *c, uint phyno, uint reg, ushort v)
1145 {
1146         if(setpage(c, phyno, reg>>8, reg & 0xff) == ~0)
1147                 panic("%s: bad phy reg %.4ux", cname(c), reg);
1148         return phywrite0(c, phyno, reg & 0xff, v);
1149 }
1150
1151 static void
1152 phyerrata(Ether *e, Ctlr *c, uint phyno)
1153 {
1154         if(e->mbps == 0){
1155                 if(c->phyerrata == 0){
1156                         c->phyerrata++;
1157                         phywrite(c, phyno, Phyprst, Prst);      /* try a port reset */
1158                         print("%s: phy port reset\n", cname(c));
1159                 }
1160         }else
1161                 c->phyerrata = 0;
1162 }
1163
1164 static uint
1165 phyprobe(Ctlr *c, uint mask)
1166 {
1167         uint phy, phyno;
1168
1169         for(phyno=0; mask != 0; phyno++, mask>>=1){
1170                 if((mask & 1) == 0)
1171                         continue;
1172                 if(phyread(c, phyno, Physr) == ~0)
1173                         continue;
1174                 phy = (phyread(c, phyno, Phyid1) & 0x3FFF)<<6;
1175                 phy |= phyread(c, phyno, Phyid2) >> 10;
1176                 if(phy == 0xFFFFF || phy == 0)
1177                         continue;
1178                 print("%s: phy%d oui %#ux\n", cname(c), phyno, phy);
1179                 return phyno;
1180         }
1181         print("%s: no phy\n", cname(c));
1182         return ~0;
1183 }
1184
1185 static void
1186 lsleep(Ctlr *c, uint m)
1187 {
1188         c->lim = 0;
1189         i82563im(c, m);
1190         c->lsleep++;
1191         sleep(&c->lrendez, i82563lim, c);
1192 }
1193
1194 static void
1195 phyl79proc(void *v)
1196 {
1197         uint a, i, r, phy, phyno;
1198         Ctlr *c;
1199         Ether *e;
1200
1201         e = v;
1202         c = e->ctlr;
1203         while(waserror())
1204                 ;
1205
1206         while((phyno = phyprobe(c, 3<<1)) == ~0)
1207                 lsleep(c, Lsc);
1208
1209         for(;;){
1210                 phy = phyread(c, phyno, Phystat);
1211                 if(phy == ~0){
1212                         phy = 0;
1213                         i = 3;
1214                         goto next;
1215                 }
1216                 i = (phy>>8) & 3;
1217                 a = phy & Ans;
1218                 if(a){
1219                         r = phyread(c, phyno, Phyctl);
1220                         phywrite(c, phyno, Phyctl, r | Ran | Ean);
1221                 }
1222 next:
1223                 e->link = i != 3 && (phy & Link) != 0;
1224                 if(e->link == 0)
1225                         i = 3;
1226                 c->speeds[i]++;
1227                 e->mbps = speedtab[i];
1228                 lsleep(c, Lsc);
1229         }
1230 }
1231
1232 static void
1233 phylproc(void *v)
1234 {
1235         uint a, i, phy, phyno;
1236         Ctlr *c;
1237         Ether *e;
1238
1239         e = v;
1240         c = e->ctlr;
1241         while(waserror())
1242                 ;
1243
1244         while((phyno = phyprobe(c, 3<<1)) == ~0)
1245                 lsleep(c, Lsc);
1246
1247         if(c->type == i82573 && (phy = phyread(c, phyno, Phyier)) != ~0)
1248                 phywrite(c, phyno, Phyier, phy | Lscie | Ancie | Spdie | Panie);
1249
1250         for(;;){
1251                 phy = phyread(c, phyno, Physsr);
1252                 if(phy == ~0){
1253                         phy = 0;
1254                         i = 3;
1255                         goto next;
1256                 }
1257                 i = (phy>>14) & 3;
1258                 switch(c->type){
1259                 default:
1260                         a = 0;
1261                         break;
1262                 case i82563:
1263                 case i82578:
1264                 case i82578m:
1265                 case i82583:
1266                         a = phyread(c, phyno, Phyisr) & Ane;
1267                         break;
1268                 case i82571:
1269                 case i82572:
1270                 case i82575:
1271                 case i82576:
1272                         a = phyread(c, phyno, Phylhr) & Anf;
1273                         i = (i-1) & 3;
1274                         break;
1275                 }
1276                 if(a)
1277                         phywrite(c, phyno, Phyctl, phyread(c, phyno, Phyctl) | Ran | Ean);
1278 next:
1279                 e->link = (phy & Rtlink) != 0;
1280                 if(e->link == 0)
1281                         i = 3;
1282                 c->speeds[i]++;
1283                 e->mbps = speedtab[i];
1284                 if(c->type == i82563)
1285                         phyerrata(e, c, phyno);
1286                 lsleep(c, Lsc);
1287         }
1288 }
1289
1290 static void
1291 pcslproc(void *v)
1292 {
1293         uint i, phy;
1294         Ctlr *c;
1295         Ether *e;
1296
1297         e = v;
1298         c = e->ctlr;
1299         while(waserror())
1300                 ;
1301
1302         if(c->type == i82575 || c->type == i82576)
1303                 csr32w(c, Connsw, Enrgirq);
1304         for(;;){
1305                 phy = csr32r(c, Pcsstat);
1306                 e->link = phy & Linkok;
1307                 i = 3;
1308                 if(e->link)
1309                         i = (phy & 6) >> 1;
1310                 else if(phy & Anbad)
1311                         csr32w(c, Pcsctl, csr32r(c, Pcsctl) | Pan | Prestart);
1312                 c->speeds[i]++;
1313                 e->mbps = speedtab[i];
1314                 lsleep(c, Lsc | Omed);
1315         }
1316 }
1317
1318 static void
1319 serdeslproc(void *v)
1320 {
1321         uint i, tx, rx;
1322         Ctlr *c;
1323         Ether *e;
1324
1325         e = v;
1326         c = e->ctlr;
1327         while(waserror())
1328                 ;
1329         for(;;){
1330                 rx = csr32r(c, Rxcw);
1331                 tx = csr32r(c, Txcw);
1332                 USED(tx);
1333                 e->link = (rx & 1<<31) != 0;
1334 //              e->link = (csr32r(c, Status) & Lu) != 0;
1335                 i = 3;
1336                 if(e->link)
1337                         i = 2;
1338                 c->speeds[i]++;
1339                 e->mbps = speedtab[i];
1340                 lsleep(c, Lsc);
1341         }
1342 }
1343
1344 static void
1345 i82563attach(Ether *edev)
1346 {
1347         char name[KNAMELEN];
1348         Ctlr *ctlr;
1349
1350         ctlr = edev->ctlr;
1351         qlock(&ctlr->alock);
1352         if(ctlr->alloc != nil){
1353                 qunlock(&ctlr->alock);
1354                 return;
1355         }
1356
1357         ctlr->nrd = Nrd;
1358         ctlr->ntd = Ntd;
1359         ctlr->alloc = malloc(ctlr->nrd*sizeof(Rd)+ctlr->ntd*sizeof(Td) + 255);
1360         ctlr->rb = malloc(ctlr->nrd * sizeof(Block*));
1361         ctlr->tb = malloc(ctlr->ntd * sizeof(Block*));
1362         if(ctlr->alloc == nil || ctlr->rb == nil || ctlr->tb == nil){
1363                 free(ctlr->rb);
1364                 ctlr->rb = nil;
1365                 free(ctlr->tb);
1366                 ctlr->tb = nil;
1367                 free(ctlr->alloc);
1368                 ctlr->alloc = nil;
1369                 qunlock(&ctlr->alock);
1370                 error(Enomem);
1371         }
1372         ctlr->rdba = (Rd*)ROUNDUP((uintptr)ctlr->alloc, 256);
1373         ctlr->tdba = (Td*)(ctlr->rdba + ctlr->nrd);
1374
1375         if(waserror()){
1376                 free(ctlr->tb);
1377                 ctlr->tb = nil;
1378                 free(ctlr->rb);
1379                 ctlr->rb = nil;
1380                 free(ctlr->alloc);
1381                 ctlr->alloc = nil;
1382                 qunlock(&ctlr->alock);
1383                 nexterror();
1384         }
1385
1386         snprint(name, sizeof name, "#l%dl", edev->ctlrno);
1387         if(csr32r(ctlr, Status) & Tbimode)
1388                 kproc(name, serdeslproc, edev);         /* mac based serdes */
1389         else if((csr32r(ctlr, Ctrlext) & Linkmode) == Serdes)
1390                 kproc(name, pcslproc, edev);            /* phy based serdes */
1391         else if(cttab[ctlr->type].flag & F79phy)
1392                 kproc(name, phyl79proc, edev);
1393         else
1394                 kproc(name, phylproc, edev);
1395
1396         snprint(name, sizeof name, "#l%dr", edev->ctlrno);
1397         kproc(name, i82563rproc, edev);
1398
1399         snprint(name, sizeof name, "#l%dt", edev->ctlrno);
1400         kproc(name, i82563tproc, edev);
1401
1402         qunlock(&ctlr->alock);
1403         poperror();
1404 }
1405
1406 static void
1407 i82563interrupt(Ureg*, void *arg)
1408 {
1409         Ctlr *ctlr;
1410         Ether *edev;
1411         int icr, im;
1412
1413         edev = arg;
1414         ctlr = edev->ctlr;
1415
1416         ilock(&ctlr->imlock);
1417         csr32w(ctlr, Imc, ~0);
1418         im = ctlr->im;
1419
1420         while(icr = csr32r(ctlr, Icr) & ctlr->im){
1421                 if(icr & (Lsc | Omed)){
1422                         im &= ~(Lsc | Omed);
1423                         ctlr->lim = icr & (Lsc | Omed);
1424                         wakeup(&ctlr->lrendez);
1425                         ctlr->lintr++;
1426                 }
1427                 if(icr & (Rxt0|Rxo|Rxdmt0|Rxseq|Ack)){
1428                         ctlr->rim = icr & (Rxt0|Rxo|Rxdmt0|Rxseq|Ack);
1429                         im &= ~(Rxt0|Rxo|Rxdmt0|Rxseq|Ack);
1430                         wakeup(&ctlr->rrendez);
1431                         ctlr->rintr++;
1432                 }
1433                 if(icr & Txdw){
1434                         im &= ~Txdw;
1435                         ctlr->tintr++;
1436                         wakeup(&ctlr->trendez);
1437                 }
1438         }
1439
1440         ctlr->im = im;
1441         csr32w(ctlr, Ims, im);
1442         iunlock(&ctlr->imlock);
1443 }
1444
1445 static int
1446 i82563detach(Ctlr *ctlr)
1447 {
1448         int r, timeo;
1449
1450         /* balance rx/tx packet buffer; survives reset */
1451         if(ctlr->rbsz > 8192 && cttab[ctlr->type].flag & Fpba){
1452                 ctlr->pba = csr32r(ctlr, Pba);
1453                 r = ctlr->pba >> 16;
1454                 r += ctlr->pba & 0xffff;
1455                 r >>= 1;
1456                 csr32w(ctlr, Pba, r);
1457         }else if(ctlr->type == i82573 && ctlr->rbsz > 1514)
1458                 csr32w(ctlr, Pba, 14);
1459         ctlr->pba = csr32r(ctlr, Pba);
1460
1461         /*
1462          * Perform a device reset to get the chip back to the
1463          * power-on state, followed by an EEPROM reset to read
1464          * the defaults for some internal registers.
1465          */
1466         csr32w(ctlr, Imc, ~0);
1467         csr32w(ctlr, Rctl, 0);
1468         csr32w(ctlr, Tctl, csr32r(ctlr, Tctl) & ~Ten);
1469
1470         delay(10);
1471
1472         r = csr32r(ctlr, Ctrl);
1473         if(ctlr->type == i82566 || ctlr->type == i82579)
1474                 r |= Phyrst;
1475         /*
1476          * hack: 82579LM on lenovo X230 is stuck at 10mbps after
1477          * reseting the phy, but works fine if we dont reset.
1478          */
1479         if(ctlr->pcidev->did == 0x1502)
1480                 r &= ~Phyrst;
1481         csr32w(ctlr, Ctrl, Devrst | r);
1482         delay(1);
1483         for(timeo = 0;; timeo++){
1484                 if((csr32r(ctlr, Ctrl) & (Devrst|Phyrst)) == 0)
1485                         break;
1486                 if(timeo >= 1000)
1487                         return -1;
1488                 delay(1);
1489         }
1490
1491         r = csr32r(ctlr, Ctrl);
1492         csr32w(ctlr, Ctrl, Slu|r);
1493
1494         r = csr32r(ctlr, Ctrlext);
1495         csr32w(ctlr, Ctrlext, r|Eerst);
1496         delay(1);
1497         for(timeo = 0; timeo < 1000; timeo++){
1498                 if(!(csr32r(ctlr, Ctrlext) & Eerst))
1499                         break;
1500                 delay(1);
1501         }
1502         if(csr32r(ctlr, Ctrlext) & Eerst)
1503                 return -1;
1504
1505         csr32w(ctlr, Imc, ~0);
1506         delay(1);
1507         for(timeo = 0; timeo < 1000; timeo++){
1508                 if((csr32r(ctlr, Icr) & ~Rxcfg) == 0)
1509                         break;
1510                 delay(1);
1511         }
1512         if(csr32r(ctlr, Icr) & ~Rxcfg)
1513                 return -1;
1514
1515         return 0;
1516 }
1517
1518 static void
1519 i82563shutdown(Ether *edev)
1520 {
1521         i82563detach(edev->ctlr);
1522 }
1523
1524 static int
1525 eeread(Ctlr *ctlr, int adr)
1526 {
1527         int timeout;
1528
1529         csr32w(ctlr, Eerd, EEstart | adr << 2);
1530         timeout = 1000;
1531         while ((csr32r(ctlr, Eerd) & EEdone) == 0 && timeout--)
1532                 microdelay(5);
1533         if (timeout < 0) {
1534                 print("%s: eeread timeout\n", cname(ctlr));
1535                 return -1;
1536         }
1537         return (csr32r(ctlr, Eerd) >> 16) & 0xffff;
1538 }
1539
1540 static int
1541 eeload(Ctlr *ctlr)
1542 {
1543         u16int sum;
1544         int data, adr;
1545
1546         sum = 0;
1547         for (adr = 0; adr < 0x40; adr++) {
1548                 data = eeread(ctlr, adr);
1549                 if(data == -1) return -1;
1550                 ctlr->eeprom[adr] = data;
1551                 sum += data;
1552         }
1553         return sum;
1554 }
1555
1556 static int
1557 fread16(Ctlr *c, Flash *f, int ladr)
1558 {
1559         u16int s;
1560         int timeout;
1561
1562         delay(1);
1563         s = f->reg[Fsts];
1564         if((s&Fvalid) == 0)
1565                 return -1;
1566         f->reg[Fsts] |= Fcerr | Ael;
1567         for(timeout = 0; timeout < 10; timeout++){
1568                 if((s&Scip) == 0)
1569                         goto done;
1570                 delay(1);
1571                 s = f->reg[Fsts];
1572         }
1573         return -1;
1574 done:
1575         f->reg[Fsts] |= Fdone;
1576         f->reg32[Faddr] = ladr;
1577
1578         /* setup flash control register */
1579         s = f->reg[Fctl] & ~0x3ff;
1580         f->reg[Fctl] = s | 1<<8 | Fgo;  /* 2 byte read */
1581         timeout = 1000;
1582         while((f->reg[Fsts] & Fdone) == 0 && timeout--)
1583                 microdelay(5);
1584         if(timeout < 0){
1585                 print("%s: fread timeout\n", cname(c));
1586                 return -1;
1587         }
1588         if(f->reg[Fsts] & (Fcerr|Ael))
1589                 return -1;
1590         return f->reg32[Fdata] & 0xffff;
1591 }
1592
1593 static int
1594 fread32(Ctlr *c, Flash *f, int ladr, u32int *data)
1595 {
1596         u32int s;
1597         int timeout;
1598
1599         delay(1);
1600         s = f->reg32[Fsts/2];
1601         if((s&Fvalid) == 0)
1602                 return -1;
1603         f->reg32[Fsts/2] |= Fcerr | Ael;
1604         for(timeout = 0; timeout < 10; timeout++){
1605                 if((s&Scip) == 0)
1606                         goto done;
1607                 delay(1);
1608                 s = f->reg32[Fsts/2];
1609         }
1610         return -1;
1611 done:
1612         f->reg32[Fsts/2] |= Fdone;
1613         f->reg32[Faddr] = ladr;
1614
1615         /* setup flash control register */
1616         s = (f->reg32[Fctl/2] >> 16) & ~0x3ff;
1617         f->reg32[Fctl/2] = (s | 3<<8 | Fgo) << 16;      /* 4 byte read */
1618         timeout = 1000;
1619         while((f->reg32[Fsts/2] & Fdone) == 0 && timeout--)
1620                 microdelay(5);
1621         if(timeout < 0){
1622                 print("%s: fread timeout\n", cname(c));
1623                 return -1;
1624         }
1625         if(f->reg32[Fsts/2] & (Fcerr|Ael))
1626                 return -1;
1627         *data = f->reg32[Fdata];
1628         return 0;
1629 }
1630
1631 static int
1632 fload32(Ctlr *c)
1633 {
1634         int r, adr;
1635         u16int sum;
1636         u32int w;
1637         Flash f;
1638
1639         f.reg32 = &c->nic[0xe000/4];
1640         f.reg = nil;
1641         f.base = 0;
1642         f.lim = (((csr32r(c, 0xC) >> 1) & 0x1F) + 1) << 12;
1643         r = f.lim >> 1;
1644         if(fread32(c, &f, r + 0x24, &w) == -1  || (w & 0xC000) != 0x8000)
1645                 r = 0;
1646         sum = 0;
1647         for(adr = 0; adr < 0x20; adr++) {
1648                 if(fread32(c, &f, r + adr*4, &w) == -1)
1649                         return -1;
1650                 c->eeprom[adr*2+0] = w;
1651                 c->eeprom[adr*2+1] = w>>16;
1652                 sum += w & 0xFFFF;
1653                 sum += w >> 16;
1654         }
1655         return sum;
1656 }
1657
1658 static int
1659 fload(Ctlr *c)
1660 {
1661         int data, r, adr;
1662         u16int sum;
1663         void *va;
1664         Flash f;
1665
1666         memset(c->eeprom, 0xFF, sizeof(c->eeprom));
1667         if(c->pcidev->mem[1].bar == 0)
1668                 return fload32(c);      /* i219 */
1669
1670         va = vmap(c->pcidev->mem[1].bar & ~0x0f, c->pcidev->mem[1].size);
1671         if(va == nil)
1672                 return -1;
1673         f.reg = va;
1674         f.reg32 = va;
1675         f.base = f.reg32[Bfpr] & 0x1fff;
1676         f.lim = f.reg32[Bfpr]>>16 & 0x1fff;
1677         if(csr32r(c, Eec) & Sec1val)
1678                 f.base += f.lim+1 - f.base >> 1;
1679         r = f.base << 12;
1680         sum = 0;
1681         for(adr = 0; adr < 0x40; adr++) {
1682                 data = fread16(c, &f, r + adr*2);
1683                 if(data == -1)
1684                         goto out;
1685                 c->eeprom[adr] = data;
1686                 sum += data;
1687         }
1688 out:
1689         vunmap(va, c->pcidev->mem[1].size);
1690         return sum;
1691 }
1692
1693 static int
1694 invmload(Ctlr *c)
1695 {
1696         int i, a;
1697         u32int w;
1698
1699         memset(c->eeprom, 0xFF, sizeof(c->eeprom));
1700         for(i=0; i<64; i++){
1701                 w = csr32r(c, Invmdata0 + i*4);
1702                 switch(w & 7){
1703                 case 0: // uninitialized structure
1704                         break;
1705                 case 1: // word auto load
1706                         a = (w & 0xFE00) >> 9;
1707                         if(a < nelem(c->eeprom))
1708                                 c->eeprom[a] = w >> 16;
1709                         continue;
1710                 case 2: // csr auto load
1711                         i++;
1712                 case 3: // phy auto load
1713                         continue;
1714                 case 4: // rsa key sha256
1715                         i += 256/32;
1716                 case 5: // invalidated structure
1717                         continue;
1718                 default:
1719                         print("invm: %.2x %.8ux\n", i, w);
1720                         continue;
1721                 }
1722                 break;
1723         }
1724         return 0;
1725 }
1726
1727 static void
1728 defaultea(Ctlr *ctlr, uchar *ra)
1729 {
1730         uint i, r;
1731         uvlong u;
1732         static uchar nilea[Eaddrlen];
1733
1734         if(memcmp(ra, nilea, Eaddrlen) != 0)
1735                 return;
1736         if(cttab[ctlr->type].flag & Fflashea){
1737                 /* intel mb bug */
1738                 u = (uvlong)csr32r(ctlr, Rah)<<32u | (ulong)csr32r(ctlr, Ral);
1739                 for(i = 0; i < Eaddrlen; i++)
1740                         ra[i] = u >> 8*i;
1741         }
1742         if(memcmp(ra, nilea, Eaddrlen) != 0)
1743                 return;
1744         for(i = 0; i < Eaddrlen/2; i++){
1745                 ra[2*i] = ctlr->eeprom[Ea+i];
1746                 ra[2*i+1] = ctlr->eeprom[Ea+i] >> 8;
1747         }
1748         r = (csr32r(ctlr, Status) & Lanid) >> 2;
1749         ra[5] += r;                             /* ea ctlr[n] = ea ctlr[0]+n */
1750 }
1751
1752 static int
1753 i82563reset(Ctlr *ctlr)
1754 {
1755         uchar *ra;
1756         int i, r, flag;
1757
1758         if(i82563detach(ctlr))
1759                 return -1;
1760         flag = cttab[ctlr->type].flag;
1761
1762         if(ctlr->type == i210 && (csr32r(ctlr, Eec) & Flupd) == 0)
1763                 r = invmload(ctlr);
1764         else if(flag & Fload)
1765                 r = fload(ctlr);
1766         else
1767                 r = eeload(ctlr);
1768
1769         if(r != 0 && r != 0xbaba){
1770                 print("%s: bad eeprom checksum - %#.4ux", cname(ctlr), r);
1771                 if(flag & Fbadcsum)
1772                         print("; ignored\n");
1773                 else {
1774                         print("\n");
1775                         return -1;
1776                 }
1777         }
1778
1779         ra = ctlr->ra;
1780         defaultea(ctlr, ra);
1781         csr32w(ctlr, Ral, ra[3]<<24 | ra[2]<<16 | ra[1]<<8 | ra[0]);
1782         csr32w(ctlr, Rah, 1<<31 | ra[5]<<8 | ra[4]);
1783         for(i = 1; i < 16; i++){
1784                 csr32w(ctlr, Ral+i*8, 0);
1785                 csr32w(ctlr, Rah+i*8, 0);
1786         }
1787         memset(ctlr->mta, 0, sizeof(ctlr->mta));
1788         for(i = 0; i < 128; i++)
1789                 csr32w(ctlr, Mta + i*4, 0);
1790         csr32w(ctlr, Fcal, 0x00C28001);
1791         csr32w(ctlr, Fcah, 0x0100);
1792         if((flag & Fnofct) == 0)
1793                 csr32w(ctlr, Fct, 0x8808);
1794         csr32w(ctlr, Fcttv, 0x0100);
1795         csr32w(ctlr, Fcrtl, ctlr->fcrtl);
1796         csr32w(ctlr, Fcrth, ctlr->fcrth);
1797         if(flag & F75)
1798                 csr32w(ctlr, Eitr, 128<<2);             /* 128 ¼ microsecond intervals */
1799         return 0;
1800 }
1801
1802 enum {
1803         CMrdtr,
1804         CMradv,
1805         CMpause,
1806         CMan,
1807 };
1808
1809 static Cmdtab i82563ctlmsg[] = {
1810         CMrdtr, "rdtr", 2,
1811         CMradv, "radv", 2,
1812         CMpause, "pause", 1,
1813         CMan,   "an",   1,
1814 };
1815
1816 static long
1817 i82563ctl(Ether *edev, void *buf, long n)
1818 {
1819         char *p;
1820         ulong v;
1821         Ctlr *ctlr;
1822         Cmdbuf *cb;
1823         Cmdtab *ct;
1824
1825         if((ctlr = edev->ctlr) == nil)
1826                 error(Enonexist);
1827
1828         cb = parsecmd(buf, n);
1829         if(waserror()){
1830                 free(cb);
1831                 nexterror();
1832         }
1833
1834         ct = lookupcmd(cb, i82563ctlmsg, nelem(i82563ctlmsg));
1835         switch(ct->index){
1836         case CMrdtr:
1837                 v = strtoul(cb->f[1], &p, 0);
1838                 if(*p || v > 0xffff)
1839                         error(Ebadarg);
1840                 ctlr->rdtr = v;
1841                 csr32w(ctlr, Rdtr, v);
1842                 break;
1843         case CMradv:
1844                 v = strtoul(cb->f[1], &p, 0);
1845                 if(*p || v > 0xffff)
1846                         error(Ebadarg);
1847                 ctlr->radv = v;
1848                 csr32w(ctlr, Radv, v);
1849                 break;
1850         case CMpause:
1851                 csr32w(ctlr, Ctrl, csr32r(ctlr, Ctrl) ^ (Rfce | Tfce));
1852                 break;
1853         case CMan:
1854                 csr32w(ctlr, Ctrl, csr32r(ctlr, Ctrl) | Lrst | Phyrst);
1855                 break;
1856         }
1857         free(cb);
1858         poperror();
1859
1860         return n;
1861 }
1862
1863 static int
1864 didtype(int d)
1865 {
1866         /*
1867          * Some names and did values are from
1868          * OpenBSD's em(4) Intel driver.
1869          */
1870         switch(d){
1871         case 0x1096:            /* copper */
1872         case 0x10ba:            /* copper “gilgal” */
1873         case 0x1098:            /* serdes; not seen */
1874         case 0x10bb:            /* serdes */
1875                 return i82563;
1876         case 0x1049:            /* ich8; mm */
1877         case 0x104a:            /* ich8; dm */
1878         case 0x104b:            /* ich8; dc */
1879         case 0x104d:            /* ich8; v “ninevah” */
1880         case 0x10bd:            /* ich9; dm-2 */
1881         case 0x294c:            /* ich9 */
1882         case 0x104c:            /* ich8; untested */
1883         case 0x10c4:            /* ich8; untested */
1884         case 0x10c5:            /* ich8; untested */
1885                 return i82566;
1886         case 0x10de:            /* lm ich10d */
1887         case 0x10df:            /* lf ich10 */
1888         case 0x10e5:            /* lm ich9 */
1889         case 0x10f5:            /* lm ich9m; “boazman” */
1890         case 0x10ce:            /* v ich10 */
1891         case 0x10c0:            /* ich9 */
1892         case 0x10c2:            /* ich9; untested */
1893         case 0x10c3:            /* ich9; untested */
1894         case 0x1501:            /* ich8; untested */
1895                 return i82567;
1896         case 0x10bf:            /* lf ich9m */
1897         case 0x10cb:            /* v ich9m */
1898         case 0x10cd:            /* lf ich10 */
1899         case 0x10cc:            /* lm ich10 */
1900                 return i82567m;
1901         case 0x105e:            /* eb copper */
1902         case 0x105f:            /* eb fiber */
1903         case 0x1060:            /* eb serdes */
1904         case 0x10a4:            /* eb copper */
1905         case 0x10a5:            /* eb fiber */
1906         case 0x10bc:            /* eb copper */
1907         case 0x10d9:            /* eb serdes */
1908         case 0x10da:            /* eb serdes “ophir” */
1909         case 0x10a0:            /* eb; untested */
1910         case 0x10a1:            /* eb; untested */
1911         case 0x10d5:            /* copper; untested */
1912                 return i82571;
1913         case 0x107d:            /* ei copper */
1914         case 0x107e:            /* ei fiber */
1915         case 0x107f:            /* ei serdes */
1916         case 0x10b9:            /* ei “rimon” */
1917                 return i82572;
1918         case 0x108b:            /* e “vidalia” */
1919         case 0x108c:            /* e (iamt) */
1920         case 0x109a:            /* l “tekoa” */
1921         case 0x10b0:            /* l; untested */
1922         case 0x10b2:            /* v; untested */
1923         case 0x10b3:            /* e; untested */
1924         case 0x10b4:            /* l; untested */
1925                 return i82573;
1926         case 0x10d3:            /* l or it; “hartwell” */
1927         case 0x10f6:            /* la; untested */
1928                 return i82574;
1929         case 0x10a7:            /* eb */
1930         case 0x10a9:            /* eb fiber/serdes */
1931         case 0x10d6:            /* untested */
1932         case 0x10e2:            /* untested */
1933                 return i82575;
1934         case 0x10c9:            /* copper */
1935         case 0x10e6:            /* fiber */
1936         case 0x10e7:            /* serdes; “kawela” */
1937         case 0x10e8:            /* copper; untested */
1938         case 0x150a:            /* untested */
1939         case 0x150d:            /* serdes backplane */
1940         case 0x1518:            /* serdes; untested */
1941         case 0x1526:            /* untested */
1942                 return i82576;
1943         case 0x10ea:            /* lc “calpella”; aka pch lan */
1944                 return i82577;
1945         case 0x10eb:            /* lm “calpella” */
1946                 return i82577m;
1947         case 0x10ef:            /* dc “piketon” */
1948                 return i82578;
1949         case 0x1502:            /* lm */
1950         case 0x1503:            /* v “lewisville” */
1951                 return i82579;
1952         case 0x10f0:            /* dm “king's creek” */
1953                 return i82578m;
1954         case 0x150e:            /* copper “barton hills” */
1955         case 0x150f:            /* fiber */
1956         case 0x1510:            /* serdes backplane */
1957         case 0x1511:            /* sgmii sfp */
1958         case 0x1516:            /* copper */
1959                 return i82580;
1960         case 0x1506:            /* v */
1961         case 0x150c:            /* untested */
1962                 return i82583;
1963         case 0x1533:            /* i210-t1 */
1964         case 0x1534:            /* i210 */
1965         case 0x1536:            /* i210-fiber */
1966         case 0x1537:            /* i210-backplane */
1967         case 0x1538:            /* i210 sgmii */
1968         case 0x1539:            /* i211 copper */
1969         case 0x157b:            /* i210 copper flashless */
1970         case 0x157c:            /* i210 serdes flashless */
1971                 return i210;
1972         case 0x153a:            /* i217-lm */
1973         case 0x153b:            /* i217-v */
1974                 return i217;
1975         case 0x1559:            /* i218-v */
1976         case 0x155a:            /* i218-lm */
1977         case 0x15a0:            /* i218-lm */
1978         case 0x15a1:            /* i218-v */
1979         case 0x15a2:            /* i218-lm */
1980         case 0x15a3:            /* i218-v */
1981                 return i218;
1982         case 0x156f:            /* i219-lm */
1983         case 0x15b7:            /* i219-lm */
1984         case 0x1570:            /* i219-v */
1985         case 0x15b8:            /* i219-v */
1986         case 0x15b9:            /* i219-lm */
1987         case 0x15d6:            /* i219-v */
1988         case 0x15d7:            /* i219-lm */
1989         case 0x15d8:            /* i219-v */
1990         case 0x15e3:            /* i219-lm */
1991                 return i219;
1992         case 0x151f:            /* i350 “powerville” eeprom-less */
1993         case 0x1521:            /* i350 copper */
1994         case 0x1522:            /* i350 fiber */
1995         case 0x1523:            /* i350 serdes */
1996         case 0x1524:            /* i350 sgmii */
1997         case 0x1546:            /* i350 DA4 (untested) */
1998         case 0x1f40:            /* i354 backplane */
1999         case 0x1f41:            /* i354 sgmii */
2000         case 0x1f42:            /* i354 sgmii (c2000) */
2001         case 0x1f45:            /* i354 backplane 2.5 */
2002                 return i350;
2003         }
2004         return -1;
2005 }
2006
2007 static void
2008 hbafixup(Pcidev *p)
2009 {
2010         uint i;
2011
2012         i = pcicfgr32(p, PciSVID);
2013         if((i & 0xffff) == 0x1b52 && p->did == 1)
2014                 p->did = i>>16;
2015 }
2016
2017 static void
2018 i82563pci(void)
2019 {
2020         int type;
2021         Ctlr *ctlr;
2022         Pcidev *p;
2023
2024         for(p = nil; p = pcimatch(p, 0x8086, 0);){
2025                 hbafixup(p);
2026                 if((type = didtype(p->did)) == -1)
2027                         continue;
2028                 ctlr = malloc(sizeof(Ctlr));
2029                 if(ctlr == nil){
2030                         print("%s: can't allocate memory\n", cttab[type].name);
2031                         continue;
2032                 }
2033                 ctlr->type = type;
2034                 ctlr->pcidev = p;
2035                 ctlr->rbsz = cttab[type].mtu;
2036                 ctlr->port = p->mem[0].bar & ~0x0F;
2037                 if(i82563ctlrhead != nil)
2038                         i82563ctlrtail->next = ctlr;
2039                 else
2040                         i82563ctlrhead = ctlr;
2041                 i82563ctlrtail = ctlr;
2042         }
2043 }
2044
2045 static int
2046 setup(Ctlr *ctlr)
2047 {
2048         Pcidev *p;
2049
2050         p = ctlr->pcidev;
2051         ctlr->nic = vmap(ctlr->port, p->mem[0].size);
2052         if(ctlr->nic == nil){
2053                 print("%s: can't map 0x%lux\n", cname(ctlr), ctlr->port);
2054                 return -1;
2055         }
2056         if(i82563reset(ctlr)){
2057                 vunmap(ctlr->nic, p->mem[0].size);
2058                 return -1;
2059         }
2060         pcisetbme(ctlr->pcidev);
2061         return 0;
2062 }
2063
2064 static int
2065 pnp(Ether *edev, int type)
2066 {
2067         Ctlr *ctlr;
2068         static int done;
2069
2070         if(!done) {
2071                 i82563pci();
2072                 done = 1;
2073         }
2074
2075         /*
2076          * Any adapter matches if no edev->port is supplied,
2077          * otherwise the ports must match.
2078          */
2079         for(ctlr = i82563ctlrhead; ; ctlr = ctlr->next){
2080                 if(ctlr == nil)
2081                         return -1;
2082                 if(ctlr->active)
2083                         continue;
2084                 if(type != -1 && ctlr->type != type)
2085                         continue;
2086                 if(edev->port == 0 || edev->port == ctlr->port){
2087                         ctlr->active = 1;
2088                         memmove(ctlr->ra, edev->ea, Eaddrlen);
2089                         if(setup(ctlr) == 0)
2090                                 break;
2091                 }
2092         }
2093
2094         edev->ctlr = ctlr;
2095         edev->port = ctlr->port;
2096         edev->irq = ctlr->pcidev->intl;
2097         edev->tbdf = ctlr->pcidev->tbdf;
2098         edev->mbps = 1000;
2099         edev->maxmtu = ctlr->rbsz;
2100         memmove(edev->ea, ctlr->ra, Eaddrlen);
2101
2102         /*
2103          * Linkage to the generic ethernet driver.
2104          */
2105         edev->attach = i82563attach;
2106 //      edev->transmit = i82563transmit;
2107         edev->ifstat = i82563ifstat;
2108         edev->ctl = i82563ctl;
2109
2110         edev->arg = edev;
2111         edev->promiscuous = i82563promiscuous;
2112         edev->shutdown = i82563shutdown;
2113         edev->multicast = i82563multicast;
2114
2115         intrenable(edev->irq, i82563interrupt, edev, edev->tbdf, edev->name);
2116
2117         return 0;
2118 }
2119
2120 static int
2121 anypnp(Ether *e)
2122 {
2123         return pnp(e, -1);
2124 }
2125
2126 static int
2127 i82563pnp(Ether *e)
2128 {
2129         return pnp(e, i82563);
2130 }
2131
2132 static int
2133 i82566pnp(Ether *e)
2134 {
2135         return pnp(e, i82566);
2136 }
2137
2138 static int
2139 i82567pnp(Ether *e)
2140 {
2141         return pnp(e, i82567m) & pnp(e, i82567);
2142 }
2143
2144 static int
2145 i82571pnp(Ether *e)
2146 {
2147         return pnp(e, i82571);
2148 }
2149
2150 static int
2151 i82572pnp(Ether *e)
2152 {
2153         return pnp(e, i82572);
2154 }
2155
2156 static int
2157 i82573pnp(Ether *e)
2158 {
2159         return pnp(e, i82573);
2160 }
2161
2162 static int
2163 i82574pnp(Ether *e)
2164 {
2165         return pnp(e, i82574);
2166 }
2167
2168 static int
2169 i82575pnp(Ether *e)
2170 {
2171         return pnp(e, i82575);
2172 }
2173
2174 static int
2175 i82576pnp(Ether *e)
2176 {
2177         return pnp(e, i82576);
2178 }
2179
2180 static int
2181 i82577pnp(Ether *e)
2182 {
2183         return pnp(e, i82577m) & pnp(e, i82577);
2184 }
2185
2186 static int
2187 i82578pnp(Ether *e)
2188 {
2189         return pnp(e, i82578m) & pnp(e, i82578);
2190 }
2191
2192 static int
2193 i82579pnp(Ether *e)
2194 {
2195         return pnp(e, i82579);
2196 }
2197
2198 static int
2199 i82580pnp(Ether *e)
2200 {
2201         return pnp(e, i82580);
2202 }
2203
2204 static int
2205 i82583pnp(Ether *e)
2206 {
2207         return pnp(e, i82583);
2208 }
2209
2210 static int
2211 i210pnp(Ether *e)
2212 {
2213         return pnp(e, i210);
2214 }
2215
2216 static int
2217 i217pnp(Ether *e)
2218 {
2219         return pnp(e, i217);
2220 }
2221
2222 static int
2223 i218pnp(Ether *e)
2224 {
2225         return pnp(e, i218);
2226 }
2227
2228 static int
2229 i219pnp(Ether *e)
2230 {
2231         return pnp(e, i219);
2232 }
2233
2234 static int
2235 i350pnp(Ether *e)
2236 {
2237         return pnp(e, i350);
2238 }
2239
2240 void
2241 ether82563link(void)
2242 {
2243         /*
2244          * recognise lots of model numbers for debugging
2245          * also good for forcing onboard nic(s) as ether0
2246          * try to make that unnecessary by listing lom first.
2247          */
2248         addethercard("i82563", i82563pnp);
2249         addethercard("i82566", i82566pnp);
2250         addethercard("i82574", i82574pnp);
2251         addethercard("i82576", i82576pnp);
2252         addethercard("i82567", i82567pnp);
2253         addethercard("i82573", i82573pnp);
2254
2255         addethercard("i82571", i82571pnp);
2256         addethercard("i82572", i82572pnp);
2257         addethercard("i82575", i82575pnp);
2258         addethercard("i82577", i82577pnp);
2259         addethercard("i82578", i82578pnp);
2260         addethercard("i82579", i82579pnp);
2261         addethercard("i82580", i82580pnp);
2262         addethercard("i82583", i82583pnp);
2263         addethercard("i210", i210pnp);
2264         addethercard("i217", i217pnp);
2265         addethercard("i218", i218pnp);
2266         addethercard("i219", i219pnp);
2267         addethercard("i350", i350pnp);
2268         addethercard("igbepcie", anypnp);
2269 }