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