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