]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/ether82563.c
merge
[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|Fbadcsum,          /* 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         int     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(cttab[ctlr->type].flag & F75){
946                         csr32w(ctlr, Rctl, Lpe|Dpf|Bsize2048|Bam|RdtmsHALF|Secrc);
947                         if(ctlr->type != i82575)
948                                 i |= (ctlr->nrd/2>>4)<<20;              /* RdmsHalf */
949                         csr32w(ctlr, Srrctl, i | Dropen);
950                         csr32w(ctlr, Rmpl, ctlr->rbsz);
951 //                      csr32w(ctlr, Drxmxod, 0x7ff);
952                 }else
953                         csr32w(ctlr, Rctl, Lpe|Dpf|BsizeFlex*i|Bam|RdtmsHALF|Secrc);
954         }
955
956         if(cttab[ctlr->type].flag & Fert)
957                 csr32w(ctlr, Ert, 1024/8);
958
959         if(ctlr->type == i82566)
960                 csr32w(ctlr, Pbs, 16);
961
962         csr32w(ctlr, Rdbal, PCIWADDR(ctlr->rdba));
963         csr32w(ctlr, Rdbah, 0);
964         csr32w(ctlr, Rdlen, ctlr->nrd * sizeof(Rd));
965         ctlr->rdh = 0;
966         csr32w(ctlr, Rdh, 0);
967         ctlr->rdt = 0;
968         csr32w(ctlr, Rdt, 0);
969         ctlr->rdtr = 25;
970         ctlr->radv = 500;
971         csr32w(ctlr, Rdtr, ctlr->rdtr);
972         csr32w(ctlr, Radv, ctlr->radv);
973
974         for(i = 0; i < ctlr->nrd; i++)
975                 if((bp = ctlr->rb[i]) != nil){
976                         ctlr->rb[i] = nil;
977                         freeb(bp);
978                 }
979         if(cttab[ctlr->type].flag & F75)
980                 csr32w(ctlr, Rxdctl, 1<<WthreshSHIFT | 8<<PthreshSHIFT | 1<<HthreshSHIFT | Enable);
981         else
982                 csr32w(ctlr, Rxdctl, 2<<WthreshSHIFT | 2<<PthreshSHIFT);
983
984         /*
985          * Enable checksum offload.
986          */
987         csr32w(ctlr, Rxcsum, Tuofl | Ipofl | ETHERHDRSIZE);
988 }
989
990 static int
991 i82563rim(void *v)
992 {
993         return ((Ctlr*)v)->rim != 0;
994 }
995
996 static void
997 i82563rproc(void *arg)
998 {
999         uint rdh, rim, im;
1000         Block *bp;
1001         Ctlr *ctlr;
1002         Ether *edev;
1003         Rd *rd;
1004
1005         edev = arg;
1006         ctlr = edev->ctlr;
1007
1008         i82563rxinit(ctlr);
1009         csr32w(ctlr, Rctl, csr32r(ctlr, Rctl) | Ren);
1010         if(cttab[ctlr->type].flag & F75){
1011                 csr32w(ctlr, Rxdctl, csr32r(ctlr, Rxdctl) | Enable);
1012                 im = Rxt0|Rxo|Rxdmt0|Rxseq|Ack;
1013         }else
1014                 im = Rxt0|Rxo|Rxdmt0|Rxseq|Ack;
1015
1016         while(waserror())
1017                 ;
1018         for(;;){
1019                 i82563im(ctlr, im);
1020                 ctlr->rsleep++;
1021                 i82563replenish(ctlr);
1022                 sleep(&ctlr->rrendez, i82563rim, ctlr);
1023
1024                 rdh = ctlr->rdh;
1025                 for(;;){
1026                         rim = ctlr->rim;
1027                         ctlr->rim = 0;
1028                         rd = &ctlr->rdba[rdh];
1029                         if(!(rd->status & Rdd))
1030                                 break;
1031
1032                         /*
1033                          * Accept eop packets with no errors.
1034                          * With no errors and the Ixsm bit set,
1035                          * the descriptor status Tpcs and Ipcs bits give
1036                          * an indication of whether the checksums were
1037                          * calculated and valid.
1038                          */
1039                         bp = ctlr->rb[rdh];
1040                         if((rd->status & Reop) && rd->errors == 0){
1041                                 bp->wp += rd->length;
1042                                 if(!(rd->status & Ixsm)){
1043                                         ctlr->ixsm++;
1044                                         if(rd->status & Ipcs){
1045                                                 /*
1046                                                  * IP checksum calculated
1047                                                  * (and valid as errors == 0).
1048                                                  */
1049                                                 ctlr->ipcs++;
1050                                                 bp->flag |= Bipck;
1051                                         }
1052                                         if(rd->status & Tcpcs){
1053                                                 /*
1054                                                  * TCP/UDP checksum calculated
1055                                                  * (and valid as errors == 0).
1056                                                  */
1057                                                 ctlr->tcpcs++;
1058                                                 bp->flag |= Btcpck|Budpck;
1059                                         }
1060                                         bp->checksum = rd->checksum;
1061                                         bp->flag |= Bpktck;
1062                                 }
1063                                 etheriq(edev, bp);
1064                         } else
1065                                 freeb(bp);
1066                         ctlr->rb[rdh] = nil;
1067                         ctlr->rdfree--;
1068                         ctlr->rdh = rdh = NEXT(rdh, ctlr->nrd);
1069                         if(ctlr->nrd-ctlr->rdfree >= 32 || (rim & Rxdmt0))
1070                                 i82563replenish(ctlr);
1071                 }
1072         }
1073 }
1074
1075 static int
1076 i82563lim(void *v)
1077 {
1078         return ((Ctlr*)v)->lim != 0;
1079 }
1080
1081 static int speedtab[] = {
1082         10, 100, 1000, 0
1083 };
1084
1085 static uint
1086 phyread(Ctlr *c, int phyno, int reg)
1087 {
1088         uint phy, i;
1089
1090         csr32w(c, Mdic, MDIrop | phyno<<MDIpSHIFT | reg<<MDIrSHIFT);
1091         phy = 0;
1092         for(i = 0; i < 64; i++){
1093                 phy = csr32r(c, Mdic);
1094                 if(phy & (MDIe|MDIready))
1095                         break;
1096                 microdelay(1);
1097         }
1098         if((phy & (MDIe|MDIready)) != MDIready){
1099                 print("%s: phy %d wedged %.8ux\n", cname(c), phyno, phy);
1100                 return ~0;
1101         }
1102         return phy & 0xffff;
1103 }
1104
1105 static uint
1106 phywrite0(Ctlr *c, int phyno, int reg, ushort val)
1107 {
1108         uint phy, i;
1109
1110         csr32w(c, Mdic, MDIwop | phyno<<MDIpSHIFT | reg<<MDIrSHIFT | val);
1111         phy = 0;
1112         for(i = 0; i < 64; i++){
1113                 phy = csr32r(c, Mdic);
1114                 if(phy & (MDIe|MDIready))
1115                         break;
1116                 microdelay(1);
1117         }
1118         if((phy & (MDIe|MDIready)) != MDIready)
1119                 return ~0;
1120         return 0;
1121 }
1122
1123 static uint
1124 setpage(Ctlr *c, uint phyno, uint p, uint r)
1125 {
1126         uint pr;
1127
1128         if(c->type == i82563){
1129                 if(r >= 16 && r <= 28 && r != 22)
1130                         pr = Phypage;
1131                 else if(r == 30 || r == 31)
1132                         pr = Phyapage;
1133                 else
1134                         return 0;
1135                 return phywrite0(c, phyno, pr, p);
1136         }else if(p == 0)
1137                 return 0;
1138         return ~0;
1139 }
1140
1141 static uint
1142 phywrite(Ctlr *c, uint phyno, uint reg, ushort v)
1143 {
1144         if(setpage(c, phyno, reg>>8, reg & 0xff) == ~0)
1145                 panic("%s: bad phy reg %.4ux", cname(c), reg);
1146         return phywrite0(c, phyno, reg & 0xff, v);
1147 }
1148
1149 static void
1150 phyerrata(Ether *e, Ctlr *c, uint phyno)
1151 {
1152         if(e->mbps == 0){
1153                 if(c->phyerrata == 0){
1154                         c->phyerrata++;
1155                         phywrite(c, phyno, Phyprst, Prst);      /* try a port reset */
1156                         print("%s: phy port reset\n", cname(c));
1157                 }
1158         }else
1159                 c->phyerrata = 0;
1160 }
1161
1162 static uint
1163 phyprobe(Ctlr *c, uint mask)
1164 {
1165         uint phy, phyno;
1166
1167         for(phyno=0; mask != 0; phyno++, mask>>=1){
1168                 if((mask & 1) == 0)
1169                         continue;
1170                 if(phyread(c, phyno, Physr) == ~0)
1171                         continue;
1172                 phy = (phyread(c, phyno, Phyid1) & 0x3FFF)<<6;
1173                 phy |= phyread(c, phyno, Phyid2) >> 10;
1174                 if(phy == 0xFFFFF || phy == 0)
1175                         continue;
1176                 print("%s: phy%d oui %#ux\n", cname(c), phyno, phy);
1177                 return phyno;
1178         }
1179         print("%s: no phy\n", cname(c));
1180         return ~0;
1181 }
1182
1183 static void
1184 lsleep(Ctlr *c, uint m)
1185 {
1186         c->lim = 0;
1187         i82563im(c, m);
1188         c->lsleep++;
1189         sleep(&c->lrendez, i82563lim, c);
1190 }
1191
1192 static void
1193 phyl79proc(void *v)
1194 {
1195         uint a, i, r, phy, phyno;
1196         Ctlr *c;
1197         Ether *e;
1198
1199         e = v;
1200         c = e->ctlr;
1201         while(waserror())
1202                 ;
1203
1204         while((phyno = phyprobe(c, 3<<1)) == ~0)
1205                 lsleep(c, Lsc);
1206
1207         for(;;){
1208                 phy = phyread(c, phyno, Phystat);
1209                 if(phy == ~0){
1210                         phy = 0;
1211                         i = 3;
1212                         goto next;
1213                 }
1214                 i = (phy>>8) & 3;
1215                 a = phy & Ans;
1216                 if(a){
1217                         r = phyread(c, phyno, Phyctl);
1218                         phywrite(c, phyno, Phyctl, r | Ran | Ean);
1219                 }
1220 next:
1221                 e->link = i != 3 && (phy & Link) != 0;
1222                 if(e->link == 0)
1223                         i = 3;
1224                 c->speeds[i]++;
1225                 e->mbps = speedtab[i];
1226                 lsleep(c, Lsc);
1227         }
1228 }
1229
1230 static void
1231 phylproc(void *v)
1232 {
1233         uint a, i, phy, phyno;
1234         Ctlr *c;
1235         Ether *e;
1236
1237         e = v;
1238         c = e->ctlr;
1239         while(waserror())
1240                 ;
1241
1242         while((phyno = phyprobe(c, 3<<1)) == ~0)
1243                 lsleep(c, Lsc);
1244
1245         if(c->type == i82573 && (phy = phyread(c, phyno, Phyier)) != ~0)
1246                 phywrite(c, phyno, Phyier, phy | Lscie | Ancie | Spdie | Panie);
1247
1248         for(;;){
1249                 phy = phyread(c, phyno, Physsr);
1250                 if(phy == ~0){
1251                         phy = 0;
1252                         i = 3;
1253                         goto next;
1254                 }
1255                 i = (phy>>14) & 3;
1256                 switch(c->type){
1257                 default:
1258                         a = 0;
1259                         break;
1260                 case i82563:
1261                 case i82578:
1262                 case i82578m:
1263                 case i82583:
1264                         a = phyread(c, phyno, Phyisr) & Ane;
1265                         break;
1266                 case i82571:
1267                 case i82572:
1268                 case i82575:
1269                 case i82576:
1270                         a = phyread(c, phyno, Phylhr) & Anf;
1271                         i = (i-1) & 3;
1272                         break;
1273                 }
1274                 if(a)
1275                         phywrite(c, phyno, Phyctl, phyread(c, phyno, Phyctl) | Ran | Ean);
1276 next:
1277                 e->link = (phy & Rtlink) != 0;
1278                 if(e->link == 0)
1279                         i = 3;
1280                 c->speeds[i]++;
1281                 e->mbps = speedtab[i];
1282                 if(c->type == i82563)
1283                         phyerrata(e, c, phyno);
1284                 lsleep(c, Lsc);
1285         }
1286 }
1287
1288 static void
1289 pcslproc(void *v)
1290 {
1291         uint i, phy;
1292         Ctlr *c;
1293         Ether *e;
1294
1295         e = v;
1296         c = e->ctlr;
1297         while(waserror())
1298                 ;
1299
1300         if(c->type == i82575 || c->type == i82576)
1301                 csr32w(c, Connsw, Enrgirq);
1302         for(;;){
1303                 phy = csr32r(c, Pcsstat);
1304                 e->link = phy & Linkok;
1305                 i = 3;
1306                 if(e->link)
1307                         i = (phy & 6) >> 1;
1308                 else if(phy & Anbad)
1309                         csr32w(c, Pcsctl, csr32r(c, Pcsctl) | Pan | Prestart);
1310                 c->speeds[i]++;
1311                 e->mbps = speedtab[i];
1312                 lsleep(c, Lsc | Omed);
1313         }
1314 }
1315
1316 static void
1317 serdeslproc(void *v)
1318 {
1319         uint i, tx, rx;
1320         Ctlr *c;
1321         Ether *e;
1322
1323         e = v;
1324         c = e->ctlr;
1325         while(waserror())
1326                 ;
1327         for(;;){
1328                 rx = csr32r(c, Rxcw);
1329                 tx = csr32r(c, Txcw);
1330                 USED(tx);
1331                 e->link = (rx & 1<<31) != 0;
1332 //              e->link = (csr32r(c, Status) & Lu) != 0;
1333                 i = 3;
1334                 if(e->link)
1335                         i = 2;
1336                 c->speeds[i]++;
1337                 e->mbps = speedtab[i];
1338                 lsleep(c, Lsc);
1339         }
1340 }
1341
1342 static void
1343 i82563attach(Ether *edev)
1344 {
1345         char name[KNAMELEN];
1346         Ctlr *ctlr;
1347
1348         ctlr = edev->ctlr;
1349         qlock(&ctlr->alock);
1350         if(ctlr->alloc != nil){
1351                 qunlock(&ctlr->alock);
1352                 return;
1353         }
1354
1355         ctlr->nrd = Nrd;
1356         ctlr->ntd = Ntd;
1357         ctlr->alloc = malloc(ctlr->nrd*sizeof(Rd)+ctlr->ntd*sizeof(Td) + 255);
1358         ctlr->rb = malloc(ctlr->nrd * sizeof(Block*));
1359         ctlr->tb = malloc(ctlr->ntd * sizeof(Block*));
1360         if(ctlr->alloc == nil || ctlr->rb == nil || ctlr->tb == nil){
1361                 free(ctlr->rb);
1362                 ctlr->rb = nil;
1363                 free(ctlr->tb);
1364                 ctlr->tb = nil;
1365                 free(ctlr->alloc);
1366                 ctlr->alloc = nil;
1367                 qunlock(&ctlr->alock);
1368                 error(Enomem);
1369         }
1370         ctlr->rdba = (Rd*)ROUNDUP((uintptr)ctlr->alloc, 256);
1371         ctlr->tdba = (Td*)(ctlr->rdba + ctlr->nrd);
1372
1373         if(waserror()){
1374                 free(ctlr->tb);
1375                 ctlr->tb = nil;
1376                 free(ctlr->rb);
1377                 ctlr->rb = nil;
1378                 free(ctlr->alloc);
1379                 ctlr->alloc = nil;
1380                 qunlock(&ctlr->alock);
1381                 nexterror();
1382         }
1383
1384         snprint(name, sizeof name, "#l%dl", edev->ctlrno);
1385         if(csr32r(ctlr, Status) & Tbimode)
1386                 kproc(name, serdeslproc, edev);         /* mac based serdes */
1387         else if((csr32r(ctlr, Ctrlext) & Linkmode) == Serdes)
1388                 kproc(name, pcslproc, edev);            /* phy based serdes */
1389         else if(cttab[ctlr->type].flag & F79phy)
1390                 kproc(name, phyl79proc, edev);
1391         else
1392                 kproc(name, phylproc, edev);
1393
1394         snprint(name, sizeof name, "#l%dr", edev->ctlrno);
1395         kproc(name, i82563rproc, edev);
1396
1397         snprint(name, sizeof name, "#l%dt", edev->ctlrno);
1398         kproc(name, i82563tproc, edev);
1399
1400         qunlock(&ctlr->alock);
1401         poperror();
1402 }
1403
1404 static void
1405 i82563interrupt(Ureg*, void *arg)
1406 {
1407         Ctlr *ctlr;
1408         Ether *edev;
1409         int icr, im;
1410
1411         edev = arg;
1412         ctlr = edev->ctlr;
1413
1414         ilock(&ctlr->imlock);
1415         csr32w(ctlr, Imc, ~0);
1416         im = ctlr->im;
1417
1418         while(icr = csr32r(ctlr, Icr) & ctlr->im){
1419                 if(icr & (Lsc | Omed)){
1420                         im &= ~(Lsc | Omed);
1421                         ctlr->lim = icr & (Lsc | Omed);
1422                         wakeup(&ctlr->lrendez);
1423                         ctlr->lintr++;
1424                 }
1425                 if(icr & (Rxt0|Rxo|Rxdmt0|Rxseq|Ack)){
1426                         ctlr->rim = icr & (Rxt0|Rxo|Rxdmt0|Rxseq|Ack);
1427                         im &= ~(Rxt0|Rxo|Rxdmt0|Rxseq|Ack);
1428                         wakeup(&ctlr->rrendez);
1429                         ctlr->rintr++;
1430                 }
1431                 if(icr & Txdw){
1432                         im &= ~Txdw;
1433                         ctlr->tintr++;
1434                         wakeup(&ctlr->trendez);
1435                 }
1436         }
1437
1438         ctlr->im = im;
1439         csr32w(ctlr, Ims, im);
1440         iunlock(&ctlr->imlock);
1441 }
1442
1443 static int
1444 i82563detach(Ctlr *ctlr)
1445 {
1446         int r, timeo;
1447
1448         /* balance rx/tx packet buffer; survives reset */
1449         if(ctlr->rbsz > 8192 && cttab[ctlr->type].flag & Fpba){
1450                 ctlr->pba = csr32r(ctlr, Pba);
1451                 r = ctlr->pba >> 16;
1452                 r += ctlr->pba & 0xffff;
1453                 r >>= 1;
1454                 csr32w(ctlr, Pba, r);
1455         }else if(ctlr->type == i82573 && ctlr->rbsz > 1514)
1456                 csr32w(ctlr, Pba, 14);
1457         ctlr->pba = csr32r(ctlr, Pba);
1458
1459         /*
1460          * Perform a device reset to get the chip back to the
1461          * power-on state, followed by an EEPROM reset to read
1462          * the defaults for some internal registers.
1463          */
1464         csr32w(ctlr, Imc, ~0);
1465         csr32w(ctlr, Rctl, 0);
1466         csr32w(ctlr, Tctl, csr32r(ctlr, Tctl) & ~Ten);
1467
1468         delay(10);
1469
1470         r = csr32r(ctlr, Ctrl);
1471         if(ctlr->type == i82566 || ctlr->type == i82579)
1472                 r |= Phyrst;
1473         /*
1474          * hack: 82579LM on lenovo X230 is stuck at 10mbps after
1475          * reseting the phy, but works fine if we dont reset.
1476          */
1477         if(ctlr->pcidev->did == 0x1502)
1478                 r &= ~Phyrst;
1479         csr32w(ctlr, Ctrl, Devrst | r);
1480         delay(1);
1481         for(timeo = 0;; timeo++){
1482                 if((csr32r(ctlr, Ctrl) & (Devrst|Phyrst)) == 0)
1483                         break;
1484                 if(timeo >= 1000)
1485                         return -1;
1486                 delay(1);
1487         }
1488
1489         r = csr32r(ctlr, Ctrl);
1490         csr32w(ctlr, Ctrl, Slu|r);
1491
1492         r = csr32r(ctlr, Ctrlext);
1493         csr32w(ctlr, Ctrlext, r|Eerst);
1494         delay(1);
1495         for(timeo = 0; timeo < 1000; timeo++){
1496                 if(!(csr32r(ctlr, Ctrlext) & Eerst))
1497                         break;
1498                 delay(1);
1499         }
1500         if(csr32r(ctlr, Ctrlext) & Eerst)
1501                 return -1;
1502
1503         csr32w(ctlr, Imc, ~0);
1504         delay(1);
1505         for(timeo = 0; timeo < 1000; timeo++){
1506                 if((csr32r(ctlr, Icr) & ~Rxcfg) == 0)
1507                         break;
1508                 delay(1);
1509         }
1510         if(csr32r(ctlr, Icr) & ~Rxcfg)
1511                 return -1;
1512
1513         return 0;
1514 }
1515
1516 static void
1517 i82563shutdown(Ether *edev)
1518 {
1519         i82563detach(edev->ctlr);
1520 }
1521
1522 static int
1523 eeread(Ctlr *ctlr, int adr)
1524 {
1525         int timeout;
1526
1527         csr32w(ctlr, Eerd, EEstart | adr << 2);
1528         timeout = 1000;
1529         while ((csr32r(ctlr, Eerd) & EEdone) == 0 && timeout--)
1530                 microdelay(5);
1531         if (timeout < 0) {
1532                 print("%s: eeread timeout\n", cname(ctlr));
1533                 return -1;
1534         }
1535         return (csr32r(ctlr, Eerd) >> 16) & 0xffff;
1536 }
1537
1538 static int
1539 eeload(Ctlr *ctlr)
1540 {
1541         u16int sum;
1542         int data, adr;
1543
1544         sum = 0;
1545         for (adr = 0; adr < 0x40; adr++) {
1546                 data = eeread(ctlr, adr);
1547                 if(data == -1) return -1;
1548                 ctlr->eeprom[adr] = data;
1549                 sum += data;
1550         }
1551         return sum;
1552 }
1553
1554 static int
1555 fread16(Ctlr *c, Flash *f, int ladr)
1556 {
1557         u16int s;
1558         int timeout;
1559
1560         delay(1);
1561         s = f->reg[Fsts];
1562         if((s&Fvalid) == 0)
1563                 return -1;
1564         f->reg[Fsts] |= Fcerr | Ael;
1565         for(timeout = 0; timeout < 10; timeout++){
1566                 if((s&Scip) == 0)
1567                         goto done;
1568                 delay(1);
1569                 s = f->reg[Fsts];
1570         }
1571         return -1;
1572 done:
1573         f->reg[Fsts] |= Fdone;
1574         f->reg32[Faddr] = ladr;
1575
1576         /* setup flash control register */
1577         s = f->reg[Fctl] & ~0x3ff;
1578         f->reg[Fctl] = s | 1<<8 | Fgo;  /* 2 byte read */
1579         timeout = 1000;
1580         while((f->reg[Fsts] & Fdone) == 0 && timeout--)
1581                 microdelay(5);
1582         if(timeout < 0){
1583                 print("%s: fread timeout\n", cname(c));
1584                 return -1;
1585         }
1586         if(f->reg[Fsts] & (Fcerr|Ael))
1587                 return -1;
1588         return f->reg32[Fdata] & 0xffff;
1589 }
1590
1591 static int
1592 fread32(Ctlr *c, Flash *f, int ladr, u32int *data)
1593 {
1594         u32int s;
1595         int timeout;
1596
1597         delay(1);
1598         s = f->reg32[Fsts/2];
1599         if((s&Fvalid) == 0)
1600                 return -1;
1601         f->reg32[Fsts/2] |= Fcerr | Ael;
1602         for(timeout = 0; timeout < 10; timeout++){
1603                 if((s&Scip) == 0)
1604                         goto done;
1605                 delay(1);
1606                 s = f->reg32[Fsts/2];
1607         }
1608         return -1;
1609 done:
1610         f->reg32[Fsts/2] |= Fdone;
1611         f->reg32[Faddr] = ladr;
1612
1613         /* setup flash control register */
1614         s = (f->reg32[Fctl/2] >> 16) & ~0x3ff;
1615         f->reg32[Fctl/2] = (s | 3<<8 | Fgo) << 16;      /* 4 byte read */
1616         timeout = 1000;
1617         while((f->reg32[Fsts/2] & Fdone) == 0 && timeout--)
1618                 microdelay(5);
1619         if(timeout < 0){
1620                 print("%s: fread timeout\n", cname(c));
1621                 return -1;
1622         }
1623         if(f->reg32[Fsts/2] & (Fcerr|Ael))
1624                 return -1;
1625         *data = f->reg32[Fdata];
1626         return 0;
1627 }
1628
1629 static int
1630 fload32(Ctlr *c)
1631 {
1632         int r, adr;
1633         u16int sum;
1634         u32int w;
1635         Flash f;
1636
1637         f.reg32 = &c->nic[0xe000/4];
1638         f.reg = nil;
1639         f.base = 0;
1640         f.lim = (((csr32r(c, 0xC) >> 1) & 0x1F) + 1) << 12;
1641         r = f.lim >> 1;
1642         if(fread32(c, &f, r + 0x24, &w) == -1  || (w & 0xC000) != 0x8000)
1643                 r = 0;
1644         sum = 0;
1645         for(adr = 0; adr < 0x20; adr++) {
1646                 if(fread32(c, &f, r + adr*4, &w) == -1)
1647                         return -1;
1648                 c->eeprom[adr*2+0] = w;
1649                 c->eeprom[adr*2+1] = w>>16;
1650                 sum += w & 0xFFFF;
1651                 sum += w >> 16;
1652         }
1653         return sum;
1654 }
1655
1656 static int
1657 fload(Ctlr *c)
1658 {
1659         int data, r, adr;
1660         u16int sum;
1661         void *va;
1662         Flash f;
1663
1664         memset(c->eeprom, 0xFF, sizeof(c->eeprom));
1665         if(c->pcidev->mem[1].bar == 0)
1666                 return fload32(c);      /* i219 */
1667
1668         va = vmap(c->pcidev->mem[1].bar & ~0x0f, c->pcidev->mem[1].size);
1669         if(va == nil)
1670                 return -1;
1671         f.reg = va;
1672         f.reg32 = va;
1673         f.base = f.reg32[Bfpr] & 0x1fff;
1674         f.lim = f.reg32[Bfpr]>>16 & 0x1fff;
1675         if(csr32r(c, Eec) & Sec1val)
1676                 f.base += f.lim+1 - f.base >> 1;
1677         r = f.base << 12;
1678         sum = 0;
1679         for(adr = 0; adr < 0x40; adr++) {
1680                 data = fread16(c, &f, r + adr*2);
1681                 if(data == -1)
1682                         goto out;
1683                 c->eeprom[adr] = data;
1684                 sum += data;
1685         }
1686 out:
1687         vunmap(va, c->pcidev->mem[1].size);
1688         return sum;
1689 }
1690
1691 static int
1692 invmload(Ctlr *c)
1693 {
1694         int i, a;
1695         u32int w;
1696
1697         memset(c->eeprom, 0xFF, sizeof(c->eeprom));
1698         for(i=0; i<64; i++){
1699                 w = csr32r(c, Invmdata0 + i*4);
1700                 switch(w & 7){
1701                 case 0: // uninitialized structure
1702                         break;
1703                 case 1: // word auto load
1704                         a = (w & 0xFE00) >> 9;
1705                         if(a < nelem(c->eeprom))
1706                                 c->eeprom[a] = w >> 16;
1707                         continue;
1708                 case 2: // csr auto load
1709                         i++;
1710                 case 3: // phy auto load
1711                         continue;
1712                 case 4: // rsa key sha256
1713                         i += 256/32;
1714                 case 5: // invalidated structure
1715                         continue;
1716                 default:
1717                         print("invm: %.2x %.8ux\n", i, w);
1718                         continue;
1719                 }
1720                 break;
1721         }
1722         return 0;
1723 }
1724
1725 static void
1726 defaultea(Ctlr *ctlr, uchar *ra)
1727 {
1728         uint i, r;
1729         uvlong u;
1730         static uchar nilea[Eaddrlen];
1731
1732         if(memcmp(ra, nilea, Eaddrlen) != 0)
1733                 return;
1734         if(cttab[ctlr->type].flag & Fflashea){
1735                 /* intel mb bug */
1736                 u = (uvlong)csr32r(ctlr, Rah)<<32u | (ulong)csr32r(ctlr, Ral);
1737                 for(i = 0; i < Eaddrlen; i++)
1738                         ra[i] = u >> 8*i;
1739         }
1740         if(memcmp(ra, nilea, Eaddrlen) != 0)
1741                 return;
1742         for(i = 0; i < Eaddrlen/2; i++){
1743                 ra[2*i] = ctlr->eeprom[Ea+i];
1744                 ra[2*i+1] = ctlr->eeprom[Ea+i] >> 8;
1745         }
1746         r = (csr32r(ctlr, Status) & Lanid) >> 2;
1747         ra[5] += r;                             /* ea ctlr[n] = ea ctlr[0]+n */
1748 }
1749
1750 static int
1751 i82563reset(Ctlr *ctlr)
1752 {
1753         uchar *ra;
1754         int i, r, flag;
1755
1756         if(i82563detach(ctlr))
1757                 return -1;
1758         flag = cttab[ctlr->type].flag;
1759
1760         if(ctlr->type == i210 && (csr32r(ctlr, Eec) & Flupd) == 0)
1761                 r = invmload(ctlr);
1762         else if(flag & Fload)
1763                 r = fload(ctlr);
1764         else
1765                 r = eeload(ctlr);
1766
1767         if(r != 0 && r != 0xbaba){
1768                 print("%s: bad eeprom checksum - %#.4ux", cname(ctlr), r);
1769                 if(flag & Fbadcsum)
1770                         print("; ignored\n");
1771                 else {
1772                         print("\n");
1773                         return -1;
1774                 }
1775         }
1776
1777         ra = ctlr->ra;
1778         defaultea(ctlr, ra);
1779         csr32w(ctlr, Ral, ra[3]<<24 | ra[2]<<16 | ra[1]<<8 | ra[0]);
1780         csr32w(ctlr, Rah, 1<<31 | ra[5]<<8 | ra[4]);
1781         for(i = 1; i < 16; i++){
1782                 csr32w(ctlr, Ral+i*8, 0);
1783                 csr32w(ctlr, Rah+i*8, 0);
1784         }
1785         memset(ctlr->mta, 0, sizeof(ctlr->mta));
1786         for(i = 0; i < 128; i++)
1787                 csr32w(ctlr, Mta + i*4, 0);
1788         csr32w(ctlr, Fcal, 0x00C28001);
1789         csr32w(ctlr, Fcah, 0x0100);
1790         if((flag & Fnofct) == 0)
1791                 csr32w(ctlr, Fct, 0x8808);
1792         csr32w(ctlr, Fcttv, 0x0100);
1793         csr32w(ctlr, Fcrtl, ctlr->fcrtl);
1794         csr32w(ctlr, Fcrth, ctlr->fcrth);
1795         if(flag & F75)
1796                 csr32w(ctlr, Eitr, 128<<2);             /* 128 ¼ microsecond intervals */
1797         return 0;
1798 }
1799
1800 enum {
1801         CMrdtr,
1802         CMradv,
1803         CMpause,
1804         CMan,
1805 };
1806
1807 static Cmdtab i82563ctlmsg[] = {
1808         CMrdtr, "rdtr", 2,
1809         CMradv, "radv", 2,
1810         CMpause, "pause", 1,
1811         CMan,   "an",   1,
1812 };
1813
1814 static long
1815 i82563ctl(Ether *edev, void *buf, long n)
1816 {
1817         char *p;
1818         ulong v;
1819         Ctlr *ctlr;
1820         Cmdbuf *cb;
1821         Cmdtab *ct;
1822
1823         if((ctlr = edev->ctlr) == nil)
1824                 error(Enonexist);
1825
1826         cb = parsecmd(buf, n);
1827         if(waserror()){
1828                 free(cb);
1829                 nexterror();
1830         }
1831
1832         ct = lookupcmd(cb, i82563ctlmsg, nelem(i82563ctlmsg));
1833         switch(ct->index){
1834         case CMrdtr:
1835                 v = strtoul(cb->f[1], &p, 0);
1836                 if(*p || v > 0xffff)
1837                         error(Ebadarg);
1838                 ctlr->rdtr = v;
1839                 csr32w(ctlr, Rdtr, v);
1840                 break;
1841         case CMradv:
1842                 v = strtoul(cb->f[1], &p, 0);
1843                 if(*p || v > 0xffff)
1844                         error(Ebadarg);
1845                 ctlr->radv = v;
1846                 csr32w(ctlr, Radv, v);
1847                 break;
1848         case CMpause:
1849                 csr32w(ctlr, Ctrl, csr32r(ctlr, Ctrl) ^ (Rfce | Tfce));
1850                 break;
1851         case CMan:
1852                 csr32w(ctlr, Ctrl, csr32r(ctlr, Ctrl) | Lrst | Phyrst);
1853                 break;
1854         }
1855         free(cb);
1856         poperror();
1857
1858         return n;
1859 }
1860
1861 static int
1862 didtype(int d)
1863 {
1864         /*
1865          * Some names and did values are from
1866          * OpenBSD's em(4) Intel driver.
1867          */
1868         switch(d){
1869         case 0x1096:            /* copper */
1870         case 0x10ba:            /* copper “gilgal” */
1871         case 0x1098:            /* serdes; not seen */
1872         case 0x10bb:            /* serdes */
1873                 return i82563;
1874         case 0x1049:            /* ich8; mm */
1875         case 0x104a:            /* ich8; dm */
1876         case 0x104b:            /* ich8; dc */
1877         case 0x104d:            /* ich8; v “ninevah” */
1878         case 0x10bd:            /* ich9; dm-2 */
1879         case 0x294c:            /* ich9 */
1880         case 0x104c:            /* ich8; untested */
1881         case 0x10c4:            /* ich8; untested */
1882         case 0x10c5:            /* ich8; untested */
1883                 return i82566;
1884         case 0x10de:            /* lm ich10d */
1885         case 0x10df:            /* lf ich10 */
1886         case 0x10e5:            /* lm ich9 */
1887         case 0x10f5:            /* lm ich9m; “boazman” */
1888         case 0x10ce:            /* v ich10 */
1889         case 0x10c0:            /* ich9 */
1890         case 0x10c2:            /* ich9; untested */
1891         case 0x10c3:            /* ich9; untested */
1892         case 0x1501:            /* ich8; untested */
1893                 return i82567;
1894         case 0x10bf:            /* lf ich9m */
1895         case 0x10cb:            /* v ich9m */
1896         case 0x10cd:            /* lf ich10 */
1897         case 0x10cc:            /* lm ich10 */
1898                 return i82567m;
1899         case 0x105e:            /* eb copper */
1900         case 0x105f:            /* eb fiber */
1901         case 0x1060:            /* eb serdes */
1902         case 0x10a4:            /* eb copper */
1903         case 0x10a5:            /* eb fiber */
1904         case 0x10bc:            /* eb copper */
1905         case 0x10d9:            /* eb serdes */
1906         case 0x10da:            /* eb serdes “ophir” */
1907         case 0x10a0:            /* eb; untested */
1908         case 0x10a1:            /* eb; untested */
1909         case 0x10d5:            /* copper; untested */
1910                 return i82571;
1911         case 0x107d:            /* ei copper */
1912         case 0x107e:            /* ei fiber */
1913         case 0x107f:            /* ei serdes */
1914         case 0x10b9:            /* ei “rimon” */
1915                 return i82572;
1916         case 0x108b:            /* e “vidalia” */
1917         case 0x108c:            /* e (iamt) */
1918         case 0x109a:            /* l “tekoa” */
1919         case 0x10b0:            /* l; untested */
1920         case 0x10b2:            /* v; untested */
1921         case 0x10b3:            /* e; untested */
1922         case 0x10b4:            /* l; untested */
1923                 return i82573;
1924         case 0x10d3:            /* l or it; “hartwell” */
1925         case 0x10f6:            /* la; untested */
1926                 return i82574;
1927         case 0x10a7:            /* eb */
1928         case 0x10a9:            /* eb fiber/serdes */
1929         case 0x10d6:            /* untested */
1930         case 0x10e2:            /* untested */
1931                 return i82575;
1932         case 0x10c9:            /* copper */
1933         case 0x10e6:            /* fiber */
1934         case 0x10e7:            /* serdes; “kawela” */
1935         case 0x10e8:            /* copper; untested */
1936         case 0x150a:            /* untested */
1937         case 0x150d:            /* serdes backplane */
1938         case 0x1518:            /* serdes; untested */
1939         case 0x1526:            /* untested */
1940                 return i82576;
1941         case 0x10ea:            /* lc “calpella”; aka pch lan */
1942                 return i82577;
1943         case 0x10eb:            /* lm “calpella” */
1944                 return i82577m;
1945         case 0x10ef:            /* dc “piketon” */
1946                 return i82578;
1947         case 0x1502:            /* lm */
1948         case 0x1503:            /* v “lewisville” */
1949                 return i82579;
1950         case 0x10f0:            /* dm “king's creek” */
1951                 return i82578m;
1952         case 0x150e:            /* copper “barton hills” */
1953         case 0x150f:            /* fiber */
1954         case 0x1510:            /* serdes backplane */
1955         case 0x1511:            /* sgmii sfp */
1956         case 0x1516:            /* copper */
1957                 return i82580;
1958         case 0x1506:            /* v */
1959         case 0x150c:            /* untested */
1960                 return i82583;
1961         case 0x1533:            /* i210-t1 */
1962         case 0x1534:            /* i210 */
1963         case 0x1536:            /* i210-fiber */
1964         case 0x1537:            /* i210-backplane */
1965         case 0x1538:            /* i210 sgmii */
1966         case 0x1539:            /* i211 copper */
1967         case 0x157b:            /* i210 copper flashless */
1968         case 0x157c:            /* i210 serdes flashless */
1969                 return i210;
1970         case 0x153a:            /* i217-lm */
1971         case 0x153b:            /* i217-v */
1972                 return i217;
1973         case 0x1559:            /* i218-v */
1974         case 0x155a:            /* i218-lm */
1975         case 0x15a0:            /* i218-lm */
1976         case 0x15a1:            /* i218-v */
1977         case 0x15a2:            /* i218-lm */
1978         case 0x15a3:            /* i218-v */
1979                 return i218;
1980         case 0x156f:            /* i219-lm */
1981         case 0x15b7:            /* i219-lm */
1982         case 0x1570:            /* i219-v */
1983         case 0x15b8:            /* i219-v */
1984         case 0x15b9:            /* i219-lm */
1985         case 0x15d6:            /* i219-v */
1986         case 0x15d7:            /* i219-lm */
1987         case 0x15d8:            /* i219-v */
1988         case 0x15e3:            /* i219-lm */
1989                 return i219;
1990         case 0x151f:            /* i350 “powerville” eeprom-less */
1991         case 0x1521:            /* i350 copper */
1992         case 0x1522:            /* i350 fiber */
1993         case 0x1523:            /* i350 serdes */
1994         case 0x1524:            /* i350 sgmii */
1995         case 0x1546:            /* i350 DA4 (untested) */
1996         case 0x1f40:            /* i354 backplane */
1997         case 0x1f41:            /* i354 sgmii */
1998         case 0x1f42:            /* i354 sgmii (c2000) */
1999         case 0x1f45:            /* i354 backplane 2.5 */
2000                 return i350;
2001         }
2002         return -1;
2003 }
2004
2005 static void
2006 hbafixup(Pcidev *p)
2007 {
2008         uint i;
2009
2010         i = pcicfgr32(p, PciSVID);
2011         if((i & 0xffff) == 0x1b52 && p->did == 1)
2012                 p->did = i>>16;
2013 }
2014
2015 static void
2016 i82563pci(void)
2017 {
2018         int type;
2019         Ctlr *ctlr;
2020         Pcidev *p;
2021
2022         for(p = nil; p = pcimatch(p, 0x8086, 0);){
2023                 hbafixup(p);
2024                 if((type = didtype(p->did)) == -1)
2025                         continue;
2026                 ctlr = malloc(sizeof(Ctlr));
2027                 if(ctlr == nil){
2028                         print("%s: can't allocate memory\n", cttab[type].name);
2029                         continue;
2030                 }
2031                 ctlr->type = type;
2032                 ctlr->pcidev = p;
2033                 ctlr->rbsz = ROUND(cttab[type].mtu, 1024);
2034                 ctlr->port = p->mem[0].bar & ~0x0F;
2035                 if(i82563ctlrhead != nil)
2036                         i82563ctlrtail->next = ctlr;
2037                 else
2038                         i82563ctlrhead = ctlr;
2039                 i82563ctlrtail = ctlr;
2040         }
2041 }
2042
2043 static int
2044 setup(Ctlr *ctlr)
2045 {
2046         Pcidev *p;
2047
2048         p = ctlr->pcidev;
2049         ctlr->nic = vmap(ctlr->port, p->mem[0].size);
2050         if(ctlr->nic == nil){
2051                 print("%s: can't map 0x%lux\n", cname(ctlr), ctlr->port);
2052                 return -1;
2053         }
2054         pcienable(p);
2055         if(i82563reset(ctlr)){
2056                 pcidisable(p);
2057                 vunmap(ctlr->nic, p->mem[0].size);
2058                 return -1;
2059         }
2060         pcisetbme(p);
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 = cttab[ctlr->type].mtu;
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 }