]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/ether8169.c
kernel: fix inproper use of malloc/smalloc
[plan9front.git] / sys / src / 9 / pc / ether8169.c
1 /*
2  * Realtek RTL8110S/8169S Gigabit Ethernet Controllers.
3  * Mostly there. There are some magic register values used
4  * which are not described in any datasheet or driver but seem
5  * to be necessary.
6  * No tuning has been done. Only tested on an RTL8110S, there
7  * are slight differences between the chips in the series so some
8  * tweaks may be needed.
9  */
10 #include "u.h"
11 #include "../port/lib.h"
12 #include "mem.h"
13 #include "dat.h"
14 #include "fns.h"
15 #include "io.h"
16 #include "../port/error.h"
17 #include "../port/netif.h"
18
19 #include "etherif.h"
20 #include "ethermii.h"
21
22 enum {                                  /* registers */
23         Idr0            = 0x00,         /* MAC address */
24         Mar0            = 0x08,         /* Multicast address */
25         Dtccr           = 0x10,         /* Dump Tally Counter Command */
26         Tnpds           = 0x20,         /* Transmit Normal Priority Descriptors */
27         Thpds           = 0x28,         /* Transmit High Priority Descriptors */
28         Flash           = 0x30,         /* Flash Memory Read/Write */
29         Erbcr           = 0x34,         /* Early Receive Byte Count */
30         Ersr            = 0x36,         /* Early Receive Status */
31         Cr              = 0x37,         /* Command Register */
32         Tppoll          = 0x38,         /* Transmit Priority Polling */
33         Imr             = 0x3C,         /* Interrupt Mask */
34         Isr             = 0x3E,         /* Interrupt Status */
35         Tcr             = 0x40,         /* Transmit Configuration */
36         Rcr             = 0x44,         /* Receive Configuration */
37         Tctr            = 0x48,         /* Timer Count */
38         Mpc             = 0x4C,         /* Missed Packet Counter */
39         Cr9346          = 0x50,         /* 9346 Command Register */
40         Config0         = 0x51,         /* Configuration Register 0 */
41         Config1         = 0x52,         /* Configuration Register 1 */
42         Config2         = 0x53,         /* Configuration Register 2 */
43         Config3         = 0x54,         /* Configuration Register 3 */
44         Config4         = 0x55,         /* Configuration Register 4 */
45         Config5         = 0x56,         /* Configuration Register 5 */
46         Timerint        = 0x58,         /* Timer Interrupt */
47         Mulint          = 0x5C,         /* Multiple Interrupt Select */
48         Phyar           = 0x60,         /* PHY Access */
49         Tbicsr0         = 0x64,         /* TBI Control and Status */
50         Tbianar         = 0x68,         /* TBI Auto-Negotiation Advertisment */
51         Tbilpar         = 0x6A,         /* TBI Auto-Negotiation Link Partner */
52         Phystatus       = 0x6C,         /* PHY Status */
53
54         Rms             = 0xDA,         /* Receive Packet Maximum Size */
55         Cplusc          = 0xE0,         /* C+ Command */
56         Coal            = 0xE2,         /* Interrupt Mitigation (Coalesce) */
57         Rdsar           = 0xE4,         /* Receive Descriptor Start Address */
58         Etx             = 0xEC,         /* Early Transmit Threshold */
59 };
60
61 enum {                                  /* Dtccr */
62         Cmd             = 0x00000008,   /* Command */
63 };
64
65 enum {                                  /* Cr */
66         Te              = 0x04,         /* Transmitter Enable */
67         Re              = 0x08,         /* Receiver Enable */
68         Rst             = 0x10,         /* Software Reset */
69 };
70
71 enum {                                  /* Tppoll */
72         Fswint          = 0x01,         /* Forced Software Interrupt */
73         Npq             = 0x40,         /* Normal Priority Queue polling */
74         Hpq             = 0x80,         /* High Priority Queue polling */
75 };
76
77 enum {                                  /* Imr/Isr */
78         Rok             = 0x0001,       /* Receive OK */
79         Rer             = 0x0002,       /* Receive Error */
80         Tok             = 0x0004,       /* Transmit OK */
81         Ter             = 0x0008,       /* Transmit Error */
82         Rdu             = 0x0010,       /* Receive Descriptor Unavailable */
83         Punlc           = 0x0020,       /* Packet Underrun or Link Change */
84         Fovw            = 0x0040,       /* Receive FIFO Overflow */
85         Tdu             = 0x0080,       /* Transmit Descriptor Unavailable */
86         Swint           = 0x0100,       /* Software Interrupt */
87         Timeout         = 0x4000,       /* Timer */
88         Serr            = 0x8000,       /* System Error */
89 };
90
91 enum {                                  /* Tcr */
92         MtxdmaSHIFT     = 8,            /* Max. DMA Burst Size */
93         MtxdmaMASK      = 0x00000700,
94         Mtxdmaunlimited = 0x00000700,
95         Acrc            = 0x00010000,   /* Append CRC (not) */
96         Lbk0            = 0x00020000,   /* Loopback Test 0 */
97         Lbk1            = 0x00040000,   /* Loopback Test 1 */
98         Ifg2            = 0x00080000,   /* Interframe Gap 2 */
99         HwveridSHIFT    = 23,           /* Hardware Version ID */
100         HwveridMASK     = 0x7C800000,
101         Macv01          = 0x00000000,   /* RTL8169 */
102         Macv02          = 0x00800000,   /* RTL8169S/8110S */
103         Macv03          = 0x04000000,   /* RTL8169S/8110S */
104         Macv04          = 0x10000000,   /* RTL8169SB/8110SB */
105         Macv05          = 0x18000000,   /* RTL8169SC/8110SC */
106         Macv07          = 0x24800000,   /* RTL8102e */
107         Macv07a         = 0x34800000,   /* RTL8102e */
108         Macv11          = 0x30000000,   /* RTL8168B/8111B */
109         Macv12          = 0x38000000,   /* RTL8169B/8111B */
110         Macv12a         = 0x3c000000,   /* RTL8169C/8111C */
111         Macv13          = 0x34000000,   /* RTL8101E */
112         Macv14          = 0x30800000,   /* RTL8100E */
113         Macv15          = 0x38800000,   /* RTL8100E */
114 //      Macv19          = 0x3c000000,   /* dup Macv12a: RTL8111c-gr */
115         Macv25          = 0x28000000,   /* RTL8168D */
116         Ifg0            = 0x01000000,   /* Interframe Gap 0 */
117         Ifg1            = 0x02000000,   /* Interframe Gap 1 */
118 };
119
120 enum {                                  /* Rcr */
121         Aap             = 0x00000001,   /* Accept All Packets */
122         Apm             = 0x00000002,   /* Accept Physical Match */
123         Am              = 0x00000004,   /* Accept Multicast */
124         Ab              = 0x00000008,   /* Accept Broadcast */
125         Ar              = 0x00000010,   /* Accept Runt */
126         Aer             = 0x00000020,   /* Accept Error */
127         Sel9356         = 0x00000040,   /* 9356 EEPROM used */
128         MrxdmaSHIFT     = 8,            /* Max. DMA Burst Size */
129         MrxdmaMASK      = 0x00000700,
130         Mrxdmaunlimited = 0x00000700,
131         RxfthSHIFT      = 13,           /* Receive Buffer Length */
132         RxfthMASK       = 0x0000E000,
133         Rxfth256        = 0x00008000,
134         Rxfthnone       = 0x0000E000,
135         Rer8            = 0x00010000,   /* Accept Error Packets > 8 bytes */
136         MulERINT        = 0x01000000,   /* Multiple Early Interrupt Select */
137 };
138
139 enum {                                  /* Cr9346 */
140         Eedo            = 0x01,         /* */
141         Eedi            = 0x02,         /* */
142         Eesk            = 0x04,         /* */
143         Eecs            = 0x08,         /* */
144         Eem0            = 0x40,         /* Operating Mode */
145         Eem1            = 0x80,
146 };
147
148 enum {                                  /* Phyar */
149         DataMASK        = 0x0000FFFF,   /* 16-bit GMII/MII Register Data */
150         DataSHIFT       = 0,
151         RegaddrMASK     = 0x001F0000,   /* 5-bit GMII/MII Register Address */
152         RegaddrSHIFT    = 16,
153         Flag            = 0x80000000,   /* */
154 };
155
156 enum {                                  /* Phystatus */
157         Fd              = 0x01,         /* Full Duplex */
158         Linksts         = 0x02,         /* Link Status */
159         Speed10         = 0x04,         /* */
160         Speed100        = 0x08,         /* */
161         Speed1000       = 0x10,         /* */
162         Rxflow          = 0x20,         /* */
163         Txflow          = 0x40,         /* */
164         Entbi           = 0x80,         /* */
165 };
166
167 enum {                                  /* Cplusc */
168         Txenb           = 0x0001,       /* enable C+ transmit mode */
169         Rxenb           = 0x0002,       /* enable C+ receive mode */
170         Mulrw           = 0x0008,       /* PCI Multiple R/W Enable */
171         Dac             = 0x0010,       /* PCI Dual Address Cycle Enable */
172         Rxchksum        = 0x0020,       /* Receive Checksum Offload Enable */
173         Rxvlan          = 0x0040,       /* Receive VLAN De-tagging Enable */
174         Endian          = 0x0200,       /* Endian Mode */
175 };
176
177 typedef struct D D;                     /* Transmit/Receive Descriptor */
178 struct D {
179         u32int  control;
180         u32int  vlan;
181         u32int  addrlo;
182         u32int  addrhi;
183 };
184
185 enum {                                  /* Transmit Descriptor control */
186         TxflMASK        = 0x0000FFFF,   /* Transmit Frame Length */
187         TxflSHIFT       = 0,
188         Tcps            = 0x00010000,   /* TCP Checksum Offload */
189         Udpcs           = 0x00020000,   /* UDP Checksum Offload */
190         Ipcs            = 0x00040000,   /* IP Checksum Offload */
191         Lgsen           = 0x08000000,   /* TSO; WARNING: contains lark's vomit */
192 };
193
194 enum {                                  /* Receive Descriptor control */
195         RxflMASK        = 0x00001FFF,   /* Receive Frame Length */
196         Tcpf            = 0x00004000,   /* TCP Checksum Failure */
197         Udpf            = 0x00008000,   /* UDP Checksum Failure */
198         Ipf             = 0x00010000,   /* IP Checksum Failure */
199         Pid0            = 0x00020000,   /* Protocol ID0 */
200         Pid1            = 0x00040000,   /* Protocol ID1 */
201         Crce            = 0x00080000,   /* CRC Error */
202         Runt            = 0x00100000,   /* Runt Packet */
203         Res             = 0x00200000,   /* Receive Error Summary */
204         Rwt             = 0x00400000,   /* Receive Watchdog Timer Expired */
205         Fovf            = 0x00800000,   /* FIFO Overflow */
206         Bovf            = 0x01000000,   /* Buffer Overflow */
207         Bar             = 0x02000000,   /* Broadcast Address Received */
208         Pam             = 0x04000000,   /* Physical Address Matched */
209         Mar             = 0x08000000,   /* Multicast Address Received */
210 };
211
212 enum {                                  /* General Descriptor control */
213         Ls              = 0x10000000,   /* Last Segment Descriptor */
214         Fs              = 0x20000000,   /* First Segment Descriptor */
215         Eor             = 0x40000000,   /* End of Descriptor Ring */
216         Own             = 0x80000000,   /* Ownership */
217 };
218
219 /*
220  */
221 enum {                                  /* Ring sizes  (<= 1024) */
222         Ntd             = 64,           /* Transmit Ring */
223         Nrd             = 256,          /* Receive Ring */
224
225         Mtu             = ETHERMAXTU,
226         Mps             = ROUNDUP(ETHERMAXTU+4, 128),
227 };
228
229 typedef struct Dtcc Dtcc;
230 struct Dtcc {
231         u64int  txok;
232         u64int  rxok;
233         u64int  txer;
234         u32int  rxer;
235         u16int  misspkt;
236         u16int  fae;
237         u32int  tx1col;
238         u32int  txmcol;
239         u64int  rxokph;
240         u64int  rxokbrd;
241         u32int  rxokmu;
242         u16int  txabt;
243         u16int  txundrn;
244 };
245
246 enum {                                          /* Variants */
247         Rtl8100e        = (0x8136<<16)|0x10EC,  /* RTL810[01]E: pci -e */
248         Rtl8169c        = (0x0116<<16)|0x16EC,  /* RTL8169C+ (USR997902) */
249         Rtl8169sc       = (0x8167<<16)|0x10EC,  /* RTL8169SC */
250         Rtl8168b        = (0x8168<<16)|0x10EC,  /* RTL8168B: pci-e */
251         Rtl8169         = (0x8169<<16)|0x10EC,  /* RTL8169 */
252 };
253
254 typedef struct Ctlr Ctlr;
255 typedef struct Ctlr {
256         Lock;
257
258         int     port;
259         Pcidev* pcidev;
260         Ctlr*   next;
261         int     active;
262
263         QLock   alock;                  /* attach */
264         int     init;                   /*  */
265         Rendez  reset;
266
267         int     pciv;                   /*  */
268         int     macv;                   /* MAC version */
269         int     phyv;                   /* PHY version */
270         int     pcie;                   /* flag: pci-express device? */
271
272         uvlong  mchash;                 /* multicast hash */
273
274         Mii*    mii;
275
276         D*      td;                     /* descriptor ring */
277         Block** tb;                     /* transmit buffers */
278         int     ntd;
279
280         int     tdh;                    /* head - producer index (host) */
281         int     tdt;                    /* tail - consumer index (NIC) */
282         int     ntq;
283
284         D*      rd;                     /* descriptor ring */
285         Block** rb;                     /* receive buffers */
286         int     nrd;
287
288         int     rdh;                    /* head - producer index (NIC) */
289         int     rdt;                    /* tail - consumer index (host) */
290         int     nrq;
291
292         int     tcr;                    /* transmit configuration register */
293         int     rcr;                    /* receive configuration register */
294         int     imr;
295
296         QLock   slock;                  /* statistics */
297         Dtcc*   dtcc;
298         uint    txdu;
299         uint    tcpf;
300         uint    udpf;
301         uint    ipf;
302         uint    fovf;
303         uint    rer;
304         uint    rdu;
305         uint    punlc;
306         uint    serr;
307         uint    fovw;
308         uint    mcast;
309         uint    frag;                   /* partial packets; rb was too small */
310 } Ctlr;
311
312 static Ctlr* rtl8169ctlrhead;
313 static Ctlr* rtl8169ctlrtail;
314
315 #define csr8r(c, r)     (inb((c)->port+(r)))
316 #define csr16r(c, r)    (ins((c)->port+(r)))
317 #define csr32r(c, r)    (inl((c)->port+(r)))
318 #define csr8w(c, r, b)  (outb((c)->port+(r), (u8int)(b)))
319 #define csr16w(c, r, w) (outs((c)->port+(r), (u16int)(w)))
320 #define csr32w(c, r, l) (outl((c)->port+(r), (u32int)(l)))
321
322 static int
323 rtl8169miimir(Mii* mii, int pa, int ra)
324 {
325         uint r;
326         int timeo;
327         Ctlr *ctlr;
328
329         if(pa != 1)
330                 return -1;
331         ctlr = mii->ctlr;
332
333         r = (ra<<16) & RegaddrMASK;
334         csr32w(ctlr, Phyar, r);
335         delay(1);
336         for(timeo = 0; timeo < 2000; timeo++){
337                 if((r = csr32r(ctlr, Phyar)) & Flag)
338                         break;
339                 microdelay(100);
340         }
341         if(!(r & Flag))
342                 return -1;
343
344         return (r & DataMASK)>>DataSHIFT;
345 }
346
347 static int
348 rtl8169miimiw(Mii* mii, int pa, int ra, int data)
349 {
350         uint r;
351         int timeo;
352         Ctlr *ctlr;
353
354         if(pa != 1)
355                 return -1;
356         ctlr = mii->ctlr;
357
358         r = Flag|((ra<<16) & RegaddrMASK)|((data<<DataSHIFT) & DataMASK);
359         csr32w(ctlr, Phyar, r);
360         delay(1);
361         for(timeo = 0; timeo < 2000; timeo++){
362                 if(!((r = csr32r(ctlr, Phyar)) & Flag))
363                         break;
364                 microdelay(100);
365         }
366         if(r & Flag)
367                 return -1;
368
369         return 0;
370 }
371
372 static int
373 rtl8169mii(Ctlr* ctlr)
374 {
375         MiiPhy *phy;
376
377         /*
378          * Link management.
379          */
380         if((ctlr->mii = malloc(sizeof(Mii))) == nil)
381                 return -1;
382         ctlr->mii->mir = rtl8169miimir;
383         ctlr->mii->miw = rtl8169miimiw;
384         ctlr->mii->ctlr = ctlr;
385
386         /*
387          * Get rev number out of Phyidr2 so can config properly.
388          * There's probably more special stuff for Macv0[234] needed here.
389          */
390         ctlr->phyv = rtl8169miimir(ctlr->mii, 1, Phyidr2) & 0x0F;
391         if(ctlr->macv == Macv02){
392                 csr8w(ctlr, 0x82, 1);                           /* magic */
393                 rtl8169miimiw(ctlr->mii, 1, 0x0B, 0x0000);      /* magic */
394         }
395
396         if(mii(ctlr->mii, (1<<1)) == 0 || (phy = ctlr->mii->curphy) == nil){
397                 free(ctlr->mii);
398                 ctlr->mii = nil;
399                 return -1;
400         }
401         print("rtl8169: oui %#ux phyno %d, macv = %#8.8ux phyv = %#4.4ux\n",
402                 phy->oui, phy->phyno, ctlr->macv, ctlr->phyv);
403
404         miiane(ctlr->mii, ~0, ~0, ~0);
405
406         return 0;
407 }
408
409 static void
410 rtl8169promiscuous(void* arg, int on)
411 {
412         Ether *edev;
413         Ctlr * ctlr;
414
415         edev = arg;
416         ctlr = edev->ctlr;
417         ilock(ctlr);
418         if(on)
419                 ctlr->rcr |= Aap;
420         else
421                 ctlr->rcr &= ~Aap;
422         csr32w(ctlr, Rcr, ctlr->rcr);
423         iunlock(ctlr);
424 }
425
426 enum {
427         /* everyone else uses 0x04c11db7, but they both produce the same crc */
428         Etherpolybe = 0x04c11db6,
429         Bytemask = (1<<8) - 1,
430 };
431
432 static ulong
433 ethercrcbe(uchar *addr, long len)
434 {
435         int i, j;
436         ulong c, crc, carry;
437
438         crc = ~0UL;
439         for (i = 0; i < len; i++) {
440                 c = addr[i];
441                 for (j = 0; j < 8; j++) {
442                         carry = ((crc & (1UL << 31))? 1: 0) ^ (c & 1);
443                         crc <<= 1;
444                         c >>= 1;
445                         if (carry)
446                                 crc = (crc ^ Etherpolybe) | carry;
447                 }
448         }
449         return crc;
450 }
451
452 static ulong
453 swabl(ulong l)
454 {
455         return l>>24 | (l>>8) & (Bytemask<<8) |
456                 (l<<8) & (Bytemask<<16) | l<<24;
457 }
458
459 static void
460 rtl8169multicast(void* ether, uchar *eaddr, int add)
461 {
462         Ether *edev;
463         Ctlr *ctlr;
464
465         if (!add)
466                 return; /* ok to keep receiving on old mcast addrs */
467
468         edev = ether;
469         ctlr = edev->ctlr;
470         ilock(ctlr);
471
472         ctlr->mchash |= 1ULL << (ethercrcbe(eaddr, Eaddrlen) >> 26);
473
474         ctlr->rcr |= Am;
475         csr32w(ctlr, Rcr, ctlr->rcr);
476
477         /* pci-e variants reverse the order of the hash byte registers */
478         if (ctlr->pcie) {
479                 csr32w(ctlr, Mar0,   swabl(ctlr->mchash>>32));
480                 csr32w(ctlr, Mar0+4, swabl(ctlr->mchash));
481         } else {
482                 csr32w(ctlr, Mar0,   ctlr->mchash);
483                 csr32w(ctlr, Mar0+4, ctlr->mchash>>32);
484         }
485
486         iunlock(ctlr);
487 }
488
489 static long
490 rtl8169ifstat(Ether* edev, void* a, long n, ulong offset)
491 {
492         char *p;
493         Ctlr *ctlr;
494         Dtcc *dtcc;
495         int i, l, r, timeo;
496
497         p = smalloc(READSTR);
498
499         ctlr = edev->ctlr;
500         qlock(&ctlr->slock);
501
502         if(waserror()){
503                 qunlock(&ctlr->slock);
504                 free(p);
505                 nexterror();
506         }
507
508         csr32w(ctlr, Dtccr+4, 0);
509         csr32w(ctlr, Dtccr, PCIWADDR(ctlr->dtcc)|Cmd);
510         for(timeo = 0; timeo < 1000; timeo++){
511                 if(!(csr32r(ctlr, Dtccr) & Cmd))
512                         break;
513                 delay(1);
514         }
515         if(csr32r(ctlr, Dtccr) & Cmd)
516                 error(Eio);
517         dtcc = ctlr->dtcc;
518
519         edev->oerrs = dtcc->txer;
520         edev->crcs = dtcc->rxer;
521         edev->frames = dtcc->fae;
522         edev->buffs = dtcc->misspkt;
523         edev->overflows = ctlr->txdu+ctlr->rdu;
524
525         if(n == 0){
526                 qunlock(&ctlr->slock);
527                 poperror();
528                 free(p);
529                 return 0;
530         }
531
532         l = snprint(p, READSTR, "TxOk: %llud\n", dtcc->txok);
533         l += snprint(p+l, READSTR-l, "RxOk: %llud\n", dtcc->rxok);
534         l += snprint(p+l, READSTR-l, "TxEr: %llud\n", dtcc->txer);
535         l += snprint(p+l, READSTR-l, "RxEr: %ud\n", dtcc->rxer);
536         l += snprint(p+l, READSTR-l, "MissPkt: %ud\n", dtcc->misspkt);
537         l += snprint(p+l, READSTR-l, "FAE: %ud\n", dtcc->fae);
538         l += snprint(p+l, READSTR-l, "Tx1Col: %ud\n", dtcc->tx1col);
539         l += snprint(p+l, READSTR-l, "TxMCol: %ud\n", dtcc->txmcol);
540         l += snprint(p+l, READSTR-l, "RxOkPh: %llud\n", dtcc->rxokph);
541         l += snprint(p+l, READSTR-l, "RxOkBrd: %llud\n", dtcc->rxokbrd);
542         l += snprint(p+l, READSTR-l, "RxOkMu: %ud\n", dtcc->rxokmu);
543         l += snprint(p+l, READSTR-l, "TxAbt: %ud\n", dtcc->txabt);
544         l += snprint(p+l, READSTR-l, "TxUndrn: %ud\n", dtcc->txundrn);
545
546         l += snprint(p+l, READSTR-l, "serr: %ud\n", ctlr->serr);
547         l += snprint(p+l, READSTR-l, "fovw: %ud\n", ctlr->fovw);
548
549         l += snprint(p+l, READSTR-l, "txdu: %ud\n", ctlr->txdu);
550         l += snprint(p+l, READSTR-l, "tcpf: %ud\n", ctlr->tcpf);
551         l += snprint(p+l, READSTR-l, "udpf: %ud\n", ctlr->udpf);
552         l += snprint(p+l, READSTR-l, "ipf: %ud\n", ctlr->ipf);
553         l += snprint(p+l, READSTR-l, "fovf: %ud\n", ctlr->fovf);
554         l += snprint(p+l, READSTR-l, "rer: %ud\n", ctlr->rer);
555         l += snprint(p+l, READSTR-l, "rdu: %ud\n", ctlr->rdu);
556         l += snprint(p+l, READSTR-l, "punlc: %ud\n", ctlr->punlc);
557
558         l += snprint(p+l, READSTR-l, "tcr: %#8.8ux\n", ctlr->tcr);
559         l += snprint(p+l, READSTR-l, "rcr: %#8.8ux\n", ctlr->rcr);
560         l += snprint(p+l, READSTR-l, "multicast: %ud\n", ctlr->mcast);
561
562         if(ctlr->mii != nil && ctlr->mii->curphy != nil){
563                 l += snprint(p+l, READSTR, "phy:   ");
564                 for(i = 0; i < NMiiPhyr; i++){
565                         if(i && ((i & 0x07) == 0))
566                                 l += snprint(p+l, READSTR-l, "\n       ");
567                         r = miimir(ctlr->mii, i);
568                         l += snprint(p+l, READSTR-l, " %4.4ux", r);
569                 }
570                 snprint(p+l, READSTR-l, "\n");
571         }
572
573         n = readstr(offset, a, n, p);
574
575         qunlock(&ctlr->slock);
576         poperror();
577         free(p);
578
579         return n;
580 }
581
582 static void
583 rtl8169halt(Ctlr* ctlr)
584 {
585         csr8w(ctlr, Cr, 0);
586         csr16w(ctlr, Imr, 0);
587         csr16w(ctlr, Isr, ~0);
588 }
589
590 static int
591 rtl8169reset(Ctlr* ctlr)
592 {
593         u32int r;
594         int timeo;
595
596         /*
597          * Soft reset the controller.
598          */
599         csr8w(ctlr, Cr, Rst);
600         for(r = timeo = 0; timeo < 1000; timeo++){
601                 r = csr8r(ctlr, Cr);
602                 if(!(r & Rst))
603                         break;
604                 delay(1);
605         }
606         rtl8169halt(ctlr);
607
608         if(r & Rst)
609                 return -1;
610         return 0;
611 }
612
613 static void
614 rtl8169replenish(Ctlr* ctlr)
615 {
616         D *d;
617         int x;
618         Block *bp;
619
620         x = ctlr->rdt;
621         while(NEXT(x, ctlr->nrd) != ctlr->rdh){
622                 bp = iallocb(Mps);
623                 if(bp == nil){
624                         iprint("rtl8169: no available buffers\n");
625                         break;
626                 }
627                 ctlr->rb[x] = bp;
628                 ctlr->nrq++;
629                 d = &ctlr->rd[x];
630                 d->addrlo = PCIWADDR(bp->rp);
631                 d->addrhi = 0;
632                 coherence();
633                 d->control = (d->control & Eor) | Own | BALLOC(bp);
634                 x = NEXT(x, ctlr->nrd);
635                 ctlr->rdt = x;
636         }
637 }
638
639 static int
640 rtl8169init(Ether* edev)
641 {
642         int i;
643         u32int r;
644         Block *bp;
645         Ctlr *ctlr;
646         u8int cplusc;
647
648         ctlr = edev->ctlr;
649         ilock(ctlr);
650
651         rtl8169reset(ctlr);
652
653         memset(ctlr->td, 0, sizeof(D)*ctlr->ntd);
654         ctlr->tdh = ctlr->tdt = ctlr->ntq = 0;
655         ctlr->td[ctlr->ntd-1].control = Eor;
656         for(i = 0; i < ctlr->ntd; i++)
657                 if(bp = ctlr->tb[i]){
658                         ctlr->tb[i] = nil;
659                         freeb(bp);
660                 }
661
662         memset(ctlr->rd, 0, sizeof(D)*ctlr->nrd);
663         ctlr->rdh = ctlr->rdt = ctlr->nrq = 0;
664         ctlr->rd[ctlr->nrd-1].control = Eor;
665         for(i = 0; i < ctlr->nrd; i++)
666                 if(bp = ctlr->rb[i]){
667                         ctlr->rb[i] = nil;
668                         freeb(bp);
669                 }
670
671         rtl8169replenish(ctlr);
672
673         cplusc = csr16r(ctlr, Cplusc);
674         cplusc &= ~(Endian|Rxchksum);
675         cplusc |= Txenb|Rxenb|Mulrw;
676         csr16w(ctlr, Cplusc, cplusc);
677
678         csr32w(ctlr, Tnpds+4, 0);
679         csr32w(ctlr, Tnpds, PCIWADDR(ctlr->td));
680         csr32w(ctlr, Rdsar+4, 0);
681         csr32w(ctlr, Rdsar, PCIWADDR(ctlr->rd));
682
683         csr8w(ctlr, Cr, Te|Re);
684
685         csr32w(ctlr, Tcr, Ifg1|Ifg0|Mtxdmaunlimited);
686         ctlr->tcr = csr32r(ctlr, Tcr);
687         ctlr->rcr = Rxfthnone|Mrxdmaunlimited|Ab|Am|Apm;
688         ctlr->mchash = 0;
689         csr32w(ctlr, Mar0,   0);
690         csr32w(ctlr, Mar0+4, 0);
691         csr32w(ctlr, Rcr, ctlr->rcr);
692
693         /* maximum packet sizes, unlimited */
694         csr8w(ctlr, Etx, 0x3f);
695         csr16w(ctlr, Rms, 0x3fff);
696
697         csr16w(ctlr, Coal, 0);
698
699         /* no early rx interrupts */
700         r = csr16r(ctlr, Mulint) & 0xF000;
701         csr16w(ctlr, Mulint, r);
702
703         ctlr->imr = Serr|Fovw|Punlc|Rdu|Ter|Rer|Rok|Tdu;
704         csr16w(ctlr, Imr, ctlr->imr);
705
706         csr32w(ctlr, Mpc, 0);
707
708         iunlock(ctlr);
709
710         return 0;
711 }
712
713 static void
714 rtl8169reseter(void *arg)
715 {
716         Ether *edev;
717         Ctlr *ctlr;
718
719         edev = arg;
720
721         for(;;){
722                 rtl8169init(edev);
723
724                 ctlr = edev->ctlr;
725                 qunlock(&ctlr->alock);
726
727                 while(waserror())
728                         ;
729                 sleep(&ctlr->reset, return0, nil);
730                 poperror();
731
732                 qlock(&ctlr->alock);
733         }
734 }
735
736 static void
737 rtl8169attach(Ether* edev)
738 {
739         int timeo;
740         Ctlr *ctlr;
741
742         ctlr = edev->ctlr;
743         qlock(&ctlr->alock);
744         if(ctlr->init++ == 0){
745                 ctlr->td = mallocalign(sizeof(D)*Ntd, 256, 0, 0);
746                 ctlr->tb = malloc(Ntd*sizeof(Block*));
747                 ctlr->ntd = Ntd;
748                 ctlr->rd = mallocalign(sizeof(D)*Nrd, 256, 0, 0);
749                 ctlr->rb = malloc(Nrd*sizeof(Block*));
750                 ctlr->nrd = Nrd;
751                 ctlr->dtcc = mallocalign(sizeof(Dtcc), 64, 0, 0);
752
753                 kproc("rtl8169", rtl8169reseter, edev);
754                 qlock(&ctlr->alock);
755         }
756         qunlock(&ctlr->alock);
757
758         /*
759          * Wait for link to be ready.
760          */
761         for(timeo = 0; timeo < 35; timeo++){
762                 if(miistatus(ctlr->mii) == 0)
763                         break;
764                 delay(100);             /* print fewer miistatus messages */
765         }
766 }
767
768 static void
769 rtl8169link(Ether* edev)
770 {
771         uint r;
772         int limit;
773         Ctlr *ctlr;
774
775         ctlr = edev->ctlr;
776
777         /*
778          * Maybe the link changed - do we care very much?
779          * Could stall transmits if no link, maybe?
780          */
781         if(!((r = csr8r(ctlr, Phystatus)) & Linksts)){
782                 edev->link = 0;
783                 return;
784         }
785         edev->link = 1;
786
787         limit = 256*1024;
788         if(r & Speed10){
789                 edev->mbps = 10;
790                 limit = 65*1024;
791         } else if(r & Speed100)
792                 edev->mbps = 100;
793         else if(r & Speed1000)
794                 edev->mbps = 1000;
795
796         if(edev->oq != nil)
797                 qsetlimit(edev->oq, limit);
798 }
799
800 static void
801 rtl8169transmit(Ether* edev)
802 {
803         D *d;
804         Block *bp;
805         Ctlr *ctlr;
806         int x;
807
808         ctlr = edev->ctlr;
809
810         if(!canlock(ctlr))
811                 return;
812         for(x = ctlr->tdh; ctlr->ntq > 0; x = NEXT(x, ctlr->ntd)){
813                 d = &ctlr->td[x];
814                 if(d->control & Own)
815                         break;
816
817                 /*
818                  * Free it up.
819                  * Need to clean the descriptor here? Not really.
820                  * Simple freeb for now (no chain and freeblist).
821                  * Use ntq count for now.
822                  */
823                 freeb(ctlr->tb[x]);
824                 ctlr->tb[x] = nil;
825                 ctlr->ntq--;
826         }
827         ctlr->tdh = x;
828
829         x = ctlr->tdt;
830         while(ctlr->ntq < (ctlr->ntd-1)){
831                 if((bp = qget(edev->oq)) == nil)
832                         break;
833
834                 d = &ctlr->td[x];
835                 d->addrlo = PCIWADDR(bp->rp);
836                 d->addrhi = 0;
837                 coherence();
838                 d->control = (d->control & Eor) | Own | Fs | Ls | BLEN(bp);
839
840                 ctlr->tb[x] = bp;
841                 ctlr->ntq++;
842
843                 x = NEXT(x, ctlr->ntd);
844         }
845         if(x != ctlr->tdt)
846                 ctlr->tdt = x;
847         else if(ctlr->ntq >= (ctlr->ntd-1))
848                 ctlr->txdu++;
849
850         if(ctlr->ntq > 0){
851                 coherence();
852                 csr8w(ctlr, Tppoll, Npq);
853         }
854         unlock(ctlr);
855 }
856
857 static void
858 rtl8169receive(Ether* edev)
859 {
860         D *d;
861         Block *bp;
862         Ctlr *ctlr;
863         u32int control;
864         int x;
865
866         ctlr = edev->ctlr;
867         x = ctlr->rdh;
868         for(;;){
869                 d = &ctlr->rd[x];
870                 if((control = d->control) & Own)
871                         break;
872
873                 bp = ctlr->rb[x];
874                 ctlr->rb[x] = nil;
875                 ctlr->nrq--;
876
877                 x = NEXT(x, ctlr->nrd);
878                 ctlr->rdh = x;
879
880                 if(ctlr->nrq < ctlr->nrd/2)
881                         rtl8169replenish(ctlr);
882
883                 if((control & (Fs|Ls|Res)) == (Fs|Ls)){
884                         bp->wp = bp->rp + (control & RxflMASK) - 4;
885
886                         if(control & Fovf)
887                                 ctlr->fovf++;
888                         if(control & Mar)
889                                 ctlr->mcast++;
890
891                         switch(control & (Pid1|Pid0)){
892                         default:
893                                 break;
894                         case Pid0:
895                                 if(control & Tcpf){
896                                         ctlr->tcpf++;
897                                         break;
898                                 }
899                                 bp->flag |= Btcpck;
900                                 break;
901                         case Pid1:
902                                 if(control & Udpf){
903                                         ctlr->udpf++;
904                                         break;
905                                 }
906                                 bp->flag |= Budpck;
907                                 break;
908                         case Pid1|Pid0:
909                                 if(control & Ipf){
910                                         ctlr->ipf++;
911                                         break;
912                                 }
913                                 bp->flag |= Bipck;
914                                 break;
915                         }
916                         etheriq(edev, bp, 1);
917                 }else{
918                         if(!(control & Res))
919                                 ctlr->frag++;
920                         freeb(bp);
921                 }
922         }
923 }
924
925 static void
926 rtl8169restart(Ctlr *ctlr)
927 {
928         ctlr->imr = 0;
929         rtl8169halt(ctlr);
930         wakeup(&ctlr->reset);
931 }
932
933 static void
934 rtl8169interrupt(Ureg*, void* arg)
935 {
936         Ctlr *ctlr;
937         Ether *edev;
938         u32int isr;
939
940         edev = arg;
941         ctlr = edev->ctlr;
942
943         while((isr = csr16r(ctlr, Isr)) != 0 && isr != 0xFFFF){
944                 csr16w(ctlr, Isr, isr);
945                 if((isr & ctlr->imr) == 0)
946                         break;
947
948                 if(isr & Serr)
949                         ctlr->serr++;
950                 if(isr & Fovw)
951                         ctlr->fovw++;
952                 if(isr & Rer)
953                         ctlr->rer++;
954                 if(isr & Rdu)
955                         ctlr->rdu++;
956                 if(isr & Punlc)
957                         ctlr->punlc++;
958
959                 if(isr & (Serr|Fovw)){
960                         rtl8169restart(ctlr);
961                         break;
962                 }
963
964                 if(isr & (Punlc|Rdu|Rer|Rok))
965                         rtl8169receive(edev);
966
967                 if(isr & (Tdu|Ter|Tok))
968                         rtl8169transmit(edev);
969
970                 if(isr & Punlc)
971                         rtl8169link(edev);
972         }
973 }
974
975 int
976 vetmacv(Ctlr *ctlr, uint *macv)
977 {
978         *macv = csr32r(ctlr, Tcr) & HwveridMASK;
979         switch(*macv){
980         default:
981                 return -1;
982         case Macv01:
983         case Macv02:
984         case Macv03:
985         case Macv04:
986         case Macv05:
987         case Macv07:
988         case Macv07a:
989         case Macv11:
990         case Macv12:
991         case Macv12a:
992         case Macv13:
993         case Macv14:
994         case Macv15:
995         case Macv25:
996                 break;
997         }
998         return 0;
999 }
1000
1001 static void
1002 rtl8169pci(void)
1003 {
1004         Pcidev *p;
1005         Ctlr *ctlr;
1006         int i, port, pcie;
1007         uint macv;
1008
1009         p = nil;
1010         while(p = pcimatch(p, 0, 0)){
1011                 if(p->ccrb != 0x02 || p->ccru != 0)
1012                         continue;
1013
1014                 pcie = 0;
1015                 switch(i = ((p->did<<16)|p->vid)){
1016                 default:
1017                         continue;
1018                 case Rtl8100e:                  /* RTL810[01]E ? */
1019                 case Rtl8168b:                  /* RTL8168B */
1020                         pcie = 1;
1021                         break;
1022                 case Rtl8169c:                  /* RTL8169C */
1023                 case Rtl8169sc:                 /* RTL8169SC */
1024                 case Rtl8169:                   /* RTL8169 */
1025                         break;
1026                 case (0xC107<<16)|0x1259:       /* Corega CG-LAPCIGT */
1027                         i = Rtl8169;
1028                         break;
1029                 }
1030
1031                 port = p->mem[0].bar & ~0x01;
1032                 if(ioalloc(port, p->mem[0].size, 0, "rtl8169") < 0){
1033                         print("rtl8169: port %#ux in use\n", port);
1034                         continue;
1035                 }
1036                 ctlr = malloc(sizeof(Ctlr));
1037                 ctlr->port = port;
1038                 ctlr->pcidev = p;
1039                 ctlr->pciv = i;
1040                 ctlr->pcie = pcie;
1041
1042                 if(vetmacv(ctlr, &macv) == -1){
1043                         iofree(port);
1044                         free(ctlr);
1045                         print("rtl8169: unknown mac %.4ux %.8ux\n", p->did, macv);
1046                         continue;
1047                 }
1048
1049                 if(pcigetpms(p) > 0){
1050                         pcisetpms(p, 0);
1051
1052                         for(i = 0; i < 6; i++)
1053                                 pcicfgw32(p, PciBAR0+i*4, p->mem[i].bar);
1054                         pcicfgw8(p, PciINTL, p->intl);
1055                         pcicfgw8(p, PciLTR, p->ltr);
1056                         pcicfgw8(p, PciCLS, p->cls);
1057                         pcicfgw16(p, PciPCR, p->pcr);
1058                 }
1059
1060                 if(rtl8169reset(ctlr)){
1061                         iofree(port);
1062                         free(ctlr);
1063                         print("rtl8169: reset failed\n");
1064                         continue;
1065                 }
1066
1067                 /*
1068                  * Extract the chip hardware version,
1069                  * needed to configure each properly.
1070                  */
1071                 ctlr->macv = macv;
1072
1073                 rtl8169mii(ctlr);
1074
1075                 pcisetbme(p);
1076
1077                 if(rtl8169ctlrhead != nil)
1078                         rtl8169ctlrtail->next = ctlr;
1079                 else
1080                         rtl8169ctlrhead = ctlr;
1081                 rtl8169ctlrtail = ctlr;
1082         }
1083 }
1084
1085 static int
1086 rtl8169pnp(Ether* edev)
1087 {
1088         u32int r;
1089         Ctlr *ctlr;
1090         uchar ea[Eaddrlen];
1091         static int once;
1092
1093         if(once == 0){
1094                 once = 1;
1095                 rtl8169pci();
1096         }
1097
1098         /*
1099          * Any adapter matches if no edev->port is supplied,
1100          * otherwise the ports must match.
1101          */
1102         for(ctlr = rtl8169ctlrhead; ctlr != nil; ctlr = ctlr->next){
1103                 if(ctlr->active)
1104                         continue;
1105                 if(edev->port == 0 || edev->port == ctlr->port){
1106                         ctlr->active = 1;
1107                         break;
1108                 }
1109         }
1110         if(ctlr == nil)
1111                 return -1;
1112
1113         edev->ctlr = ctlr;
1114         edev->port = ctlr->port;
1115         edev->irq = ctlr->pcidev->intl;
1116         edev->tbdf = ctlr->pcidev->tbdf;
1117         edev->mbps = 100;
1118         edev->maxmtu = Mtu;
1119
1120         /*
1121          * Check if the adapter's station address is to be overridden.
1122          * If not, read it from the device and set in edev->ea.
1123          */
1124         memset(ea, 0, Eaddrlen);
1125         if(memcmp(ea, edev->ea, Eaddrlen) == 0){
1126                 r = csr32r(ctlr, Idr0);
1127                 edev->ea[0] = r;
1128                 edev->ea[1] = r>>8;
1129                 edev->ea[2] = r>>16;
1130                 edev->ea[3] = r>>24;
1131                 r = csr32r(ctlr, Idr0+4);
1132                 edev->ea[4] = r;
1133                 edev->ea[5] = r>>8;
1134         }
1135
1136         edev->attach = rtl8169attach;
1137         edev->transmit = rtl8169transmit;
1138         edev->interrupt = rtl8169interrupt;
1139         edev->ifstat = rtl8169ifstat;
1140
1141         edev->arg = edev;
1142         edev->promiscuous = rtl8169promiscuous;
1143         edev->multicast = rtl8169multicast;
1144
1145         rtl8169link(edev);
1146
1147         return 0;
1148 }
1149
1150 void
1151 ether8169link(void)
1152 {
1153         addethercard("rtl8169", rtl8169pnp);
1154 }