]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/ether82563.c
ether82563: fix multicast for i210
[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 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 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 = 0;
1209                 for(i=0; i<4; i++){
1210                         tsleep(&up->sleep, return0, 0, 150);
1211                         phy = phyread(c, phyno, Phystat);
1212                         if(phy == ~0)
1213                                 continue;
1214                         if(phy & Ans){
1215                                 r = phyread(c, phyno, Phyctl);
1216                                 if(r == ~0)
1217                                         continue;
1218                                 phywrite(c, phyno, Phyctl, r | Ran | Ean);
1219                         }
1220                         break;
1221                 }
1222                 i = (phy>>8) & 3;
1223                 e->link = i != 3 && (phy & Link) != 0;
1224                 if(e->link == 0)
1225                         i = 3;
1226                 c->speeds[i]++;
1227                 e->mbps = speedtab[i];
1228                 lsleep(c, Lsc);
1229         }
1230 }
1231
1232 static void
1233 phylproc(void *v)
1234 {
1235         uint a, i, phy, phyno;
1236         Ctlr *c;
1237         Ether *e;
1238
1239         e = v;
1240         c = e->ctlr;
1241         while(waserror())
1242                 ;
1243
1244         while((phyno = phyprobe(c, 3<<1)) == ~0)
1245                 lsleep(c, Lsc);
1246
1247         if(c->type == i82573 && (phy = phyread(c, phyno, Phyier)) != ~0)
1248                 phywrite(c, phyno, Phyier, phy | Lscie | Ancie | Spdie | Panie);
1249
1250         for(;;){
1251                 phy = phyread(c, phyno, Physsr);
1252                 if(phy == ~0){
1253                         phy = 0;
1254                         i = 3;
1255                         goto next;
1256                 }
1257                 i = (phy>>14) & 3;
1258                 switch(c->type){
1259                 default:
1260                         a = 0;
1261                         break;
1262                 case i82563:
1263                 case i82578:
1264                 case i82578m:
1265                 case i82583:
1266                         a = phyread(c, phyno, Phyisr) & Ane;
1267                         break;
1268                 case i82571:
1269                 case i82572:
1270                 case i82575:
1271                 case i82576:
1272                         a = phyread(c, phyno, Phylhr) & Anf;
1273                         i = (i-1) & 3;
1274                         break;
1275                 }
1276                 if(a)
1277                         phywrite(c, phyno, Phyctl, phyread(c, phyno, Phyctl) | Ran | Ean);
1278 next:
1279                 e->link = (phy & Rtlink) != 0;
1280                 if(e->link == 0)
1281                         i = 3;
1282                 c->speeds[i]++;
1283                 e->mbps = speedtab[i];
1284                 if(c->type == i82563)
1285                         phyerrata(e, c, phyno);
1286                 lsleep(c, Lsc);
1287         }
1288 }
1289
1290 static void
1291 pcslproc(void *v)
1292 {
1293         uint i, phy;
1294         Ctlr *c;
1295         Ether *e;
1296
1297         e = v;
1298         c = e->ctlr;
1299         while(waserror())
1300                 ;
1301
1302         if(c->type == i82575 || c->type == i82576)
1303                 csr32w(c, Connsw, Enrgirq);
1304         for(;;){
1305                 phy = csr32r(c, Pcsstat);
1306                 e->link = phy & Linkok;
1307                 i = 3;
1308                 if(e->link)
1309                         i = (phy & 6) >> 1;
1310                 else if(phy & Anbad)
1311                         csr32w(c, Pcsctl, csr32r(c, Pcsctl) | Pan | Prestart);
1312                 c->speeds[i]++;
1313                 e->mbps = speedtab[i];
1314                 lsleep(c, Lsc | Omed);
1315         }
1316 }
1317
1318 static void
1319 serdeslproc(void *v)
1320 {
1321         uint i, tx, rx;
1322         Ctlr *c;
1323         Ether *e;
1324
1325         e = v;
1326         c = e->ctlr;
1327         while(waserror())
1328                 ;
1329         for(;;){
1330                 rx = csr32r(c, Rxcw);
1331                 tx = csr32r(c, Txcw);
1332                 USED(tx);
1333                 e->link = (rx & 1<<31) != 0;
1334 //              e->link = (csr32r(c, Status) & Lu) != 0;
1335                 i = 3;
1336                 if(e->link)
1337                         i = 2;
1338                 c->speeds[i]++;
1339                 e->mbps = speedtab[i];
1340                 lsleep(c, Lsc);
1341         }
1342 }
1343
1344 static void
1345 i82563attach(Ether *edev)
1346 {
1347         char name[KNAMELEN];
1348         Ctlr *ctlr;
1349
1350         ctlr = edev->ctlr;
1351         qlock(&ctlr->alock);
1352         if(ctlr->alloc != nil){
1353                 qunlock(&ctlr->alock);
1354                 return;
1355         }
1356
1357         ctlr->nrd = Nrd;
1358         ctlr->ntd = Ntd;
1359         ctlr->alloc = malloc(ctlr->nrd*sizeof(Rd)+ctlr->ntd*sizeof(Td) + 255);
1360         ctlr->rb = malloc(ctlr->nrd * sizeof(Block*));
1361         ctlr->tb = malloc(ctlr->ntd * sizeof(Block*));
1362         if(ctlr->alloc == nil || ctlr->rb == nil || ctlr->tb == nil){
1363                 free(ctlr->rb);
1364                 ctlr->rb = nil;
1365                 free(ctlr->tb);
1366                 ctlr->tb = nil;
1367                 free(ctlr->alloc);
1368                 ctlr->alloc = nil;
1369                 qunlock(&ctlr->alock);
1370                 error(Enomem);
1371         }
1372         ctlr->rdba = (Rd*)ROUNDUP((uintptr)ctlr->alloc, 256);
1373         ctlr->tdba = (Td*)(ctlr->rdba + ctlr->nrd);
1374
1375         if(waserror()){
1376                 free(ctlr->tb);
1377                 ctlr->tb = nil;
1378                 free(ctlr->rb);
1379                 ctlr->rb = nil;
1380                 free(ctlr->alloc);
1381                 ctlr->alloc = nil;
1382                 qunlock(&ctlr->alock);
1383                 nexterror();
1384         }
1385
1386         snprint(name, sizeof name, "#l%dl", edev->ctlrno);
1387         if(csr32r(ctlr, Status) & Tbimode)
1388                 kproc(name, serdeslproc, edev);         /* mac based serdes */
1389         else if((csr32r(ctlr, Ctrlext) & Linkmode) == Serdes)
1390                 kproc(name, pcslproc, edev);            /* phy based serdes */
1391         else if(cttab[ctlr->type].flag & F79phy)
1392                 kproc(name, phyl79proc, edev);
1393         else
1394                 kproc(name, phylproc, edev);
1395
1396         snprint(name, sizeof name, "#l%dr", edev->ctlrno);
1397         kproc(name, i82563rproc, edev);
1398
1399         snprint(name, sizeof name, "#l%dt", edev->ctlrno);
1400         kproc(name, i82563tproc, edev);
1401
1402         qunlock(&ctlr->alock);
1403         poperror();
1404 }
1405
1406 static void
1407 i82563interrupt(Ureg*, void *arg)
1408 {
1409         Ctlr *ctlr;
1410         Ether *edev;
1411         int icr, im;
1412
1413         edev = arg;
1414         ctlr = edev->ctlr;
1415
1416         ilock(&ctlr->imlock);
1417         csr32w(ctlr, Imc, ~0);
1418         im = ctlr->im;
1419
1420         while(icr = csr32r(ctlr, Icr) & ctlr->im){
1421                 if(icr & (Lsc | Omed)){
1422                         im &= ~(Lsc | Omed);
1423                         ctlr->lim = icr & (Lsc | Omed);
1424                         wakeup(&ctlr->lrendez);
1425                         ctlr->lintr++;
1426                 }
1427                 if(icr & (Rxt0|Rxo|Rxdmt0|Rxseq|Ack)){
1428                         ctlr->rim = icr & (Rxt0|Rxo|Rxdmt0|Rxseq|Ack);
1429                         im &= ~(Rxt0|Rxo|Rxdmt0|Rxseq|Ack);
1430                         wakeup(&ctlr->rrendez);
1431                         ctlr->rintr++;
1432                 }
1433                 if(icr & Txdw){
1434                         im &= ~Txdw;
1435                         ctlr->tintr++;
1436                         wakeup(&ctlr->trendez);
1437                 }
1438         }
1439
1440         ctlr->im = im;
1441         csr32w(ctlr, Ims, im);
1442         iunlock(&ctlr->imlock);
1443 }
1444
1445 static int
1446 i82563detach(Ctlr *ctlr)
1447 {
1448         int r, timeo;
1449
1450         /* balance rx/tx packet buffer; survives reset */
1451         if(ctlr->rbsz > 8192 && cttab[ctlr->type].flag & Fpba){
1452                 ctlr->pba = csr32r(ctlr, Pba);
1453                 r = ctlr->pba >> 16;
1454                 r += ctlr->pba & 0xffff;
1455                 r >>= 1;
1456                 csr32w(ctlr, Pba, r);
1457         }else if(ctlr->type == i82573 && ctlr->rbsz > 1514)
1458                 csr32w(ctlr, Pba, 14);
1459         ctlr->pba = csr32r(ctlr, Pba);
1460
1461         /*
1462          * Perform a device reset to get the chip back to the
1463          * power-on state, followed by an EEPROM reset to read
1464          * the defaults for some internal registers.
1465          */
1466         csr32w(ctlr, Imc, ~0);
1467         csr32w(ctlr, Rctl, 0);
1468         csr32w(ctlr, Tctl, csr32r(ctlr, Tctl) & ~Ten);
1469
1470         delay(10);
1471
1472         r = csr32r(ctlr, Ctrl);
1473         if(ctlr->type == i82566 || ctlr->type == i82579)
1474                 r |= Phyrst;
1475         /*
1476          * hack: 82579LM on lenovo X230 is stuck at 10mbps after
1477          * reseting the phy, but works fine if we dont reset.
1478          */
1479         if(ctlr->pcidev->did == 0x1502)
1480                 r &= ~Phyrst;
1481         csr32w(ctlr, Ctrl, Devrst | r);
1482         delay(1);
1483         for(timeo = 0;; timeo++){
1484                 if((csr32r(ctlr, Ctrl) & (Devrst|Phyrst)) == 0)
1485                         break;
1486                 if(timeo >= 1000)
1487                         return -1;
1488                 delay(1);
1489         }
1490
1491         r = csr32r(ctlr, Ctrl);
1492         csr32w(ctlr, Ctrl, Slu|r);
1493
1494         r = csr32r(ctlr, Ctrlext);
1495         csr32w(ctlr, Ctrlext, r|Eerst);
1496         delay(1);
1497         for(timeo = 0; timeo < 1000; timeo++){
1498                 if(!(csr32r(ctlr, Ctrlext) & Eerst))
1499                         break;
1500                 delay(1);
1501         }
1502         if(csr32r(ctlr, Ctrlext) & Eerst)
1503                 return -1;
1504
1505         csr32w(ctlr, Imc, ~0);
1506         delay(1);
1507         for(timeo = 0; timeo < 1000; timeo++){
1508                 if((csr32r(ctlr, Icr) & ~Rxcfg) == 0)
1509                         break;
1510                 delay(1);
1511         }
1512         if(csr32r(ctlr, Icr) & ~Rxcfg)
1513                 return -1;
1514
1515         return 0;
1516 }
1517
1518 static void
1519 i82563shutdown(Ether *edev)
1520 {
1521         i82563detach(edev->ctlr);
1522 }
1523
1524 static int
1525 eeread(Ctlr *ctlr, int adr)
1526 {
1527         int timeout;
1528
1529         csr32w(ctlr, Eerd, EEstart | adr << 2);
1530         timeout = 1000;
1531         while ((csr32r(ctlr, Eerd) & EEdone) == 0 && timeout--)
1532                 microdelay(5);
1533         if (timeout < 0) {
1534                 print("%s: eeread timeout\n", cname(ctlr));
1535                 return -1;
1536         }
1537         return (csr32r(ctlr, Eerd) >> 16) & 0xffff;
1538 }
1539
1540 static int
1541 eeload(Ctlr *ctlr)
1542 {
1543         u16int sum;
1544         int data, adr;
1545
1546         sum = 0;
1547         for (adr = 0; adr < 0x40; adr++) {
1548                 data = eeread(ctlr, adr);
1549                 if(data == -1) return -1;
1550                 ctlr->eeprom[adr] = data;
1551                 sum += data;
1552         }
1553         return sum;
1554 }
1555
1556 static int
1557 fread16(Ctlr *c, Flash *f, int ladr)
1558 {
1559         u16int s;
1560         int timeout;
1561
1562         delay(1);
1563         s = f->reg[Fsts];
1564         if((s&Fvalid) == 0)
1565                 return -1;
1566         f->reg[Fsts] |= Fcerr | Ael;
1567         for(timeout = 0; timeout < 10; timeout++){
1568                 if((s&Scip) == 0)
1569                         goto done;
1570                 delay(1);
1571                 s = f->reg[Fsts];
1572         }
1573         return -1;
1574 done:
1575         f->reg[Fsts] |= Fdone;
1576         f->reg32[Faddr] = ladr;
1577
1578         /* setup flash control register */
1579         s = f->reg[Fctl] & ~0x3ff;
1580         f->reg[Fctl] = s | 1<<8 | Fgo;  /* 2 byte read */
1581         timeout = 1000;
1582         while((f->reg[Fsts] & Fdone) == 0 && timeout--)
1583                 microdelay(5);
1584         if(timeout < 0){
1585                 print("%s: fread timeout\n", cname(c));
1586                 return -1;
1587         }
1588         if(f->reg[Fsts] & (Fcerr|Ael))
1589                 return -1;
1590         return f->reg32[Fdata] & 0xffff;
1591 }
1592
1593 static int
1594 fread32(Ctlr *c, Flash *f, int ladr, u32int *data)
1595 {
1596         u32int s;
1597         int timeout;
1598
1599         delay(1);
1600         s = f->reg32[Fsts/2];
1601         if((s&Fvalid) == 0)
1602                 return -1;
1603         f->reg32[Fsts/2] |= Fcerr | Ael;
1604         for(timeout = 0; timeout < 10; timeout++){
1605                 if((s&Scip) == 0)
1606                         goto done;
1607                 delay(1);
1608                 s = f->reg32[Fsts/2];
1609         }
1610         return -1;
1611 done:
1612         f->reg32[Fsts/2] |= Fdone;
1613         f->reg32[Faddr] = ladr;
1614
1615         /* setup flash control register */
1616         s = (f->reg32[Fctl/2] >> 16) & ~0x3ff;
1617         f->reg32[Fctl/2] = (s | 3<<8 | Fgo) << 16;      /* 4 byte read */
1618         timeout = 1000;
1619         while((f->reg32[Fsts/2] & Fdone) == 0 && timeout--)
1620                 microdelay(5);
1621         if(timeout < 0){
1622                 print("%s: fread timeout\n", cname(c));
1623                 return -1;
1624         }
1625         if(f->reg32[Fsts/2] & (Fcerr|Ael))
1626                 return -1;
1627         *data = f->reg32[Fdata];
1628         return 0;
1629 }
1630
1631 static int
1632 fload32(Ctlr *c)
1633 {
1634         int r, adr;
1635         u16int sum;
1636         u32int w;
1637         Flash f;
1638
1639         f.reg32 = &c->nic[0xe000/4];
1640         f.reg = nil;
1641         f.base = 0;
1642         f.lim = (((csr32r(c, 0xC) >> 1) & 0x1F) + 1) << 12;
1643         r = f.lim >> 1;
1644         if(fread32(c, &f, r + 0x24, &w) == -1  || (w & 0xC000) != 0x8000)
1645                 r = 0;
1646         sum = 0;
1647         for(adr = 0; adr < 0x20; adr++) {
1648                 if(fread32(c, &f, r + adr*4, &w) == -1)
1649                         return -1;
1650                 c->eeprom[adr*2+0] = w;
1651                 c->eeprom[adr*2+1] = w>>16;
1652                 sum += w & 0xFFFF;
1653                 sum += w >> 16;
1654         }
1655         return sum;
1656 }
1657
1658 static int
1659 fload(Ctlr *c)
1660 {
1661         int data, r, adr;
1662         u16int sum;
1663         void *va;
1664         Flash f;
1665
1666         memset(c->eeprom, 0xFF, sizeof(c->eeprom));
1667         if(c->pcidev->mem[1].bar == 0)
1668                 return fload32(c);      /* i219 */
1669
1670         va = vmap(c->pcidev->mem[1].bar & ~0x0f, c->pcidev->mem[1].size);
1671         if(va == nil)
1672                 return -1;
1673         f.reg = va;
1674         f.reg32 = va;
1675         f.base = f.reg32[Bfpr] & 0x1fff;
1676         f.lim = f.reg32[Bfpr]>>16 & 0x1fff;
1677         if(csr32r(c, Eec) & Sec1val)
1678                 f.base += f.lim+1 - f.base >> 1;
1679         r = f.base << 12;
1680         sum = 0;
1681         for(adr = 0; adr < 0x40; adr++) {
1682                 data = fread16(c, &f, r + adr*2);
1683                 if(data == -1)
1684                         goto out;
1685                 c->eeprom[adr] = data;
1686                 sum += data;
1687         }
1688 out:
1689         vunmap(va, c->pcidev->mem[1].size);
1690         return sum;
1691 }
1692
1693 static int
1694 invmload(Ctlr *c)
1695 {
1696         int i, a;
1697         u32int w;
1698
1699         memset(c->eeprom, 0xFF, sizeof(c->eeprom));
1700         for(i=0; i<64; i++){
1701                 w = csr32r(c, Invmdata0 + i*4);
1702                 switch(w & 7){
1703                 case 0: // uninitialized structure
1704                         break;
1705                 case 1: // word auto load
1706                         a = (w & 0xFE00) >> 9;
1707                         if(a < nelem(c->eeprom))
1708                                 c->eeprom[a] = w >> 16;
1709                         continue;
1710                 case 2: // csr auto load
1711                         i++;
1712                 case 3: // phy auto load
1713                         continue;
1714                 case 4: // rsa key sha256
1715                         i += 256/32;
1716                 case 5: // invalidated structure
1717                         continue;
1718                 default:
1719                         print("invm: %.2x %.8ux\n", i, w);
1720                         continue;
1721                 }
1722                 break;
1723         }
1724         return 0;
1725 }
1726
1727 static void
1728 defaultea(Ctlr *ctlr, uchar *ra)
1729 {
1730         uint i, r;
1731         uvlong u;
1732         static uchar nilea[Eaddrlen];
1733
1734         if(memcmp(ra, nilea, Eaddrlen) != 0)
1735                 return;
1736         if(cttab[ctlr->type].flag & Fflashea){
1737                 /* intel mb bug */
1738                 u = (uvlong)csr32r(ctlr, Rah)<<32u | (ulong)csr32r(ctlr, Ral);
1739                 for(i = 0; i < Eaddrlen; i++)
1740                         ra[i] = u >> 8*i;
1741         }
1742         if(memcmp(ra, nilea, Eaddrlen) != 0)
1743                 return;
1744         for(i = 0; i < Eaddrlen/2; i++){
1745                 ra[2*i] = ctlr->eeprom[Ea+i];
1746                 ra[2*i+1] = ctlr->eeprom[Ea+i] >> 8;
1747         }
1748         r = (csr32r(ctlr, Status) & Lanid) >> 2;
1749         ra[5] += r;                             /* ea ctlr[n] = ea ctlr[0]+n */
1750 }
1751
1752 static int
1753 i82563reset(Ctlr *ctlr)
1754 {
1755         uchar *ra;
1756         int i, r, flag;
1757
1758         if(i82563detach(ctlr))
1759                 return -1;
1760         flag = cttab[ctlr->type].flag;
1761
1762         if(ctlr->type == i210 && (csr32r(ctlr, Eec) & Flupd) == 0)
1763                 r = invmload(ctlr);
1764         else if(flag & Fload)
1765                 r = fload(ctlr);
1766         else
1767                 r = eeload(ctlr);
1768
1769         if(r != 0 && r != 0xbaba){
1770                 print("%s: bad eeprom checksum - %#.4ux", cname(ctlr), r);
1771                 if(flag & Fbadcsum)
1772                         print("; ignored\n");
1773                 else {
1774                         print("\n");
1775                         return -1;
1776                 }
1777         }
1778
1779         ra = ctlr->ra;
1780         defaultea(ctlr, ra);
1781         csr32w(ctlr, Ral, ra[3]<<24 | ra[2]<<16 | ra[1]<<8 | ra[0]);
1782         csr32w(ctlr, Rah, 1<<31 | ra[5]<<8 | ra[4]);
1783         for(i = 1; i < 16; i++){
1784                 csr32w(ctlr, Ral+i*8, 0);
1785                 csr32w(ctlr, Rah+i*8, 0);
1786         }
1787         memset(ctlr->mta, 0, sizeof(ctlr->mta));
1788         for(i = 0; i < 128; i++)
1789                 csr32w(ctlr, Mta + i*4, 0);
1790         if((flag & Fnofca) == 0){
1791                 csr32w(ctlr, Fcal, 0x00C28001);
1792                 csr32w(ctlr, Fcah, 0x0100);
1793         }
1794         if((flag & Fnofct) == 0)
1795                 csr32w(ctlr, Fct, 0x8808);
1796         csr32w(ctlr, Fcttv, 0x0100);
1797         csr32w(ctlr, Fcrtl, ctlr->fcrtl);
1798         csr32w(ctlr, Fcrth, ctlr->fcrth);
1799         if(flag & F75)
1800                 csr32w(ctlr, Eitr, 128<<2);             /* 128 ¼ microsecond intervals */
1801         return 0;
1802 }
1803
1804 enum {
1805         CMrdtr,
1806         CMradv,
1807         CMpause,
1808         CMan,
1809 };
1810
1811 static Cmdtab i82563ctlmsg[] = {
1812         CMrdtr, "rdtr", 2,
1813         CMradv, "radv", 2,
1814         CMpause, "pause", 1,
1815         CMan,   "an",   1,
1816 };
1817
1818 static long
1819 i82563ctl(Ether *edev, void *buf, long n)
1820 {
1821         char *p;
1822         ulong v;
1823         Ctlr *ctlr;
1824         Cmdbuf *cb;
1825         Cmdtab *ct;
1826
1827         if((ctlr = edev->ctlr) == nil)
1828                 error(Enonexist);
1829
1830         cb = parsecmd(buf, n);
1831         if(waserror()){
1832                 free(cb);
1833                 nexterror();
1834         }
1835
1836         ct = lookupcmd(cb, i82563ctlmsg, nelem(i82563ctlmsg));
1837         switch(ct->index){
1838         case CMrdtr:
1839                 v = strtoul(cb->f[1], &p, 0);
1840                 if(*p || v > 0xffff)
1841                         error(Ebadarg);
1842                 ctlr->rdtr = v;
1843                 csr32w(ctlr, Rdtr, v);
1844                 break;
1845         case CMradv:
1846                 v = strtoul(cb->f[1], &p, 0);
1847                 if(*p || v > 0xffff)
1848                         error(Ebadarg);
1849                 ctlr->radv = v;
1850                 csr32w(ctlr, Radv, v);
1851                 break;
1852         case CMpause:
1853                 csr32w(ctlr, Ctrl, csr32r(ctlr, Ctrl) ^ (Rfce | Tfce));
1854                 break;
1855         case CMan:
1856                 csr32w(ctlr, Ctrl, csr32r(ctlr, Ctrl) | Lrst | Phyrst);
1857                 break;
1858         }
1859         free(cb);
1860         poperror();
1861
1862         return n;
1863 }
1864
1865 static int
1866 didtype(int d)
1867 {
1868         /*
1869          * Some names and did values are from
1870          * OpenBSD's em(4) Intel driver.
1871          */
1872         switch(d){
1873         case 0x1096:            /* copper */
1874         case 0x10ba:            /* copper “gilgal” */
1875         case 0x1098:            /* serdes; not seen */
1876         case 0x10bb:            /* serdes */
1877                 return i82563;
1878         case 0x1049:            /* ich8; mm */
1879         case 0x104a:            /* ich8; dm */
1880         case 0x104b:            /* ich8; dc */
1881         case 0x104d:            /* ich8; v “ninevah” */
1882         case 0x10bd:            /* ich9; dm-2 */
1883         case 0x294c:            /* ich9 */
1884         case 0x104c:            /* ich8; untested */
1885         case 0x10c4:            /* ich8; untested */
1886         case 0x10c5:            /* ich8; untested */
1887                 return i82566;
1888         case 0x10de:            /* lm ich10d */
1889         case 0x10df:            /* lf ich10 */
1890         case 0x10e5:            /* lm ich9 */
1891         case 0x10f5:            /* lm ich9m; “boazman” */
1892         case 0x10ce:            /* v ich10 */
1893         case 0x10c0:            /* ich9 */
1894         case 0x10c2:            /* ich9; untested */
1895         case 0x10c3:            /* ich9; untested */
1896         case 0x1501:            /* ich8; untested */
1897                 return i82567;
1898         case 0x10bf:            /* lf ich9m */
1899         case 0x10cb:            /* v ich9m */
1900         case 0x10cd:            /* lf ich10 */
1901         case 0x10cc:            /* lm ich10 */
1902                 return i82567m;
1903         case 0x105e:            /* eb copper */
1904         case 0x105f:            /* eb fiber */
1905         case 0x1060:            /* eb serdes */
1906         case 0x10a4:            /* eb copper */
1907         case 0x10a5:            /* eb fiber */
1908         case 0x10bc:            /* eb copper */
1909         case 0x10d9:            /* eb serdes */
1910         case 0x10da:            /* eb serdes “ophir” */
1911         case 0x10a0:            /* eb; untested */
1912         case 0x10a1:            /* eb; untested */
1913         case 0x10d5:            /* copper; untested */
1914                 return i82571;
1915         case 0x107d:            /* ei copper */
1916         case 0x107e:            /* ei fiber */
1917         case 0x107f:            /* ei serdes */
1918         case 0x10b9:            /* ei “rimon” */
1919                 return i82572;
1920         case 0x108b:            /* e “vidalia” */
1921         case 0x108c:            /* e (iamt) */
1922         case 0x109a:            /* l “tekoa” */
1923         case 0x10b0:            /* l; untested */
1924         case 0x10b2:            /* v; untested */
1925         case 0x10b3:            /* e; untested */
1926         case 0x10b4:            /* l; untested */
1927                 return i82573;
1928         case 0x10d3:            /* l or it; “hartwell” */
1929         case 0x10f6:            /* la; untested */
1930                 return i82574;
1931         case 0x10a7:            /* eb */
1932         case 0x10a9:            /* eb fiber/serdes */
1933         case 0x10d6:            /* untested */
1934         case 0x10e2:            /* untested */
1935                 return i82575;
1936         case 0x10c9:            /* copper */
1937         case 0x10e6:            /* fiber */
1938         case 0x10e7:            /* serdes; “kawela” */
1939         case 0x10e8:            /* copper; untested */
1940         case 0x150a:            /* untested */
1941         case 0x150d:            /* serdes backplane */
1942         case 0x1518:            /* serdes; untested */
1943         case 0x1526:            /* untested */
1944                 return i82576;
1945         case 0x10ea:            /* lc “calpella”; aka pch lan */
1946                 return i82577;
1947         case 0x10eb:            /* lm “calpella” */
1948                 return i82577m;
1949         case 0x10ef:            /* dc “piketon” */
1950                 return i82578;
1951         case 0x1502:            /* lm */
1952         case 0x1503:            /* v “lewisville” */
1953                 return i82579;
1954         case 0x10f0:            /* dm “king's creek” */
1955                 return i82578m;
1956         case 0x150e:            /* copper “barton hills” */
1957         case 0x150f:            /* fiber */
1958         case 0x1510:            /* serdes backplane */
1959         case 0x1511:            /* sgmii sfp */
1960         case 0x1516:            /* copper */
1961                 return i82580;
1962         case 0x1506:            /* v */
1963         case 0x150c:            /* untested */
1964                 return i82583;
1965         case 0x1533:            /* i210-t1 */
1966         case 0x1534:            /* i210 */
1967         case 0x1536:            /* i210-fiber */
1968         case 0x1537:            /* i210-backplane */
1969         case 0x1538:            /* i210 sgmii */
1970         case 0x1539:            /* i211 copper */
1971         case 0x157b:            /* i210 copper flashless */
1972         case 0x157c:            /* i210 serdes flashless */
1973                 return i210;
1974         case 0x153a:            /* i217-lm */
1975         case 0x153b:            /* i217-v */
1976                 return i217;
1977         case 0x1559:            /* i218-v */
1978         case 0x155a:            /* i218-lm */
1979         case 0x15a0:            /* i218-lm */
1980         case 0x15a1:            /* i218-v */
1981         case 0x15a2:            /* i218-lm */
1982         case 0x15a3:            /* i218-v */
1983                 return i218;
1984         case 0x156f:            /* i219-lm */
1985         case 0x15b7:            /* i219-lm */
1986         case 0x1570:            /* i219-v */
1987         case 0x15b8:            /* i219-v */
1988         case 0x15b9:            /* i219-lm */
1989         case 0x15d6:            /* i219-v */
1990         case 0x15d7:            /* i219-lm */
1991         case 0x15d8:            /* i219-v */
1992         case 0x15e3:            /* i219-lm */
1993                 return i219;
1994         case 0x151f:            /* i350 “powerville” eeprom-less */
1995         case 0x1521:            /* i350 copper */
1996         case 0x1522:            /* i350 fiber */
1997         case 0x1523:            /* i350 serdes */
1998         case 0x1524:            /* i350 sgmii */
1999         case 0x1546:            /* i350 DA4 (untested) */
2000         case 0x1f40:            /* i354 backplane */
2001         case 0x1f41:            /* i354 sgmii */
2002         case 0x1f42:            /* i354 sgmii (c2000) */
2003         case 0x1f45:            /* i354 backplane 2.5 */
2004                 return i350;
2005         }
2006         return -1;
2007 }
2008
2009 static void
2010 hbafixup(Pcidev *p)
2011 {
2012         uint i;
2013
2014         i = pcicfgr32(p, PciSVID);
2015         if((i & 0xffff) == 0x1b52 && p->did == 1)
2016                 p->did = i>>16;
2017 }
2018
2019 static void
2020 i82563pci(void)
2021 {
2022         int type;
2023         Ctlr *ctlr;
2024         Pcidev *p;
2025
2026         for(p = nil; p = pcimatch(p, 0x8086, 0);){
2027                 hbafixup(p);
2028                 if((type = didtype(p->did)) == -1)
2029                         continue;
2030                 ctlr = malloc(sizeof(Ctlr));
2031                 if(ctlr == nil){
2032                         print("%s: can't allocate memory\n", cttab[type].name);
2033                         continue;
2034                 }
2035                 ctlr->type = type;
2036                 ctlr->pcidev = p;
2037                 ctlr->rbsz = ROUND(cttab[type].mtu, 1024);
2038                 ctlr->port = p->mem[0].bar & ~0x0F;
2039                 if(i82563ctlrhead != nil)
2040                         i82563ctlrtail->next = ctlr;
2041                 else
2042                         i82563ctlrhead = ctlr;
2043                 i82563ctlrtail = ctlr;
2044         }
2045 }
2046
2047 static int
2048 setup(Ctlr *ctlr)
2049 {
2050         Pcidev *p;
2051
2052         p = ctlr->pcidev;
2053         ctlr->nic = vmap(ctlr->port, p->mem[0].size);
2054         if(ctlr->nic == nil){
2055                 print("%s: can't map 0x%lux\n", cname(ctlr), ctlr->port);
2056                 return -1;
2057         }
2058         pcienable(p);
2059         if(i82563reset(ctlr)){
2060                 pcidisable(p);
2061                 vunmap(ctlr->nic, p->mem[0].size);
2062                 return -1;
2063         }
2064         pcisetbme(p);
2065         return 0;
2066 }
2067
2068 static int
2069 pnp(Ether *edev, int type)
2070 {
2071         Ctlr *ctlr;
2072         static int done;
2073
2074         if(!done) {
2075                 i82563pci();
2076                 done = 1;
2077         }
2078
2079         /*
2080          * Any adapter matches if no edev->port is supplied,
2081          * otherwise the ports must match.
2082          */
2083         for(ctlr = i82563ctlrhead; ; ctlr = ctlr->next){
2084                 if(ctlr == nil)
2085                         return -1;
2086                 if(ctlr->active)
2087                         continue;
2088                 if(type != -1 && ctlr->type != type)
2089                         continue;
2090                 if(edev->port == 0 || edev->port == ctlr->port){
2091                         ctlr->active = 1;
2092                         memmove(ctlr->ra, edev->ea, Eaddrlen);
2093                         if(setup(ctlr) == 0)
2094                                 break;
2095                 }
2096         }
2097
2098         edev->ctlr = ctlr;
2099         edev->port = ctlr->port;
2100         edev->irq = ctlr->pcidev->intl;
2101         edev->tbdf = ctlr->pcidev->tbdf;
2102         edev->mbps = 1000;
2103         edev->maxmtu = cttab[ctlr->type].mtu;
2104         memmove(edev->ea, ctlr->ra, Eaddrlen);
2105
2106         /*
2107          * Linkage to the generic ethernet driver.
2108          */
2109         edev->attach = i82563attach;
2110 //      edev->transmit = i82563transmit;
2111         edev->ifstat = i82563ifstat;
2112         edev->ctl = i82563ctl;
2113
2114         edev->arg = edev;
2115         edev->promiscuous = i82563promiscuous;
2116         edev->shutdown = i82563shutdown;
2117         edev->multicast = i82563multicast;
2118
2119         intrenable(edev->irq, i82563interrupt, edev, edev->tbdf, edev->name);
2120
2121         return 0;
2122 }
2123
2124 static int
2125 anypnp(Ether *e)
2126 {
2127         return pnp(e, -1);
2128 }
2129
2130 static int
2131 i82563pnp(Ether *e)
2132 {
2133         return pnp(e, i82563);
2134 }
2135
2136 static int
2137 i82566pnp(Ether *e)
2138 {
2139         return pnp(e, i82566);
2140 }
2141
2142 static int
2143 i82567pnp(Ether *e)
2144 {
2145         return pnp(e, i82567m) & pnp(e, i82567);
2146 }
2147
2148 static int
2149 i82571pnp(Ether *e)
2150 {
2151         return pnp(e, i82571);
2152 }
2153
2154 static int
2155 i82572pnp(Ether *e)
2156 {
2157         return pnp(e, i82572);
2158 }
2159
2160 static int
2161 i82573pnp(Ether *e)
2162 {
2163         return pnp(e, i82573);
2164 }
2165
2166 static int
2167 i82574pnp(Ether *e)
2168 {
2169         return pnp(e, i82574);
2170 }
2171
2172 static int
2173 i82575pnp(Ether *e)
2174 {
2175         return pnp(e, i82575);
2176 }
2177
2178 static int
2179 i82576pnp(Ether *e)
2180 {
2181         return pnp(e, i82576);
2182 }
2183
2184 static int
2185 i82577pnp(Ether *e)
2186 {
2187         return pnp(e, i82577m) & pnp(e, i82577);
2188 }
2189
2190 static int
2191 i82578pnp(Ether *e)
2192 {
2193         return pnp(e, i82578m) & pnp(e, i82578);
2194 }
2195
2196 static int
2197 i82579pnp(Ether *e)
2198 {
2199         return pnp(e, i82579);
2200 }
2201
2202 static int
2203 i82580pnp(Ether *e)
2204 {
2205         return pnp(e, i82580);
2206 }
2207
2208 static int
2209 i82583pnp(Ether *e)
2210 {
2211         return pnp(e, i82583);
2212 }
2213
2214 static int
2215 i210pnp(Ether *e)
2216 {
2217         return pnp(e, i210);
2218 }
2219
2220 static int
2221 i217pnp(Ether *e)
2222 {
2223         return pnp(e, i217);
2224 }
2225
2226 static int
2227 i218pnp(Ether *e)
2228 {
2229         return pnp(e, i218);
2230 }
2231
2232 static int
2233 i219pnp(Ether *e)
2234 {
2235         return pnp(e, i219);
2236 }
2237
2238 static int
2239 i350pnp(Ether *e)
2240 {
2241         return pnp(e, i350);
2242 }
2243
2244 void
2245 ether82563link(void)
2246 {
2247         /*
2248          * recognise lots of model numbers for debugging
2249          * also good for forcing onboard nic(s) as ether0
2250          * try to make that unnecessary by listing lom first.
2251          */
2252         addethercard("i82563", i82563pnp);
2253         addethercard("i82566", i82566pnp);
2254         addethercard("i82574", i82574pnp);
2255         addethercard("i82576", i82576pnp);
2256         addethercard("i82567", i82567pnp);
2257         addethercard("i82573", i82573pnp);
2258
2259         addethercard("i82571", i82571pnp);
2260         addethercard("i82572", i82572pnp);
2261         addethercard("i82575", i82575pnp);
2262         addethercard("i82577", i82577pnp);
2263         addethercard("i82578", i82578pnp);
2264         addethercard("i82579", i82579pnp);
2265         addethercard("i82580", i82580pnp);
2266         addethercard("i82583", i82583pnp);
2267         addethercard("i210", i210pnp);
2268         addethercard("i217", i217pnp);
2269         addethercard("i218", i218pnp);
2270         addethercard("i219", i219pnp);
2271         addethercard("i350", i350pnp);
2272         addethercard("igbepcie", anypnp);
2273 }