]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/ether82563.c
62d2217366daeeaf499473933e94d51e3ca27d71
[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         Fnofca  = 1<<8,
467 };
468
469 typedef struct Ctlrtype Ctlrtype;
470 struct Ctlrtype {
471         char    *name;
472         int     mtu;
473         int     flag;
474 };
475
476 static Ctlrtype cttab[Nctlrtype] = {
477 [i82563]        "i82563",       9014,   Fpba,
478 [i82566]        "i82566",       1514,   Fload,
479 [i82567]        "i82567",       9234,   Fload,
480 [i82567m]       "i82567m",      1514,   Fload,
481 [i82571]        "i82571",       9234,   Fpba,
482 [i82572]        "i82572",       9234,   Fpba,
483 [i82573]        "i82573",       8192,   Fert|Fbadcsum,          /* terrible perf above 8k */
484 [i82574]        "i82574",       9018,   0,
485 [i82575]        "i82575",       9728,   F75|Fflashea,
486 [i82576]        "i82576",       9728,   F75,
487 [i82577]        "i82577",       4096,   Fload|Fert,
488 [i82577m]       "i82577",       1514,   Fload|Fert,
489 [i82578]        "i82578",       4096,   Fload|Fert,
490 [i82578m]       "i82578",       1514,   Fload|Fert,
491 [i82579]        "i82579",       9018,   Fload|Fert|F79phy|Fnofct,
492 [i82580]        "i82580",       9728,   F75|F79phy,
493 [i82583]        "i82583",       1514,   0,
494 [i210]          "i210",         9728,   F75|Fnofct|Fert,
495 [i217]          "i217",         2048,   Fload|Fert|F79phy|Fnofct|Fnofca|Fbadcsum,/* 9018, but unstable above 2k */
496 [i218]          "i218",         9018,   Fload|Fert|F79phy|Fnofct|Fnofca|Fbadcsum,
497 [i219]          "i219",         9018,   Fload|Fert|F79phy|Fnofct|Fnofca|Fbadcsum,
498 [i350]          "i350",         9728,   F75|F79phy|Fnofct,
499 };
500
501 typedef void (*Freefn)(Block*);
502
503 typedef struct Ctlr Ctlr;
504 struct Ctlr {
505         ulong   port;
506         Pcidev  *pcidev;
507         Ctlr    *next;
508         int     active;
509         int     type;
510         u16int  eeprom[0x40];
511
512         QLock   alock;                  /* attach */
513         void    *alloc;                 /* receive/transmit descriptors */
514         int     nrd;
515         int     ntd;
516         int     rbsz;
517
518         u32int  *nic;
519         Lock    imlock;
520         int     im;                     /* interrupt mask */
521
522         Rendez  lrendez;
523         int     lim;
524
525         QLock   slock;
526         u32int  statistics[Nstatistics];
527         uint    lsleep;
528         uint    lintr;
529         uint    rsleep;
530         uint    rintr;
531         uint    txdw;
532         uint    tintr;
533         uint    ixsm;
534         uint    ipcs;
535         uint    tcpcs;
536         uint    speeds[4];
537         uint    phyerrata;
538
539         uchar   ra[Eaddrlen];           /* receive address */
540         u32int  mta[128];               /* multicast table array */
541
542         Rendez  rrendez;
543         int     rim;
544         int     rdfree;
545         Rd      *rdba;                  /* receive descriptor base address */
546         Block   **rb;                   /* receive buffers */
547         uint    rdh;                    /* receive descriptor head */
548         uint    rdt;                    /* receive descriptor tail */
549         int     rdtr;                   /* receive delay timer ring value */
550         int     radv;                   /* receive interrupt absolute delay timer */
551
552         Rendez  trendez;
553         QLock   tlock;
554         int     tbusy;
555         Td      *tdba;                  /* transmit descriptor base address */
556         Block   **tb;                   /* transmit buffers */
557         int     tdh;                    /* transmit descriptor head */
558         int     tdt;                    /* transmit descriptor tail */
559
560         int     fcrtl;
561         int     fcrth;
562
563         u32int  pba;                    /* packet buffer allocation */
564 };
565
566 #define csr32r(c, r)    (*((c)->nic+((r)/4)))
567 #define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
568
569 static  Ctlr    *i82563ctlrhead;
570 static  Ctlr    *i82563ctlrtail;
571
572 static char *statistics[Nstatistics] = {
573         "CRC Error",
574         "Alignment Error",
575         "Symbol Error",
576         "RX Error",
577         "Missed Packets",
578         "Single Collision",
579         "Excessive Collisions",
580         "Multiple Collision",
581         "Late Collisions",
582         nil,
583         "Collision",
584         "Transmit Underrun",
585         "Defer",
586         "Transmit - No CRS",
587         "Sequence Error",
588         "Carrier Extension Error",
589         "Receive Error Length",
590         nil,
591         "XON Received",
592         "XON Transmitted",
593         "XOFF Received",
594         "XOFF Transmitted",
595         "FC Received Unsupported",
596         "Packets Received (64 Bytes)",
597         "Packets Received (65-127 Bytes)",
598         "Packets Received (128-255 Bytes)",
599         "Packets Received (256-511 Bytes)",
600         "Packets Received (512-1023 Bytes)",
601         "Packets Received (1024-mtu Bytes)",
602         "Good Packets Received",
603         "Broadcast Packets Received",
604         "Multicast Packets Received",
605         "Good Packets Transmitted",
606         nil,
607         "Good Octets Received",
608         nil,
609         "Good Octets Transmitted",
610         nil,
611         nil,
612         nil,
613         "Receive No Buffers",
614         "Receive Undersize",
615         "Receive Fragment",
616         "Receive Oversize",
617         "Receive Jabber",
618         "Management Packets Rx",
619         "Management Packets Drop",
620         "Management Packets Tx",
621         "Total Octets Received",
622         nil,
623         "Total Octets Transmitted",
624         nil,
625         "Total Packets Received",
626         "Total Packets Transmitted",
627         "Packets Transmitted (64 Bytes)",
628         "Packets Transmitted (65-127 Bytes)",
629         "Packets Transmitted (128-255 Bytes)",
630         "Packets Transmitted (256-511 Bytes)",
631         "Packets Transmitted (512-1023 Bytes)",
632         "Packets Transmitted (1024-mtu Bytes)",
633         "Multicast Packets Transmitted",
634         "Broadcast Packets Transmitted",
635         "TCP Segmentation Context Transmitted",
636         "TCP Segmentation Context Fail",
637         "Interrupt Assertion",
638         "Interrupt Rx Pkt Timer",
639         "Interrupt Rx Abs Timer",
640         "Interrupt Tx Pkt Timer",
641         "Interrupt Tx Abs Timer",
642         "Interrupt Tx Queue Empty",
643         "Interrupt Tx Desc Low",
644         "Interrupt Rx Min",
645         "Interrupt Rx Overrun",
646 };
647
648 static char*
649 cname(Ctlr *c)
650 {
651         return cttab[c->type].name;
652 }
653
654 static long
655 i82563ifstat(Ether *edev, void *a, long n, ulong offset)
656 {
657         char *s, *p, *e, *stat;
658         int i, r;
659         uvlong tuvl, ruvl;
660         Ctlr *ctlr;
661
662         p = s = smalloc(READSTR);
663         e = p + READSTR;
664
665         ctlr = edev->ctlr;
666         qlock(&ctlr->slock);
667
668         for(i = 0; i < Nstatistics; i++){
669                 r = csr32r(ctlr, Statistics + i*4);
670                 if((stat = statistics[i]) == nil)
671                         continue;
672                 switch(i){
673                 case Gorcl:
674                 case Gotcl:
675                 case Torl:
676                 case Totl:
677                         ruvl = r;
678                         ruvl += (uvlong)csr32r(ctlr, Statistics+(i+1)*4) << 32;
679                         tuvl = ruvl;
680                         tuvl += ctlr->statistics[i];
681                         tuvl += (uvlong)ctlr->statistics[i+1] << 32;
682                         if(tuvl == 0)
683                                 continue;
684                         ctlr->statistics[i] = tuvl;
685                         ctlr->statistics[i+1] = tuvl >> 32;
686                         p = seprint(p, e, "%s: %llud %llud\n", stat, tuvl, ruvl);
687                         i++;
688                         break;
689
690                 default:
691                         ctlr->statistics[i] += r;
692                         if(ctlr->statistics[i] == 0)
693                                 continue;
694                         p = seprint(p, e, "%s: %ud %ud\n", stat,
695                                 ctlr->statistics[i], r);
696                         break;
697                 }
698         }
699
700         p = seprint(p, e, "lintr: %ud %ud\n", ctlr->lintr, ctlr->lsleep);
701         p = seprint(p, e, "rintr: %ud %ud\n", ctlr->rintr, ctlr->rsleep);
702         p = seprint(p, e, "tintr: %ud %ud\n", ctlr->tintr, ctlr->txdw);
703         p = seprint(p, e, "ixcs: %ud %ud %ud\n", ctlr->ixsm, ctlr->ipcs, ctlr->tcpcs);
704         p = seprint(p, e, "rdtr: %ud\n", ctlr->rdtr);
705         p = seprint(p, e, "radv: %ud\n", ctlr->radv);
706         p = seprint(p, e, "ctrl: %.8ux\n", csr32r(ctlr, Ctrl));
707         p = seprint(p, e, "ctrlext: %.8ux\n", csr32r(ctlr, Ctrlext));
708         p = seprint(p, e, "status: %.8ux\n", csr32r(ctlr, Status));
709         p = seprint(p, e, "txcw: %.8ux\n", csr32r(ctlr, Txcw));
710         p = seprint(p, e, "txdctl: %.8ux\n", csr32r(ctlr, Txdctl));
711         p = seprint(p, e, "pba: %.8ux\n", ctlr->pba);
712
713         p = seprint(p, e, "speeds: 10:%ud 100:%ud 1000:%ud ?:%ud\n",
714                 ctlr->speeds[0], ctlr->speeds[1], ctlr->speeds[2], ctlr->speeds[3]);
715         p = seprint(p, e, "type: %s\n", cname(ctlr));
716
717         p = seprint(p, e, "eeprom:");
718         for(i = 0; i < 0x40; i++){
719                 if(i && ((i & 7) == 0))
720                         p = seprint(p, e, "\n       ");
721                 p = seprint(p, e, " %4.4ux", ctlr->eeprom[i]);
722         }
723         p = seprint(p, e, "\n");
724
725         USED(p);
726         n = readstr(offset, a, n, s);
727         free(s);
728         qunlock(&ctlr->slock);
729
730         return n;
731 }
732
733 static void
734 i82563promiscuous(void *arg, int on)
735 {
736         int rctl;
737         Ctlr *ctlr;
738         Ether *edev;
739
740         edev = arg;
741         ctlr = edev->ctlr;
742
743         rctl = csr32r(ctlr, Rctl);
744         rctl &= ~MoMASK;
745         if(on)
746                 rctl |= Upe|Mpe;
747         else
748                 rctl &= ~(Upe|Mpe);
749         csr32w(ctlr, Rctl, rctl);
750 }
751
752 static void
753 i82563multicast(void *arg, uchar *addr, int on)
754 {
755         int bit, x;
756         Ctlr *ctlr;
757         Ether *edev;
758
759         edev = arg;
760         ctlr = edev->ctlr;
761
762         switch(ctlr->type){
763         case i82566:
764         case i82567:
765         case i82567m:
766         case i82577:
767         case i82577m:
768         case i82579:
769         case i210:
770         case i217:
771         case i218:
772         case i219:
773                 bit = (addr[5]<<2)|(addr[4]>>6);
774                 x = (bit>>5) & 31;
775                 break;
776         default:
777                 bit = (addr[5]<<4)|(addr[4]>>4);
778                 x = (bit>>5) & 127;
779                 break;
780         }
781         bit &= 31;
782
783         /*
784          * multiple ether addresses can hash to the same filter bit,
785          * so it's never safe to clear a filter bit.
786          * if we want to clear filter bits, we need to keep track of
787          * all the multicast addresses in use, clear all the filter bits,
788          * then set the ones corresponding to in-use addresses.
789          */
790         if(on)
791                 ctlr->mta[x] |= 1<<bit;
792
793         csr32w(ctlr, Mta+x*4, ctlr->mta[x]);
794 }
795
796 static void
797 i82563im(Ctlr *ctlr, int im)
798 {
799         ilock(&ctlr->imlock);
800         ctlr->im |= im;
801         csr32w(ctlr, Ims, ctlr->im);
802         iunlock(&ctlr->imlock);
803 }
804
805 static void
806 i82563txinit(Ctlr *ctlr)
807 {
808         u32int r;
809         Block *b;
810         int i;
811
812         if(cttab[ctlr->type].flag & F75)
813                 csr32w(ctlr, Tctl, 0x0F<<CtSHIFT | Psp);
814         else
815                 csr32w(ctlr, Tctl, 0x0F<<CtSHIFT | Psp | 66<<ColdSHIFT | Mulr);
816         csr32w(ctlr, Tipg, 6<<20 | 8<<10 | 8);          /* yb sez: 0x702008 */
817         for(i = 0; i < ctlr->ntd; i++){
818                 if((b = ctlr->tb[i]) != nil){
819                         ctlr->tb[i] = nil;
820                         freeb(b);
821                 }
822                 memset(&ctlr->tdba[i], 0, sizeof(Td));
823         }
824         csr32w(ctlr, Tdbal, PCIWADDR(ctlr->tdba));
825         csr32w(ctlr, Tdbah, 0);
826         csr32w(ctlr, Tdlen, ctlr->ntd * sizeof(Td));
827         ctlr->tdh = PREV(0, ctlr->ntd);
828         csr32w(ctlr, Tdh, 0);
829         ctlr->tdt = 0;
830         csr32w(ctlr, Tdt, 0);
831         csr32w(ctlr, Tidv, 128);
832         csr32w(ctlr, Tadv, 64);
833         csr32w(ctlr, Tctl, csr32r(ctlr, Tctl) | Ten);
834         r = csr32r(ctlr, Txdctl) & ~WthreshMASK;
835         r |= 4<<WthreshSHIFT | 4<<PthreshSHIFT;
836         if(cttab[ctlr->type].flag & F75)
837                 r |= Enable;
838         csr32w(ctlr, Txdctl, r);
839 }
840
841 static uint
842 i82563cleanup(Ctlr *c)
843 {
844         Block *b;
845         uint tdh, n;
846
847         tdh = c->tdh;
848         while(c->tdba[n = NEXT(tdh, c->ntd)].status & Tdd){
849                 tdh = n;
850                 if((b = c->tb[tdh]) != nil){
851                         c->tb[tdh] = nil;
852                         freeb(b);
853                 }else
854                         iprint("82563 tx underrun!\n");
855                 c->tdba[tdh].status = 0;
856         }
857
858         return c->tdh = tdh;
859 }
860
861 static int
862 notrim(void *v)
863 {
864         Ctlr *c;
865
866         c = v;
867         return (c->im & Txdw) == 0;
868 }
869
870 static void
871 i82563tproc(void *v)
872 {
873         Td *td;
874         Block *bp;
875         Ether *edev;
876         Ctlr *ctlr;
877         uint tdt, n;
878
879         edev = v;
880         ctlr = edev->ctlr;
881         i82563txinit(ctlr);
882
883         tdt = ctlr->tdt;
884         while(waserror())
885                 ;
886         for(;;){
887                 n = NEXT(tdt, ctlr->ntd);
888                 if(n == i82563cleanup(ctlr)){
889                         ctlr->txdw++;
890                         i82563im(ctlr, Txdw);
891                         sleep(&ctlr->trendez, notrim, ctlr);
892                         continue;
893                 }
894                 bp = qbread(edev->oq, 100000);
895                 td = &ctlr->tdba[tdt];
896                 td->addr[0] = PCIWADDR(bp->rp);
897                 td->addr[1] = 0;
898                 td->control = Ide|Rs|Ifcs|Teop|BLEN(bp);
899                 coherence();
900                 ctlr->tb[tdt] = bp;
901                 ctlr->tdt = tdt = n;
902                 csr32w(ctlr, Tdt, tdt);
903         }
904 }
905
906 static void
907 i82563replenish(Ctlr *ctlr)
908 {
909         uint rdt, i;
910         Block *bp;
911         Rd *rd;
912
913         i = 0;
914         for(rdt = ctlr->rdt; NEXT(rdt, ctlr->nrd) != ctlr->rdh; rdt = NEXT(rdt, ctlr->nrd)){
915                 rd = &ctlr->rdba[rdt];
916                 if(ctlr->rb[rdt] != nil){
917                         iprint("82563: tx overrun\n");
918                         break;
919                 }
920                 i++;
921                 bp = allocb(ctlr->rbsz + Rbalign);
922                 bp->rp = bp->wp = (uchar*)ROUND((uintptr)bp->base, Rbalign);
923                 ctlr->rb[rdt] = bp;
924                 rd->addr[0] = PCIWADDR(bp->rp);
925                 rd->addr[1] = 0;
926                 rd->status = 0;
927                 ctlr->rdfree++;
928         }
929         if(i != 0){
930                 coherence();
931                 ctlr->rdt = rdt;
932                 csr32w(ctlr, Rdt, rdt);
933         }
934 }
935
936 static void
937 i82563rxinit(Ctlr *ctlr)
938 {
939         int i;
940         Block *bp;
941
942         if(ctlr->rbsz <= 2048)
943                 csr32w(ctlr, Rctl, Dpf|Bsize2048|Bam|RdtmsHALF);
944         else{
945                 i = ctlr->rbsz / 1024;
946                 if(cttab[ctlr->type].flag & F75){
947                         csr32w(ctlr, Rctl, Lpe|Dpf|Bsize2048|Bam|RdtmsHALF|Secrc);
948                         if(ctlr->type != i82575)
949                                 i |= (ctlr->nrd/2>>4)<<20;              /* RdmsHalf */
950                         csr32w(ctlr, Srrctl, i | Dropen);
951                         csr32w(ctlr, Rmpl, ctlr->rbsz);
952 //                      csr32w(ctlr, Drxmxod, 0x7ff);
953                 }else
954                         csr32w(ctlr, Rctl, Lpe|Dpf|BsizeFlex*i|Bam|RdtmsHALF|Secrc);
955         }
956
957         if(cttab[ctlr->type].flag & Fert)
958                 csr32w(ctlr, Ert, 1024/8);
959
960         if(ctlr->type == i82566)
961                 csr32w(ctlr, Pbs, 16);
962
963         csr32w(ctlr, Rdbal, PCIWADDR(ctlr->rdba));
964         csr32w(ctlr, Rdbah, 0);
965         csr32w(ctlr, Rdlen, ctlr->nrd * sizeof(Rd));
966         ctlr->rdh = 0;
967         csr32w(ctlr, Rdh, 0);
968         ctlr->rdt = 0;
969         csr32w(ctlr, Rdt, 0);
970         ctlr->rdtr = 25;
971         ctlr->radv = 500;
972         csr32w(ctlr, Rdtr, ctlr->rdtr);
973         csr32w(ctlr, Radv, ctlr->radv);
974
975         for(i = 0; i < ctlr->nrd; i++)
976                 if((bp = ctlr->rb[i]) != nil){
977                         ctlr->rb[i] = nil;
978                         freeb(bp);
979                 }
980         if(cttab[ctlr->type].flag & F75)
981                 csr32w(ctlr, Rxdctl, 1<<WthreshSHIFT | 8<<PthreshSHIFT | 1<<HthreshSHIFT | Enable);
982         else
983                 csr32w(ctlr, Rxdctl, 2<<WthreshSHIFT | 2<<PthreshSHIFT);
984
985         /*
986          * Enable checksum offload.
987          */
988         csr32w(ctlr, Rxcsum, Tuofl | Ipofl | ETHERHDRSIZE);
989 }
990
991 static int
992 i82563rim(void *v)
993 {
994         return ((Ctlr*)v)->rim != 0;
995 }
996
997 static void
998 i82563rproc(void *arg)
999 {
1000         uint rdh, rim, im;
1001         Block *bp;
1002         Ctlr *ctlr;
1003         Ether *edev;
1004         Rd *rd;
1005
1006         edev = arg;
1007         ctlr = edev->ctlr;
1008
1009         i82563rxinit(ctlr);
1010         csr32w(ctlr, Rctl, csr32r(ctlr, Rctl) | Ren);
1011         if(cttab[ctlr->type].flag & F75){
1012                 csr32w(ctlr, Rxdctl, csr32r(ctlr, Rxdctl) | Enable);
1013                 im = Rxt0|Rxo|Rxdmt0|Rxseq|Ack;
1014         }else
1015                 im = Rxt0|Rxo|Rxdmt0|Rxseq|Ack;
1016
1017         while(waserror())
1018                 ;
1019         for(;;){
1020                 i82563im(ctlr, im);
1021                 ctlr->rsleep++;
1022                 i82563replenish(ctlr);
1023                 sleep(&ctlr->rrendez, i82563rim, ctlr);
1024
1025                 rdh = ctlr->rdh;
1026                 for(;;){
1027                         rim = ctlr->rim;
1028                         ctlr->rim = 0;
1029                         rd = &ctlr->rdba[rdh];
1030                         if(!(rd->status & Rdd))
1031                                 break;
1032
1033                         /*
1034                          * Accept eop packets with no errors.
1035                          * With no errors and the Ixsm bit set,
1036                          * the descriptor status Tpcs and Ipcs bits give
1037                          * an indication of whether the checksums were
1038                          * calculated and valid.
1039                          */
1040                         bp = ctlr->rb[rdh];
1041                         if((rd->status & Reop) && rd->errors == 0){
1042                                 bp->wp += rd->length;
1043                                 if(!(rd->status & Ixsm)){
1044                                         ctlr->ixsm++;
1045                                         if(rd->status & Ipcs){
1046                                                 /*
1047                                                  * IP checksum calculated
1048                                                  * (and valid as errors == 0).
1049                                                  */
1050                                                 ctlr->ipcs++;
1051                                                 bp->flag |= Bipck;
1052                                         }
1053                                         if(rd->status & Tcpcs){
1054                                                 /*
1055                                                  * TCP/UDP checksum calculated
1056                                                  * (and valid as errors == 0).
1057                                                  */
1058                                                 ctlr->tcpcs++;
1059                                                 bp->flag |= Btcpck|Budpck;
1060                                         }
1061                                         bp->checksum = rd->checksum;
1062                                         bp->flag |= Bpktck;
1063                                 }
1064                                 etheriq(edev, bp);
1065                         } else
1066                                 freeb(bp);
1067                         ctlr->rb[rdh] = nil;
1068                         ctlr->rdfree--;
1069                         ctlr->rdh = rdh = NEXT(rdh, ctlr->nrd);
1070                         if(ctlr->nrd-ctlr->rdfree >= 32 || (rim & Rxdmt0))
1071                                 i82563replenish(ctlr);
1072                 }
1073         }
1074 }
1075
1076 static int
1077 i82563lim(void *v)
1078 {
1079         return ((Ctlr*)v)->lim != 0;
1080 }
1081
1082 static int speedtab[] = {
1083         10, 100, 1000, 0
1084 };
1085
1086 static uint
1087 phyread(Ctlr *c, int phyno, int reg)
1088 {
1089         uint phy, i;
1090
1091         csr32w(c, Mdic, MDIrop | phyno<<MDIpSHIFT | reg<<MDIrSHIFT);
1092         phy = 0;
1093         for(i = 0; i < 64; i++){
1094                 phy = csr32r(c, Mdic);
1095                 if(phy & (MDIe|MDIready))
1096                         break;
1097                 microdelay(1);
1098         }
1099         if((phy & (MDIe|MDIready)) != MDIready){
1100                 print("%s: phy %d wedged %.8ux\n", cname(c), phyno, phy);
1101                 return ~0;
1102         }
1103         return phy & 0xffff;
1104 }
1105
1106 static uint
1107 phywrite0(Ctlr *c, int phyno, int reg, ushort val)
1108 {
1109         uint phy, i;
1110
1111         csr32w(c, Mdic, MDIwop | phyno<<MDIpSHIFT | reg<<MDIrSHIFT | val);
1112         phy = 0;
1113         for(i = 0; i < 64; i++){
1114                 phy = csr32r(c, Mdic);
1115                 if(phy & (MDIe|MDIready))
1116                         break;
1117                 microdelay(1);
1118         }
1119         if((phy & (MDIe|MDIready)) != MDIready)
1120                 return ~0;
1121         return 0;
1122 }
1123
1124 static uint
1125 setpage(Ctlr *c, uint phyno, uint p, uint r)
1126 {
1127         uint pr;
1128
1129         if(c->type == i82563){
1130                 if(r >= 16 && r <= 28 && r != 22)
1131                         pr = Phypage;
1132                 else if(r == 30 || r == 31)
1133                         pr = Phyapage;
1134                 else
1135                         return 0;
1136                 return phywrite0(c, phyno, pr, p);
1137         }else if(p == 0)
1138                 return 0;
1139         return ~0;
1140 }
1141
1142 static uint
1143 phywrite(Ctlr *c, uint phyno, uint reg, ushort v)
1144 {
1145         if(setpage(c, phyno, reg>>8, reg & 0xff) == ~0)
1146                 panic("%s: bad phy reg %.4ux", cname(c), reg);
1147         return phywrite0(c, phyno, reg & 0xff, v);
1148 }
1149
1150 static void
1151 phyerrata(Ether *e, Ctlr *c, uint phyno)
1152 {
1153         if(e->mbps == 0){
1154                 if(c->phyerrata == 0){
1155                         c->phyerrata++;
1156                         phywrite(c, phyno, Phyprst, Prst);      /* try a port reset */
1157                         print("%s: phy port reset\n", cname(c));
1158                 }
1159         }else
1160                 c->phyerrata = 0;
1161 }
1162
1163 static uint
1164 phyprobe(Ctlr *c, uint mask)
1165 {
1166         uint phy, phyno;
1167
1168         for(phyno=0; mask != 0; phyno++, mask>>=1){
1169                 if((mask & 1) == 0)
1170                         continue;
1171                 if(phyread(c, phyno, Physr) == ~0)
1172                         continue;
1173                 phy = (phyread(c, phyno, Phyid1) & 0x3FFF)<<6;
1174                 phy |= phyread(c, phyno, Phyid2) >> 10;
1175                 if(phy == 0xFFFFF || phy == 0)
1176                         continue;
1177                 print("%s: phy%d oui %#ux\n", cname(c), phyno, phy);
1178                 return phyno;
1179         }
1180         print("%s: no phy\n", cname(c));
1181         return ~0;
1182 }
1183
1184 static void
1185 lsleep(Ctlr *c, uint m)
1186 {
1187         c->lim = 0;
1188         i82563im(c, m);
1189         c->lsleep++;
1190         sleep(&c->lrendez, i82563lim, c);
1191 }
1192
1193 static void
1194 phyl79proc(void *v)
1195 {
1196         uint i, r, phy, phyno;
1197         Ctlr *c;
1198         Ether *e;
1199
1200         e = v;
1201         c = e->ctlr;
1202         while(waserror())
1203                 ;
1204
1205         while((phyno = phyprobe(c, 3<<1)) == ~0)
1206                 lsleep(c, Lsc);
1207
1208         for(;;){
1209                 phy = 0;
1210                 for(i=0; i<4; i++){
1211                         tsleep(&up->sleep, return0, 0, 150);
1212                         phy = phyread(c, phyno, Phystat);
1213                         if(phy == ~0)
1214                                 continue;
1215                         if(phy & Ans){
1216                                 r = phyread(c, phyno, Phyctl);
1217                                 if(r == ~0)
1218                                         continue;
1219                                 phywrite(c, phyno, Phyctl, r | Ran | Ean);
1220                         }
1221                         break;
1222                 }
1223                 i = (phy>>8) & 3;
1224                 e->link = i != 3 && (phy & Link) != 0;
1225                 if(e->link == 0)
1226                         i = 3;
1227                 c->speeds[i]++;
1228                 e->mbps = speedtab[i];
1229                 lsleep(c, Lsc);
1230         }
1231 }
1232
1233 static void
1234 phylproc(void *v)
1235 {
1236         uint a, i, phy, phyno;
1237         Ctlr *c;
1238         Ether *e;
1239
1240         e = v;
1241         c = e->ctlr;
1242         while(waserror())
1243                 ;
1244
1245         while((phyno = phyprobe(c, 3<<1)) == ~0)
1246                 lsleep(c, Lsc);
1247
1248         if(c->type == i82573 && (phy = phyread(c, phyno, Phyier)) != ~0)
1249                 phywrite(c, phyno, Phyier, phy | Lscie | Ancie | Spdie | Panie);
1250
1251         for(;;){
1252                 phy = phyread(c, phyno, Physsr);
1253                 if(phy == ~0){
1254                         phy = 0;
1255                         i = 3;
1256                         goto next;
1257                 }
1258                 i = (phy>>14) & 3;
1259                 switch(c->type){
1260                 default:
1261                         a = 0;
1262                         break;
1263                 case i82563:
1264                 case i82578:
1265                 case i82578m:
1266                 case i82583:
1267                         a = phyread(c, phyno, Phyisr) & Ane;
1268                         break;
1269                 case i82571:
1270                 case i82572:
1271                 case i82575:
1272                 case i82576:
1273                         a = phyread(c, phyno, Phylhr) & Anf;
1274                         i = (i-1) & 3;
1275                         break;
1276                 }
1277                 if(a)
1278                         phywrite(c, phyno, Phyctl, phyread(c, phyno, Phyctl) | Ran | Ean);
1279 next:
1280                 e->link = (phy & Rtlink) != 0;
1281                 if(e->link == 0)
1282                         i = 3;
1283                 c->speeds[i]++;
1284                 e->mbps = speedtab[i];
1285                 if(c->type == i82563)
1286                         phyerrata(e, c, phyno);
1287                 lsleep(c, Lsc);
1288         }
1289 }
1290
1291 static void
1292 pcslproc(void *v)
1293 {
1294         uint i, phy;
1295         Ctlr *c;
1296         Ether *e;
1297
1298         e = v;
1299         c = e->ctlr;
1300         while(waserror())
1301                 ;
1302
1303         if(c->type == i82575 || c->type == i82576)
1304                 csr32w(c, Connsw, Enrgirq);
1305         for(;;){
1306                 phy = csr32r(c, Pcsstat);
1307                 e->link = phy & Linkok;
1308                 i = 3;
1309                 if(e->link)
1310                         i = (phy & 6) >> 1;
1311                 else if(phy & Anbad)
1312                         csr32w(c, Pcsctl, csr32r(c, Pcsctl) | Pan | Prestart);
1313                 c->speeds[i]++;
1314                 e->mbps = speedtab[i];
1315                 lsleep(c, Lsc | Omed);
1316         }
1317 }
1318
1319 static void
1320 serdeslproc(void *v)
1321 {
1322         uint i, tx, rx;
1323         Ctlr *c;
1324         Ether *e;
1325
1326         e = v;
1327         c = e->ctlr;
1328         while(waserror())
1329                 ;
1330         for(;;){
1331                 rx = csr32r(c, Rxcw);
1332                 tx = csr32r(c, Txcw);
1333                 USED(tx);
1334                 e->link = (rx & 1<<31) != 0;
1335 //              e->link = (csr32r(c, Status) & Lu) != 0;
1336                 i = 3;
1337                 if(e->link)
1338                         i = 2;
1339                 c->speeds[i]++;
1340                 e->mbps = speedtab[i];
1341                 lsleep(c, Lsc);
1342         }
1343 }
1344
1345 static void
1346 i82563attach(Ether *edev)
1347 {
1348         char name[KNAMELEN];
1349         Ctlr *ctlr;
1350
1351         ctlr = edev->ctlr;
1352         qlock(&ctlr->alock);
1353         if(ctlr->alloc != nil){
1354                 qunlock(&ctlr->alock);
1355                 return;
1356         }
1357
1358         ctlr->nrd = Nrd;
1359         ctlr->ntd = Ntd;
1360         ctlr->alloc = malloc(ctlr->nrd*sizeof(Rd)+ctlr->ntd*sizeof(Td) + 255);
1361         ctlr->rb = malloc(ctlr->nrd * sizeof(Block*));
1362         ctlr->tb = malloc(ctlr->ntd * sizeof(Block*));
1363         if(ctlr->alloc == nil || ctlr->rb == nil || ctlr->tb == nil){
1364                 free(ctlr->rb);
1365                 ctlr->rb = nil;
1366                 free(ctlr->tb);
1367                 ctlr->tb = nil;
1368                 free(ctlr->alloc);
1369                 ctlr->alloc = nil;
1370                 qunlock(&ctlr->alock);
1371                 error(Enomem);
1372         }
1373         ctlr->rdba = (Rd*)ROUNDUP((uintptr)ctlr->alloc, 256);
1374         ctlr->tdba = (Td*)(ctlr->rdba + ctlr->nrd);
1375
1376         if(waserror()){
1377                 free(ctlr->tb);
1378                 ctlr->tb = nil;
1379                 free(ctlr->rb);
1380                 ctlr->rb = nil;
1381                 free(ctlr->alloc);
1382                 ctlr->alloc = nil;
1383                 qunlock(&ctlr->alock);
1384                 nexterror();
1385         }
1386
1387         snprint(name, sizeof name, "#l%dl", edev->ctlrno);
1388         if(csr32r(ctlr, Status) & Tbimode)
1389                 kproc(name, serdeslproc, edev);         /* mac based serdes */
1390         else if((csr32r(ctlr, Ctrlext) & Linkmode) == Serdes)
1391                 kproc(name, pcslproc, edev);            /* phy based serdes */
1392         else if(cttab[ctlr->type].flag & F79phy)
1393                 kproc(name, phyl79proc, edev);
1394         else
1395                 kproc(name, phylproc, edev);
1396
1397         snprint(name, sizeof name, "#l%dr", edev->ctlrno);
1398         kproc(name, i82563rproc, edev);
1399
1400         snprint(name, sizeof name, "#l%dt", edev->ctlrno);
1401         kproc(name, i82563tproc, edev);
1402
1403         qunlock(&ctlr->alock);
1404         poperror();
1405 }
1406
1407 static void
1408 i82563interrupt(Ureg*, void *arg)
1409 {
1410         Ctlr *ctlr;
1411         Ether *edev;
1412         int icr, im;
1413
1414         edev = arg;
1415         ctlr = edev->ctlr;
1416
1417         ilock(&ctlr->imlock);
1418         csr32w(ctlr, Imc, ~0);
1419         im = ctlr->im;
1420
1421         while(icr = csr32r(ctlr, Icr) & ctlr->im){
1422                 if(icr & (Lsc | Omed)){
1423                         im &= ~(Lsc | Omed);
1424                         ctlr->lim = icr & (Lsc | Omed);
1425                         wakeup(&ctlr->lrendez);
1426                         ctlr->lintr++;
1427                 }
1428                 if(icr & (Rxt0|Rxo|Rxdmt0|Rxseq|Ack)){
1429                         ctlr->rim = icr & (Rxt0|Rxo|Rxdmt0|Rxseq|Ack);
1430                         im &= ~(Rxt0|Rxo|Rxdmt0|Rxseq|Ack);
1431                         wakeup(&ctlr->rrendez);
1432                         ctlr->rintr++;
1433                 }
1434                 if(icr & Txdw){
1435                         im &= ~Txdw;
1436                         ctlr->tintr++;
1437                         wakeup(&ctlr->trendez);
1438                 }
1439         }
1440
1441         ctlr->im = im;
1442         csr32w(ctlr, Ims, im);
1443         iunlock(&ctlr->imlock);
1444 }
1445
1446 static int
1447 i82563detach(Ctlr *ctlr)
1448 {
1449         int r, timeo;
1450
1451         /* balance rx/tx packet buffer; survives reset */
1452         if(ctlr->rbsz > 8192 && cttab[ctlr->type].flag & Fpba){
1453                 ctlr->pba = csr32r(ctlr, Pba);
1454                 r = ctlr->pba >> 16;
1455                 r += ctlr->pba & 0xffff;
1456                 r >>= 1;
1457                 csr32w(ctlr, Pba, r);
1458         }else if(ctlr->type == i82573 && ctlr->rbsz > 1514)
1459                 csr32w(ctlr, Pba, 14);
1460         ctlr->pba = csr32r(ctlr, Pba);
1461
1462         /*
1463          * Perform a device reset to get the chip back to the
1464          * power-on state, followed by an EEPROM reset to read
1465          * the defaults for some internal registers.
1466          */
1467         csr32w(ctlr, Imc, ~0);
1468         csr32w(ctlr, Rctl, 0);
1469         csr32w(ctlr, Tctl, csr32r(ctlr, Tctl) & ~Ten);
1470
1471         delay(10);
1472
1473         r = csr32r(ctlr, Ctrl);
1474         if(ctlr->type == i82566 || ctlr->type == i82579)
1475                 r |= Phyrst;
1476         /*
1477          * hack: 82579LM on lenovo X230 is stuck at 10mbps after
1478          * reseting the phy, but works fine if we dont reset.
1479          */
1480         if(ctlr->pcidev->did == 0x1502)
1481                 r &= ~Phyrst;
1482         csr32w(ctlr, Ctrl, Devrst | r);
1483         delay(1);
1484         for(timeo = 0;; timeo++){
1485                 if((csr32r(ctlr, Ctrl) & (Devrst|Phyrst)) == 0)
1486                         break;
1487                 if(timeo >= 1000)
1488                         return -1;
1489                 delay(1);
1490         }
1491
1492         r = csr32r(ctlr, Ctrl);
1493         csr32w(ctlr, Ctrl, Slu|r);
1494
1495         r = csr32r(ctlr, Ctrlext);
1496         csr32w(ctlr, Ctrlext, r|Eerst);
1497         delay(1);
1498         for(timeo = 0; timeo < 1000; timeo++){
1499                 if(!(csr32r(ctlr, Ctrlext) & Eerst))
1500                         break;
1501                 delay(1);
1502         }
1503         if(csr32r(ctlr, Ctrlext) & Eerst)
1504                 return -1;
1505
1506         csr32w(ctlr, Imc, ~0);
1507         delay(1);
1508         for(timeo = 0; timeo < 1000; timeo++){
1509                 if((csr32r(ctlr, Icr) & ~Rxcfg) == 0)
1510                         break;
1511                 delay(1);
1512         }
1513         if(csr32r(ctlr, Icr) & ~Rxcfg)
1514                 return -1;
1515
1516         return 0;
1517 }
1518
1519 static void
1520 i82563shutdown(Ether *edev)
1521 {
1522         i82563detach(edev->ctlr);
1523 }
1524
1525 static int
1526 eeread(Ctlr *ctlr, int adr)
1527 {
1528         int timeout;
1529
1530         csr32w(ctlr, Eerd, EEstart | adr << 2);
1531         timeout = 1000;
1532         while ((csr32r(ctlr, Eerd) & EEdone) == 0 && timeout--)
1533                 microdelay(5);
1534         if (timeout < 0) {
1535                 print("%s: eeread timeout\n", cname(ctlr));
1536                 return -1;
1537         }
1538         return (csr32r(ctlr, Eerd) >> 16) & 0xffff;
1539 }
1540
1541 static int
1542 eeload(Ctlr *ctlr)
1543 {
1544         u16int sum;
1545         int data, adr;
1546
1547         sum = 0;
1548         for (adr = 0; adr < 0x40; adr++) {
1549                 data = eeread(ctlr, adr);
1550                 if(data == -1) return -1;
1551                 ctlr->eeprom[adr] = data;
1552                 sum += data;
1553         }
1554         return sum;
1555 }
1556
1557 static int
1558 fread16(Ctlr *c, Flash *f, int ladr)
1559 {
1560         u16int s;
1561         int timeout;
1562
1563         delay(1);
1564         s = f->reg[Fsts];
1565         if((s&Fvalid) == 0)
1566                 return -1;
1567         f->reg[Fsts] |= Fcerr | Ael;
1568         for(timeout = 0; timeout < 10; timeout++){
1569                 if((s&Scip) == 0)
1570                         goto done;
1571                 delay(1);
1572                 s = f->reg[Fsts];
1573         }
1574         return -1;
1575 done:
1576         f->reg[Fsts] |= Fdone;
1577         f->reg32[Faddr] = ladr;
1578
1579         /* setup flash control register */
1580         s = f->reg[Fctl] & ~0x3ff;
1581         f->reg[Fctl] = s | 1<<8 | Fgo;  /* 2 byte read */
1582         timeout = 1000;
1583         while((f->reg[Fsts] & Fdone) == 0 && timeout--)
1584                 microdelay(5);
1585         if(timeout < 0){
1586                 print("%s: fread timeout\n", cname(c));
1587                 return -1;
1588         }
1589         if(f->reg[Fsts] & (Fcerr|Ael))
1590                 return -1;
1591         return f->reg32[Fdata] & 0xffff;
1592 }
1593
1594 static int
1595 fread32(Ctlr *c, Flash *f, int ladr, u32int *data)
1596 {
1597         u32int s;
1598         int timeout;
1599
1600         delay(1);
1601         s = f->reg32[Fsts/2];
1602         if((s&Fvalid) == 0)
1603                 return -1;
1604         f->reg32[Fsts/2] |= Fcerr | Ael;
1605         for(timeout = 0; timeout < 10; timeout++){
1606                 if((s&Scip) == 0)
1607                         goto done;
1608                 delay(1);
1609                 s = f->reg32[Fsts/2];
1610         }
1611         return -1;
1612 done:
1613         f->reg32[Fsts/2] |= Fdone;
1614         f->reg32[Faddr] = ladr;
1615
1616         /* setup flash control register */
1617         s = (f->reg32[Fctl/2] >> 16) & ~0x3ff;
1618         f->reg32[Fctl/2] = (s | 3<<8 | Fgo) << 16;      /* 4 byte read */
1619         timeout = 1000;
1620         while((f->reg32[Fsts/2] & Fdone) == 0 && timeout--)
1621                 microdelay(5);
1622         if(timeout < 0){
1623                 print("%s: fread timeout\n", cname(c));
1624                 return -1;
1625         }
1626         if(f->reg32[Fsts/2] & (Fcerr|Ael))
1627                 return -1;
1628         *data = f->reg32[Fdata];
1629         return 0;
1630 }
1631
1632 static int
1633 fload32(Ctlr *c)
1634 {
1635         int r, adr;
1636         u16int sum;
1637         u32int w;
1638         Flash f;
1639
1640         f.reg32 = &c->nic[0xe000/4];
1641         f.reg = nil;
1642         f.base = 0;
1643         f.lim = (((csr32r(c, 0xC) >> 1) & 0x1F) + 1) << 12;
1644         r = f.lim >> 1;
1645         if(fread32(c, &f, r + 0x24, &w) == -1  || (w & 0xC000) != 0x8000)
1646                 r = 0;
1647         sum = 0;
1648         for(adr = 0; adr < 0x20; adr++) {
1649                 if(fread32(c, &f, r + adr*4, &w) == -1)
1650                         return -1;
1651                 c->eeprom[adr*2+0] = w;
1652                 c->eeprom[adr*2+1] = w>>16;
1653                 sum += w & 0xFFFF;
1654                 sum += w >> 16;
1655         }
1656         return sum;
1657 }
1658
1659 static int
1660 fload(Ctlr *c)
1661 {
1662         int data, r, adr;
1663         u16int sum;
1664         void *va;
1665         Flash f;
1666
1667         memset(c->eeprom, 0xFF, sizeof(c->eeprom));
1668         if(c->pcidev->mem[1].bar == 0)
1669                 return fload32(c);      /* i219 */
1670
1671         va = vmap(c->pcidev->mem[1].bar & ~0x0f, c->pcidev->mem[1].size);
1672         if(va == nil)
1673                 return -1;
1674         f.reg = va;
1675         f.reg32 = va;
1676         f.base = f.reg32[Bfpr] & 0x1fff;
1677         f.lim = f.reg32[Bfpr]>>16 & 0x1fff;
1678         if(csr32r(c, Eec) & Sec1val)
1679                 f.base += f.lim+1 - f.base >> 1;
1680         r = f.base << 12;
1681         sum = 0;
1682         for(adr = 0; adr < 0x40; adr++) {
1683                 data = fread16(c, &f, r + adr*2);
1684                 if(data == -1)
1685                         goto out;
1686                 c->eeprom[adr] = data;
1687                 sum += data;
1688         }
1689 out:
1690         vunmap(va, c->pcidev->mem[1].size);
1691         return sum;
1692 }
1693
1694 static int
1695 invmload(Ctlr *c)
1696 {
1697         int i, a;
1698         u32int w;
1699
1700         memset(c->eeprom, 0xFF, sizeof(c->eeprom));
1701         for(i=0; i<64; i++){
1702                 w = csr32r(c, Invmdata0 + i*4);
1703                 switch(w & 7){
1704                 case 0: // uninitialized structure
1705                         break;
1706                 case 1: // word auto load
1707                         a = (w & 0xFE00) >> 9;
1708                         if(a < nelem(c->eeprom))
1709                                 c->eeprom[a] = w >> 16;
1710                         continue;
1711                 case 2: // csr auto load
1712                         i++;
1713                 case 3: // phy auto load
1714                         continue;
1715                 case 4: // rsa key sha256
1716                         i += 256/32;
1717                 case 5: // invalidated structure
1718                         continue;
1719                 default:
1720                         print("invm: %.2x %.8ux\n", i, w);
1721                         continue;
1722                 }
1723                 break;
1724         }
1725         return 0;
1726 }
1727
1728 static void
1729 defaultea(Ctlr *ctlr, uchar *ra)
1730 {
1731         uint i, r;
1732         uvlong u;
1733         static uchar nilea[Eaddrlen];
1734
1735         if(memcmp(ra, nilea, Eaddrlen) != 0)
1736                 return;
1737         if(cttab[ctlr->type].flag & Fflashea){
1738                 /* intel mb bug */
1739                 u = (uvlong)csr32r(ctlr, Rah)<<32u | (ulong)csr32r(ctlr, Ral);
1740                 for(i = 0; i < Eaddrlen; i++)
1741                         ra[i] = u >> 8*i;
1742         }
1743         if(memcmp(ra, nilea, Eaddrlen) != 0)
1744                 return;
1745         for(i = 0; i < Eaddrlen/2; i++){
1746                 ra[2*i] = ctlr->eeprom[Ea+i];
1747                 ra[2*i+1] = ctlr->eeprom[Ea+i] >> 8;
1748         }
1749         r = (csr32r(ctlr, Status) & Lanid) >> 2;
1750         ra[5] += r;                             /* ea ctlr[n] = ea ctlr[0]+n */
1751 }
1752
1753 static int
1754 i82563reset(Ctlr *ctlr)
1755 {
1756         uchar *ra;
1757         int i, r, flag;
1758
1759         if(i82563detach(ctlr))
1760                 return -1;
1761         flag = cttab[ctlr->type].flag;
1762
1763         if(ctlr->type == i210 && (csr32r(ctlr, Eec) & Flupd) == 0)
1764                 r = invmload(ctlr);
1765         else if(flag & Fload)
1766                 r = fload(ctlr);
1767         else
1768                 r = eeload(ctlr);
1769
1770         if(r != 0 && r != 0xbaba){
1771                 print("%s: bad eeprom checksum - %#.4ux", cname(ctlr), r);
1772                 if(flag & Fbadcsum)
1773                         print("; ignored\n");
1774                 else {
1775                         print("\n");
1776                         return -1;
1777                 }
1778         }
1779
1780         ra = ctlr->ra;
1781         defaultea(ctlr, ra);
1782         csr32w(ctlr, Ral, ra[3]<<24 | ra[2]<<16 | ra[1]<<8 | ra[0]);
1783         csr32w(ctlr, Rah, 1<<31 | ra[5]<<8 | ra[4]);
1784         for(i = 1; i < 16; i++){
1785                 csr32w(ctlr, Ral+i*8, 0);
1786                 csr32w(ctlr, Rah+i*8, 0);
1787         }
1788         memset(ctlr->mta, 0, sizeof(ctlr->mta));
1789         for(i = 0; i < 128; i++)
1790                 csr32w(ctlr, Mta + i*4, 0);
1791         if((flag & Fnofca) == 0){
1792                 csr32w(ctlr, Fcal, 0x00C28001);
1793                 csr32w(ctlr, Fcah, 0x0100);
1794         }
1795         if((flag & Fnofct) == 0)
1796                 csr32w(ctlr, Fct, 0x8808);
1797         csr32w(ctlr, Fcttv, 0x0100);
1798         csr32w(ctlr, Fcrtl, ctlr->fcrtl);
1799         csr32w(ctlr, Fcrth, ctlr->fcrth);
1800         if(flag & F75)
1801                 csr32w(ctlr, Eitr, 128<<2);             /* 128 ¼ microsecond intervals */
1802         return 0;
1803 }
1804
1805 enum {
1806         CMrdtr,
1807         CMradv,
1808         CMpause,
1809         CMan,
1810 };
1811
1812 static Cmdtab i82563ctlmsg[] = {
1813         CMrdtr, "rdtr", 2,
1814         CMradv, "radv", 2,
1815         CMpause, "pause", 1,
1816         CMan,   "an",   1,
1817 };
1818
1819 static long
1820 i82563ctl(Ether *edev, void *buf, long n)
1821 {
1822         char *p;
1823         ulong v;
1824         Ctlr *ctlr;
1825         Cmdbuf *cb;
1826         Cmdtab *ct;
1827
1828         if((ctlr = edev->ctlr) == nil)
1829                 error(Enonexist);
1830
1831         cb = parsecmd(buf, n);
1832         if(waserror()){
1833                 free(cb);
1834                 nexterror();
1835         }
1836
1837         ct = lookupcmd(cb, i82563ctlmsg, nelem(i82563ctlmsg));
1838         switch(ct->index){
1839         case CMrdtr:
1840                 v = strtoul(cb->f[1], &p, 0);
1841                 if(*p || v > 0xffff)
1842                         error(Ebadarg);
1843                 ctlr->rdtr = v;
1844                 csr32w(ctlr, Rdtr, v);
1845                 break;
1846         case CMradv:
1847                 v = strtoul(cb->f[1], &p, 0);
1848                 if(*p || v > 0xffff)
1849                         error(Ebadarg);
1850                 ctlr->radv = v;
1851                 csr32w(ctlr, Radv, v);
1852                 break;
1853         case CMpause:
1854                 csr32w(ctlr, Ctrl, csr32r(ctlr, Ctrl) ^ (Rfce | Tfce));
1855                 break;
1856         case CMan:
1857                 csr32w(ctlr, Ctrl, csr32r(ctlr, Ctrl) | Lrst | Phyrst);
1858                 break;
1859         }
1860         free(cb);
1861         poperror();
1862
1863         return n;
1864 }
1865
1866 static int
1867 didtype(int d)
1868 {
1869         /*
1870          * Some names and did values are from
1871          * OpenBSD's em(4) Intel driver.
1872          */
1873         switch(d){
1874         case 0x1096:            /* copper */
1875         case 0x10ba:            /* copper “gilgal” */
1876         case 0x1098:            /* serdes; not seen */
1877         case 0x10bb:            /* serdes */
1878                 return i82563;
1879         case 0x1049:            /* ich8; mm */
1880         case 0x104a:            /* ich8; dm */
1881         case 0x104b:            /* ich8; dc */
1882         case 0x104d:            /* ich8; v “ninevah” */
1883         case 0x10bd:            /* ich9; dm-2 */
1884         case 0x294c:            /* ich9 */
1885         case 0x104c:            /* ich8; untested */
1886         case 0x10c4:            /* ich8; untested */
1887         case 0x10c5:            /* ich8; untested */
1888                 return i82566;
1889         case 0x10de:            /* lm ich10d */
1890         case 0x10df:            /* lf ich10 */
1891         case 0x10e5:            /* lm ich9 */
1892         case 0x10f5:            /* lm ich9m; “boazman” */
1893         case 0x10ce:            /* v ich10 */
1894         case 0x10c0:            /* ich9 */
1895         case 0x10c2:            /* ich9; untested */
1896         case 0x10c3:            /* ich9; untested */
1897         case 0x1501:            /* ich8; untested */
1898                 return i82567;
1899         case 0x10bf:            /* lf ich9m */
1900         case 0x10cb:            /* v ich9m */
1901         case 0x10cd:            /* lf ich10 */
1902         case 0x10cc:            /* lm ich10 */
1903                 return i82567m;
1904         case 0x105e:            /* eb copper */
1905         case 0x105f:            /* eb fiber */
1906         case 0x1060:            /* eb serdes */
1907         case 0x10a4:            /* eb copper */
1908         case 0x10a5:            /* eb fiber */
1909         case 0x10bc:            /* eb copper */
1910         case 0x10d9:            /* eb serdes */
1911         case 0x10da:            /* eb serdes “ophir” */
1912         case 0x10a0:            /* eb; untested */
1913         case 0x10a1:            /* eb; untested */
1914         case 0x10d5:            /* copper; untested */
1915                 return i82571;
1916         case 0x107d:            /* ei copper */
1917         case 0x107e:            /* ei fiber */
1918         case 0x107f:            /* ei serdes */
1919         case 0x10b9:            /* ei “rimon” */
1920                 return i82572;
1921         case 0x108b:            /* e “vidalia” */
1922         case 0x108c:            /* e (iamt) */
1923         case 0x109a:            /* l “tekoa” */
1924         case 0x10b0:            /* l; untested */
1925         case 0x10b2:            /* v; untested */
1926         case 0x10b3:            /* e; untested */
1927         case 0x10b4:            /* l; untested */
1928                 return i82573;
1929         case 0x10d3:            /* l or it; “hartwell” */
1930         case 0x10f6:            /* la; untested */
1931                 return i82574;
1932         case 0x10a7:            /* eb */
1933         case 0x10a9:            /* eb fiber/serdes */
1934         case 0x10d6:            /* untested */
1935         case 0x10e2:            /* untested */
1936                 return i82575;
1937         case 0x10c9:            /* copper */
1938         case 0x10e6:            /* fiber */
1939         case 0x10e7:            /* serdes; “kawela” */
1940         case 0x10e8:            /* copper; untested */
1941         case 0x150a:            /* untested */
1942         case 0x150d:            /* serdes backplane */
1943         case 0x1518:            /* serdes; untested */
1944         case 0x1526:            /* untested */
1945                 return i82576;
1946         case 0x10ea:            /* lc “calpella”; aka pch lan */
1947                 return i82577;
1948         case 0x10eb:            /* lm “calpella” */
1949                 return i82577m;
1950         case 0x10ef:            /* dc “piketon” */
1951                 return i82578;
1952         case 0x1502:            /* lm */
1953         case 0x1503:            /* v “lewisville” */
1954                 return i82579;
1955         case 0x10f0:            /* dm “king's creek” */
1956                 return i82578m;
1957         case 0x150e:            /* copper “barton hills” */
1958         case 0x150f:            /* fiber */
1959         case 0x1510:            /* serdes backplane */
1960         case 0x1511:            /* sgmii sfp */
1961         case 0x1516:            /* copper */
1962                 return i82580;
1963         case 0x1506:            /* v */
1964         case 0x150c:            /* untested */
1965                 return i82583;
1966         case 0x1533:            /* i210-t1 */
1967         case 0x1534:            /* i210 */
1968         case 0x1536:            /* i210-fiber */
1969         case 0x1537:            /* i210-backplane */
1970         case 0x1538:            /* i210 sgmii */
1971         case 0x1539:            /* i211 copper */
1972         case 0x157b:            /* i210 copper flashless */
1973         case 0x157c:            /* i210 serdes flashless */
1974                 return i210;
1975         case 0x153a:            /* i217-lm */
1976         case 0x153b:            /* i217-v */
1977                 return i217;
1978         case 0x1559:            /* i218-v */
1979         case 0x155a:            /* i218-lm */
1980         case 0x15a0:            /* i218-lm */
1981         case 0x15a1:            /* i218-v */
1982         case 0x15a2:            /* i218-lm */
1983         case 0x15a3:            /* i218-v */
1984                 return i218;
1985         case 0x156f:            /* i219-lm */
1986         case 0x15b7:            /* i219-lm */
1987         case 0x1570:            /* i219-v */
1988         case 0x15b8:            /* i219-v */
1989         case 0x15b9:            /* i219-lm */
1990         case 0x15d6:            /* i219-v */
1991         case 0x15d7:            /* i219-lm */
1992         case 0x15d8:            /* i219-v */
1993         case 0x15e3:            /* i219-lm */
1994                 return i219;
1995         case 0x151f:            /* i350 “powerville” eeprom-less */
1996         case 0x1521:            /* i350 copper */
1997         case 0x1522:            /* i350 fiber */
1998         case 0x1523:            /* i350 serdes */
1999         case 0x1524:            /* i350 sgmii */
2000         case 0x1546:            /* i350 DA4 (untested) */
2001         case 0x1f40:            /* i354 backplane */
2002         case 0x1f41:            /* i354 sgmii */
2003         case 0x1f42:            /* i354 sgmii (c2000) */
2004         case 0x1f45:            /* i354 backplane 2.5 */
2005                 return i350;
2006         }
2007         return -1;
2008 }
2009
2010 static void
2011 hbafixup(Pcidev *p)
2012 {
2013         uint i;
2014
2015         i = pcicfgr32(p, PciSVID);
2016         if((i & 0xffff) == 0x1b52 && p->did == 1)
2017                 p->did = i>>16;
2018 }
2019
2020 static void
2021 i82563pci(void)
2022 {
2023         int type;
2024         Ctlr *ctlr;
2025         Pcidev *p;
2026
2027         for(p = nil; p = pcimatch(p, 0x8086, 0);){
2028                 hbafixup(p);
2029                 if((type = didtype(p->did)) == -1)
2030                         continue;
2031                 ctlr = malloc(sizeof(Ctlr));
2032                 if(ctlr == nil){
2033                         print("%s: can't allocate memory\n", cttab[type].name);
2034                         continue;
2035                 }
2036                 ctlr->type = type;
2037                 ctlr->pcidev = p;
2038                 ctlr->rbsz = ROUND(cttab[type].mtu, 1024);
2039                 ctlr->port = p->mem[0].bar & ~0x0F;
2040                 if(i82563ctlrhead != nil)
2041                         i82563ctlrtail->next = ctlr;
2042                 else
2043                         i82563ctlrhead = ctlr;
2044                 i82563ctlrtail = ctlr;
2045         }
2046 }
2047
2048 static int
2049 setup(Ctlr *ctlr)
2050 {
2051         Pcidev *p;
2052
2053         p = ctlr->pcidev;
2054         ctlr->nic = vmap(ctlr->port, p->mem[0].size);
2055         if(ctlr->nic == nil){
2056                 print("%s: can't map 0x%lux\n", cname(ctlr), ctlr->port);
2057                 return -1;
2058         }
2059         pcienable(p);
2060         if(i82563reset(ctlr)){
2061                 pcidisable(p);
2062                 vunmap(ctlr->nic, p->mem[0].size);
2063                 return -1;
2064         }
2065         pcisetbme(p);
2066         return 0;
2067 }
2068
2069 static int
2070 pnp(Ether *edev, int type)
2071 {
2072         Ctlr *ctlr;
2073         static int done;
2074
2075         if(!done) {
2076                 i82563pci();
2077                 done = 1;
2078         }
2079
2080         /*
2081          * Any adapter matches if no edev->port is supplied,
2082          * otherwise the ports must match.
2083          */
2084         for(ctlr = i82563ctlrhead; ; ctlr = ctlr->next){
2085                 if(ctlr == nil)
2086                         return -1;
2087                 if(ctlr->active)
2088                         continue;
2089                 if(type != -1 && ctlr->type != type)
2090                         continue;
2091                 if(edev->port == 0 || edev->port == ctlr->port){
2092                         ctlr->active = 1;
2093                         memmove(ctlr->ra, edev->ea, Eaddrlen);
2094                         if(setup(ctlr) == 0)
2095                                 break;
2096                 }
2097         }
2098
2099         edev->ctlr = ctlr;
2100         edev->port = ctlr->port;
2101         edev->irq = ctlr->pcidev->intl;
2102         edev->tbdf = ctlr->pcidev->tbdf;
2103         edev->mbps = 1000;
2104         edev->maxmtu = cttab[ctlr->type].mtu;
2105         memmove(edev->ea, ctlr->ra, Eaddrlen);
2106
2107         /*
2108          * Linkage to the generic ethernet driver.
2109          */
2110         edev->attach = i82563attach;
2111 //      edev->transmit = i82563transmit;
2112         edev->ifstat = i82563ifstat;
2113         edev->ctl = i82563ctl;
2114
2115         edev->arg = edev;
2116         edev->promiscuous = i82563promiscuous;
2117         edev->shutdown = i82563shutdown;
2118         edev->multicast = i82563multicast;
2119
2120         intrenable(edev->irq, i82563interrupt, edev, edev->tbdf, edev->name);
2121
2122         return 0;
2123 }
2124
2125 static int
2126 anypnp(Ether *e)
2127 {
2128         return pnp(e, -1);
2129 }
2130
2131 static int
2132 i82563pnp(Ether *e)
2133 {
2134         return pnp(e, i82563);
2135 }
2136
2137 static int
2138 i82566pnp(Ether *e)
2139 {
2140         return pnp(e, i82566);
2141 }
2142
2143 static int
2144 i82567pnp(Ether *e)
2145 {
2146         return pnp(e, i82567m) & pnp(e, i82567);
2147 }
2148
2149 static int
2150 i82571pnp(Ether *e)
2151 {
2152         return pnp(e, i82571);
2153 }
2154
2155 static int
2156 i82572pnp(Ether *e)
2157 {
2158         return pnp(e, i82572);
2159 }
2160
2161 static int
2162 i82573pnp(Ether *e)
2163 {
2164         return pnp(e, i82573);
2165 }
2166
2167 static int
2168 i82574pnp(Ether *e)
2169 {
2170         return pnp(e, i82574);
2171 }
2172
2173 static int
2174 i82575pnp(Ether *e)
2175 {
2176         return pnp(e, i82575);
2177 }
2178
2179 static int
2180 i82576pnp(Ether *e)
2181 {
2182         return pnp(e, i82576);
2183 }
2184
2185 static int
2186 i82577pnp(Ether *e)
2187 {
2188         return pnp(e, i82577m) & pnp(e, i82577);
2189 }
2190
2191 static int
2192 i82578pnp(Ether *e)
2193 {
2194         return pnp(e, i82578m) & pnp(e, i82578);
2195 }
2196
2197 static int
2198 i82579pnp(Ether *e)
2199 {
2200         return pnp(e, i82579);
2201 }
2202
2203 static int
2204 i82580pnp(Ether *e)
2205 {
2206         return pnp(e, i82580);
2207 }
2208
2209 static int
2210 i82583pnp(Ether *e)
2211 {
2212         return pnp(e, i82583);
2213 }
2214
2215 static int
2216 i210pnp(Ether *e)
2217 {
2218         return pnp(e, i210);
2219 }
2220
2221 static int
2222 i217pnp(Ether *e)
2223 {
2224         return pnp(e, i217);
2225 }
2226
2227 static int
2228 i218pnp(Ether *e)
2229 {
2230         return pnp(e, i218);
2231 }
2232
2233 static int
2234 i219pnp(Ether *e)
2235 {
2236         return pnp(e, i219);
2237 }
2238
2239 static int
2240 i350pnp(Ether *e)
2241 {
2242         return pnp(e, i350);
2243 }
2244
2245 void
2246 ether82563link(void)
2247 {
2248         /*
2249          * recognise lots of model numbers for debugging
2250          * also good for forcing onboard nic(s) as ether0
2251          * try to make that unnecessary by listing lom first.
2252          */
2253         addethercard("i82563", i82563pnp);
2254         addethercard("i82566", i82566pnp);
2255         addethercard("i82574", i82574pnp);
2256         addethercard("i82576", i82576pnp);
2257         addethercard("i82567", i82567pnp);
2258         addethercard("i82573", i82573pnp);
2259
2260         addethercard("i82571", i82571pnp);
2261         addethercard("i82572", i82572pnp);
2262         addethercard("i82575", i82575pnp);
2263         addethercard("i82577", i82577pnp);
2264         addethercard("i82578", i82578pnp);
2265         addethercard("i82579", i82579pnp);
2266         addethercard("i82580", i82580pnp);
2267         addethercard("i82583", i82583pnp);
2268         addethercard("i210", i210pnp);
2269         addethercard("i217", i217pnp);
2270         addethercard("i218", i218pnp);
2271         addethercard("i219", i219pnp);
2272         addethercard("i350", i350pnp);
2273         addethercard("igbepcie", anypnp);
2274 }