]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/ether82543gc.c
pc, pc64: more conservative pcirouting
[plan9front.git] / sys / src / 9 / pc / ether82543gc.c
1 /*
2  * Intel RS-82543GC Gigabit Ethernet Controller
3  * as found on the Intel PRO/1000[FT] Server Adapter.
4  * The older non-[FT] cards use the 82542 (LSI L2A1157) chip; no attempt
5  * is made to handle the older chip although it should be possible.
6  * The datasheet is not very clear about running on a big-endian system
7  * and this driver assumes little-endian throughout.
8  * To do:
9  *      GMII/MII
10  *      receive tuning
11  *      transmit tuning
12  */
13 #include "u.h"
14 #include "../port/lib.h"
15 #include "mem.h"
16 #include "dat.h"
17 #include "fns.h"
18 #include "io.h"
19 #include "../port/error.h"
20 #include "../port/netif.h"
21
22 #include "etherif.h"
23
24 enum {
25         Ctrl            = 0x00000000,   /* Device Control */
26         Status          = 0x00000008,   /* Device Status */
27         Eecd            = 0x00000010,   /* EEPROM/Flash Control/Data */
28         Ctrlext         = 0x00000018,   /* Extended Device Control */
29         Mdic            = 0x00000020,   /* MDI Control */
30         Fcal            = 0x00000028,   /* Flow Control Address Low */
31         Fcah            = 0x0000002C,   /* Flow Control Address High */
32         Fct             = 0x00000030,   /* Flow Control Type */
33         Icr             = 0x000000C0,   /* Interrupt Cause Read */
34         Ics             = 0x000000C8,   /* Interrupt Cause Set */
35         Ims             = 0x000000D0,   /* Interrupt Mask Set/Read */
36         Imc             = 0x000000D8,   /* Interrupt mask Clear */
37         Rctl            = 0x00000100,   /* Receive Control */
38         Fcttv           = 0x00000170,   /* Flow Control Transmit Timer Value */
39         Txcw            = 0x00000178,   /* Transmit configuration word reg. */
40         Rxcw            = 0x00000180,   /* Receive configuration word reg. */
41         Tctl            = 0x00000400,   /* Transmit Control */
42         Tipg            = 0x00000410,   /* Transmit IPG */
43         Tbt             = 0x00000448,   /* Transmit Burst Timer */
44         Ait             = 0x00000458,   /* Adaptive IFS Throttle */
45         Fcrtl           = 0x00002160,   /* Flow Control RX Threshold Low */
46         Fcrth           = 0x00002168,   /* Flow Control Rx Threshold High */
47         Rdfh            = 0x00002410,   /* Receive data fifo head */
48         Rdft            = 0x00002418,   /* Receive data fifo tail */
49         Rdfhs           = 0x00002420,   /* Receive data fifo head saved */
50         Rdfts           = 0x00002428,   /* Receive data fifo tail saved */
51         Rdfpc           = 0x00002430,   /* Receive data fifo packet count */
52         Rdbal           = 0x00002800,   /* Rdesc Base Address Low */
53         Rdbah           = 0x00002804,   /* Rdesc Base Address High */
54         Rdlen           = 0x00002808,   /* Receive Descriptor Length */
55         Rdh             = 0x00002810,   /* Receive Descriptor Head */
56         Rdt             = 0x00002818,   /* Receive Descriptor Tail */
57         Rdtr            = 0x00002820,   /* Receive Descriptor Timer Ring */
58         Rxdctl          = 0x00002828,   /* Receive Descriptor Control */
59         Txdmac          = 0x00003000,   /* Transfer DMA Control */
60         Ett             = 0x00003008,   /* Early Transmit Control */
61         Tdfh            = 0x00003410,   /* Transmit data fifo head */
62         Tdft            = 0x00003418,   /* Transmit data fifo tail */
63         Tdfhs           = 0x00003420,   /* Transmit data Fifo Head saved */
64         Tdfts           = 0x00003428,   /* Transmit data fifo tail saved */
65         Tdfpc           = 0x00003430,   /* Trasnmit data Fifo packet count */
66         Tdbal           = 0x00003800,   /* Tdesc Base Address Low */
67         Tdbah           = 0x00003804,   /* Tdesc Base Address High */
68         Tdlen           = 0x00003808,   /* Transmit Descriptor Length */
69         Tdh             = 0x00003810,   /* Transmit Descriptor Head */
70         Tdt             = 0x00003818,   /* Transmit Descriptor Tail */
71         Tidv            = 0x00003820,   /* Transmit Interrupt Delay Value */
72         Txdctl          = 0x00003828,   /* Transmit Descriptor Control */
73
74         Statistics      = 0x00004000,   /* Start of Statistics Area */
75         Gorcl           = 0x88/4,       /* Good Octets Received Count */
76         Gotcl           = 0x90/4,       /* Good Octets Transmitted Count */
77         Torl            = 0xC0/4,       /* Total Octets Received */
78         Totl            = 0xC8/4,       /* Total Octets Transmitted */
79         Nstatistics     = 64,
80
81         Rxcsum          = 0x00005000,   /* Receive Checksum Control */
82         Mta             = 0x00005200,   /* Multicast Table Array */
83         Ral             = 0x00005400,   /* Receive Address Low */
84         Rah             = 0x00005404,   /* Receive Address High */
85 };
86
87 enum {                                  /* Ctrl */
88         Bem             = 0x00000002,   /* Big Endian Mode */
89         Prior           = 0x00000004,   /* Priority on the PCI bus */
90         Lrst            = 0x00000008,   /* Link Reset */
91         Asde            = 0x00000020,   /* Auto-Speed Detection Enable */
92         Slu             = 0x00000040,   /* Set Link Up */
93         Ilos            = 0x00000080,   /* Invert Loss of Signal (LOS) */
94         Frcspd          = 0x00000800,   /* Force Speed */
95         Frcdplx         = 0x00001000,   /* Force Duplex */
96         Swdpinslo       = 0x003C0000,   /* Software Defined Pins - lo nibble */
97         Swdpin0         = 0x00040000,
98         Swdpin1         = 0x00080000,
99         Swdpin2         = 0x00100000,
100         Swdpin3         = 0x00200000,
101         Swdpiolo        = 0x03C00000,   /* Software Defined I/O Pins */
102         Swdpio0         = 0x00400000,
103         Swdpio1         = 0x00800000,
104         Swdpio2         = 0x01000000,
105         Swdpio3         = 0x02000000,
106         Devrst          = 0x04000000,   /* Device Reset */
107         Rfce            = 0x08000000,   /* Receive Flow Control Enable */
108         Tfce            = 0x10000000,   /* Transmit Flow Control Enable */
109         Vme             = 0x40000000,   /* VLAN Mode Enable */
110 };
111
112 enum {                                  /* Status */
113         Lu              = 0x00000002,   /* Link Up */
114         Tckok           = 0x00000004,   /* Transmit clock is running */
115         Rbcok           = 0x00000008,   /* Receive clock is running */
116         Txoff           = 0x00000010,   /* Transmission Paused */
117         Tbimode         = 0x00000020,   /* TBI Mode Indication */
118         SpeedMASK       = 0x000000C0,
119         Speed10         = 0x00000000,   /* 10Mb/s */
120         Speed100        = 0x00000040,   /* 100Mb/s */
121         Speed1000       = 0x00000080,   /* 1000Mb/s */
122         Mtxckok         = 0x00000400,   /* MTX clock is running */
123         Pci66           = 0x00000800,   /* PCI Bus speed indication */
124         Bus64           = 0x00001000,   /* PCI Bus width indication */
125 };
126
127 enum {                                  /* Ctrl and Status */
128         Fd              = 0x00000001,   /* Full-Duplex */
129         AsdvMASK        = 0x00000300,
130         Asdv10          = 0x00000000,   /* 10Mb/s */
131         Asdv100         = 0x00000100,   /* 100Mb/s */
132         Asdv1000        = 0x00000200,   /* 1000Mb/s */
133 };
134
135 enum {                                  /* Eecd */
136         Sk              = 0x00000001,   /* Clock input to the EEPROM */
137         Cs              = 0x00000002,   /* Chip Select */
138         Di              = 0x00000004,   /* Data Input to the EEPROM */
139         Do              = 0x00000008,   /* Data Output from the EEPROM */
140 };
141
142 enum {                                  /* Ctrlext */
143         Gpien           = 0x0000000F,   /* General Purpose Interrupt Enables */
144         Swdpinshi       = 0x000000F0,   /* Software Defined Pins - hi nibble */
145         Swdpiohi        = 0x00000F00,   /* Software Defined Pins - I or O */
146         Asdchk          = 0x00001000,   /* ASD Check */
147         Eerst           = 0x00002000,   /* EEPROM Reset */
148         Ips             = 0x00004000,   /* Invert Power State */
149         Spdbyps         = 0x00008000,   /* Speed Select Bypass */
150 };
151
152 enum {                                  /* EEPROM content offsets */
153         Ea              = 0x00,         /* Ethernet Address */
154         Cf              = 0x03,         /* Compatibility Field */
155         Pba             = 0x08,         /* Printed Board Assembly number */
156         Icw1            = 0x0A,         /* Initialization Control Word 1 */
157         Sid             = 0x0B,         /* Subsystem ID */
158         Svid            = 0x0C,         /* Subsystem Vendor ID */
159         Did             = 0x0D,         /* Device ID */
160         Vid             = 0x0E,         /* Vendor ID */
161         Icw2            = 0x0F,         /* Initialization Control Word 2 */
162 };
163
164 enum {                                  /* Mdic */
165         MDIdMASK        = 0x0000FFFF,   /* Data */
166         MDIdSHIFT       = 0,
167         MDIrMASK        = 0x001F0000,   /* PHY Register Address */
168         MDIrSHIFT       = 16,
169         MDIpMASK        = 0x03E00000,   /* PHY Address */
170         MDIpSHIFT       = 21,
171         MDIwop          = 0x04000000,   /* Write Operation */
172         MDIrop          = 0x08000000,   /* Read Operation */
173         MDIready        = 0x10000000,   /* End of Transaction */
174         MDIie           = 0x20000000,   /* Interrupt Enable */
175         MDIe            = 0x40000000,   /* Error */
176 };
177
178 enum {                                  /* Icr, Ics, Ims, Imc */
179         Txdw            = 0x00000001,   /* Transmit Descriptor Written Back */
180         Txqe            = 0x00000002,   /* Transmit Queue Empty */
181         Lsc             = 0x00000004,   /* Link Status Change */
182         Rxseq           = 0x00000008,   /* Receive Sequence Error */
183         Rxdmt0          = 0x00000010,   /* Rdesc Minimum Threshold Reached */
184         Rxo             = 0x00000040,   /* Receiver Overrun */
185         Rxt0            = 0x00000080,   /* Receiver Timer Interrupt */
186         Mdac            = 0x00000200,   /* MDIO Access Completed */
187         Rxcfg           = 0x00000400,   /* Receiving /C/ ordered sets */
188         Gpi0            = 0x00000800,   /* General Purpose Interrupts */
189         Gpi1            = 0x00001000,
190         Gpi2            = 0x00002000,
191         Gpi3            = 0x00004000,
192 };
193
194 enum {                                  /* Txcw */
195         Ane             = 0x80000000,   /* Autonegotiate enable */
196         Np              = 0x00008000,   /* Next Page */
197         As              = 0x00000100,   /* Asymmetric Flow control desired */
198         Ps              = 0x00000080,   /* Pause supported */
199         Hd              = 0x00000040,   /* Half duplex supported */
200         TxcwFd          = 0x00000020,   /* Full Duplex supported */
201 };
202
203 enum {                                  /* Rxcw */
204         Rxword          = 0x0000FFFF,   /* Data from auto-negotiation process */
205         Rxnocarrier     = 0x04000000,   /* Carrier Sense indication */
206         Rxinvalid       = 0x08000000,   /* Invalid Symbol during configuration */
207         Rxchange        = 0x10000000,   /* Change to the Rxword indication */
208         Rxconfig        = 0x20000000,   /* /C/ order set reception indication */
209         Rxsync          = 0x40000000,   /* Lost bit synchronization indication */
210         Anc             = 0x80000000,   /* Auto Negotiation Complete */
211 };
212
213 enum {                                  /* Rctl */
214         Rrst            = 0x00000001,   /* Receiver Software Reset */
215         Ren             = 0x00000002,   /* Receiver Enable */
216         Sbp             = 0x00000004,   /* Store Bad Packets */
217         Upe             = 0x00000008,   /* Unicast Promiscuous Enable */
218         Mpe             = 0x00000010,   /* Multicast Promiscuous Enable */
219         Lpe             = 0x00000020,   /* Long Packet Reception Enable */
220         LbmMASK         = 0x000000C0,   /* Loopback Mode */
221         LbmOFF          = 0x00000000,   /* No Loopback */
222         LbmTBI          = 0x00000040,   /* TBI Loopback */
223         LbmMII          = 0x00000080,   /* GMII/MII Loopback */
224         LbmXCVR         = 0x000000C0,   /* Transceiver Loopback */
225         RdtmsMASK       = 0x00000300,   /* Rdesc Minimum Threshold Size */
226         RdtmsHALF       = 0x00000000,   /* Threshold is 1/2 Rdlen */
227         RdtmsQUARTER    = 0x00000100,   /* Threshold is 1/4 Rdlen */
228         RdtmsEIGHTH     = 0x00000200,   /* Threshold is 1/8 Rdlen */
229         MoMASK          = 0x00003000,   /* Multicast Offset */
230         Bam             = 0x00008000,   /* Broadcast Accept Mode */
231         BsizeMASK       = 0x00030000,   /* Receive Buffer Size */
232         Bsize2048       = 0x00000000,   /* Bsex = 0 */
233         Bsize1024       = 0x00010000,   /* Bsex = 0 */
234         Bsize512        = 0x00020000,   /* Bsex = 0 */
235         Bsize256        = 0x00030000,   /* Bsex = 0 */
236         Bsize16384      = 0x00010000,   /* Bsex = 1 */
237         Vfe             = 0x00040000,   /* VLAN Filter Enable */
238         Cfien           = 0x00080000,   /* Canonical Form Indicator Enable */
239         Cfi             = 0x00100000,   /* Canonical Form Indicator value */
240         Dpf             = 0x00400000,   /* Discard Pause Frames */
241         Pmcf            = 0x00800000,   /* Pass MAC Control Frames */
242         Bsex            = 0x02000000,   /* Buffer Size Extension */
243         Secrc           = 0x04000000,   /* Strip CRC from incoming packet */
244 };
245
246 enum {                                  /* Tctl */
247         Trst            = 0x00000001,   /* Transmitter Software Reset */
248         Ten             = 0x00000002,   /* Transmit Enable */
249         Psp             = 0x00000008,   /* Pad Short Packets */
250         CtMASK          = 0x00000FF0,   /* Collision Threshold */
251         CtSHIFT         = 4,
252         ColdMASK        = 0x003FF000,   /* Collision Distance */
253         ColdSHIFT       = 12,
254         Swxoff          = 0x00400000,   /* Sofware XOFF Transmission */
255         Pbe             = 0x00800000,   /* Packet Burst Enable */
256         Rtlc            = 0x01000000,   /* Re-transmit on Late Collision */
257         Nrtu            = 0x02000000,   /* No Re-transmit on Underrrun */
258 };
259
260 enum {                                  /* [RT]xdctl */
261         PthreshMASK     = 0x0000003F,   /* Prefetch Threshold */
262         PthreshSHIFT    = 0,
263         HthreshMASK     = 0x00003F00,   /* Host Threshold */
264         HthreshSHIFT    = 8,
265         WthreshMASK     = 0x003F0000,   /* Writeback Threshold */
266         WthreshSHIFT    = 16,
267         Gran            = 0x00000000,   /* Granularity */
268         RxGran          = 0x01000000,   /* Granularity */
269 };
270
271 enum {                                  /* Rxcsum */
272         PcssMASK        = 0x000000FF,   /* Packet Checksum Start */
273         PcssSHIFT       = 0,
274         Ipofl           = 0x00000100,   /* IP Checksum Off-load Enable */
275         Tuofl           = 0x00000200,   /* TCP/UDP Checksum Off-load Enable */
276 };
277
278 enum {                                  /* Receive Delay Timer Ring */
279         Fpd             = 0x80000000,   /* Flush partial Descriptor Block */
280 };
281
282 typedef struct Rdesc {                  /* Receive Descriptor */
283         uint    addr[2];
284         ushort  length;
285         ushort  checksum;
286         uchar   status;
287         uchar   errors;
288         ushort  special;
289 } Rdesc;
290
291 enum {                                  /* Rdesc status */
292         Rdd             = 0x01,         /* Descriptor Done */
293         Reop            = 0x02,         /* End of Packet */
294         Ixsm            = 0x04,         /* Ignore Checksum Indication */
295         Vp              = 0x08,         /* Packet is 802.1Q (matched VET) */
296         Tcpcs           = 0x20,         /* TCP Checksum Calculated on Packet */
297         Ipcs            = 0x40,         /* IP Checksum Calculated on Packet */
298         Pif             = 0x80,         /* Passed in-exact filter */
299 };
300
301 enum {                                  /* Rdesc errors */
302         Ce              = 0x01,         /* CRC Error or Alignment Error */
303         Se              = 0x02,         /* Symbol Error */
304         Seq             = 0x04,         /* Sequence Error */
305         Cxe             = 0x10,         /* Carrier Extension Error */
306         Tcpe            = 0x20,         /* TCP/UDP Checksum Error */
307         Ipe             = 0x40,         /* IP Checksum Error */
308         Rxe             = 0x80,         /* RX Data Error */
309 };
310
311 typedef struct Tdesc {                  /* Legacy+Normal Transmit Descriptor */
312         uint    addr[2];
313         uint    control;                /* varies with descriptor type */
314         uint    status;                 /* varies with descriptor type */
315 } Tdesc;
316
317 enum {                                  /* Tdesc control */
318         CsoMASK         = 0x00000F00,   /* Checksum Offset */
319         CsoSHIFT        = 16,
320         Teop            = 0x01000000,   /* End of Packet */
321         Ifcs            = 0x02000000,   /* Insert FCS */
322         Ic              = 0x04000000,   /* Insert Checksum (Dext == 0) */
323         Tse             = 0x04000000,   /* TCP Segmentaion Enable (Dext == 1) */
324         Rs              = 0x08000000,   /* Report Status */
325         Rps             = 0x10000000,   /* Report Status Sent */
326         Dext            = 0x20000000,   /* Extension (!legacy) */
327         Vle             = 0x40000000,   /* VLAN Packet Enable */
328         Ide             = 0x80000000,   /* Interrupt Delay Enable */
329 };
330
331 enum {                                  /* Tdesc status */
332         Tdd             = 0x00000001,   /* Descriptor Done */
333         Ec              = 0x00000002,   /* Excess Collisions */
334         Lc              = 0x00000004,   /* Late Collision */
335         Tu              = 0x00000008,   /* Transmit Underrun */
336         CssMASK         = 0x0000FF00,   /* Checksum Start Field */
337         CssSHIFT        = 8,
338 };
339
340 enum {
341         Nrdesc          = 256,          /* multiple of 8 */
342         Ntdesc          = 256,          /* multiple of 8 */
343         Nblocks         = 4098,         /* total number of blocks to use */
344
345         SBLOCKSIZE      = 2048,
346         JBLOCKSIZE      = 16384,
347
348         NORMAL          = 1,
349         JUMBO           = 2,
350 };
351
352 typedef struct Ctlr Ctlr;
353 typedef struct Ctlr {
354         int     port;
355         Pcidev* pcidev;
356         Ctlr*   next;
357         int     active;
358         int     started;
359         int     id;
360         ushort  eeprom[0x40];
361
362         int*    nic;
363         int     im;                     /* interrupt mask */
364
365         Lock    slock;
366         uint    statistics[Nstatistics];
367
368         Lock    rdlock;
369         Rdesc*  rdba;                   /* receive descriptor base address */
370         Block*  rb[Nrdesc];             /* receive buffers */
371         int     rdh;                    /* receive descriptor head */
372         int     rdt;                    /* receive descriptor tail */
373         Block** freehead;               /* points to long or short head */
374
375         Lock    tdlock;
376         Tdesc*  tdba;                   /* transmit descriptor base address */
377         Block*  tb[Ntdesc];             /* transmit buffers */
378         int     tdh;                    /* transmit descriptor head */
379         int     tdt;                    /* transmit descriptor tail */
380         int     txstalled;              /* count of times unable to send */
381
382         int     txcw;
383         int     fcrtl;
384         int     fcrth;
385
386         ulong   multimask[128];         /* bit mask for multicast addresses */
387 } Ctlr;
388
389 static Ctlr* gc82543ctlrhead;
390 static Ctlr* gc82543ctlrtail;
391
392 static Lock freelistlock;
393 static Block* freeShortHead;
394 static Block* freeJumboHead;
395
396 #define csr32r(c, r)    (*((c)->nic+((r)/4)))
397 #define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
398
399 static void gc82543watchdog(void* arg);
400
401 static void
402 gc82543attach(Ether* edev)
403 {
404         int ctl;
405         Ctlr *ctlr;
406         char name[KNAMELEN];
407
408         /*
409          * To do here:
410          *      one-time stuff;
411          *              adjust queue length depending on speed;
412          *              flow control.
413          *      more needed here...
414          */
415         ctlr = edev->ctlr;
416         lock(&ctlr->slock);
417         if(ctlr->started == 0){
418                 ctlr->started = 1;
419                 snprint(name, KNAMELEN, "#l%d82543", edev->ctlrno);
420                 kproc(name, gc82543watchdog, edev);
421         }
422         unlock(&ctlr->slock);
423
424         ctl = csr32r(ctlr, Rctl)|Ren;
425         csr32w(ctlr, Rctl, ctl);
426         ctl = csr32r(ctlr, Tctl)|Ten;
427         csr32w(ctlr, Tctl, ctl);
428
429         csr32w(ctlr, Ims, ctlr->im);
430 }
431
432 static char* statistics[Nstatistics] = {
433         "CRC Error",
434         "Alignment Error",
435         "Symbol Error",
436         "RX Error",
437         "Missed Packets",
438         "Single Collision",
439         "Excessive Collisions",
440         "Multiple Collision",
441         "Late Collisions",
442         nil,
443         "Collision",
444         "Transmit Underrun",
445         "Defer",
446         "Transmit - No CRS",
447         "Sequence Error",
448         "Carrier Extension Error",
449         "Receive Error Length",
450         nil,
451         "XON Received",
452         "XON Transmitted",
453         "XOFF Received",
454         "XOFF Transmitted",
455         "FC Received Unsupported",
456         "Packets Received (64 Bytes)",
457         "Packets Received (65-127 Bytes)",
458         "Packets Received (128-255 Bytes)",
459         "Packets Received (256-511 Bytes)",
460         "Packets Received (512-1023 Bytes)",
461         "Packets Received (1024-1522 Bytes)",
462         "Good Packets Received",
463         "Broadcast Packets Received",
464         "Multicast Packets Received",
465         "Good Packets Transmitted",
466         nil,
467         "Good Octets Received",
468         nil,
469         "Good Octets Transmitted",
470         nil,
471         nil,
472         nil,
473         "Receive No Buffers",
474         "Receive Undersize",
475         "Receive Fragment",
476         "Receive Oversize",
477         "Receive Jabber",
478         nil,
479         nil,
480         nil,
481         "Total Octets Received",
482         nil,
483         "Total Octets Transmitted",
484         nil,
485         "Total Packets Received",
486         "Total Packets Transmitted",
487         "Packets Transmitted (64 Bytes)",
488         "Packets Transmitted (65-127 Bytes)",
489         "Packets Transmitted (128-255 Bytes)",
490         "Packets Transmitted (256-511 Bytes)",
491         "Packets Transmitted (512-1023 Bytes)",
492         "Packets Transmitted (1024-1522 Bytes)",
493         "Multicast Packets Transmitted",
494         "Broadcast Packets Transmitted",
495         "TCP Segmentation Context Transmitted",
496         "TCP Segmentation Context Fail",
497 };
498
499 static long
500 gc82543ifstat(Ether* edev, void* a, long n, ulong offset)
501 {
502         Ctlr *ctlr;
503         char *p, *s;
504         int i, l, r;
505         uvlong tuvl, ruvl;
506
507         p = smalloc(READSTR);
508
509         ctlr = edev->ctlr;
510         lock(&ctlr->slock);
511         l = 0;
512         for(i = 0; i < Nstatistics; i++){
513                 r = csr32r(ctlr, Statistics+i*4);
514                 if((s = statistics[i]) == nil)
515                         continue;
516                 switch(i){
517                 case Gorcl:
518                 case Gotcl:
519                 case Torl:
520                 case Totl:
521                         ruvl = r;
522                         ruvl += ((uvlong)csr32r(ctlr, Statistics+(i+1)*4))<<32;
523                         tuvl = ruvl;
524                         tuvl += ctlr->statistics[i];
525                         tuvl += ((uvlong)ctlr->statistics[i+1])<<32;
526                         if(tuvl == 0)
527                                 continue;
528                         ctlr->statistics[i] = tuvl;
529                         ctlr->statistics[i+1] = tuvl>>32;
530                         l += snprint(p+l, READSTR-l, "%s: %llud %llud\n",
531                                 s, tuvl, ruvl);
532                         i++;
533                         break;
534
535                 default:
536                         ctlr->statistics[i] += r;
537                         if(ctlr->statistics[i] == 0)
538                                 continue;
539                         l += snprint(p+l, READSTR-l, "%s: %ud %ud\n",
540                                 s, ctlr->statistics[i], r);
541                         break;
542                 }
543         }
544
545         l += snprint(p+l, READSTR-l, "eeprom:");
546         for(i = 0; i < 0x40; i++){
547                 if(i && ((i & 0x07) == 0))
548                         l += snprint(p+l, READSTR-l, "\n       ");
549                 l += snprint(p+l, READSTR-l, " %4.4uX", ctlr->eeprom[i]);
550         }
551
552         snprint(p+l, READSTR-l, "\ntxstalled %d\n", ctlr->txstalled);
553         n = readstr(offset, a, n, p);
554         free(p);
555         unlock(&ctlr->slock);
556
557         return n;
558 }
559
560 static void
561 gc82543promiscuous(void* arg, int on)
562 {
563         int rctl;
564         Ctlr *ctlr;
565         Ether *edev;
566
567         edev = arg;
568         ctlr = edev->ctlr;
569
570         rctl = csr32r(ctlr, Rctl);
571         rctl &= ~MoMASK;                /* make sure we're using bits 47:36 */
572         if(on)
573                 rctl |= Upe|Mpe;
574         else
575                 rctl &= ~(Upe|Mpe);
576         csr32w(ctlr, Rctl, rctl);
577 }
578
579 static void
580 gc82543multicast(void* arg, uchar* addr, int on)
581 {
582         int bit, x;
583         Ctlr *ctlr;
584         Ether *edev;
585
586         edev = arg;
587         ctlr = edev->ctlr;
588         x = addr[5]>>1;
589         bit = ((addr[5] & 1)<<4)|(addr[4]>>4);
590         if(on)
591                 ctlr->multimask[x] |= 1<<bit;
592         else
593                 ctlr->multimask[x] &= ~(1<<bit);
594         
595         csr32w(ctlr, Mta+x*4, ctlr->multimask[x]);
596 }
597
598 static long
599 gc82543ctl(Ether* edev, void* buf, long n)
600 {
601         Cmdbuf *cb;
602         Ctlr *ctlr;
603         int ctrl, i, r;
604
605         ctlr = edev->ctlr;
606         if(ctlr == nil)
607                 error(Enonexist);
608
609         lock(&ctlr->slock);
610         r = 0;
611         cb = parsecmd(buf, n);
612         if(cb->nf < 2)
613                 r = -1;
614         else if(cistrcmp(cb->f[0], "auto") == 0){
615                 ctrl = csr32r(ctlr, Ctrl);
616                 if(cistrcmp(cb->f[1], "off") == 0){
617                         csr32w(ctlr, Txcw, ctlr->txcw & ~Ane);
618                         ctrl |= (Slu|Fd);
619                         if(ctlr->txcw & As)
620                                 ctrl |= Rfce;
621                         if(ctlr->txcw & Ps)
622                                 ctrl |= Tfce;
623                         csr32w(ctlr, Ctrl, ctrl);
624                 }
625                 else if(cistrcmp(cb->f[1], "on") == 0){
626                         csr32w(ctlr, Txcw, ctlr->txcw);
627                         ctrl &= ~(Slu|Fd);
628                         csr32w(ctlr, Ctrl, ctrl);
629                 }
630                 else
631                         r = -1;
632         }
633         else if(cistrcmp(cb->f[0], "clear") == 0){
634                 if(cistrcmp(cb->f[1], "stats") == 0){
635                         for(i = 0; i < Nstatistics; i++)
636                                 ctlr->statistics[i] = 0;
637                 }
638                 else
639                         r = -1;
640         }
641         else
642                 r = -1;
643         unlock(&ctlr->slock);
644
645         free(cb);
646         return (r == 0) ? n : r;
647 }
648
649 static void
650 gc82543txinit(Ctlr* ctlr)
651 {
652         int i;
653         int tdsize;
654         Block *bp, **bpp;
655
656         tdsize = ROUND(Ntdesc*sizeof(Tdesc), 4096);
657
658         if(ctlr->tdba == nil)
659                 ctlr->tdba = xspanalloc(tdsize, 32, 0);
660
661         for(i = 0; i < Ntdesc; i++){
662                 bpp = &ctlr->tb[i];
663                 bp = *bpp;
664                 if(bp != nil){
665                         *bpp = nil;
666                         freeb(bp);
667                 }
668                 memset(&ctlr->tdba[i], 0, sizeof(Tdesc));
669         }
670
671         csr32w(ctlr, Tdbal, PCIWADDR(ctlr->tdba));
672         csr32w(ctlr, Tdbah, 0);
673         csr32w(ctlr, Tdlen, Ntdesc*sizeof(Tdesc));
674
675         /*
676          * set the ring head and tail pointers.
677          */
678         ctlr->tdh = 0;
679         csr32w(ctlr, Tdh, ctlr->tdh);
680         ctlr->tdt = 0;
681         csr32w(ctlr, Tdt, ctlr->tdt);
682
683         csr32w(ctlr, Tipg, (6<<20)|(8<<10)|6);
684         csr32w(ctlr, Tidv, 128);
685         csr32w(ctlr, Ait, 0);
686         csr32w(ctlr, Txdmac, 0);
687         csr32w(ctlr, Txdctl, Gran|(4<<WthreshSHIFT)|(1<<HthreshSHIFT)|16);
688         csr32w(ctlr, Tctl, (0x0F<<CtSHIFT)|Psp|(6<<ColdSHIFT));
689
690         ctlr->im |= Txdw;
691 }
692
693 static void
694 gc82543transmit(Ether* edev)
695 {
696         Block *bp, **bpp;
697         Ctlr *ctlr;
698         Tdesc *tdesc;
699         int tdh, tdt, s;
700
701         ctlr = edev->ctlr;
702
703         ilock(&ctlr->tdlock);
704         tdh = ctlr->tdh;
705         for(;;){
706                 /*
707                  * Free any completed packets
708                  */
709                 tdesc = &ctlr->tdba[tdh];
710                 if(!(tdesc->status & Tdd))
711                         break;
712                 memset(tdesc, 0, sizeof(Tdesc));
713                 bpp = &ctlr->tb[tdh];
714                 bp = *bpp;
715                 if(bp != nil){
716                         *bpp = nil;
717                         freeb(bp);
718                 }
719                 tdh = NEXT(tdh, Ntdesc);
720         }
721         ctlr->tdh = tdh;
722         s = csr32r(ctlr, Status);
723
724         /*
725          * Try to fill the ring back up
726          * but only if link is up and transmission isn't paused.
727          */
728         if((s & (Txoff|Lu)) == Lu){
729                 tdt = ctlr->tdt;
730                 while(NEXT(tdt, Ntdesc) != tdh){
731                         if((bp = qget(edev->oq)) == nil)
732                                 break;
733
734                         tdesc = &ctlr->tdba[tdt];
735                         tdesc->addr[0] = PCIWADDR(bp->rp);
736                         tdesc->control = Ide|Rs|Ifcs|Teop|BLEN(bp);
737                         ctlr->tb[tdt] = bp;
738                         tdt = NEXT(tdt, Ntdesc);
739                 }
740
741                 if(tdt != ctlr->tdt){
742                         ctlr->tdt = tdt;
743                         csr32w(ctlr, Tdt, tdt);
744                 }
745         }
746         else
747                 ctlr->txstalled++;
748
749         iunlock(&ctlr->tdlock);
750 }
751
752 static Block *
753 gc82543allocb(Ctlr* ctlr)
754 {
755         Block *bp;
756
757         ilock(&freelistlock);
758         if((bp = *(ctlr->freehead)) != nil){
759                 *(ctlr->freehead) = bp->next;
760                 bp->next = nil;
761         }
762         iunlock(&freelistlock);
763         return bp;
764 }
765
766 static void
767 gc82543replenish(Ctlr* ctlr)
768 {
769         int rdt;
770         Block *bp;
771         Rdesc *rdesc;
772
773         ilock(&ctlr->rdlock);
774         rdt = ctlr->rdt;
775         while(NEXT(rdt, Nrdesc) != ctlr->rdh){
776                 rdesc = &ctlr->rdba[rdt];
777                 if(ctlr->rb[rdt] == nil){
778                         bp = gc82543allocb(ctlr);
779                         if(bp == nil){
780                                 iprint("no available buffers\n");
781                                 break;
782                         }
783                         ctlr->rb[rdt] = bp;
784                         rdesc->addr[0] = PCIWADDR(bp->rp);
785                         rdesc->addr[1] = 0;
786                 }
787                 coherence();
788                 rdesc->status = 0;
789                 rdt = NEXT(rdt, Nrdesc);
790         }
791         ctlr->rdt = rdt;
792         csr32w(ctlr, Rdt, rdt);
793         iunlock(&ctlr->rdlock);
794 }
795
796 static void
797 gc82543rxinit(Ctlr* ctlr)
798 {
799         int rdsize, i;
800
801         csr32w(ctlr, Rctl, Dpf|Bsize2048|Bam|RdtmsHALF);
802
803         /*
804          * Allocate the descriptor ring and load its
805          * address and length into the NIC.
806          */
807         rdsize = ROUND(Nrdesc*sizeof(Rdesc), 4096);
808         if(ctlr->rdba == nil)
809                 ctlr->rdba = xspanalloc(rdsize, 32, 0);
810         memset(ctlr->rdba, 0, rdsize);
811
812         ctlr->rdh = 0;
813         ctlr->rdt = 0;
814
815         csr32w(ctlr, Rdtr, Fpd|64);
816         csr32w(ctlr, Rdbal, PCIWADDR(ctlr->rdba));
817         csr32w(ctlr, Rdbah, 0);
818         csr32w(ctlr, Rdlen, Nrdesc*sizeof(Rdesc));
819         csr32w(ctlr, Rdh, 0);
820         csr32w(ctlr, Rdt, 0);
821         for(i = 0; i < Nrdesc; i++){
822                 if(ctlr->rb[i] != nil){
823                         freeb(ctlr->rb[i]);
824                         ctlr->rb[i] = nil;
825                 }
826         }
827         gc82543replenish(ctlr);
828
829         csr32w(ctlr, Rxdctl, RxGran|(8<<WthreshSHIFT)|(4<<HthreshSHIFT)|1);
830         ctlr->im |= Rxt0|Rxo|Rxdmt0|Rxseq;
831 }
832
833 static void
834 gc82543recv(Ether* edev, int icr)
835 {
836         Block *bp;
837         Ctlr *ctlr;
838         Rdesc *rdesc;
839         int rdh;
840
841         ctlr = edev->ctlr;
842
843         rdh = ctlr->rdh;
844         for(;;){
845                 rdesc = &ctlr->rdba[rdh];
846
847                 if(!(rdesc->status & Rdd))
848                         break;
849
850                 if((rdesc->status & Reop) && rdesc->errors == 0){
851                         bp = ctlr->rb[rdh];
852                         ctlr->rb[rdh] = nil;
853                         bp->wp += rdesc->length;
854                         bp->next = nil;
855                         etheriq(edev, bp, 1);
856                 }
857
858                 if(ctlr->rb[rdh] != nil){
859                         /* either non eop packet, or error */
860                         freeb(ctlr->rb[rdh]);
861                         ctlr->rb[rdh] = nil;
862                 }
863                 memset(rdesc, 0, sizeof(Rdesc));
864                 coherence();
865                 rdh = NEXT(rdh, Nrdesc);
866         }
867         ctlr->rdh = rdh;
868
869         if(icr & Rxdmt0)
870                 gc82543replenish(ctlr);
871 }
872
873 static void
874 freegc82543short(Block *bp)
875 {
876         ilock(&freelistlock);
877         /* reset read/write pointer to proper positions */
878         bp->rp = bp->lim - ROUND(SBLOCKSIZE, BLOCKALIGN);
879         bp->wp = bp->rp;
880         bp->next = freeShortHead;
881         freeShortHead = bp;
882         iunlock(&freelistlock);
883 }
884
885 static void
886 freegc82532jumbo(Block *bp)
887 {
888         ilock(&freelistlock);
889         /* reset read/write pointer to proper positions */
890         bp->rp = bp->lim - ROUND(JBLOCKSIZE, BLOCKALIGN);
891         bp->wp = bp->rp;
892         bp->next = freeJumboHead;
893         freeJumboHead = bp;
894         iunlock(&freelistlock);
895 }
896
897 static void
898 linkintr(Ctlr* ctlr)
899 {
900         int ctrl;
901
902         ctrl = csr32r(ctlr, Ctrl);
903
904         if((ctrl & Swdpin1) ||
905           ((csr32r(ctlr, Rxcw) & Rxconfig) && !(csr32r(ctlr, Txcw) & Ane))){
906                 csr32w(ctlr, Txcw, ctlr->txcw);
907                 ctrl &= ~(Slu|Fd|Frcdplx);
908                 csr32w(ctlr, Ctrl, ctrl);
909         }
910 }
911
912 static void
913 gc82543interrupt(Ureg*, void* arg)
914 {
915         Ctlr *ctlr;
916         Ether *edev;
917         int icr;
918
919         edev = arg;
920         ctlr = edev->ctlr;
921
922         while((icr = csr32r(ctlr, Icr) & ctlr->im) != 0){
923                 /*
924                  * Link status changed.
925                  */
926                 if(icr & (Lsc|Rxseq))
927                         linkintr(ctlr);
928
929                 /*
930                  * Process recv buffers.
931                  */
932                 gc82543recv(edev, icr);
933
934                 /*
935                  * Refill transmit ring and free packets.
936                  */
937                 gc82543transmit(edev);
938         }
939 }
940
941 static int
942 gc82543init(Ether* edev)
943 {
944         int csr, i;
945         Block *bp;
946         Ctlr *ctlr;
947
948         ctlr = edev->ctlr;
949
950         /*
951          * Allocate private buffer pool to use for receiving packets.
952          */
953         ilock(&freelistlock);
954         if (ctlr->freehead == nil){
955                 for(i = 0; i < Nblocks; i++){
956                         bp = iallocb(SBLOCKSIZE);
957                         if(bp != nil){
958                                 bp->next = freeShortHead;
959                                 bp->free = freegc82543short;
960                                 freeShortHead = bp;
961                         }
962                         else{
963                                 print("82543gc: no memory\n");
964                                 break;
965                         }
966                 }
967                 ctlr->freehead = &freeShortHead;
968         }
969         iunlock(&freelistlock);
970
971         /*
972          * Set up the receive addresses.
973          * There are 16 addresses. The first should be the MAC address.
974          * The others are cleared and not marked valid (MS bit of Rah).
975          */
976         csr = (edev->ea[3]<<24)|(edev->ea[2]<<16)|(edev->ea[1]<<8)|edev->ea[0];
977         csr32w(ctlr, Ral, csr);
978         csr = 0x80000000|(edev->ea[5]<<8)|edev->ea[4];
979         csr32w(ctlr, Rah, csr);
980         for(i = 1; i < 16; i++){
981                 csr32w(ctlr, Ral+i*8, 0);
982                 csr32w(ctlr, Rah+i*8, 0);
983         }
984
985         /*
986          * Clear the Multicast Table Array.
987          * It's a 4096 bit vector accessed as 128 32-bit registers.
988          */
989         for(i = 0; i < 128; i++)
990                 csr32w(ctlr, Mta+i*4, 0);
991
992         gc82543txinit(ctlr);
993         gc82543rxinit(ctlr);
994
995         return 0;
996 }
997
998 static int
999 at93c46io(Ctlr* ctlr, char* op, int data)
1000 {
1001         char *lp, *p;
1002         int i, loop, eecd, r;
1003
1004         eecd = csr32r(ctlr, Eecd);
1005
1006         r = 0;
1007         loop = -1;
1008         lp = nil;
1009         for(p = op; *p != '\0'; p++){
1010                 switch(*p){
1011                 default:
1012                         return -1;
1013                 case ' ':
1014                         continue;
1015                 case ':':                       /* start of loop */
1016                         if(lp != nil){
1017                                 if(p != (lp+1) || loop != 7)
1018                                         return -1;
1019                                 lp = p;
1020                                 loop = 15;
1021                                 continue;
1022                         }
1023                         lp = p;
1024                         loop = 7;
1025                         continue;
1026                 case ';':                       /* end of loop */
1027                         if(lp == nil)
1028                                 return -1;
1029                         loop--;
1030                         if(loop >= 0)
1031                                 p = lp;
1032                         else
1033                                 lp = nil;
1034                         continue;
1035                 case 'C':                       /* assert clock */
1036                         eecd |= Sk;
1037                         break;
1038                 case 'c':                       /* deassert clock */
1039                         eecd &= ~Sk;
1040                         break;
1041                 case 'D':                       /* next bit in 'data' byte */
1042                         if(loop < 0)
1043                                 return -1;
1044                         if(data & (1<<loop))
1045                                 eecd |= Di;
1046                         else
1047                                 eecd &= ~Di;
1048                         break;
1049                 case 'O':                       /* collect data output */
1050                         i = (csr32r(ctlr, Eecd) & Do) != 0;
1051                         if(loop >= 0)
1052                                 r |= (i<<loop);
1053                         else
1054                                 r = i;
1055                         continue;
1056                 case 'I':                       /* assert data input */
1057                         eecd |= Di;
1058                         break;
1059                 case 'i':                       /* deassert data input */
1060                         eecd &= ~Di;
1061                         break;
1062                 case 'S':                       /* enable chip select */
1063                         eecd |= Cs;
1064                         break;
1065                 case 's':                       /* disable chip select */
1066                         eecd &= ~Cs;
1067                         break;
1068                 }
1069                 csr32w(ctlr, Eecd, eecd);
1070                 microdelay(1);
1071         }
1072         if(loop >= 0)
1073                 return -1;
1074         return r;
1075 }
1076
1077 static int
1078 at93c46r(Ctlr* ctlr)
1079 {
1080         ushort sum;
1081         int addr, data;
1082
1083         sum = 0;
1084         for(addr = 0; addr < 0x40; addr++){
1085                 /*
1086                  * Read a word at address 'addr' from the Atmel AT93C46
1087                  * 3-Wire Serial EEPROM or compatible. The EEPROM access is
1088                  * controlled by 4 bits in Eecd. See the AT93C46 datasheet
1089                  * for protocol details.
1090                  */
1091                 if(at93c46io(ctlr, "S ICc :DCc;", (0x02<<6)|addr) != 0)
1092                         break;
1093                 data = at93c46io(ctlr, "::COc;", 0);
1094                 at93c46io(ctlr, "sic", 0);
1095                 ctlr->eeprom[addr] = data;
1096                 sum += data;
1097         }
1098
1099         return sum;
1100 }
1101
1102 static void
1103 gc82543detach(Ctlr* ctlr)
1104 {
1105         /*
1106          * Perform a device reset to get the chip back to the
1107          * power-on state, followed by an EEPROM reset to read
1108          * the defaults for some internal registers.
1109          */
1110         csr32w(ctlr, Imc, ~0);
1111         csr32w(ctlr, Rctl, 0);
1112         csr32w(ctlr, Tctl, 0);
1113
1114         delay(10);
1115
1116         csr32w(ctlr, Ctrl, Devrst);
1117         while(csr32r(ctlr, Ctrl) & Devrst)
1118                 ;
1119
1120         csr32w(ctlr, Ctrlext, Eerst);
1121         while(csr32r(ctlr, Ctrlext) & Eerst)
1122                 ;
1123
1124         csr32w(ctlr, Imc, ~0);
1125         while(csr32r(ctlr, Icr))
1126                 ;
1127 }
1128
1129 static void
1130 gc82543checklink(Ctlr* ctlr)
1131 {
1132         int ctrl, status, rxcw;
1133
1134         ctrl = csr32r(ctlr, Ctrl);
1135         status = csr32r(ctlr, Status);
1136         rxcw = csr32r(ctlr, Rxcw);
1137
1138         if(!(status & Lu)){
1139                 if(!(ctrl & (Swdpin1|Slu)) && !(rxcw & Rxconfig)){
1140                         csr32w(ctlr, Txcw, ctlr->txcw & ~Ane);
1141                         ctrl |= (Slu|Fd);
1142                         if(ctlr->txcw & As)
1143                                 ctrl |= Rfce;
1144                         if(ctlr->txcw & Ps)
1145                                 ctrl |= Tfce;
1146                         csr32w(ctlr, Ctrl, ctrl);
1147                 }
1148         }
1149         else if((ctrl & Slu) && (rxcw & Rxconfig)){
1150                 csr32w(ctlr, Txcw, ctlr->txcw);
1151                 ctrl &= ~(Slu|Fd);
1152                 csr32w(ctlr, Ctrl, ctrl);
1153         }
1154 }
1155
1156 static void
1157 gc82543shutdown(Ether* ether)
1158 {
1159         gc82543detach(ether->ctlr);
1160 }
1161
1162 static int
1163 gc82543reset(Ctlr* ctlr)
1164 {
1165         int ctl;
1166         int te;
1167
1168         /*
1169          * Read the EEPROM, validate the checksum
1170          * then get the device back to a power-on state.
1171          */
1172         if(at93c46r(ctlr) != 0xBABA)
1173                 return -1;
1174
1175         gc82543detach(ctlr);
1176
1177         te = ctlr->eeprom[Icw2];
1178         if((te & 0x3000) == 0){
1179                 ctlr->fcrtl = 0x00002000;
1180                 ctlr->fcrth = 0x00004000;
1181                 ctlr->txcw = Ane|TxcwFd;
1182         }
1183         else if((te & 0x3000) == 0x2000){
1184                 ctlr->fcrtl = 0;
1185                 ctlr->fcrth = 0;
1186                 ctlr->txcw = Ane|TxcwFd|As;
1187         }
1188         else{
1189                 ctlr->fcrtl = 0x00002000;
1190                 ctlr->fcrth = 0x00004000;
1191                 ctlr->txcw = Ane|TxcwFd|As|Ps;
1192         }
1193
1194         csr32w(ctlr, Txcw, ctlr->txcw);
1195
1196         csr32w(ctlr, Ctrlext, (te & 0x00f0)<<4);
1197
1198         csr32w(ctlr, Tctl, csr32r(ctlr, Tctl)|(64<<ColdSHIFT));
1199
1200         te = ctlr->eeprom[Icw1];
1201         ctl = ((te & 0x01E0)<<17)|(te & 0x0010)<<3;
1202         csr32w(ctlr, Ctrl, ctl);
1203
1204         delay(10);
1205
1206         /*
1207          * Flow control - values from the datasheet.
1208          */
1209         csr32w(ctlr, Fcal, 0x00C28001);
1210         csr32w(ctlr, Fcah, 0x00000100);
1211         csr32w(ctlr, Fct, 0x00008808);
1212         csr32w(ctlr, Fcttv, 0x00000100);
1213
1214         csr32w(ctlr, Fcrtl, ctlr->fcrtl);
1215         csr32w(ctlr, Fcrth, ctlr->fcrth);
1216
1217         ctlr->im = Lsc;
1218         gc82543checklink(ctlr);
1219
1220         return 0;
1221 }
1222
1223 static void
1224 gc82543watchdog(void* arg)
1225 {
1226         Ether *edev;
1227         Ctlr *ctlr;
1228
1229         edev = arg;
1230         while(waserror())
1231                 ;
1232         for(;;){
1233                 tsleep(&up->sleep, return0, 0, 1000);
1234                 ctlr = edev->ctlr;
1235                 if(ctlr == nil)
1236                         break;
1237
1238                 gc82543checklink(ctlr);
1239                 gc82543replenish(ctlr);
1240         }
1241         print("%s: exiting\n", up->text);
1242         pexit("disabled", 1);
1243 }
1244
1245 static void
1246 gc82543pci(void)
1247 {
1248         int cls;
1249         void *mem;
1250         Pcidev *p;
1251         Ctlr *ctlr;
1252
1253         p = nil;
1254         while(p = pcimatch(p, 0, 0)){
1255                 if(p->ccrb != 0x02 || p->ccru != 0)
1256                         continue;
1257
1258                 switch((p->did<<16)|p->vid){
1259                 case (0x1000<<16)|0x8086:       /* LSI L2A1157 (82542) */
1260                 case (0x1004<<16)|0x8086:       /* Intel PRO/1000 T */
1261                 case (0x1008<<16)|0x8086:       /* Intel PRO/1000 XT */
1262                 default:
1263                         continue;
1264                 case (0x1001<<16)|0x8086:       /* Intel PRO/1000 F */
1265                         break;
1266                 }
1267
1268                 ctlr = malloc(sizeof(Ctlr));
1269                 if(ctlr == nil){
1270                         print("82543gc: can't allocate memory\n");
1271                         continue;
1272                 }
1273                 mem = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
1274                 if(mem == 0){
1275                         print("82543gc: can't map %8.8luX\n", p->mem[0].bar);
1276                         free(ctlr);
1277                         continue;
1278                 }
1279                 cls = pcicfgr8(p, PciCLS);
1280                 switch(cls){
1281                 case 0x08:
1282                 case 0x10:
1283                         break;
1284                 default:
1285                         print("82543gc: p->cls %#ux, setting to 0x10\n", p->cls);
1286                         p->cls = 0x10;
1287                         pcicfgw8(p, PciCLS, p->cls);
1288                 }
1289                 ctlr->port = p->mem[0].bar & ~0x0F;
1290                 ctlr->pcidev = p;
1291                 ctlr->id = (p->did<<16)|p->vid;
1292                 ctlr->nic = mem;
1293
1294                 if(gc82543reset(ctlr)){
1295                         free(ctlr);
1296                         continue;
1297                 }
1298
1299                 if(gc82543ctlrhead != nil)
1300                         gc82543ctlrtail->next = ctlr;
1301                 else
1302                         gc82543ctlrhead = ctlr;
1303                 gc82543ctlrtail = ctlr;
1304         }
1305 }
1306
1307 static int
1308 gc82543pnp(Ether* edev)
1309 {
1310         int i;
1311         Ctlr *ctlr;
1312         uchar ea[Eaddrlen];
1313
1314         if(gc82543ctlrhead == nil)
1315                 gc82543pci();
1316
1317         /*
1318          * Any adapter matches if no edev->port is supplied,
1319          * otherwise the ports must match.
1320          */
1321         for(ctlr = gc82543ctlrhead; ctlr != nil; ctlr = ctlr->next){
1322                 if(ctlr->active)
1323                         continue;
1324                 if(edev->port == 0 || edev->port == ctlr->port){
1325                         ctlr->active = 1;
1326                         break;
1327                 }
1328         }
1329         if(ctlr == nil)
1330                 return -1;
1331
1332         edev->ctlr = ctlr;
1333         edev->port = ctlr->port;
1334         edev->irq = ctlr->pcidev->intl;
1335         edev->tbdf = ctlr->pcidev->tbdf;
1336         edev->mbps = 1000;
1337
1338         /*
1339          * Check if the adapter's station address is to be overridden.
1340          * If not, read it from the EEPROM and set in ether->ea prior to
1341          * loading the station address in the hardware.
1342          */
1343         memset(ea, 0, Eaddrlen);
1344         if(memcmp(ea, edev->ea, Eaddrlen) == 0){
1345                 for(i = Ea; i < Eaddrlen/2; i++){
1346                         edev->ea[2*i] = ctlr->eeprom[i];
1347                         edev->ea[2*i+1] = ctlr->eeprom[i]>>8;
1348                 }
1349         }
1350         gc82543init(edev);
1351
1352         /*
1353          * Linkage to the generic ethernet driver.
1354          */
1355         edev->attach = gc82543attach;
1356         edev->transmit = gc82543transmit;
1357         edev->interrupt = gc82543interrupt;
1358         edev->ifstat = gc82543ifstat;
1359         edev->shutdown = gc82543shutdown;
1360         edev->ctl = gc82543ctl;
1361         edev->arg = edev;
1362         edev->promiscuous = gc82543promiscuous;
1363         edev->multicast = gc82543multicast;
1364
1365         return 0;
1366 }
1367
1368 void
1369 ether82543gclink(void)
1370 {
1371         addethercard("82543GC", gc82543pnp);
1372 }